首页> 中国专利> 一种基于反汇编的源码解析装置

一种基于反汇编的源码解析装置

摘要

本发明提供了一种基于反汇编的源码解析装置,包括输入模块、指令和数据分离模块及指令反汇编模块,其中,输入模块,用于读取目标代码至内存;指令和数据分离模块,用于对输入模块读进来的目标代码进行分析以分离出指令代码和数据;指令反汇编模块,用于对目标代码的指令代码和数据分别进行反汇编,生成目标代码对应的汇编文件。本源码解析装置首先分离目标代码中的指令代码和数据,在使用反汇编工具进行反汇编时能够直接针对指令代码和数据进行有针对性的处理,避免数据对指令代码反汇编工作造成干扰,提高反汇编效率。

著录项

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2022-10-21

    实质审查的生效 IPC(主分类):G06F 8/53 专利申请号:2022102542339 申请日:20220315

    实质审查的生效

说明书

技术领域

本发明属于软件分析技术领域,尤其是涉及一种基于反汇编的源码解析装置。

背景技术

逆向工程又称软件反向工程,是指从可运行的程序系统出发, 运用反汇编、系统分析、程序理解等多种计算机技术,对软件的结构、流程、算法、代码等进行逆向拆解和分析,推导出软件产品的源代码、设计原理、结构、算法、处理过程、运行方法及相关文档等。可以简单理解为通过识别并分析计算机软件的源代码来构造出一个新的系统轮廓。它对计算机软件的原始系统进行基础分析,继而识别系统软件的构成部分,通过将软件各组成部分的关系明确化而构造全新的、高级的软件系统。通常,人们把对软件进行反向分析的整个过程统称为软件逆向工程,把在这个过程中所采用的技术都统称为软件逆向工程技术。

通过软件逆向技术可以探究目前软件防护的漏洞,有针对的对现有软件成果的保护进行审查,或者实现在生产环境无源码的情况下进行对软件的调试以及功能修复。亦或者通过对恶意程序的审查,然后进行恶意行为的限制等。

反编译技术可以分为两大类,一种是针对虚拟机进行的反编译,即基于字节码的反编译,另外一种是针对真正机器指令的反编译,即基于机器码的反编译。前者是针对虚拟机的反编译,后者是针对真实的反编译。

从高级语言(C++)编译成最低级语言(汇编),是编译器的工作,但是这个过程不是完全可逆的。目前,经过大量研究人们研发出了一些反汇编工具,能够在一定程度上帮助用户将目标代码反汇编成汇编代码或源代码,例如ILspy等,但是这一类工具无法对目标代码中的指令代码和数据进行分离,需要用户人工分离或直接对所有代码进行反汇编,而这会增加反汇编工作的工作量,导致反汇编效率降低。另外,这一类工具也无法区分用户自定义函数和系统库函数,无差别地对两类函数进行反汇编,这也会增加反汇编的工作量,甚至提高反汇编的错误率。

发明内容

本发明的目的是针对上述问题,提供一种基于反汇编的源码解析装置。

为达到上述目的,本发明采用了下列技术方案:

一种基于反汇编的源码解析装置,包括输入模块、指令和数据分离模块及指令反汇编模块,其中,

输入模块,用于读取目标代码至内存;

指令和数据分离模块,用于对输入模块读进来的目标代码进行分析以分离出指令代码和数据;

指令反汇编模块,用于对目标代码的指令代码和数据分别进行反汇编,生成目标代码对应的汇编文件。

在上述的基于反汇编的源码解析装置中,所述的输入模块通过以下方式读取目标代码至内存:

A1.从目标二进制格式文件中读取若干个字节存放到 Content对象里;

A2.将Content对象存放到Vector容器里;

A3.重复步骤A1和A2,直到文件结尾。

在上述的基于反汇编的源码解析装置中,所述的指令和数据分离模块通过以下方式分离出指令代码和数据:

B1.跟踪指令控制流,遍历并标识出每条指令;

B2.将指令流可到达的代码部分标识为指令代码,其余部分标识为数据。

