CN107506644B - 动态生成代码中隐式常数威胁的安全保护方法 - Google Patents
动态生成代码中隐式常数威胁的安全保护方法 Download PDFInfo
- Publication number
- CN107506644B CN107506644B CN201710703706.8A CN201710703706A CN107506644B CN 107506644 B CN107506644 B CN 107506644B CN 201710703706 A CN201710703706 A CN 201710703706A CN 107506644 B CN107506644 B CN 107506644B
- Authority
- CN
- China
- Prior art keywords
- implicit
- register
- linked list
- code
- instruction
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F21/00—Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
- G06F21/50—Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
- G06F21/55—Detecting local intrusion or implementing counter-measures
- G06F21/56—Computer malware detection or handling, e.g. anti-virus arrangements
- G06F21/562—Static detection
- G06F21/563—Static detection by source code analysis
Landscapes
- Engineering & Computer Science (AREA)
- Computer Security & Cryptography (AREA)
- Software Systems (AREA)
- Computer Hardware Design (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Virology (AREA)
- Health & Medical Sciences (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- General Health & Medical Sciences (AREA)
- Devices For Executing Special Programs (AREA)
- Executing Machine-Instructions (AREA)
Abstract
本发明公开了一种动态生成代码中隐式常数威胁的安全保护方法,包括采用寄存器动态随机化方法变换动态生成代码中的隐式常数;在动态生成代码中收集到所有直接call指令与直接jmp指令,将直接call指令与直接jmp指令保存到链表;查找链表中隐式常数中是否包含控制流转移指令编码,删除链表中没有控制流转移指令编码的隐式常数;对链表中隐式常数中的控制流转移指令编码所在位置之前的字节序列进行反汇编,确定隐式常数中是否包含有效的代码片段;删除链表中不包含有效的代码片段的隐式常数;定位代码缓存区中存在有害隐式常数的位置,在该位置对包含有害隐式常数的直接跳转指令进行改写;本方法消除了动态生成代码中隐式常数的威胁。
Description
技术领域
本发明涉及动态生成代码中针对代码复用攻击的安全保护方法技术领域,特别涉及一种动态生成代码中隐式常数威胁的安全保护方法。
背景技术
在传统的静态代码上实施代码复用攻击,攻击者需要耐心且细致地去寻找能够被复用的代码片段。然而在即时编译执行环境,攻击者可以通过操控脚本代码中的内容,将攻击所需的代码片段有目的地编码到动态生成代码的隐式常数中,随后通过劫持程序的控制流,解码出这些代码片段以完成后续的代码复用攻击。这种利用动态生成代码中隐式常数来组织代码片段,从而实施代码复用攻击的方式严重威胁着浏览器的运行安全。因此,对动态生成代码中的隐式常数实施有针对性的保护,对于缓解动态生成代码中的代码复用攻击具有非常现实的意义,能够有效地阻止攻击行为,从而提升浏览器的安全性,因此目前需要一种动态生成代码中隐式常数威胁的安全保护方法。
发明内容
本发明所要解决的技术问题是针对上述现有技术的不足提供一种动态生成代码中隐式常数威胁的安全保护方法,本动态生成代码中隐式常数威胁的安全保护方法在动态代码的生成过程中变换隐式常数,之后对动态生成代码中的隐式常数进行进一步的检查,根据检查的结果,对其中有害的隐式常数进行隐藏处理,既消除了动态生成代码中隐式常数的威胁,又减少了系统整体的性能开销。
为实现上述技术目的,本发明采取的技术方案为:
一种动态生成代码中隐式常数威胁的安全保护方法,包括以下步骤:步骤1:采用寄存器动态随机化方法变换动态生成代码中的隐式常数;步骤2:在动态生成代码中收集到所有的直接call指令与直接跳转指令,将直接call指令与直接跳转指令保存在链表中;
步骤3:查找链表中的隐式常数中是否包含控制流转移指令编码,删除链表中没有控制流转移指令编码的隐式常数并确定控制流转移指令编码在每个隐式常数中的位置;
步骤4:对链表中每个隐式常数中的控制流转移指令编码所在位置之前的字节序列进行反汇编,确定隐式常数中是否包含有效的代码片段;
步骤5:删除链表中不包含有效的代码片段的隐式常数,链表中剩余的隐式常数均为有害隐式常数;
步骤6:定位代码缓存区中存在有害隐式常数的位置,在该位置对包含有害隐式常数的直接跳转指令进行改写,使改写后的动态生成代码中有害隐式常数被隐藏在寄存器中。
作为本发明进一步改进的技术方案,所述的步骤1中的寄存器动态随机化方法具体包括以下步骤:
(a)从无前缀寄存器集合中随机选择一个寄存器;
(b)判断步骤(a)中选择的寄存器是否被选择过,若已选择过,则执行步骤(a)从而重新选择一个寄存器;否则执行步骤(c);
(c)从有前缀寄存器集合中随机选择一个寄存器;
(d)判断步骤(c)中选择的寄存器是否被选择过,若已选择过,则执行步骤(c)从而重新选择一个寄存器;否则执行步骤(e);
(e)将步骤(a)选择的寄存器和步骤(c)选择的寄存器组成一个寄存器对放到表示置换规则的集合中;
(f)判断是否需要在表示置换规则的集合中添加新的置换规则,若需要,则执行步骤(a),从而开始选择寄存器;否则执行步骤(g);
(g)根据置换规则对动态生成代码中的寄存器进行置换。
作为本发明进一步改进的技术方案,所述的步骤2具体包括以下步骤:
(a)将寄存器动态随机化后的动态生成代码转储到磁盘文件中;
(b)判断动态生成代码是否成功转储到磁盘文件中,若转储失败,则执行步骤2中的步骤(a)从而重新转储;否则执行步骤2中的步骤(c);
(c)搜索动态生成代码中所有call指令与跳转指令;
(d)去除所有的间接call指令与间接跳转指令,得到所有的直接call指令与直接跳转指令;
(e)将步骤2中的步骤(d)得到的结果保存到链表中。
作为本发明进一步改进的技术方案,所述的链表中节点信息包括指令在动态生成代码中的偏移量、隐式常数的字符串表示、一个用于表示隐式常数中控制流转移指令编码的位置的整型值和一个用于表示隐式常数是否有害的布尔值。
作为本发明进一步改进的技术方案,所述控制流转移指令编码为ret指令编码。
作为本发明进一步改进的技术方案,所述的步骤3具体包括以下步骤:
(a)获取步骤2得到的链表的头节点指针;
(b)判断链表的指针是否为空指针,若为空,则结束;否则执行步骤3中的步骤(c);
(c)调用自定义函数,通过自定义函数查找ret指令编码所在的位置,若ret指令编码不在隐式常数中,则自定义函数返回的整型值为T,从链表中删除该节点且链表的指针指向下一个节点并执行步骤3中的步骤(b);否则自定义函数返回ret指令编码在隐式常数中的位置并执行步骤3中的步骤(d);
(d)更新节点中ret指令编码在隐式常数中的位置且链表的指针指向下一个节点并执行步骤3中的步骤(b)。
作为本发明进一步改进的技术方案,所述的步骤4具体包括以下步骤:
(a)获取步骤3得到的链表的头节点指针;
(b)判断链表的指针是否为空指针,若为空,则结束;否则执行步骤4中的步骤(c);
(c)根据隐式常数中ret指令编码的位置获取ret指令编码前面的n个字节的字节序列,n的初始值为1;
(d)判断ret指令编码前面的n个字节的字节序列是否获取成功,若不成功,则链表的指针指向下一个节点并执行步骤4中的步骤(b);否则执行步骤4中的步骤(e);
(e)调用接口函数,将步骤4中的步骤(d)获取成功的ret指令编码前面的n个字节的字节序列作为输入,若接口函数返回值不为0,则字节序列为有效的指令,执行步骤4中的步骤 (f);否则执行步骤4中的步骤(g);
(f)判断步骤4中的步骤(e)中有效的指令是否为nop指令或ret指令编码的叠加,若是,则执行步骤4中的步骤(g);否则更新节点中的布尔值,布尔值更新为1,链表的指针指向下一个节点并执行步骤4中的步骤(b);
(g)更新n的值,更新公式为:n=n+l,根据隐式常数中ret指令编码的位置获取ret指令编码前面的n个字节的字节序列并执行步骤4中的步骤(d)。
作为本发明进一步改进的技术方案,所述的步骤5具体包括以下步骤:
(a)获取步骤4得到的链表的头节点指针;
(b)判断链表的指针是否为空指针,若为空,则结束;否则执行步骤5中的步骤(c);
(c)获取节点中隐式常数的布尔值,若隐式常数的布尔值为0,则从链表中删除该节点,链表的指针指向下一个节点并执行步骤5中的步骤(b),其中隐式常数的布尔值为0表示该隐式常数包含ret指令编码,但该隐式常数不包含有效的代码片段;若隐式常数的布尔值不为0,则链表的指针指向下一个节点并执行步骤5中的步骤(b)。
作为本发明进一步改进的技术方案,所述的步骤6具体包括以下步骤:
(a)获取步骤5得到的链表的头节点指针;
(b)判断链表的指针是否为空指针,若为空,则结束;否则执行步骤6中的步骤(c);
(c)根据节点里面的偏移量信息查找代码缓存区中直接跳转指令的位置;
(d)选择两个寄存器,分别为第一寄存器和第二寄存器,对第一寄存器和第二寄存器进行压栈操作;
(e)随机产生一个密钥值,对该密钥值与直接跳转指令中的隐式常数进行异或计算,计算结果保存到第一寄存器中;
(f)将密钥值保存到第二寄存器中;
(g)在直接跳转指令的位置前增加一条第一寄存器和第二寄存器进行异或计算的指令;
(h)用第一寄存器替代直接跳转指令中的隐式常数,使直接跳转指令被改写成间接跳转指令;
(i)在修改后的直接跳转指令后还原压栈的第一寄存器和第二寄存器的内容,并在直接跳转指令跳转到的位置前插入从栈上弹出的第一寄存器和第二寄存器的内容的指令,链表的指针指向下一个节点并执行步骤6中的步骤(b)。
本发明在动态代码的生成过程中变换隐式常数,之后对动态生成代码中的隐式常数进行进一步的检查,根据检查的结果,对其中有害的隐式常数进行隐藏处理。结合变换与隐藏的处理隐式常数的方法,不仅使得整个过程不会产生漏报,同时可减少系统的性能开销。本发明的有益效果是,寄存器动态随机化阶段能够将多数有害的隐式常数变得无害,几乎对系统性能没有影响。而对于后续剩余有害的隐式常数,进行整块代码的检查与改写。因此,本方法既消除了动态生成代码中隐式常数的威胁,又减少了系统整体的性能开销。
附图说明
图1为本发明的整体流程图。
图2为本发明的寄存器的动态随机化流程图。
图3为本发明包含隐式常数指令的收集流程图。
图4为本发明查找隐式常数中的控制流转移指令流程图。
图5为本发明判定隐式常数中是否包含代码片段流程图。
图6为本发明隐式常数的判定流程图。
图7为本发明改写包含隐式常数的指令流程图。
具体实施方式
下面根据图1至图7对本发明的具体实施方式作出进一步说明:
如图1所示,本发明提出一种动态生成代码中隐式常数威胁的安全保护方法,具体在 Firefox中的即时编译引擎SpiderMonkey上进行实现。采用以下技术方案:变换和隐藏隐式常数相结合来缓解代码复用攻击的安全保护方法,包括即时编译过程中寄存器动态随机化、代码缓存中包含隐式常数指令的收集、隐式常数是否有害的判定以及指令改写等4个阶段。寄存器动态随机化阶段,动态代码的生成过程中对指令中用到的寄存器进行随机化处理,达到变换动态生成代码中隐式常数的目的。由于64位Linux平台下,某些寄存器有前缀,而另一些没有前缀,因此通过对寄存器随机化,使得含有寄存器的指令的长度发生变化,最终使得反应某个代码块大小的隐式常数发生变换。包含隐式常数的指令收集阶段,对包含隐式常数的指令进行收集与分类,作为后续工作的输入。判定隐式常数是否有害阶段,利用反汇编工具,检查隐式常数能否被解码为可被攻击者利用的代码片段。指令改写,将经过判定后的有害隐式常数隐藏于寄存器中,使其不再出现在动态生成的代码里,改写相关指令。本方法在整体上分为两个部分,第一部分在即时编译过程中运用寄存器动态随机化方法变换隐式常数,第二部分为检测与隐藏有害的隐式常数。大致的操作流程如下:SpiderMonkey中的Ion 编译器在寄存器分配阶段,对每个即将生成的动态代码块,随机地选择寄存器置换规则,使得生成的指令中的寄存器发生变化,最终达到变换隐式常数的目的。在动态生成的代码链接运行之前,对存放在code buffer中动态生成的代码块进行整体的检查,收集包含隐式常数的直接call指令与直接跳转指令将其存放到directlns链表中,链表中节点信息包括指令的偏移量、隐式常数的字符串表示、一个用于表示隐式常数中控制流指令位置的整型值(默认为T) 以及一个表示隐式常数是否有害的布尔值(默认为0)。根据隐式常数中是否包含有控制流转移指令的编码遍历链表进行第一轮删除处理,接着根据directlns链表中隐式常数的反汇编结果遍历链表进行第二轮删除处理。经过两次处理后,剩余链表每个节点中的隐式常数都可能被攻击者滥用,因此此时根据节点中指令的偏移信息定位代码块中的指令,对每条包含有害隐式常数的直接跳转指令进行精确地改写,将隐式常数隐藏于寄存器中,再用寄存器代替指令中的隐式常数。
图2为寄存器的动态随机化流程图。在64位Linux平台上,为了与32位系统中的寄存器兼容,对于新增加的寄存器在编码上都添加了一个字节的前缀,因此一条指令中,若所使用的寄存器有前缀,那么该条指令整体的长度将增加一个字节。一个动态生成的代码块中,若将无前缀的寄存器都换成有前缀的寄存器,或者相反,那么最终反映代码块大小的隐式常数必然因此而改变。通过寄存器动态随机化,当Ion编译器分配寄存器时,修改寄存器的分配规则,通过随机选择置换规则,来实现寄存器的随机分配。考虑到某些寄存器的特殊用途,可用来置换的无前缀寄存器集合NoPreRegister=(%rax,%rbx,%rcx,%rdx},有前缀寄存器集合 PreRegister={%r8,%r9,%rl0,%rll,%rl2,%rl3,%rl4,%rl5}o具体的置换规则为:随机地在 NoPreRegister集合中选择一个或多个要置换的寄存器,在PreRegister集合中随机的选取同等个数的寄存器,将两个集合中分别选取的寄存器组成寄存器对存放于表示置换规则的集合 RuleRegister中。
本过程作用于Ion编译器生成动态代码前的寄存器分配阶段,输入为两个寄存器的集合,输出为一个表示置换规则的寄存器对的集合。采用寄存器动态随机化方法变换动态生成代码中的隐式常数具体的流程如下:参见图2,步骤20是初始动作;步骤21表示从无前缀寄存器集合NoPreRegister中随机选择一个寄存器;步骤22判断该寄存器是否已经被选择过,若已经被选择过,那么转到步骤21重新选择一个寄存器,否则转到步骤23;步骤23表示从有前缀寄存器集合PreRegister中随机选择一个寄存器(用于与前面选择的无前缀寄存器进行互换);步骤24判断步骤23选择的寄存器是否已经选择过,如果已经选择过,那么转到步骤23进行重新选择,否则转到步骤25;步骤25表示将前面选择的两个寄存器组成一个寄存器对存放到集合RuleRegister中,一个这样的寄存器对表示—置换规则;步骤26判断是否还要添加新的置换规则,若是的话,则转到步骤21开始选择寄存器,否则转到步骤27,开始对生成的指令中的寄存器进行置换;步骤27是结束状态。
图3为包含隐式常数指令的收集流程图Ocode buffer中能够被攻击者控制的隐式常数除了出现在直接跳转指令中,还有小部分出现在直接call指令中,因此收集包含隐式常数的指令主要针对的就是这两类指令。为了便于分析,我们将生成的代码块在链接之前使用dump命令转储到文件中,然后在相应的文件中使用grep"call"-n与grep"jmp"-n两条命令找到所有的call指令与跳转指令,这两条命令会在dump文件中搜索到所有包含"cal1"与“jmp”的指令,同时也会输出相应的行号。接着再使用grep-v"%rax"等命令剔除所有的间接call指令与间接跳转指令。经过这样的处理,剩下的便是我们所想得到的包含隐式常数的直接call指令与直接跳转指令。我们将这些指令在动态代码块中的行号与指令中的隐式常数作为一个节点信息保存在directlns链表中,供后续工作使用。
本过程的输入是寄存器随机化后生成的动态代码块,将链接之前的动态代码块dump到文件中,经过两轮的搜索,找到包含隐式常数的直接call指令与直接跳转指令,将其信息保存到链表directlns中。在动态生成代码中收集到所有的直接call指令与直接跳转指令,将直接cal 1指令与直接跳转指令保存在链表中的具体流程如下:步骤30为初始动作;步骤31表示将动态生成的代码转储到磁盘文件中,这里需要在目录moz js-45.0.2/js/src/jit下 CodeGenerator.cpp文件中的CodeGenerator::generate()函数里进行插装,将动态生成的代码在链接前转储到文件中;步骤32对将代码转储到文件中的动作进行判断,若转储失败,则转到步骤31重新进行转储,否则,转到步骤33;步骤33对文件中的代码内容使用两条grep命令搜索并保存所有动态代码中的call指令与跳转指令;步骤34表示使用grep命令去掉步骤 33结果中的所有间接call指令与间接跳转指令,得到所有的直接call指令与直接跳转指令;步骤35表示将搜索结果保存到directlns链表中,该链表中节点的数据结构为指令在动态代码块中的偏移、指令中隐式常数的字符串表示形式、一个整型值用于表示隐式常数内的控制流指令编码的位置、一个布尔变量表示隐式常数是否有害;步骤36为结束状态。
图4为查找隐式常数中的控制流转移指令流程图。在搜索到的隐式常数中,继续去搜索隐式常数中是否包含控制流转移指令的编码。一个隐式常数能被攻击者滥用为代码片段的基本条件是其内部含有与控制流转移相关的指令编码,如频繁被使用的ret指令编码(可被编码为C2、C3、CA、CB)可能就包含在隐式常数中,在这里,我们主要针对的也是ret指令的编码。对图3的输出的链表directlns进行一次遍历,对链表的每个节点,查找节点里隐式常数中是否包含ret指令的编码,如果没有的话,我们认为该隐式常数没有危害并将其从链表中删除,否则我们将找出隐式常数中最后一个ret指令编码出现的位置,将其在隐式常数中的位置信息存放到节点中。为了在处理节点时达到这样的目的,我们自定义了一个查找函数int find_ret(string strl,string str2),该函数以ret的指令编码与隐式常数对应的字符串作为输入,返回值为最后一个ret指令编码在隐式常数中的位置,如果隐式常数中没有ret指令的编码,那么输出为-1。所述控制流转移指令编码为ret指令编码。
本过程的输入为图3创建的directlns链表,包含所有能收集到的隐式常数,输出为所有包含ret指令编码的隐式常数所构成的directlns链表。查找链表中的隐式常数中是否包含控制流转移指令编码,删除链表中没有控制流转移指令编码的隐式常数并确定控制流转移指令编码在每个隐式常数中的位置的具体流程如下:步骤40为初始动作;步骤41表示获取directlns 链表的头节点指针;步骤42判断指针是否为空指针,若为空,则转到步骤48,否则转到步骤 43;步骤43调用了一个自定义的函数,作用是在隐式常数中找到ret指令编码所在的位置,ret 指令的编码不在隐式常数中,则返回值为-1,否则返回对应的位置;步骤44判断函数find_ret 的返回值,若为-1则转到步骤45,否则转到步骤46;步骤45表示该结点中的隐式常数中没有 ret指令的编码,可认为该隐式常数没有危害,因此可从链表中删除;步骤46对节点中ret指令编码在隐式常数中的位置信息进行更新;步骤47表示指针指向下一个节点;步骤48为结束状态。
图5为判定隐式常数中是否包含代码片段流程图。在确定了隐式常数中控制流跳转指令的位置后,对该位置之前的字节序列进行反汇编,尽管由于x86平台采用的是变长指令集结构会导致反汇编后的结果有多个,但是因为隐式常数反映的是代码块的大小所包含的字节序列非常短,因此我们认为只要反汇编后的字节序列是有效指令且不是某些单字节指令的叠加 (如连续的N0P指令或连续的RET指令或者两者的结合),那么该反汇编后的结果就能成为被攻击者滥用的代码片段。本发明使用反汇编器LIBDASM对字节序列反汇编,LIBDASM 提供的接口函数是get_instruction函数,该函数的输入是字节序列和基于LIBDASMINSTRUCTION结构体,输出是反汇编后指令字节数,若返回结果为0,则表示该字节序列无法反汇编为有效指令,增加字节序列长度再次判断,否则,对输入的字节序列进行进一步的判断,判断该字节序列是否为nop指令或ret指令编码的叠加,若是,则增加字节序列的长度进行下一步的反汇编,否则认为该隐式常数包含代码片段并修改directlns链表中该节点里的布尔值,然后将指向directlns链表中节点的指针下移进行下一个隐式常数的判断。
本过程判断directlns链表中每个节点里的隐式常数是否包含可能被滥用的代码片段。对链表中每个隐式常数中的控制流转移指令编码所在位置之前的字节序列进行反汇编,确定隐式常数中是否包含有效的代码片段的具体的流程如下:步骤50为初始动作;步骤51表示获取directlns链表的头节点指针;步骤52对获取到的指针判断其是否为空,若为空,则跳转到步骤5b,否则跳转到步骤53;步骤53表示在节点中根据隐式常数中ret的位置信息获取ret前的n(n初始值为1)个字节长度的字节序列;步骤54判断获取n个字节长度的字节序列时是否成功,若不成功则转到步骤5a,否则转到步骤55;步骤55调用LIBDASM里的接口函数 get_instruction,将之前获取的字节序列作为输入,根绝返回结果判断该字节序列是否为有效指令;步骤56对函数get_instruction的返回值进行判断,若不为0,则说明字节序列是有效的指令转到步骤58,否则转到步骤57;步骤57在隐式常数中重新获取多一个字节长度的字节序列;步骤58判断有效的指令是否为nop或ret指令编码的叠加,若是则说明该条指令虽有效但是不能成为代码片段而转到步骤57,否则,转到步骤59;步骤59更新结点中的布尔值,此时说明该节点中的隐式常数包含代码片段;步骤5a将指向链表directlns中节点的指针指向下一个新的节点;步骤5b是结束状态。
图6为隐式常数的判定流程图。根据图5流程后的结果,依据隐式常数是否包含可被利用的代码片段从而判断该隐式常数是否有害。在上一步的处理后,directlns链表中的每个节点里都保存里隐式常数中是否包含代码片段的信息,依据这个信息,对directlns链表进行进一步地处理,删除那些不构成威胁的隐式常数所在的节点。
本过程依据directlns链表中节点里的信息对directlns链表作进一步的处理。删除链表中不包含有效的代码片段的隐式常数的具体流程如下:步骤60为初始动作;步骤61表示获取 directlns链表的头节点指针;步骤62对获取到的指针判断其是否为空,若为空,则转到步骤 67,否则转到步骤63;步骤63获取节点中表示隐式常数是否有害的布尔值;步骤64对获取到的布尔值判断其是否为0,若为。则转到步骤65,否则转到步骤66;步骤65表示该隐式常数尽管包含ret指令的编码,但是不能够反汇编出有效的代码片段,因此可认为该隐式常数不具危害性,可以从链表中删除对应的节点;步骤66表示指针指向下一个节点;步骤67是结束状态。
图7为改写包含隐式常数的指令流程图。前面图3到图6的处理流程,使得我们最终找到并确定了可能被滥用的隐式常数,与此同时,这些隐式常数所在指令的位置(代码块中的偏移值)也保存在directlns链表的数据结构中。为了使得这些有害的隐式常数不能够为攻击者所用,这里我们将用寄存器代替直接跳转指令中的这些隐式常数。而在把隐式常数隐藏到寄存器中时,为了不让这些有害的隐式常数再出现在动态代码块中,我们首先生成一个随机的密钥值,将其与隐式常数异或后的结果保存在某个寄存器regl中,然后将该密钥保存在另一个寄存器reg2中,再次使用一条异或指令将两个寄存器异或后的结果保存到寄存器regl中(此时regl中保存的值即为我们想要隐藏的隐式常数)。
本过程的输入为direct Ins链表,根据链表中的信息,先定位到代码缓存区codebuffer中存在有害隐式常数的位置,然后在该位置对包含有害隐式常数的直接跳转指令进行改写,使得改写后的动态代码中有害隐式常数被隐藏在寄存器中。具体的流程如下:步骤70为初始动作;步骤71表示获取链表directlns的头节点指针;步骤72对获取到的指针进行判断,若为空则转到步骤7b,否则,转到步骤73;步骤73根据节点里面的偏移信息在codebuffer中找到需要改写的直接跳转指令的位置;步骤74表示选择两个寄存器,分别为:regl与reg2,将其内容压到栈上,之所以要对寄存器进行压栈操作,是因为后面需要覆盖该寄存器的内容;步骤75表示随机产生一个密钥值,将其与直接跳转指令中的隐式常数异或后的结果保存到寄存器regl中;步骤76表示将密钥值保存到寄存器reg2中;步骤77表示在直接跳转指令前添加一条寄存器regl与寄存器reg2异或的指令,这样做的结果是直接跳转指令中的隐式常数已经隐藏到了寄存器regl中;步骤78表示此时可以直接用寄存器regl替代直接跳转指令中的隐式常数,直接跳转指令被改写为了间接跳转指令,并且被替换下来的隐式常数也不再出现在code buffer中;步骤79表示在修改后的直接跳转指令后还原寄存器regl与寄存器reg2的内容,另外跳转到的位置也要插入两条弹出寄存器内容的指令;步骤7a表示指针指向下一个节点;步骤7b是结束状态。
综上所述,本发明在动态代码的生成过程中变换隐式常数,之后对动态生成代码中的隐式常数进行进一步的检查,根据检查的结果,对其中有害的隐式常数进行隐藏处理。结合变换与隐藏的处理隐式常数的方法,不仅使得整个过程不会产生漏报,同时可减少系统的性能开销。本发明的有益效果是,寄存器动态随机化阶段能够将多数有害的隐式常数变得无害,几乎对系统性能没有影响。而对于后续剩余有害的隐式常数,进行整块代码的检查与改写。因此,本方法既消除了动态生成代码中隐式常数的威胁,又减少了系统整体的性能开销。
本发明的保护范围包括但不限于以上实施方式,本发明的保护范围以权利要求书为准,任何对本技术做出的本领域的技术人员容易想到的替换、变形、改进均落入本发明的保护范围。
Claims (3)
1.一种动态生成代码中隐式常数威胁的安全保护方法,其特征在于:包括以下步骤:
步骤1:采用寄存器动态随机化方法变换动态生成代码中的隐式常数;
步骤2:在动态生成代码中收集到所有的直接call指令与直接跳转指令,将直接call指令与直接跳转指令保存在链表中;
步骤3:查找链表中的隐式常数中是否包含控制流转移指令编码,删除链表中没有控制流转移指令编码的隐式常数并确定控制流转移指令编码在每个隐式常数中的位置;
步骤4:对链表中每个隐式常数中的控制流转移指令编码所在位置之前的字节序列进行反汇编,确定隐式常数中是否包含有效的代码片段;
步骤5:删除链表中不包含有效的代码片段的隐式常数,链表中剩余的隐式常数均为有害隐式常数;
步骤6:定位代码缓存区中存在有害隐式常数的位置,在该位置对包含有害隐式常数的直接跳转指令进行改写,使改写后的动态生成代码中有害隐式常数被隐藏在寄存器中,所述直接跳转指令是指跳转目标地址为常数的跳转指令;
所述的步骤1中的寄存器动态随机化方法具体包括以下步骤:
S11,从无前缀寄存器集合中随机选择一个寄存器;
S12,判断步骤S11中选择的寄存器是否被选择过,若已选择过,则执行步骤S11从而重新选择一个寄存器;否则执行步骤S13;
S13,从有前缀寄存器集合中随机选择一个寄存器;
S14,判断步骤S13中选择的寄存器是否被选择过,若已选择过,则执行步骤S13从而重新选择一个寄存器;否则执行步骤S15;
S15,将步骤S11选择的寄存器和步骤S13选择的寄存器组成一个寄存器对放到表示置换规则的集合中;
S16,判断是否需要在表示置换规则的集合中添加新的置换规则,若需要,则执行步骤S11,从而开始选择寄存器;否则执行步骤S17;
S17,根据置换规则对动态生成代码中的寄存器进行置换;
所述控制流转移指令编码为ret指令编码;
所述的步骤3具体包括以下步骤:
S31,获取步骤2得到的链表的头节点指针;
S32,判断链表的指针是否为空指针,若为空,则结束;否则执行步骤S33;
S33,调用自定义函数,通过自定义函数查找ret指令编码所在的位置,若ret指令编码不在隐式常数中,则自定义函数返回的整型值为T,从链表中删除当前链表的指针指向的节点且链表的指针指向下一个节点并执行步骤S32;否则自定义函数返回ret指令编码在隐式常数中的位置并执行步骤S34;
S34,更新节点中ret指令编码在隐式常数中的位置且链表的指针指向下一个节点并执行步骤S32;
所述的步骤4具体包括以下步骤:
S41,获取步骤3得到的链表的头节点指针;
S42,判断链表的指针是否为空指针,若为空,则结束;否则执行步骤S43;
S43,根据隐式常数中ret指令编码的位置获取ret指令编码前面的n个字节的字节序列,n的初始值为1;
S44,判断ret指令编码前面的n个字节的字节序列是否获取成功,若不成功,则链表的指针指向下一个节点并执行步骤S42;否则执行步骤S45;
S45,调用接口函数,将步骤S44获取成功的ret指令编码前面的n个字节的字节序列作为输入,若接口函数返回值不为0,则字节序列为有效的指令,执行步骤S46;否则执行步骤S47;
S46,判断步骤S45中有效的指令是否为nop指令或ret指令编码的叠加,若是,则执行步骤S47;否则更新节点中的布尔值,布尔值更新为1,链表的指针指向下一个节点并执行步骤S42;
S47,更新n的值,更新公式为:n=n+l,根据隐式常数中ret指令编码的位置获取ret指令编码前面的n个字节的字节序列并执行步骤S44;
所述的步骤5具体包括以下步骤:
S51,获取步骤4得到的链表的头节点指针;
S52,判断链表的指针是否为空指针,若为空,则结束;否则执行步骤S53;
S53,获取节点中隐式常数的布尔值,若隐式常数的布尔值为0,则从链表中删除该节点,链表的指针指向下一个节点并执行步骤S52,其中隐式常数的布尔值为0表示该隐式常数包含ret指令编码,但该隐式常数不包含有效的代码片段;若隐式常数的布尔值不为0,则链表的指针指向下一个节点并执行步骤S52;
所述的步骤6具体包括以下步骤:
S61,获取步骤5得到的链表的头节点指针;
S62,判断链表的指针是否为空指针,若为空,则结束;否则执行步骤S63;
S63,根据节点里面的偏移量信息查找代码缓存区中直接跳转指令的位置;
S64,选择两个寄存器,分别为第一寄存器和第二寄存器,对第一寄存器和第二寄存器进行压栈操作;
S65,随机产生一个密钥值,对该密钥值与直接跳转指令中的隐式常数进行异或计算,计算结果保存到第一寄存器中;
S66,将密钥值保存到第二寄存器中;
S67,在直接跳转指令的位置前增加一条第一寄存器和第二寄存器进行异或计算的指令;
S68,用第一寄存器替代直接跳转指令中的隐式常数,使直接跳转指令被改写成间接跳转指令;
S69,在修改后的直接跳转指令后还原压栈的第一寄存器和第二寄存器的内容,并在直接跳转指令跳转到的位置前插入从栈上弹出的第一寄存器和第二寄存器的内容的指令,链表的指针指向下一个节点并执行步骤S62。
2.根据权利要求1所述的动态生成代码中隐式常数威胁的安全保护方法,其特征在于:所述的步骤2具体包括以下步骤:
S21,将寄存器动态随机化后的动态生成代码转储到磁盘文件中;
S22,判断动态生成代码是否成功转储到磁盘文件中,若转储失败,则执行步骤S21从而重新转储;否则执行步骤S23;
S23,搜索动态生成代码中所有call指令与跳转指令;
S24,去除所有的间接call指令与间接跳转指令,得到所有的直接call指令与直接跳转指令;
S25,将步骤S24得到的结果保存到链表中。
3.根据权利要求2所述的动态生成代码中隐式常数威胁的安全保护方法,其特征在于:所述的链表中节点信息包括指令在动态生成代码中的偏移量、隐式常数的字符串表示、一个用于表示隐式常数中控制流转移指令编码的位置的整型值和一个用于表示隐式常数是否有害的布尔值。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201710703706.8A CN107506644B (zh) | 2017-08-16 | 2017-08-16 | 动态生成代码中隐式常数威胁的安全保护方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201710703706.8A CN107506644B (zh) | 2017-08-16 | 2017-08-16 | 动态生成代码中隐式常数威胁的安全保护方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN107506644A CN107506644A (zh) | 2017-12-22 |
CN107506644B true CN107506644B (zh) | 2020-10-30 |
Family
ID=60692249
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201710703706.8A Active CN107506644B (zh) | 2017-08-16 | 2017-08-16 | 动态生成代码中隐式常数威胁的安全保护方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN107506644B (zh) |
Families Citing this family (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US11709675B2 (en) * | 2020-10-30 | 2023-07-25 | Apple Inc. | Software verification of dynamically generated code |
CN115906014B (zh) * | 2021-08-13 | 2024-07-23 | 华为技术有限公司 | 一种数据处理方法及相关装置 |
Family Cites Families (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101968766B (zh) * | 2010-10-21 | 2012-09-05 | 上海交通大学 | 计算机程序实际运行时触发软件漏洞的检测系统 |
US9256427B2 (en) * | 2012-12-11 | 2016-02-09 | International Business Machines Corporation | Tracking multiple conditions in a general purpose register and instruction therefor |
CN106022166B (zh) * | 2016-06-02 | 2018-10-23 | 东北大学 | 一种代码复用攻击防御系统及方法 |
-
2017
- 2017-08-16 CN CN201710703706.8A patent/CN107506644B/zh active Active
Also Published As
Publication number | Publication date |
---|---|
CN107506644A (zh) | 2017-12-22 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
JP4855400B2 (ja) | マルチパターン検索のための方法およびシステム | |
Linn et al. | Obfuscation of executable code to improve resistance to static disassembly | |
US20090049425A1 (en) | Code Obfuscation By Reference Linking | |
US11349816B2 (en) | Obfuscating source code sent, from a server computer, to a browser on a client computer | |
JPH0869370A (ja) | データ圧縮方法およびシステム | |
CN107506644B (zh) | 动态生成代码中隐式常数威胁的安全保护方法 | |
KR101356676B1 (ko) | 컴퓨팅 환경에서 표현식을 번역하는 방법, 소프트웨어 및시스템 | |
US20190286818A1 (en) | Methods and systems for defending against cyber-attacks | |
TW202013178A (zh) | 動態分段位址空間佈局隨機化技術 | |
EP2937803B1 (en) | Control flow flattening for code obfuscation where the next block calculation needs run-time information | |
CN111475168A (zh) | 一种代码编译方法及装置 | |
CN108932407B (zh) | 一种程序安全保护方法及装置 | |
JP2007304726A (ja) | プログラム難読化装置、難読化方法及び難読化プログラム | |
CN110147238B (zh) | 一种程序编译方法、装置及系统 | |
CN111898130A (zh) | 一种细粒度控制流完整性保护实现方法及系统 | |
CN111190604A (zh) | 一种安卓应用内存混淆方法、装置、电子设备及介质 | |
CN113541922B (zh) | 交换网络和跳转算法指令化的侧信道攻击抵抗方法及系统 | |
US6532532B1 (en) | Instruction execution mechanism | |
CN113282893B (zh) | 源代码加固方法、装置、计算机设备和存储介质 | |
CN115756480A (zh) | 一种安卓应用加固方法、系统及设备 | |
CN114637988A (zh) | 一种面向二进制的函数级软件随机化方法 | |
CN109344576B (zh) | 一种应用程序处理方法、装置、电子设备及可读存储介质 | |
CN111143845A (zh) | 一种基于寄存器随机化和常数致盲的隐式常量防御策略 | |
Yang et al. | AR Exploit: An Automatic ROP Exploit Based on Long Sequence | |
CN113439271B (zh) | 受保护操作处理 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |