CN110673852A - 一种基于编译器前端实现控制流平坦的方法、系统及设备 - Google Patents

一种基于编译器前端实现控制流平坦的方法、系统及设备 Download PDF

Info

Publication number
CN110673852A
CN110673852A CN201910894799.6A CN201910894799A CN110673852A CN 110673852 A CN110673852 A CN 110673852A CN 201910894799 A CN201910894799 A CN 201910894799A CN 110673852 A CN110673852 A CN 110673852A
Authority
CN
China
Prior art keywords
syntax tree
function
statement
variable
block
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.)
Granted
Application number
CN201910894799.6A
Other languages
English (en)
Other versions
CN110673852B (zh
Inventor
方令
肖巍
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Beijing Zhiyouwang'an Technology Co Ltd
Original Assignee
Beijing Zhiyouwang'an Technology Co Ltd
Priority date (The priority date 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 date listed.)
Filing date
Publication date
Application filed by Beijing Zhiyouwang'an Technology Co Ltd filed Critical Beijing Zhiyouwang'an Technology Co Ltd
Priority to CN201910894799.6A priority Critical patent/CN110673852B/zh
Publication of CN110673852A publication Critical patent/CN110673852A/zh
Application granted granted Critical
Publication of CN110673852B publication Critical patent/CN110673852B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/43Checking; Contextual analysis
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/10Protecting distributed programs or content, e.g. vending or licensing of copyrighted material ; Digital rights management [DRM]
    • G06F21/12Protecting executable software
    • G06F21/14Protecting executable software against software analysis or reverse engineering, e.g. by obfuscation
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/44Encoding
    • G06F8/447Target code generation

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Software Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Multimedia (AREA)
  • Technology Law (AREA)
  • Computer Hardware Design (AREA)
  • Computer Security & Cryptography (AREA)
  • Devices For Executing Special Programs (AREA)

Abstract

本发明提供一种基于编译器前端实现控制流平坦的方法、系统及设备,所述方法包括:分析处理源文件得到对应的语法树及其包含的头文件;生成控制变量对应的语法树节点和流程控制结构所对应的语法树节点;对函数体内的语句进行分块并处理得到相应的语法树节点,将相应的语法树节点插入到流程控制结构所对应的语法树节点中;用新生成的语法树节点替换相应的原语法树节点;根据修改后的语法树输出源代码。本发明通过在编译器前端对语法树进行平坦处理,使破解者无法重建出函数控制流图,并能输出得到C/C++源代码,使其可被各种编译器编译,兼顾了程序的安全性和可移植性。

Description

一种基于编译器前端实现控制流平坦的方法、系统及设备
技术领域
本发明涉及移动信息安全领域,尤其涉及一种基于编译器前端实现控制流平坦的方法、系统及设备。
背景技术
在移动信息安全领域,代码混淆的目的是为了使代码变得更难懂,防止软件被恶意逆向分析。控制流平坦是一种混淆方法,它可以“压扁”程序中原有的控制流结构(嵌套的循环和条件转移语句),使破解者无法利用静态分析工具重建出原始的函数控制流图。
OLLVM(Obfuscator-LLVM)是一个开源项目,旨在提供一套开源的针对LLVM的代码混淆工具,以增加逆向工程的难度。目前的C/C++混淆技术是基于OLLVM实现的,混淆的是中间层表示形式的代码。混淆的结果只能由LLVM编译器转化成相应平台的机器指令,无法移植,更不可被其他编译器再次处理。
因此,现有技术有待改进和发展。
发明内容
鉴于上述现有技术的不足,本发明提供了一种基于编译器前端实现控制流平坦的方法、系统及设备,旨在解决现有技术OLLVM混淆平坦中间层表示形式代码,只能由LLVM编译器转化成机器指令,无法移植无法被其他编译器再次处理的问题。
为了解决上述问题,本发明公开了一种基于编译器前端实现控制流平坦的方法,所述方法包括步骤:
分析处理源文件得到源文件对应的语法树及其包含的头文件;
检查语法树中的每一个函数,找出包含选择语句或循环语句的第一类函数;
在第一类函数中分析判断出所有变量声明语句都能移动到函数体开始处的第二类函数;
将第二类函数的变量声明语句移动到函数体开始处得到第三类函数;
根据第三类函数生成控制变量对应的语法树节点和流程控制结构所对应的语法树节点;
第三类函数中除函数体开始处的变量声明语句外,对函数体内的语句进行分块并对各个块进行处理得到相应的语法树节点;
将各个块进行处理得到相应的语法树节点插入到流程控制结构所对应的语法树节点中;
用新生成的语法树节点替换相应的原语法树节点;
根据修改后的语法树输出源代码。
进一步,所述在第一类函数中分析判断出所有变量声明语句都能移动到函数体开始处的第二类函数的步骤中,第二类函数是指将变量声明语句移动到函数体开始处时不会对程序的逻辑及输出结果造成实质影响的函数。
进一步,所述将第二类函数的变量声明语句移动到函数体开始处得到第三类函数的步骤具体包括:判断变量声明语句中是否包含初始化表达式,若有则将变量声明语句拆分成不含初始化表达式的变量声明和与初始化表达式等价的语句,将不含初始化表达式的变量声明移到函数开始处,将与初始化表达式等价的语句留在原来位置。
进一步,所述在根据第三类函数生成控制变量对应的语法树节点和流程控制结构所对应的语法树节点的步骤中,流程控制结构为:While-Switch结构,所述While-Switch结构外层是一个while循环,控制表达式为控制变量不等于退出值,退出值为预设的任意值,所述Whlie-Switch结构内层是一个switch语句,控制表达式为控制变量的值。
进一步,所述第三类函数中除函数体开始处的变量声明语句外,对函数体内的语句进行分块并对各个块进行处理得到相应的语法树节点步骤中,分块为:将函数体内的语句根据出现的前后顺序和种类分成多个语句块,if语句,switch语句,do语句,while语句,for语句,复合语句,try block语句各自成一块,其余连续或单独的语句成一个块。
进一步,所述在第三类函数中除函数体开始处的变量声明语句外,对函数体内的语句进行分块并对各个块进行处理得到相应的语法树节点步骤中,对各个块进行处理得到相应的语法树节点具体步骤包括:判断语句块的类型;调用相应的程序对语句块进行处理;根据处理结果生成对应的语法树节点。
进一步,所述用新生成的语法树节点替换相应的原语法树节点步骤具体包括:对不含try-catch块的函数,当函数体内的语句处理完毕后,用函数体开始处的变量声明语句对应的语法树节点、函数体对应的流程控制变量定义声明语句对应的语法树结点和函数体对应的流程控制结构的语法树结点替换原来函数体中的节点,对于包含try-catch块的函数当关键字try后面花括号中语句处理完毕后,要用其对应的控制流程结构及控制变量的语法树结点替换其原有结点;
进一步,所述根据修改后的语法树输出平坦处理后的源代码的步骤具体包括:创建一个与源文件类型一致的空白文件;将源文件包含的头文件按正确语法形式输出到所述空白文件;将语法树中的顶级声明按正确语法形式输出到所述空白文件。
一种基于编译器前端实现控制流平坦的系统,包括
代码编译模块、所述代码编译模块用于分析处理源文件得到源文件对应的语法树及其包含的头文件;
语句检查模块、所述语句检查模块用于检查语法树中的每一个函数,找出包含选择语句或循环语句的第一类函数;
在第一类函数中分析判断出所有变量声明语句都能移动到函数体开始处的第二类函数;
平坦处理模块、所述平坦处理模块用于将第二类函数的变量声明语句移动到函数体开始处得到第三类函数;
根据第三类函数生成控制变量对应的语法树节点和流程控制结构所对应的语法树节点;
第三类函数中除函数体开始处的变量声明语句外,对函数体内的语句进行分块并对各个块进行处理得到相应的语法树节点;
将各个块进行处理得到相应的语法树节点插入到流程控制结构所对应的语法树节点中;
用新生成的语法树节点替换相应的原语法树节点;
代码输出模块、所述代码输出模块用于根据修改后的语法树输出平坦处理后的源代码。
一种基于编译器前端实现控制流平坦的设备,包括有处理器,以及与所述处理器连接的存储器;
所述存储器存储有基于编译器前端实现控制流平坦的程序,所述基于编译器前端实现控制流平坦的程序被所述处理器执行时实现所述的基于编译器前端实现控制流平坦的方法
有益效果:本实施例提供了一种基于编译器前端实现控制流平坦的方法,具体为分析处理源文件得到源文件对应的语法树及其包含的头文件;检查语法树中的每一个函数,找出包含选择语句或循环语句的第一类函数;
在第一类函数中分析判断出所有变量声明语句都能移动到函数体开始处的第二类函数;将第二类函数的变量声明语句移动到函数体开始处得到第三类函数;根据第三类函数生成控制变量对应的语法树节点和流程控制结构所对应的语法树节点;第三类函数中除函数体开始处的变量声明语句外,对函数体内的语句进行分块并对各个块进行处理得到相应的语法树节点;将各个块进行处理得到相应的语法树节点插入到流程控制结构所对应的语法树节点中;用新生成的语法树节点替换相应的原语法树节点;根据修改后的语法树输出源代码。通过上述技术方案,对编译器前端抽象语法树进行修改,实现了在编译器前端抽象语法树进行控制流平坦处理,改变程序中原有的控制流结构,使破解者无法利用静态分析工具重建出原始的函数控制流图,并根据修改后的抽象语法树输出得到C/C++源代码,能经各种编译器编译成特定平台上的二进制代码,从而在特定运平台上运行,使得代码兼备安全性和可移植性。
附图说明
图1为本发明基于编译器前端实现控制流平坦的方法的实施例流程图。
图2为本发明基于编译器前端实现控制流平坦的方法的较佳实施例流程图。
图3为本发明基于编译器前端实现控制流平坦的系统的实施例结构框图。
图4为本发明基于编译器前端实现控制流平坦的设备的实施例结构框图。
图中:10、代码编译模块;20、语句检查模块;30、平坦处理模块;40、代码输出模块;50、处理器;51、显示屏;52、存储器;53、通信接口;54、总线。
具体实施方式
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
如图1、图2所示,本发明的一个实施例提供的一种基于编译器前端实现控制流平坦的方法,本方法可以用于应用程序代码的代码保护等领域,本方法包括步骤:
步骤S100、分析处理源文件得到源文件对应的语法树及其包含的头文件。
具体的,LLVM(Low Level Virtual Machine)工程是一个模块可重用的编译器及工具链技术的集合。其子工程Clang为编写需要语义分析、语法分析的工具提供了基础。利用Clang工程可对源文件进行词法分析和语义分析,得到源文件对应的语法树及头文件。这里的源文件是开发人员提前编写好的源代码,语法树是抽象语法树,抽象语法树,是源代码语法结构的一种抽象表示,它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。
步骤S200、检查语法树中的每一个函数,找出包含选择语句或循环语句的第一类函数。
具体的,遍历源文件抽象语法树中的每一个节点,检查抽象语法树中的函数,需要检查的函数为源文件中定义的函数,对于仅声明的函数不进行检查处理,避免不必要的处理步骤。检查定义的函数中是否包含选择语句或循环语句,选择语句如if语句、switch语句等,循环语句如for语句、while语句、do语句等。若函数中包含选择语句或循环语句,将函数标记为第一类函数。
步骤S300、在第一类函数中分析判断出所有变量声明语句都能移动到函数体开始处的第二类函数。
具体的,得到包含选择语句或循环语句的第一类函数后,分析判断第一类函数中所有的变量声明语句是否能移动到函数体开始处,将变量声明语句移动到函数体开始处指的是将抽象语法树中表示变量声明语句的节点,从原有位置移动到抽象语法树中函数体节点的子节点靠前的位置,能移动到函数体开始处指的是将变量声明语句移动到函数体开始处时不会对整个程序的逻辑及输出结果造成实质影响的函数,如标量类型(scalar type)及union类型的变量声明,这种变量声明能够直接移动到函数开始处,不会对程序造成影响;而如struct及class类型的变量声明可能会使整个程序出现错误,则不能移动到函数体开始处,对于不能移动的变量声明,不对函数做处理。控制流平坦主要是将函数的语句放入一个while-switch结构内,对于变量声明语句能移动到函数体开始处的函数,将变量声明语句移动到函数体开始处可以确保声明的变量在switch的其他部分被使用,避免了因为变量声明语句处于局部的某个case下而造成另外的case无法访问这个变量的问题。
步骤S400、将第二类函数的变量声明语句移动到函数体开始处得到第三类函数。
具体的,将变量声明能移动到函数体开始处的第二类函数区别出来后,将其抽象语法树中变量声明语句的节点移动到函数体节点的子节点中靠前的位置。
在优选的方案中,步骤S400具体包括步骤:
步骤S410、判断变量声明语句中是否包含初始化表达式,若无则直接移动,若有则执行下一步骤;
具体的,没有包含初始化表达式的变量声明,能够直接移动到函数体开始处。
步骤S420、将变量声明语句拆分成不含初始化表达式的变量声明和与初始化表达式等价的语句。
具体的,变量声明中的初始化表达式可能依赖的是声明语句之前的一些语句,直接把变量声明语句整体移到函数体开始处,可能会因为初始化表达式不能寻回所依赖的语句而出现错误,因此需要对包含初始化表达式的变量声明做处理,将变量声明拆分成不含初始化表达式的变量声明和与初始化表达式等价的语句,如赋值语句等。
步骤S430、将不含初始化表达式的变量声明移到函数开始处,将与初始化表达式等价的语句留在原来位置。
具体的,拆分后,不含初始化表达式的变量声明能够直接移动到函数体开始处,将其移动到函数体开始处,而与初始化表达式等价的语句则留在原来的位置,便于寻回其所依赖的语句,避免出现错误。
步骤S500、根据第三类函数生成控制变量对应的语法树节点和流程控制结构所对应的语法树节点。
具体的,调用流程控制结构生成函数FLATTEN_BLOCK生成一个流程控制结构所对应的语法树节点。FLATTEN_BLOCK伪代码如下:
Figure BDA0002209876790000071
生成的节点具体为以while语句为节点的一棵语法树,while语句的体内是一个switch语句,但是switch语句只有控制表达式的节点,switch的体的节点下,暂时没有子节点,上述子节点在后续对抽象语法树的处理中得到并填入相对应的位置。即流程控制结构为while-switch结构,其外层是一个while循环,具体的,控制表达式为控制变量不等于退出值,退出值可以任意设定;其内层是一个switch语句,具体的,控制表达式为控制变量的值,switch下的case暂时没有内容,case部分会在后续填入语句平坦处理后的语法树节点,变量声明语句、控制变量语句及流程控制结构替换原有的函数体下的内容。
步骤S600、第三类函数中除函数体开始处的变量声明语句外,对函数体内的语句进行分块并对各个块进行处理得到相应的语法树节点,将各个块进行处理得到相应的语法树节点插入到流程控制结构所对应的语法树节点中。
具体的,对各个函数,除函数体的声明语句意以外,将函数体内的语句进行分块。调用分块处理函数TRANSFORM_BLOCK进行分块,TRANSFORM_BLOCK伪代码如下:
Figure BDA0002209876790000082
Figure BDA0002209876790000091
其中,if语句(IfStmt),switch语句(SwitchStmt),do语句(DoStmt),while语句(WhileStmt),for语句(ForStmt),复合语句(CompoundStmt),try block(CXXTryStmt)所对应的节点分别单独为一块,被上述语句块分隔的语句分别形成一个块,即将语句根据出现顺序和其类型分为多个块。
在进行分块处理时,某些语句如If语句、While语句和For语句等,语句下面可能会包含一个或多个复合语句,在这些语句下面的复合语句,不将其当做复合语句,而把这种语句当作是If语句、While语句和For语句等语句的一部分,不将其分入复合语句块中,即在进行分块处理时是平级分块,保证准确性,便于后续处理。
分块结束后,调用相应的函数对各个块进行处理,处理完成后将生成对应的语法树节点,分别作为一个case插入到流程控制结构语法树节点中switch下,将流程控制结构补充完整。
步骤S610、判断语句块的类型。
具体的,判断所需处理的语句块的类型,从而调用相应的程序。
步骤S620、调用相应的程序对语句块进行处理。
步骤S630、根据处理结果生成对应的语法树节点。
具体的,根据语句块的类型,调用相应的语句块进行处理,具体处理各类型语句块函数分为TRANSFORM_BLOCK(分块处理函数)、TRANSFORM_IF(if语句块处理函数)、TRNASFORM_SWITCH(switch语句块处理函数)、TRANSFORM_WHILE(while语句块处理函数)、TRANSFORM_DO(do语句块处理函数)、TRANSFORM_FOR(for语句块处理函数)、TRANSFORM_TRY(异常语句块处理函数)、TRANSFORM_SEQUENCE(顺序语句块处理函数)。
当前语句块是if语句块时,调用TRANSFORM_IF对其进行处理,TRANSFORM_IF伪代码如下:
Figure BDA0002209876790000101
Figure BDA0002209876790000102
Figure BDA0002209876790000103
Figure BDA0002209876790000111
源代码中if语句可能存在有3个或3个以上分支的情况,而抽象语法树中,if语句在抽象语法树中的节点只有2个分支,第一分支和第二分支,对于源代码if语句中更多的分支,是用多个层级来表示,第一级是if语句,然后第一级if语句的else分支的下级结构,是另一个带有两个分支的第二级if语句,如果源代码出现四个分支,则第二级if语句else分支的下级结构中是再一个带有两个分支的if语句,出现更多分支的情况,以此类推。
对于if语句的分支,进一步调用TRANSFORM_BLOCK进行分块,然后再对分出的各个块调用相应的处理函数进行处理。
if语句块经过处理后生成的case,其产生的case作为流程控制结构内侧switch下的case节点,补充流程控制结构中的语法树节点。除了开始处的case,其分支经过进一步处理后也会产生case。如果if语句前面有标签,则将标签添加到case entry所对应的case块下的第一条语句前面。
当前语句块是switch语句块时,调用TRNASFORM_SWITCH对其进行处理,TRNASFORM_SWITCH伪代码如下:
Figure BDA0002209876790000122
Figure BDA0002209876790000123
对于switch的体,进一步调用TRANSFROM_BLOCK对其进行分块,再对分出的各个块调用相应的处理函数进行处理。
switch语句块经过处理后,其产生的case,作为流程控制结构的内侧switch下的case节点,补充流程控制结构中的语法树节点。如果switch语句前面有标签,则将标签添加到case entry所对应的case块下的switch语句前面。
当前语句块是while语句块时,调用TRANSFORM_WHILE对其进行处理,TRANSFORM_WHILE伪代码如下:
Figure BDA0002209876790000131
Figure BDA0002209876790000132
Figure BDA0002209876790000133
对于while的体,进一步调用TRANSFORM_BLOCK进行分块,然后再对分出的各个块调用相应的处理函数进行处理。
while语句块经过处理后,其产生的case作为流程控制结构的内侧switch下的case节点,补充流程控制结构中的语法树节点。如果while语句前面有标签,则将标签添加到case entry所对应的case块下的第一条语句前面。
while语句中可能会包含continue语句和break语句,continue语句执行时跳转到while体内最后一条语句后面,继续执行while体内的语句,break语句则跳出while,程序执行while后面的语句。continue语句和break语句的实际作用是将程序跳的正确的地方,将continue语句和break语句直接搬到混淆平坦后的代码中,可能会出现break语句执行后跳的switch外面,此时控制变量的值没有改变,依然会执行原来的case,造成死循环,因此我们将continue语句和break语句在TRANSFORM_SEQUENCE中进行处理,通过改变相应的控制变量的值,使执行步骤跳到正确的位置。TRANSFORM_SEQUENCE伪代码如下:
Figure BDA0002209876790000142
Figure BDA0002209876790000144
Figure BDA0002209876790000161
当前语句块是do语句块时,调用TRANSFORM_DO对其进行处理,TRANSFORM_DO伪代码如下:
Figure BDA0002209876790000162
Figure BDA0002209876790000163
Figure BDA0002209876790000164
Figure BDA0002209876790000171
Figure BDA0002209876790000172
Figure BDA0002209876790000173
对于do的体,进一步调用TRANSFORM_BLOCK进行分块,然后再对分出的各个块调用相应的处理函数进行处理。do语句块经过处理后,其产生的case,作为流程控制结构的内层switch下的case节点,补充补充流程控制结构的语法树节点,如果do语句前面有标签,则将标签添加到case value of entry所对应的case块下的第一条语句前面。
当前语句块是for语句时,调用TRANSFORM_FOR对其进行处理,TRANSFORM_FOR伪代码如下:
Figure BDA0002209876790000181
Figure BDA0002209876790000182
Figure BDA0002209876790000191
对于for的体,进一步调用TRANSFORM_BLOCK进行分块,然后再对分出的各个块调用相应的处理函数进行处理。for语句中的初始化表达式、条件表达式及第三表达式在混淆后分别对应3个case,for语句混淆平坦后可能形成多个case,处理后每个case作为流程控制结构的内层switch下的case语法树节点。如果for语句前面有标签,则将标签添加到for的初始化表达式前。
在优选的实施例中,程序中会存在异常处理,异常指的是程序在执行期间产生的问题,本实施例中采用TRANSFORM_TRY对异常语句进行处理。TRANSFORM_TRY伪代码如下:
Figure BDA0002209876790000201
Figure BDA0002209876790000202
Figure BDA0002209876790000203
Figure BDA0002209876790000211
正常情况下流程控制结构只会有一个while-switch结构,但涉及到异常时,在一个while-switch的某个case下会有一个或多个while-switch,简单的将其包含的块作为流程控制结构中的一个case部分,会违背异常处理的逻辑。
异常是程序在执行期间产生的问题。C++异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。异常提供了一种转移程序控制权的方式。C++异常处理涉及到两个块,try块和catch块。Catch块表示在想要处理问题的地方,通过异常处理程序捕获异常。catch关键字用于捕获异常。try块中的代码标识将被激活的特定异常。它后面通常跟着一个或多个catch块,形成try-catch块;如果有一个块抛出一个异常,捕获异常的方法会使用try和catch关键字。try块中放置可能抛出异常的代码,try块中的代码被称为保护代码。如果try块在不同的情境下会抛出不同的异常,这个时候可以尝试罗列多个catch语句,形成try-catch块用于捕获不同类型的异常。
将异常处理指令从try块里面移出,移出的指令将不会被异常机制保护,且原来try块里抛出的异常将不会被捕捉,因此需要对try-catch块单独进行平坦处理。在单独对其处理时,每个try-catch块有一个while-switch结构与之对应,这样混淆后函数体内可能有二个以上的while-switch结构,当程序需要跳出while-switch结构时,可能会有从控制结构内层跳转到控制结构外层的情况,因此需要在每层控制结构的while前面添加一个标签,使用goto从内层控制结构跳到外层控制结构。
具体的,定义三个栈类型的全局变量,第一全局变量、第二全局变量和第三全局变量,以辅助异常处理。第一全局变量记录各层控制结构对应的标签和控制变量,其元素类型为std::pair<VarDecl*,LabelDecl*>。第二全局变量记录break语句所对应的流程控制结构层(即第一全局变量中对应的元素)及break所在语句块执行完毕应转向所对应的流程控制结构while-switch中switch的哪一个case部分,其元素类型为std::pair<int,int>。第三全局变量记录continue语句所对应的流程控制结构(即第一全局变量中对应的元素)及continue所在语句块执行完毕后应转向所对应的流程控制结构while-switch中switch的哪一个case部分,其元素类型为std::pair<int,int>。在生成一个while-switch结构时,会在该结构前面生成一个标签,并且将控制变量及标签压入第一全局变量所表示的栈。在处理while,for,do的体之前,会将当前对应的流程结构层次及break之后控制流应转向流程控制结构中对应的case压入第二全变量所表示的栈。同样的,需将当前对应的流程结构层次及continue后控制流应转向流程控制结构中对应的case压入第三全局变量所表示的栈。另外,在处理switch语句的体之前,也应向第二全局变量压入一个相应的元素,switch语句中不存在continue语句,所以不需要向第三全局变量所表示的栈中压入元素。在处理顺序语句块中的语句时,若遇到一个break语句,则从第二全局变量中读取栈顶元素,即当前break语句应处的流程结构层次及应转向的case。如果该流程结构层次与第一变量中的元素个数不等,则应使用goto语句跳转到该流程结构层次前面的标签处,否则可以直接break跳出。上述不同类型的语句,若其位于源代码中关键字try后面的花括号中,则对其进行平坦处理后产生的case应属于try所对应的流程控制结构的switch,否则属于函数体对应的流程控制结构的switch。try语句的catch中的内容平坦处理后可以放在外层的while-switch流程控制结构中,然后替换catch中原有的内容,设置外层的控制变量为相应的值。
每一个try-catch块都会有一个与其对应的控制变量语法树节点和流程控制结构语法树节点,该控制变量及流程结构均处于try{}中。
步骤S700、用新生成的语法树节点替换相应的原语法树节点;
具体的,对于不含try-catch块的函数,当函数体内的语句处理完毕后,用函数体开始处的变量声明语句对应的语法树节点、函数体对应的流程控制变量定义声明语句对应的语法树结点、函数体对应的流程控制结构的语法树结点替换原来函数体中的节点;对于包含try-catch块的函数当关键字try后面花括号中语句处理完毕后,用其对应的控制变量及控制流程结构的语法树结点替换其原有结点,得到平坦处理后的抽象语法树。
步骤S800、根据修改后的语法树输出源代码。
具体的,对抽象语法树进行修改完成后,在编译器前端根据修改后的抽象语法树转换成平坦处理的程序,该程序的控制流结构发生改变,难以利用静态分析工具重建出原始的函数控制流图,增加了代码的安全性,防止代码被恶意逆向分析。
在优选的实施例中,步骤S800具体包括:
步骤S810、创建一个与源文件类型一致的空白文件。
具体的,创建一个空白的C/C++文件,该文件与原始源文件的类型相同,类型相同指的是原始源文件为C文件时,创建的空白文件为C文件,原始源文件为C++文件时,创建的空白文件为C++文件。根据源文件的类型,创建一个与源文件类型一致的空白文件,以使得输出的程序的文件类型与源文件一致。
步骤S820、将源文件包含的头文件按正确语法形式输出到所述空白文件。
具体的,将获取的头文件,例如cstdio、stdio.h、math.h等按照头文件包含的语法形式,输出到创建的空白文件中。将头文件按照其语法形式输出到空白文件中,得到一个头文件与源文件的头文件相符的半空白的文件。
步骤S830、将语法树中的顶级声明按正确语法形式输出到所述空白文件。
具体的,将修改后的抽象语法树中的顶级声明,如声明或定义的全局变量等,按其正确的语法形式输出到创建的空白文件中,根据修改后的抽象语法树,变换输出得到相对应的平坦后的C/C++源代码。平坦处理后得到的时C/C++源代码,其可以被各种编译器编译,可被移植到各种平台,具有很强的可移植性。
从上述技术方案可以看出,本实施例提供了一种基于编译器前端实现控制流平坦的方法,实现了在编译器前端抽象语法树进行控制流平坦处理,改变程序中原有的控制流结构,使破解者无法利用静态分析工具重建出原始的函数控制流图,并根据修改后的抽象语法树输出得到C/C++源代码,能经各种编译器编译成特定平台上的二进制代码,从而在特定运平台上运行,使得代码兼备安全性和可移植性。
需要说明的是,对于方法实施例,为了简单描述,故将其都表述为一系列的动作组合,但是本领域技术人员应该知悉,本发明实施例并不受所描述的动作顺序的限制,因为依据本发明实施例,某些步骤可以采用其他顺序或者同时进行。其次,本领域技术人员也应该知悉,说明书中所描述的实施例均属于优选实施例,所涉及的动作并不一定是本发明实施例所必须的。
如图3所示,本发明的另一个实施例所提供的一种基于编译器前端实现字符串混淆的系统,包括:代码编译模块10、语句检查模块20、平坦处理模块30、代码输出模块40,其中:
代码编译模块10用于分析处理源文件得到源文件对应的语法树及其包含的头文件;
语句检查模块20用于检查语法树中的每一个函数,找出包含选择语句或循环语句的第一类函数;在第一类函数中分析判断出所有变量声明语句都能移动到函数体开始处的第二类函数;
平坦处理模块30用于将第二类函数的变量声明语句移动到函数体开始处得到第三类函数;根据第三类函数生成控制变量对应的语法树节点和流程控制结构所对应的语法树节点;第三类函数中除函数体开始处的变量声明语句外,对函数体内的语句进行分块并对各个块进行处理得到相应的语法树节点,将各个块进行处理得到相应的语法树节点插入到流程控制结构所对应的语法树节点中;用新生成的语法树节点替换相应的原语法树节点;
代码输出模块40用于根据修改后的语法树输出源代码。
从上述技术方案可以看出,本实施例提供了一种基于编译器前端实现控制流平坦的系统,实现了在编译器前端抽象语法树进行控制流平坦处理,改变程序中原有的控制流结构,使破解者无法利用静态分析工具重建出原始的函数控制流图,并根据修改后的抽象语法树输出得到C/C++源代码,能经各种编译器编译成特定平台上的二进制代码,从而在特定运平台上运行,使得代码兼备安全性和可移植性。
对于系统实施例而言,由于其与方法实施例基本相似,所以描述的比较简单,相关说明书之处参见方法实施例的部分说明即可。
如图4所示,本发明还提供一种设备,其包括至少一个处理器50和存储器52,还可以包括通信接口53,总线54和显示屏51。其中,处理器、显示屏、存储器和通信接口之间可以通过总线完成相互间的通信。显示屏设置为显示初始设置模式中预设的用户引导界面。通信接口可以传输信息。处理器可以处理和调用存储器中的逻辑指令,以执行上述实施例中的方法。
在本发明所提供的实施例中,应该理解到,所揭露的方法、系统及设备,可以通过其它的方式实现。例如,以上所描述的系统实施例仅仅是示意性的,例如,所述模块的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。本领域内的技术人员应明白,本发明实施例的实施例可提供为方法、装置、或计算机程序产品。因此,本发明实施例可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本发明实施例可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。这些计算机程序指令也可装载到计算机或其他可编程数据处理终端设备上,使得在计算机或其他可编程终端设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程终端设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。

Claims (10)

1.一种控制流平坦的方法,其特征在于,包括步骤:
分析处理源文件得到源文件对应的语法树及其包含的头文件;
检查语法树中的每一个函数,找出包含选择语句或循环语句的第一类函数;在第一类函数中分析判断出所有变量声明语句都能移动到函数体开始处的第二类函数;
将第二类函数的变量声明语句移动到函数体开始处得到第三类函数;
根据第三类函数生成控制变量对应的语法树节点和流程控制结构所对应的语法树节点;
第三类函数中除函数体开始处的变量声明语句外,对函数体内的语句进行分块并对各个块进行处理得到相应的语法树节点,将各个块进行处理得到相应的语法树节点插入到流程控制结构所对应的语法树节点中;
用新生成的语法树节点替换相应的原语法树节点;
根据修改后的语法树输出源代码。
2.根据权利要求1所述的控制流平坦的方法,其特征在于,所述在第一类函数中分析判断出所有变量声明语句都能移动到函数体开始处的第二类函数的步骤中,第二类函数是指将变量声明语句移动到函数体开始处时不会对程序的逻辑及输出结果造成实质影响的函数。
3.根据权利要求2所述的控制流平坦的方法,其特征在于,所述将第二类函数的变量声明语句移动到函数体开始处得到第三类函数的步骤具体包括:
判断变量声明语句中是否包含初始化表达式,若有则将变量声明语句拆分成不含初始化表达式的变量声明和与初始化表达式等价的语句,将不含初始化表达式的变量声明移到函数开始处,将与初始化表达式等价的语句留在原来位置。
4.根据权利要求3所述的控制流平坦的方法,其特征在于,所述在根据第三类函数生成控制变量对应的语法树节点和流程控制结构所对应的语法树节点的步骤中,流程控制结构为:
While-Switch结构,所述While-Switch结构外层是一个while循环,控制表达式为控制变量不等于退出值,退出值为预设的任意值,所述Whlie-Switch结构内层是一个switch语句,控制表达式为控制变量的值。
5.根据权利要求4所述的控制流平坦的方法,其特征在于,所述第三类函数中除函数体开始处的变量声明语句外,对函数体内的语句进行分块并对各个块进行处理得到相应的语法树节点步骤中,分块为:
将函数体内的语句根据出现的前后顺序和种类分成多个语句块,其中if语句,switch语句,do语句,while语句,for语句,复合语句,try block语句各自成一块,其余连续或单独的语句成一个块。
6.根据权利要求5所述的控制流平坦的方法,其特征在于,所述在第三类函数中除函数体开始处的变量声明语句外,对函数体内的语句进行分块并对各个块进行处理得到相应的语法树节点步骤中,对各个块进行处理得到相应的语法树节点具体步骤包括:
判断语句块的类型;
调用相应的程序对语句块进行处理;
根据处理结果生成对应的语法树节点。
7.根据权利要求6所述的控制流平坦的方法,其特征在于,所述用新生成的语法树节点替换相应的原语法树节点步骤具体包括:
对不含try-catch块的函数,当函数体内的语句处理完毕后,用函数体开始处的变量声明语句对应的语法树节点、函数体对应的流程控制变量定义声明语句对应的语法树结点和函数体对应的流程控制结构的语法树结点替换原来函数体中的节点,对于包含try-catch块的函数当关键字try后面花括号中语句处理完毕后,要用其对应的控制流程结构及控制变量的语法树结点替换其原有结点。
8.根据权利要求7所述的控制流平坦的方法,其特征在于,所述根据修改后的语法树输出平坦处理后的源代码的步骤具体包括:
创建一个与源文件类型一致的空白文件;
将源文件包含的头文件按正确语法形式输出到所述空白文件;
将语法树中的顶级声明按正确语法形式输出到所述空白文件。
9.一种基于编译器前端实现控制流平坦的系统,其特征在于,包括:
代码编译模块、所述代码编译模块用于分析处理源文件得到源文件对应的语法树及其包含的头文件;
语句检查模块、所述语句检查模块用于检查语法树中的每一个函数,找出包含选择语句或循环语句的第一类函数;
在第一类函数中分析判断出所有变量声明语句都能移动到函数体开始处的第二类函数;
平坦处理模块、所述平坦处理模块用于将第二类函数的变量声明语句移动到函数体开始处得到第三类函数;
根据第三类函数生成控制变量对应的语法树节点和流程控制结构所对应的语法树节点;
第三类函数中除函数体开始处的变量声明语句外,对函数体内的语句进行分块并对各个块进行处理得到相应的语法树节点;
将各个块进行处理得到相应的语法树节点插入到流程控制结构所对应的语法树节点中;
用新生成的语法树节点替换相应的原语法树节点;代码输出模块、所述代码输出模块用于根据修改后的语法树输出平坦处理后的源代码。
10.一种基于编译器前端实现控制流平坦的设备,其特征在于:包括有处理器,以及与所述处理器连接的存储器;
所述存储器存储有基于编译器前端实现控制流平坦的程序,所述基于编译器前端实现控制流平坦的程序被所述处理器执行时实现如权利要求1-8任一所述的基于编译器前端实现控制流平坦的方法。
CN201910894799.6A 2019-09-20 2019-09-20 一种基于编译器前端实现控制流平坦的方法、系统及设备 Active CN110673852B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN201910894799.6A CN110673852B (zh) 2019-09-20 2019-09-20 一种基于编译器前端实现控制流平坦的方法、系统及设备

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN201910894799.6A CN110673852B (zh) 2019-09-20 2019-09-20 一种基于编译器前端实现控制流平坦的方法、系统及设备

Publications (2)

Publication Number Publication Date
CN110673852A true CN110673852A (zh) 2020-01-10
CN110673852B CN110673852B (zh) 2023-06-23

Family

ID=69077331

Family Applications (1)

Application Number Title Priority Date Filing Date
CN201910894799.6A Active CN110673852B (zh) 2019-09-20 2019-09-20 一种基于编译器前端实现控制流平坦的方法、系统及设备

Country Status (1)

Country Link
CN (1) CN110673852B (zh)

Cited By (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111708572A (zh) * 2020-05-20 2020-09-25 西安理工大学 一种基于Clang程序结构的控制流程图自动生成方法
CN111857811A (zh) * 2020-07-29 2020-10-30 湖南泛联新安信息科技有限公司 一种资源流图的构建方法
CN113641361A (zh) * 2021-06-28 2021-11-12 武汉极意网络科技有限公司 一种基于Clang的代码隐藏方法及装置
WO2023284172A1 (zh) * 2021-07-14 2023-01-19 苏州浪潮智能科技有限公司 一种控制流平坦化自动检测方法、装置

Citations (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20100199354A1 (en) * 2006-12-21 2010-08-05 Johan Eker Obfuscating Computer Program Code
US20120159458A1 (en) * 2010-12-17 2012-06-21 Microsoft Corporation Reconstructing program control flow
CN108021790A (zh) * 2017-12-28 2018-05-11 江苏通付盾信息安全技术有限公司 文件保护方法、装置、计算设备及计算机存储介质
CN108710787A (zh) * 2018-03-26 2018-10-26 江苏通付盾信息安全技术有限公司 代码混淆方法及装置、计算设备、计算机存储介质
CN109711118A (zh) * 2018-12-29 2019-05-03 上海上讯信息技术股份有限公司 一种基于插件化的iOS安全编译器及安全编译方法

Patent Citations (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20100199354A1 (en) * 2006-12-21 2010-08-05 Johan Eker Obfuscating Computer Program Code
US20120159458A1 (en) * 2010-12-17 2012-06-21 Microsoft Corporation Reconstructing program control flow
CN108021790A (zh) * 2017-12-28 2018-05-11 江苏通付盾信息安全技术有限公司 文件保护方法、装置、计算设备及计算机存储介质
CN108710787A (zh) * 2018-03-26 2018-10-26 江苏通付盾信息安全技术有限公司 代码混淆方法及装置、计算设备、计算机存储介质
CN109711118A (zh) * 2018-12-29 2019-05-03 上海上讯信息技术股份有限公司 一种基于插件化的iOS安全编译器及安全编译方法

Non-Patent Citations (3)

* Cited by examiner, † Cited by third party
Title
CSDN用户:GDUTXIAOXU: "Android 代码混淆语法讲解及常用模板", 《CSDN,网址:HTTPS://BLOG.CSDN.NET/GDUTXIAOXU/ARTICLE/DETAILS/78253651》 *
SAMUEL NDICHU 等: "A machine learning approach to detection of JavaScript-based attacks using AST features and paragraph vectors", 《APPLIED SOFT COMPUTING JOURNAL》 *
张清泉: "基于Clang的C++代码混潜工具设计与实现", 《中国优秀硕士学位论文全文数据库 (基础科学辑)》 *

Cited By (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111708572A (zh) * 2020-05-20 2020-09-25 西安理工大学 一种基于Clang程序结构的控制流程图自动生成方法
CN111708572B (zh) * 2020-05-20 2022-11-25 西安理工大学 一种基于Clang程序结构的控制流程图自动生成方法
CN111857811A (zh) * 2020-07-29 2020-10-30 湖南泛联新安信息科技有限公司 一种资源流图的构建方法
CN111857811B (zh) * 2020-07-29 2023-09-22 湖南泛联新安信息科技有限公司 一种资源流图的构建方法
CN113641361A (zh) * 2021-06-28 2021-11-12 武汉极意网络科技有限公司 一种基于Clang的代码隐藏方法及装置
CN113641361B (zh) * 2021-06-28 2024-01-26 武汉极意网络科技有限公司 一种基于Clang的代码隐藏方法及装置
WO2023284172A1 (zh) * 2021-07-14 2023-01-19 苏州浪潮智能科技有限公司 一种控制流平坦化自动检测方法、装置

Also Published As

Publication number Publication date
CN110673852B (zh) 2023-06-23

Similar Documents

Publication Publication Date Title
CN112100054B (zh) 一种面向数据管控的程序静态分析方法和系统
Hegedűs Towards analyzing the complexity landscape of solidity based ethereum smart contracts
CN110673852B (zh) 一种基于编译器前端实现控制流平坦的方法、系统及设备
US9128722B2 (en) Systems, methods, and computer-readable media for fertilizing machine-executable code
US8141035B2 (en) Method for accessing internal states of objects in object oriented programming
Combemale et al. Reifying concurrency for executable metamodeling
CN106547520B (zh) 一种代码路径分析方法及装置
EP1636701A2 (en) An intermediate representation for multiple exception handling models
US10303467B2 (en) Target typing-dependent combinatorial code analysis
Kinder Static analysis of x86 executables
Davis et al. The reflective Milawa theorem prover is sound (down to the machine code that runs it)
Cimato et al. Overcoming the obfuscation of Java programs by identifier renaming
Cifuentes et al. Experience in the design, implementation and use of a retargetable static binary translation framework
US20170075668A1 (en) Methods and Systems for Generating Client-Server Applications for Target Devices
Tuong et al. Deeply integrating C11 code support into Isabelle/PIDE
CN110413283B (zh) 基于编译器前端的混淆方法、存储介质及终端设备
Schrans et al. Flint for safer smart contracts
Blanchard et al. Logic against ghosts: comparison of two proof approaches for a list module
Wang Type system for resource bounds with type-preserving compilation
Penttilä Improving C++ software quality with static code analysis
CN114003868A (zh) 一种处理软件代码的方法和电子设备
Bedadala et al. Generation of Call Graph for Java Higher Order Functions
Grigorev et al. String-embedded language support in integrated development environment
Tuong et al. Isabelle/C
Mista et al. Deriving compositional random generators

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