在上述的基于反汇编的源码解析装置中,步骤B1中,指令和数据分离模块通过以下方式跟踪指令控制流:

B11.将PC值设为0;

B12.从Vector容器中取出特定的Content对象;

B13.将取出的Content对象标识为指令,并标记该指令为已经访问过;

B14.判断步骤B13中标识的指令是否为程序结束指令,若是,则执行步骤B15,否则执行B16;

B15.继续判断显示表是否为空,若是,则结束跟踪,否则从显示表中取出一个Elem元素,并判断Elem元素中addr地址处的指令是否访问过,若没有,则恢复包括PC值的当前现场信息并回到步骤B12,若有,则对下一个Elem元素中addr地址处的指令是否访问过进行判断,直到遍历所有Elem元素后结束跟踪;

B16.进一步判断B13中标识的指令是否为转移指令,若是,则根据具体转移指令,更新PC值、显示表、返回表,否则将PC 自增,并回到步骤B12。

在上述的基于反汇编的源码解析装置中,步骤B16中,更新 PC值、显示表、返回表的具体步骤如下:

若为无条件转移指令,则将此指令所在地址填段表,其显式地址填段表,且将显式地址作为当前PC地址;

若为无条件转移指令子程序调用指令,则将此指令所在地址填段表,返回地址填入返回地址表,显式地址填段表,且将显式地址作为当前PC地址;

若为无条件转移指令中的返回指令,则在返回地址表中按“后进先出”原则找到返回地址,将此指令所在地址填段表,其返回地址填段表,且将返回地址作为当前PC地址;

若为二叉点指令,则将显式地址填入显式地址表,然后将隐式地址作为当前PC地址。

在上述的基于反汇编的源码解析装置中,指令反汇编模块通过以下方式进行反汇编:

C1.从Vector容器里依次取出对象,并根据指令和数据分离模块的分离结果判断该对象是指令代码还是数据;

C2.若对象是指令代码,则将指令代码反汇编成汇编指令形式;若是数据,则将数据翻译成数据的值。

在上述的基于反汇编的源码解析装置中,还包括用于识别库函数的函数识别模块,其该函数识别模块用于执行以下步骤:

C3.将汇编指令代码归一化为中间代码;

C4.提取库函数,并识别系统库函数和用户自定义函数;

C5.恢复用户自定义函数包括名称、参数个数、返回值和类型在内的关键信息。

在上述的基于反汇编的源码解析装置中,步骤C4中,通过动态调试中间代码提取库函数。

在上述的基于反汇编的源码解析装置中,步骤C4中,通过以下方式识别用户自定义函数:

D1.准备若干只有一个库函数调用语句且仅在调用函数的参数方面存在不同的调用程序,

D2.执行步骤D1准备的若干调用程序,并将有效操作指令固定不变的函数确定为用户自定义函数。

在上述的基于反汇编的源码解析装置中,对步骤D2中确定的用户自定义函数进行地址核对,选出最高地址的函数,并将该函数及所有更低地址的函数确定为用户自定义函数。

本发明的优点在于:

1、本源码解析装置首先分离目标代码中的指令代码和数据,在使用反汇编工具进行反汇编时能够直接针对指令代码和数据进行有针对性的处理,避免数据对指令代码反汇编工作造成干扰,提高反汇编效率;

2、使用Vector容器存放Content对象,便于内容提取与标记以及便于后续跟踪指令控制流;

3、通过跟踪PC值的方式跟踪指令控制流能够保证遍历每一条指令,从而确保指令代码与数据分离的彻底分离,保证分离效果;

4、对汇编文件进行处理之前先识别用户自定义函数,分开用户自定义函数和系统库函数,并还原用户自定义函数的关键信息,便于后续的源代码级别代码的还原工作。

附图说明

图1为本发明基于反汇编的源码解析装置的方法流程图;

图2为本发明基于反汇编的源码解析装置中输入模块的工作流程图;

图3为本发明基于反汇编的源码解析装置中分离数据和指令代码的工作流程图;

图4为本发明基于反汇编的源码解析装置中指令反汇编模块的工作流程图;

图5为本发明基于反汇编的源码解析装置中指令反汇编模块对数据和指令代码的具体处理流程图;

图6为函数在存储器中的位置布局示意图。

具体实施方式

下面结合附图和具体实施方式对本发明做进一步详细的说明。

如图1所示,本实施例公开了一种基于反汇编的源码解析装置,包括输入模块、指令和数据分离模块、指令反汇编模块,其中,

输入模块,用于读取目标代码至内存;

指令和数据分离模块,用于对输入模块读进来的目标代码进行分析以分离出指令代码和数据;

指令反汇编模块,用于对目标代码的指令代码和数据分别进行反汇编,生成目标代码对应的汇编文件。

具体地,首先定义一个Content对象的Vector容器,且如图 2所示,输入模块通过以下方式从外部文件中读取二进制格式的文件:

A1.首先定义一个Content对象,从目标二进制格式文件中读取若干个字节存放到Content对象里;每次读取的字节数量由本领域技术人员根据具体情况确定,如针对32位指令的反汇编,可以每次读取4个字节;

A2.将Content对象存放到Vector容器里;

A3.重复步骤A1和A2,直到文件结尾。

具体地,指令和数据分离模块通过以下方式分离出指令代码和数据:

B1.跟踪指令控制流,遍历并标识出每条指令;

B2.将指令流可到达的代码部分标识为指令代码,其余部分标识为数据。

具体地,如图3所示,步骤B1中,指令和数据分离模块通过以下方式跟踪指令控制流:

B11.将PC值设为0;

B12.从Vector容器中取出特定的Content对象,例如,在对 32位操作系统的指令进行反编译时,由于在32位操作系统中,每个指令存储为4个字节,所以这时,特定Content对象是指下标为PC/4的Content对象,表示PC地址除以4然后取整,代表的是每个4字节指令的收尾地址,也就是指令的开始地址;

B13.将取出的Content对象标识为指令,并标记该指令为已经访问过;

B14.判断步骤B13中标识的指令是否为程序结束指令,若是,则执行步骤B15,否则执行步骤B16;

B15.继续判断显示表是否为空,若是,则结束跟踪,否则从显示表中取出一个Elem元素,显示表不为空则代表调用链中有压栈的Elem指令,这些指令仍然映射着Vector容器中的Content 对象,因此本方案在分离的过程中重复该过程,直至显示表没有 Elem元素以实现完全分离效果;

并判断Elem元素中addr地址处的指令是否访问过,若没有,则恢复包括PC值的当前现场信息并回到步骤B12,即将addr地址处的数据压栈置顶,若有,则对下一个Elem元素中addr地址处的指令是否访问过进行判断,直到遍历所有Elem元素后结束跟踪;

B16.进一步判断B13中标识的指令是否为转移指令,若是,则根据具体转移指令,更新PC值、显示表、返回表,否则将PC 自增,并回到步骤B12。该步骤是一个循环遍历过程,用于将识别出的符合指令转移表示的指令进行返回表和显示表的入栈操作。返回表,用于记录程序调用时的返回地址;显示表,碰到双分支指令时,将其显示地址和现场(程序各寄存器的值)填入该表中。

具体地,步骤B16中,更新PC值、显示表、返回表的具体步骤如下:

若为无条件转移指令(B指令等,MOV PC,0x16),则将此指令所在地址填段表,其显式地址填段表,且将显式地址作为当前PC 地址;

若为无条件转移指令子程序调用指令(BL指令),则将此指令所在地址填段表,返回地址填入返回地址表,显式地址填段表, 且将显式地址作为当前PC地址;

若为无条件转移指令中的返回指令(MOV PC,LR),则在返回地址表中按“后进先出”原则找到返回地址,将此指令所在地址填段表,其返回地址填段表,且将返回地址作为当前PC地址;

若为二叉点指令(BEQ,MOVEQ PC,0x16等),则将显式地址填入显式地址表(还要保存当时的寄存器值),然后将隐式地址作为当前PC地址。

段表,是指将所有转移指令除条件转移的转移地址填入此表包括本指令地址和转向地址。通过段表能够得到若干段的代码段,使代码更加清晰明了便于后续的反汇编等工作。进一步地,如图 4和图5所示,指令反汇编模块通过以下方式进行反汇编:

C1.从Vector容器里依次取出对象,并根据指令和数据分离模块的分离结果判断该对象是指令代码还是数据;

C2.若对象是指令代码,则将指令代码反汇编成汇编指令形式;若是数据,则将数据翻译成数据的值。先对代码进行分离,使反汇编器能够分别有针对性地对指令代码进行反汇编,对数据直接进行翻译,提高提高反汇编效率。

进一步地,本装置还包括用于识别库函数的函数识别模块,其该函数识别模块用于执行以下步骤:

C3.将汇编指令代码归一化为中间代码

(Low2levelIntermediateLanguage,LIL),并在转换过程中构建各种符号表,留待后期工作使用;

C4.通过动态调试中间代码提取库函数并识别系统库函数和用户自定义函数;动态调试是指让程序运行起来,可以采用 Ollydbg等动态调试工具。

C5.恢复用户自定义函数包括名称、参数个数、返回值和类型在内的关键信息。

中间代码是源程序的一种内部表示,不依赖目标机的结构,将汇编指令归一化为中间代码再继续后面的工作有助于编译器程序的开发和移植(鲁棒性),同时能够帮助用户更方便地对代码进行优化处理。

指令反汇编模块可以采用只能实现汇编的汇编工具,也可以采用能够实现汇编、编译的汇编工具,本方案优选后者。且这里的函数识别模块可以嵌入汇编工具中,也可以接入汇编工具,采用接入方式时,反汇编工具在对目标代码进行汇编得到汇编文件后将汇编文件输出至函数识别模块进行函数识别,函数识别模块再将识别结果返回给反汇编工具,再由反汇编工具继续对系统库函数和用户自定义函数分别进行控制流分析和数据类型分析等工作完成编译工作进而得到源代码级别的反汇编结果。这里先将用户自定义函数和系统库函数分别开,然后再用汇编工具进行控制流分析和数据类型分析,能够避免用户自定义数据对反汇编工作的影响,提高反汇编效率的同时降低反汇编的错误率。

具体地,步骤C4中,通过以下方式识别用户自定义函数:

D1.准备若干只有一个库函数调用语句且仅在调用函数的参数方面存在不同的调用程序;

D2.执行步骤D1准备的若干调用程序,并将有效操作指令固定不变的函数确定为用户自定义函数。这里的有效操作指令指用户自定义库函数指令的操作码,用户自定义库函数指令的操作码是固定不变的,在编译链接过程中不会发生地址重定位的问题,也不会受到不同版本编译器以及编译优化的影响。所以在不同的调用程序中,同一库函数的有效操作指令是不变的,所以通过上述步骤能够将用户自定义的库函数从系统库函数中分离出来。

进一步地,对步骤D2中确定的用户自定义函数进行地址核对,选出最高地址的函数,并将该函数及所有更低地址的函数确定为用户自定义函数。如图6所示,用户自定义的库函数,其代码是连续存放的,存放顺序与它们在源程序中的定义顺序一致,并且用户自定义库函数代码位于低地址,系统库函数代码位于高地址,所以通过该方法,能够有效地将用户自定义的库函数从系统库函数中分离出来。

本文中所描述的具体实施例仅仅是对本发明精神作举例说明。本发明所属技术领域的技术人员可以对所描述的具体实施例做各种各样的修改或补充或采用类似的方式替代,但并不会偏离本发明的精神或者超越所附权利要求书所定义的范围。

尽管本文较多地使用了输入模块、指令和数据分离模块、函数识别模块、指令反汇编模块等术语,但并不排除使用其它术语的可能性。使用这些术语仅仅是为了更方便地描述和解释本发明的本质;把它们解释成任何一种附加的限制都是与本发明精神相违背的。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号