CN103019739A - 重定位表的修复方法、程序脱壳方法及相关装置 - Google Patents
重定位表的修复方法、程序脱壳方法及相关装置 Download PDFInfo
- Publication number
- CN103019739A CN103019739A CN2012105877218A CN201210587721A CN103019739A CN 103019739 A CN103019739 A CN 103019739A CN 2012105877218 A CN2012105877218 A CN 2012105877218A CN 201210587721 A CN201210587721 A CN 201210587721A CN 103019739 A CN103019739 A CN 103019739A
- Authority
- CN
- China
- Prior art keywords
- address
- data rewriting
- data
- information
- cryptor
- 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
Links
Images
Landscapes
- Stored Programmes (AREA)
Abstract
本发明公开了一种重定位表的修复方法、程序脱壳方法及相关装置,该方法包括:记录运行加壳程序过程中产生的数据改写信息和模块加载信息;在确定加壳程序对应的原始程序的OEP后,将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表;若搜寻到待选重定位表,获取在到达OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为所述加壳程序对应的原始程序的重定位表;若搜寻不到,重新建立重定位表。方案可以适用于修复各种加壳程序对应的原始程序的重定位表,方法简单,修复效率高。
Description
技术领域
本发明涉及计算机技术领域,尤指一种重定位表的修复方法、程序脱壳方法及相关装置。
背景技术
加壳是可执行程序资源压缩的简称,是保护文件的常用手段,其原理是利用特殊的算法,对可执行程序里的资源进行压缩、加密。加壳程序可以直接运行,但是不能获取原始程序,要经过脱壳才可以获取。脱壳的过程主要为三步:第一步,确定原始程序的入口点(Original Entry Point,OEP);第二步,修复导入表和重定位表;第三步,将内存中的原始程序写入文件,更改程序的新入口地址为OEP,这一步通常称为转储(Dump)。修复重定位表是非常关键的步骤。
下面介绍重定位表的概念。
有的可执行程序,加载到内存中运行时,加载基地址是不固定的,因此可执行程序中有绝对寻址的地方需要加上实际加载基地址与默认加载基地址的差值。
假设dll类型的可执行程序的默认加载基地址是0x10000000,它的程序中有如下汇编代码:
mov eax,[0x10001000]。
该代码表示将地址为0x10001000中的数据传递给eax,也就是将默认加载基地址偏移0x1000后的地址中的数据传递给eax。
但是当这个dll类型的可执行程序的实际加载基地址为0x600000000时,这个代码就有问题了,必须改成下面的代码才正确:
mov eax,[0x60002000]。
在这里需要一个修正偏移,也就是dll类型的可执行程序的默认加载地址和实际加载地址的差值,即0x60002000-0x10001000=0x50000000,这样才能保证寻址正确。
因此,这类可执行文件需要一个重定位表,来存放每一个需要修正偏移的项,也称为重定项。操作系统在加载可执行程序时,在发现重定位表后,会解析重定位表,得到每一个重定位项,然后填充差值到每一个需要修正偏移的项。
要想对有重定位表的原始程序加壳,所加的壳必须能处理重定位表,原始程序加壳后,新的重定位表是壳自身的重定位表,原始程序需要修正偏移的项不再由操作系统自身来修正,而是由壳来修正。
当加壳程序运行到OEP后,此时加壳程序虽然需要修正偏移的项已经被壳修正,但是重定位表却不一定正确,这样即便dump,下次运行时系统仍然不能修正加壳程序需要重定位的数据,导致加壳程序崩溃。所以要想完成脱壳,还必须修复加壳程序对应的原始程序的重定位表。
目前,在修复重定位表时,通常会采用特征定位法,根据已知类型壳的特征对加壳程序对应的原始程序的重定位表进行修复,现有的产品有针对具体壳的脱壳脚本或自动脱壳机等。这种方法在修复重定位表时成功率很高,修复得完美,但是一旦已知类型壳升级可能导致特征定位失效,并且对于使用未知类型壳的加壳程序对应的原始程序的重定位表不能使用。因此,现有的重定位表修复方法并不能普遍适用于修复各种加壳程度对应的原始程序的重定位表。
发明内容
本发明实施例提供一种重定位表的修复方法、基于加壳程序的脱壳方法及装置,用以解决现有的重定位表修复方法不能普遍适用于修复各种加壳程序对应的原始程序的重定位表的问题。
一种重定位表的修复方法,包括:
记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和终止地址;
在确定所述加壳程序对应的原始程序的入口点OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表;
若搜寻到待选重定位表,获取在到达所述OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为所述加壳程序对应的原始程序的重定位表;
若搜寻不到待选重定位表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的重定位表。
一种重定位表的修复装置,包括:
记录单元,用于记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和终止地址;
搜寻单元,用于在确定所述加壳程序对应的原始程序的入口点OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表;
确定单元,用于若所述搜寻单元搜寻到待选重定位表,获取在到达所述OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为所述加壳程序对应的原始程序的重定位表;若所述搜寻单元搜寻不到待选重定位表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的重定位表。
一种程序脱壳方法,包括:
记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和终止地址;
确定所述加壳程序对应的原始程序的入口点OEP;
修复所述加壳程序对应的原始程序的导入表和重定位表,其中修复重定位表的过程具体包括:在确定所述加壳程序对应的原始程序的OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表;若搜寻到待选重定位表,获取在到达所述OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为所述加壳程序对应的原始程序的重定位表;若搜寻不到待选重定位表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的重定位表;
在文件中存储到达所述加壳程序对应的原始程序的OEP时内存中的原始程序。
一种程序脱壳装置,包括:
记录模块,用于记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和终止地址;
确定模块,用于确定所述加壳程序对应的原始程序的入口点OEP;
修复模块,用于修复所述加壳程序对应的原始程序的导入表和重定位表,其中修复重定位表的过程具体包括:在确定所述加壳程序对应的原始程序的OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表;若搜寻到待选重定位表,获取在到达所述OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为所述加壳程序对应的原始程序的重定位表;若搜寻不到待选重定位表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的重定位表;
存储模块,用于在文件中存储到达所述加壳程序对应的原始程序的OEP时内存中的原始程序。
本发明有益效果如下:
本发明实施例提供的重定位表的修复方法、基于加壳程序的脱壳方法及装置,通过记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和终止地址;在确定所述加壳程序对应的原始程序的入口点OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表;若搜寻到待选重定位表,获取在到达所述OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为所述加壳程序对应的原始程序的重定位表;若搜寻不到待选重定位表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的重定位表。该方案可以适用于修复各种加壳程序对应的原始程序的重定位表,方法简单,修复效率高。
附图说明
图1为本发明实施例中重定位的修复方法的流程图;
图2为本发明实施例中的原始程序加壳及运行时占用的内存空间的示意图;
图3为本发明实施例中重定位的修复装置的结构示意图;
图4为本发明实施例中程序脱壳方法的流程图;
图5为本发明实施例中确定OEP的流程图;
图6为本发明实施例中的可执行程序的结构示意图;
图7为本发明实施例中修复导入表的流程图;
图8为本发明实施例中的导入表的结构示意图;
图9本发明实施例中程序脱壳装置的结构示意图。
具体实施方式
针对现有的重定位表修复方法不能普遍适用于修复各种加壳程序对应的原始程序的重定位表的问题,本发明实施例提供的重定位表的修复方法,该方法的流程如图1所示,执行步骤如下:
S10:记录运行加壳程序过程中产生的数据改写信息和模块加载信息,数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,模块加载信息包括加壳程序映射到内存中的基地址和终止地址。
可以使用虚拟机或者调试器等运行加壳程序,并记录运行过程中产生的数据改写信息和模块加载信息。
S11:在确定加壳程序对应的原始程序的OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合。
S12:根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表,若搜寻到待选重定位表,执行S13;若搜寻不到待选重定位表,执行S14。
S13:获取在到达OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为加壳程序对应的原始程序的重定位表。
这种情况是重定位表未完全破坏的情况,也就是说壳在还原原始程序过程中,原始程序的的重定位表会在某一时刻出现在内存地址的数据中,甚至在一开始加壳程序就保留原始程序的重定位表在可执行程序中。壳解析原始程序的重定位表,然后修正原始程序需要重定位的数据之后,可以选择清除或者不清除这份重定位表。
由于重定位表会在内存地址的数据中出现,所以如果那时将重定位表的数据保存起来,然后在到达OEP后,将保存的重定位表数据填充回去,并更新可执行程序的头部指向的重定位表地址,则成功实现了重定位表的修复,dump后再次运行,可执行程序就能自动解析重定位表。
如果搜寻到多个待选重定位表,可以对搜寻到的待选重定位表进行筛选,如图2所示,在到达OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为加壳程序对应的原始程序的重定位表。
S14:根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立加壳程序对应的原始程序的重定位表。
这种情况是壳可以在一开始就完全破坏掉原始程序的重定位表,用自定义的格式来保存原始程序重定位表,当原始程序还原后,解析自定义格式去修正原始程序需要重定位的数据,这样,任何时刻内存地址的数据中都不可能有原始程序的重定位表出现。
虽然重定位表完全破坏的情况,不会在某一时刻内存地址的数据中完全重现,但是到达OEP时,需要重定位的数据肯定已经被壳修正,所以,如果能找到这些数据的数据改写地址,就可以根据重定位表结构,重新建立一个新的重定位表,脱壳后,系统以后运行都使用的是新的重定位表,系统都可以根据新重定位表解析每一个重定位项,修正需要重定位的数据。
该方案可以适用于修复各种加壳程序对应的原始程序的重定位表,方法简单,修复效率高。
具体的,上述S11中的根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,具体包括:在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
加壳程序运行过程中,会产生大量的数据改写信息,这些数据改写信息有些是相关的,对于获取重定位表是有贡献的,有些则是离散的,不会对获取重定位表有贡献,由于重定位表往往会出现在连续大块被改写的内存地址中,因此:
第一种方案,可以获取数据改写信息连续、并且数据改写地址连续的数据改写信息。
下面以两个具体实例来说明:
例一:在T1、T2、T3、T4、T5、T6这六个连续的时刻记录的数据改写信息如下表所示,A1、A2、A3、B1、B2、B3表示在相应的内存地址写的数据:
内存地址/时间 | T1 | T2 | T3 | T4 | T5 | T6 |
x | A1 | A2 | ||||
x+d1 | B1 | B2 | ||||
x+d2 | C1 | C2 |
从上表中可以看出,共有2*2*2=8种改写数据的组合,但是由于T1-T3是连续的,x-x+d2也是连续的,这也就可以看为一种改写数据的组合,即A1B1C1;同理,由于T4-T6是连续的,x-x+d2也是连续的,也就可以看为一种改写数据的组合,即A2B2C2。也就是说上述六条数据改写信息实际上只是两种改写数据的组合。这样就可以减少改写数据的组合的数量。
例二:在T1、T2、T3……TN这段时间记录的数据改写信息如下表所示,A1、B1……BN、C1表示在相应的内存地址写入的数据:
内存地址/时间 | T1 | T2 | T3 | ...... | TN | 备注 |
x | A1 | ...... | A1 | 始终未被改写 | ||
x+d1 | B1 | B2 | B3 | ...... | BN | 一个循环,写多次 |
x+d2 | C1 | ...... | 始终未被改写 |
在记录的数据改写地址中,会改写很多零散的数据改写地址,可以不考虑这些改写形成的改写数据的组合,上述3N条数据改写信息实际上只有1种改写数据的组合:A1+B1+C1。
第二种方案,还可以获取数据改写信息连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
下面以两个具体实例来说明:
例一:在T1、T2、T3、T4这四个连续的时刻记录的数据改写信息如下表所示,E1T1、E2T2、E1T3、E2T4表示在相应的内存地址写的数据:
从上表中可以看出,共有2*2=4种改写数据的组合,但是由于在T1-T4这四个连续的时刻,E1先对d1执行数据改写,然后E2在对d1执行数据改写,然后E1再对d2执行数据改写,然后E2在对d2执行数据改写,这就可以看成一个循环,因此在在T1-T4这个时间段,改写数据的组合只有两种:E1T1E1T3和E2T1E2T4,这样就可以减少改写数据组合的数量。
例二:在T1、T2、T3、T4这四个连续的时刻记录的数据改写信息如下表所示,E1T1、E2T2、E1T3、E2T4表示在相应的内存地址写的数据:
从上表中可以看出,共有2*2=4种改写数据的组合,但是由于在T1-T4这四个连续的时刻,E1先对d1执行两次数据改写,然后E2再对d2执行两次数据改写,这就可以看成一个循环,因此在在T1-T4这个时间段,改写数据的组合只有两种:E1T1E2T3和E1T2E2T4,这样就可以减少改写数据组合的数量。
当然也可以将第一种方案和第二中方案综合起来考虑。
具体的,上述S11中的根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表,具体包括:
在所有改写数据的组合中搜寻符合下列条件的待选重定位表:
所有重定位块的头部包括基地址和地址长度都落入模块加载信息中包括的基地址和终止地址范围内,并且地址长度为偶数;
每个重定位块包含至少两个重定位项;
每个重定位项指向的数据改写地址在到达OEP的时刻之前最后两次的改写数据的差值等于加壳程序的默认加载基地址与加壳程序映射到内存中的基地址之差;
写入重定位项中的内存地址顺序排列。
重定位表可以由多个重定位块IMAGE_BASE_RELOCATION组成,每个IMAGE_BASE_RELOCATION指向一个基地址和地址长度,重定位块的基地址和地址长度位于重定位块的头部,地址长度也就是该重定位块占用的内存地址大小,基地址和地址长度都必须落入模块加载信息中包括的基地址和终止地址范围内,每一个重定位块的地址长度都是偶数,也就是按偶数地址对齐。
确定重定位块后,可以计算出重定位块中包含的重定位项IMAGE_FIXUP_ENTRY的个数,每个重定位块中至少有两个到重定位项。
每一个重定位项指向的内存地址可以对应4字节数据,并且每个重定位项指向的数据改写地址在到达OEP的时刻之前最后两次的改写数据的差值等于加壳程序的默认加载基地址与加壳程序映射到内存中的基地址之差。
壳在修正需要重定位的数据过程中,通常也是有顺序的,从低到高或从高到低,因此,写入重定位项中的内存地址也是顺序排列的。
根据上面的重定位表的格式搜寻,可能找到多个符合条件的待选重定位表。
具体的,上述S14中的根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立加壳程序对应的原始程序的重定位表,具体包括:计算记录的数据改写信息中每个数据改写地址到达OEP的时刻之前最后两次的改写数据的差值;获取计算的差值等于加壳程序的默认加载基地址与加壳程序映射到内存中的基地址之差的数据改写地址;将获取的数据改写地址中对应的数据改写执行地址相同的数据改写地址分为一组;从所有分组中选取到达OEP的时刻之前最后两次数据改写的数据改写地址顺序排列、且包含的数据改写地址最多的分组;根据选取的分组中每条数据改写信息中包括的数据改写地址生成对应的重定位项;将内存中的原始程序写入文件后,在文件末尾添加一个节,在该节中组合生成的重定位项得到重定位表,并修改文件头部的重定位信息指向得到的重定位表。
当需要重新建立加壳程序对应的原始程序的重定位表时,首先需要计算记录的数据改写信息中每个数据改写地址到达OEP的时刻之前最后两次的改写数据的差值,如下表所示。
然后可以获取计算的差值等于加壳程序的默认加载基地址与加壳程序映射到内存中的基地址之差的数据改写地址,这些数据改写地址中的改写数据有可能是加壳程序对应的原始程序的重定位表中的重定位项,获取这些数据改写地址中的改写数据就有可能得到加壳程序对应的原始程序的重定位表。
由于壳代码在修正重定位数据时,都是在一个循环中,所以,修正重定位项指向内存地址中的数据的数据改写执行地址应该是同一个;修正重定位项指向内存地址中的数据的数据改写地址应该是连续的且有顺序,从小到大或从大到小。例如:可以是0x1000、0x1004、0x1008,不能是0x1000、0x1008、0x1004。
符合条件的数据改写执行地址可能有多个,可以选取重定位项数量最多的那一个,也就是包含的数据改写地址最多的分组中对应的数据改写执行地址,根据选取的分组中每条数据改写信息中包括的数据改写地址生成对应的重定位项;将内存中的原始程序写入文件后,在文件末尾添加一个节,在该节中组合生成的重定位项得到重定位表,并修改文件头部的重定位信息指向得到的重定位表。该文件就是原始程序对应的可执行程序文件。
基于同一发明构思,本发明实施例提供一种重定位表的修复装置,该装置的结构如图3所示,包括:
记录单元30,用于记录运行加壳程序过程中产生的数据改写信息和模块加载信息,数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,模块加载信息包括加壳程序映射到内存中的基地址和终止地址。
搜寻单元31,用于在确定加壳程序对应的原始程序的OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表。
确定单元32,用于若搜寻单元31搜寻到待选重定位表,获取在到达OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为加壳程序对应的原始程序的重定位表;若搜寻单元31搜寻不到待选重定位表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立加壳程序对应的原始程序的重定位表。
具体的,上述搜寻单元31,具体用于:在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
具体的,上述搜寻单元31,具体用于:在所有改写数据的组合中搜寻符合下列条件的待选重定位表:所有重定位块的头部包括基地址和地址长度都落入模块加载信息中包括的基地址和终止地址范围内,并且地址长度为偶数;每个重定位块包含至少两个重定位项;每个重定位项指向的数据改写地址在到达OEP的时刻之前最后两次的改写数据的差值等于加壳程序的默认加载基地址与加壳程序映射到内存中的基地址之差;写入重定位项中的内存地址顺序排列。
具体的,上述确定单元32,具体用于:计算记录的数据改写信息中每个数据改写地址到达OEP的时刻之前最后两次的改写数据的差值;获取计算的差值等于加壳程序的默认加载基地址与加壳程序映射到内存中的基地址之差的数据改写地址;将获取的数据改写地址中对应的数据改写执行地址相同的数据改写地址分为一组;从所有分组中选取到达OEP的时刻之前最后两次数据改写的数据改写地址顺序排列、且包含的数据改写地址最多的分组;根据选取的分组中每条数据改写信息中包括的数据改写地址生成对应的重定位项;将内存中的原始程序写入文件后,在文件末尾添加一个节,在该节中组合生成的重定位项得到重定位表,并修改文件头部的重定位信息指向得到的重定位表。
基于同一发明构思,本发明实施例提供一种程序脱壳方法,该方法的流程如图4所示,包括:
S40:记录运行加壳程序过程中产生的数据改写信息和模块加载信息,数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,模块加载信息包括加壳程序映射到内存中的基地址和终止地址;
S41:确定加壳程序对应的原始程序的OEP。
S42:修复加壳程序对应的原始程序的导入表和重定位表。
S43:在文件中存储到达加壳程序对应的原始程序的OEP时内存中的原始程序。
该方案可以适用于为各种加壳程序脱壳,方法简单,效率较高。
具体的,上述S42中的修复重定位表的过程与上述重定位表的修复方法是相同的,这里不再赘述。
具体的,如图5所示,上述S41中的确定加壳程序对应的原始程序的OEP,具体包括:
S51:根据记录的数据改写信息确定加壳程序运行过程中进入后直到结束没有离开的内存区域。
加壳程序运行的过程中,运行到OEP后,原始程序已还原,后面的流程都是执行原始程序的流程。假设原始程序运行在内存区域A中,那么当到达原始程序的OEP后,即进入内存区域A,直到加壳程序运行结束再也不会离开内存区域A,则时刻T进入内存区域A的那个地址,就是OEP。因此,可以根据记录的数据改写信息确定加壳程序运行过程中进入后直到结束没有离开的内存区域。
S52:获取记录每条数据改写信息后内存区域中每个内存地址的数据,并根据获取的数据计算在对应的数据改写信息中包括的数据改写时间的内存区域的熵值。
在确定出内存区域A后,可以进一步确定到达OEP的数据改写地址和数据改写时间,因为到达内存区域A的时间不一定是到达OEP的时间。可以通过计算每次数据改写后内存区域的熵值来确定到达OEP的数据改写地址和数据改写时刻。
S53:获取熵值开始大于等于设定阈值的数据改写时间对应的数据改写地址为加壳程序对应的原始程序的OEP。
运行加壳程序时,如果在执行壳的代码,内存区域的熵值一般比较小,一旦还原了原始程序,开始执行原始程序的代码后,内存区域的熵值就会变大,并且在执行原始程序的过程中,内存区域的熵值基本不变,因此,可以预先确定一个设定阈值,当熵值开始大于等于设定阈值的数据改写时间对应的数据改写地址就可以认为是加壳程序对应的原始程序的OEP。设定阈值可以根据统计结果预先确定,例如可以为0.9。当然也可以根据统计确定为其他值,这里仅仅是举例进行说明。
该方案可以适用于确定各种加壳程序对应的原始程序的OEP,方法简单,效率高。
具体的,数据改写信息还包括数据改写执行地址时,上述S51中的根据记录的数据改写信息确定加壳程序运行过程中进入后直到结束没有离开的内存区域,具体包括:遍历记录的数据改写信息,获取在连续的数据改写时间对应的时间长度内,数据改写地址连续且连续的数据改写地址对应的内存地址范围大于等于设定长度的内存地址范围作为待选内存区域;根据数据改写信息中包括的数据改写执行地址,确定加壳程序运行过程中进入后直到结束没有离开的最后一个待选内存区域作为内存区域。
由于很多壳在还原原始程序的过程中,会连续改写,也就是说数据改写地址连续是连续的,当连续的数据改写地址的内存地址范围大于等于设定长度时,该内存地址范围可以作为待选内存区域,确定每个待选内存区域对应的时间长度内的数据改写执行地址,若所有的数据改写执行地址都落入对应的待选内存区域内,该待选内存区域为选定内存区域,按时间先后顺序将得到的选定内存区域中的最后一个作为内存区域。设定长度可以根据实际需要进行设定,例如设为512等等。
较佳的,上述程序OEP的确定方法,还包括:记录加壳程序运行过程中产生的模块加载信息,模块加载信息包括加壳程序映射到内存中的基地址和结束地址;以及根据记录的数据改写信息和模块加载信息确定加壳程序运行过程中进入后直到结束没有离开的内存区域。
还可以使用虚拟机或者调试器等运行加壳程序,并记录运行过程中产生的模块加载信息。
那么就可以根据记录的数据改写信息和模块加载信息共同确定加壳程序运行过程中进入后直到结束没有离开的内存区域。
具体的,上述根据记录的数据改写信息和模块加载信息确定加壳程序运行过程中进入后直到结束没有离开的内存区域,可以包括两种方式:
第一种方式,获取加壳程序运行过程中最后一条数据改写信息中包括的数据改写地址;将基地址与获取的最后一条数据改写信息中包括的数据改写地址之间的内存地址范围作为内存区域。
在windows上,可执行程序的格式为可移植执行(Portable Execute,PE)文件格式,常见的扩展名包括exe、dll、sys等。PE文件格式主要由PE头部、节表、节组成,PE文件格式的节保存了原始程序运行的代码节、数据节、资源节等,如图6所示为可执行程序映射到内存空间的示意图,代码节一般是在“基地址-----数据节”的内存地址范围之间,OEP在代码节中,所以可以将代码节与基地址之间的内存地址范围记为内存区域。图6所示为壳还原原始程序的过程,带箭头的实线表示写操作,箭头指向者表示被写的区域。带箭头的虚线表示跳转,箭头指向者表示跳转过去要执行的位置。
利用回溯法,找到加壳程序运行过程中最后一条数据改写信息中包括的数据改写地址,可以认为这次数据改写是加壳程序到达OEP之后才执行的,根据这次改写数据的数据改写地址,可以得到数据节的大致地址;将基地址与获取的最后一条数据改写信息中包括的数据改写地址之间的内存地址范围作为内存区域。
第二种方式,若模块加载信息中包括加壳程序对应的原始程序的资源节,确定资源节映射到内存中的最小内存地址;将基地址与最小内存地址之间的内存地址范围作为内存区域。
首先判断原始程序是否有资源节,若有,确定资源节映射到内存中的最小内存地址;将基地址与最小内存地址之间的内存地址范围作为内存区域。
由于壳很少更改PE文件的资源节,所以可以根据记录的模块加载信息,解析PE文件得到资源节映射到内存中的最小内存地址,设最小内存地址为X,从而得到一个“基地址-----X”的内存地址范围,将该内存地址范围作为内存区域。
具体的,上述S52中的根据获取的数据计算在对应的数据改写信息中包括的数据改写时间的内存区域的熵值,具体包括:确定内存地址中的数据可能的种类;根据获取的数据统计确定出的每种数据出现的次数,以及获取的数据的总个数;用每种数据出现的次数除以获取的数据的总个数得到对应数据出现的频率,计算得到的频率的均值;计算得到的频率的方差,方差作为在对应的数据改写信息中包括的数据改写时间的内存区域的熵值。
在计算机中,一个字节为8位,所以每个字节可以有28=256种数据,统计获取的内存中的字节有相同数据出现的次数,由于还原原始程序后很多内存地址中的数据为0,可以不用统计数据为0出现的次数,也就相当于数据可能的种类是255,用每种数据出现的次数除以获取的数据的总个数即可得到对应数据出现的频率,假设每种数据出现的次数分别为X1、X2……Xn,获取的数据的总个数为N,那么每种数据出现的频率x1=X1/N、x2=X2/N……xn=Xn/N。
计算这些频率的均值x=(x1+x2+……+xn)/255,再计算这些频率的方差s2=[(x1-x)2+(x2-x)2+……+(xn-x)2]/255,此方差作为在对应的数据改写信息中包括的数据改写时间的内存区域的熵值,次方差是恒小于1,也就是说内存区域的熵值恒小于1。
当内存地址中的数据的位数变化时,计算过程是类似的,这里不再赘述。
具体的,如图7所示,上述S42中的修复加壳程序对应的原始程序的导入表的过程,具体包括:
S71:在确定加壳程序对应的原始程序的OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合。
S72:根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表,若搜寻到,执行S73;若搜寻不到,执行S74。
S73:确定每个待选导入表对应的导入地址表,获取在到达OEP的时刻存在于内存中、并且内存地址最小的导入地址表,将获取的导入地址表对应的待选导入表为加壳程序对应的原始程序的导入表。
这种情况是导入表未完全破坏的情况,也就是说壳在还原原始程序过程中,原始程序的的导入表会在某一时刻出现在内存地址的数据中,甚至在一开始加壳程序就保留原始程序的导入表在可执行程序中。壳解析原始程序的导入表,然后填充原始程序的导入地址表后,可以选择清除或者不清除这份导入表。
由于导入表会在内存地址的数据中出现,所以如果那时将导入表的数据保存起来,然后在到达OEP后,将保存的导入表数据填充回去,并更新可执行程序的头部指向的导入表地址,则成功实现了导入表的修复,dump后再次运行,可执行程序就能找到所需的函数库和函数。
如果搜寻到多个待选导入表,可以对搜寻到的待选导入表进行筛选,确定每个待选导入表对应的导入地址表,获取在到达OEP的时刻存在于内存中、并且内存地址最小的导入地址表,将获取的导入地址表对应的待选导入表为加壳程序对应的原始程序的导入表。
S74:根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立加壳程序对应的原始程序的导入表。
这种情况是壳在一开始就完全破坏掉原始程序的导入表,用自定义的格式来保存原始程序的导入表,当原始程序还原后,解析自定义格式去填充原始程序的导入地址表,这样,任何时刻内存地址的数据中都不可能有原始程序的导入表出现。
虽然导入表完全破坏后,整个导入表不会在某一时刻内存地址的数据中完全重现,但是到达OEP时,导入地址表已经被壳正确填充,所以,如果能找到导入地址表,就可以根据函数地址反查得到函数库和函数,再根据导入表结构,重新建立一个新的导入表,脱壳后,系统运行都使用新的导入表,系统就可以根据新导入表填充函数到导入地址表了。
该方案可以适用于修复各种加壳程序对应的原始程序的重定位表,方法简单,修复效率高。
具体的,上述S71中的根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,具体包括:在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
加壳程序运行过程中,会产生大量的数据改写信息,这些数据改写信息有些是相关的,对于获取重定位表是有贡献的,有些则是离散的,不会对获取重定位表有贡献,由于重定位表往往会出现在连续大块被改写的内存地址中,因此:
第一种方案,可以获取数据改写信息连续、并且数据改写地址连续的数据改写信息。
下面以两个具体实例来说明:
例一:在T1、T2、T3、T4、T5、T6这六个连续的时刻记录的数据改写信息如下表所示,A1、A2、A3、B1、B2、B3表示在相应的内存地址写的数据:
内存地址/时间 | T1 | T2 | T3 | T4 | T5 | T6 |
x | A1 | A2 | ||||
x+d1 | B1 | B2 | ||||
x+d2 | C1 | C2 |
从上表中可以看出,共有2*2*2=8种改写数据的组合,但是由于T1-T3是连续的,x-x+d2也是连续的,这也就可以看为一种改写数据的组合,即A1B1C1;同理,由于T4-T6是连续的,x-x+d2也是连续的,也就可以看为一种改写数据的组合,即A2B2C2。也就是说上述六条数据改写信息实际上只是两种改写数据的组合。这样就可以减少改写数据的组合的数量。
例二:在T1、T2、T3……TN这段时间记录的数据改写信息如下表所示,A1、B1……BN、C1表示在相应的内存地址写入的数据:
内存地址/时间 | T1 | T2 | T3 | ...... | TN | 备注 |
x | A1 | ...... | A1 | 始终未被改写 | ||
x+d1 | B1 | B2 | B3 | ...... | BN | 一个循环,写多次 |
x+d2 | C1 | ...... | 始终未被改写 |
在记录的数据改写地址中,会改写很多零散的数据改写地址,可以不考虑这些改写形成的改写数据的组合,上述3N条数据改写信息实际上只有1种改写数据的组合:A1+B1+C1。
第二种方案,还可以获取数据改写信息连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
下面以两个具体实例来说明:
例一:在T1、T2、T3、T4这四个连续的时刻记录的数据改写信息如下表所示,E1T1、E2T2、E1T3、E2T4表示在相应的内存地址写的数据:
从上表中可以看出,共有2*2=4种改写数据的组合,但是由于在T1-T4这四个连续的时刻,E1先对d1执行数据改写,然后E2在对d1执行数据改写,然后E1再对d2执行数据改写,然后E2在对d2执行数据改写,这就可以看成一个循环,因此在在T1-T4这个时间段,改写数据的组合只有两种:E1T1E1T3和E2T1E2T4,这样就可以减少改写数据组合的数量。
例二:在T1、T2、T3、T4这四个连续的时刻记录的数据改写信息如下表所示,E1T1、E2T2、E1T3、E2T4表示在相应的内存地址写的数据:
从上表中可以看出,共有2*2=4种改写数据的组合,但是由于在T1-T4这四个连续的时刻,E1先对d1执行两次数据改写,然后E2再对d2执行两次数据改写,这就可以看成一个循环,因此在在T1-T4这个时间段,改写数据的组合只有两种:E1T1E2T3和E1T2E2T4,这样就可以减少改写数据组合的数量。
当然也可以将第一种方案和第二中方案综合起来考虑。
具体的,模块加载信息还包括加载模块的名称,上述S72中的根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表,具体包括:
在所有改写数据的组合中搜寻符合下列条件的待选导入表:
大小大于等于第一设定字节;
原始第一换长(Original First Thunk,OFT)指向的内存地址不为零,且落入模块加载信息中包括的基地址和结束地址范围内;
OFT指向的内存地址为零,第一换长(First Thunk,FT)指向的内存地址不为零且落入模块加载信息中包括的基地址和结束地址范围内;
模块名称虚拟地址偏移Name RVA与基地址的和指向的内存地址落入模块加载信息中包括的基地址和结束地址范围内,且Name RVA与基地址的和指向的内存地址中的模块包含在模块加载信息包括的加载模块的名称中;
OFT和FT指向的内存地址中的函数包含在模块加载信息包括的加载模块对应的函数中。
对于32位可执行程序来说,导入表中的每个导入描述符IMAGE_IMPORT_DESCRIPTOR大小是20个字节,通常最后还有一个20字节的值全部为0的IMAGE_IMPORT_DESCRIPTOR,所以一个导入表至少40个字节,那么可以先排除大小小于40个字节的改写数据的组合。第一设定字节是根据可执行程序的类型确定的,例如对于32位可执行程序来说,第一设定字节为40个字节。
导入表的结构如图8所示,可以在改写数据的组合中查找OFT指向的内存地址,若不为0,则必须落入加载模块信息中包括的基地址和结束地址范围内,若为0,则查找FT指向的内存地址,若FT也为0,则不符合导入表格式,跳过该内存地址,若FT不为0,也必须落入加载模块信息中包括的基地址和结束地址范围内,才符合导入表的格式。
Name RVA指向的内存地址可以是需要加载模块的内存地址,加载模块可以是dll,也必须落入加载模块信息中包括的基地址和结束地址范围内,并且该内存地址中的模块包含在模块加载信息包括的加载模块的名称中。
导入表的格式要求OFT或FT指向的内存地址中的函数包含在模块加载信息包括的加载模块对应的函数中,例如图8中,可以看到描述KERNEL32.dll的LoadLibraryA和GetProcAddress两个函数,这两个函数都属于KERNEL32.dll的函数,这个IMAGE_IMPORT_DESCRIPTOR符合导入表格式,反之,则不符合,所以肯定不是导入表。
根据上面的格式查找,可能找到多个符合条件的导入表然后可以进一步筛选出真正的导入表。
具体的,数据改写信息还包括改写长度,上述S74中的根据记录的数据改写信息重新建立加壳程序对应的原始程序的导入表,具体包括:
在到达OEP的时刻之前记录的数据改写信息中,获取改写数据为函数地址、改写长度为第二设定字节的数据改写信息;
将获取的数据改写信息中包括的数据改写执行地址相同的数据改写信息分为一组;
从所有分组中选取数据改写地址顺序排列、且包含的数据改写地址最多的分组,选取的分组中的数据改写信息中的改写数据指向的函数包含在模块加载信息包括的加载模块对应的函数中,选取的分组中的数据改写信息中的改写数据指向的函数中归属于同一加载模块的相邻;
根据选取的分组中每条数据改写信息中包括的改写数据,确定加壳程序对应的原始程度的导入地址表;
从确定的导入地址表中获取运行加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;
根据获取的函数库及每个函数库的函数重新建立加壳程序对应的原始程序的导入表。
首先在到达OEP的时刻之前记录的数据改写信息中,获取改写数据为函数地址、改写长度为第二设定字节的数据改写信息。第二设定字节是根据可执行程序的类型来确定的,例如,对于32位可执行程序来说,第二设定字节是4个字节。
下面以32位可执行程序为例进行说明:
首先获取改写长度为4个字节、且改写数据为函数地址的数据改写信息,假设可以得到下表:
执行地址 | 写入地址 | 函数地址 |
E1 | A11 | F11 |
E1 | A12 | F12 |
... | ||
E2 | A21 | F21 |
... | ||
En | An1 | Fn1 |
... |
由于壳代码在填充导入地址表的函数时,都是在一个循环中,因此,填写导入地址表的数据改写执行地址应该是同一个;填写导入地址表时的数据改写地址应该是有顺序的,从小到大或从大到小,例如:可以是0x1000、0x1004、0x1008,不能是0x1000、0x1008、0x1004这种无顺序的;选取的分组中的数据改写信息中的改写数据指向的函数包含在模块加载信息包括的加载模块对应的函数中;选取的分组中的数据改写信息中的改写数据指向的函数中归属于同一加载模块的相邻,例如先写入5个kernel32.dll的函数,再写入3个user32.dll的函数。
根据选取的分组中每条数据改写信息中包括的改写数据,确定加壳程序对应的原始程度的导入地址表;从确定的导入地址表中获取运行加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;根据获取的函数库及每个函数库的函数重新建立加壳程序对应的原始程序的导入表。
较佳的,上述导入表的修复方法,还包括:记录运行加壳程序过程中产生的代码块信息,代码块信息包括代码块的起始地址和结束地址;根据记录的代码块信息重新建立加壳程序对应的原始程序的导入表。
还可以根据代码块信息来重建加壳程序对应的原始程序的导入表。
具体的,上述根据记录的代码块信息重新建立加壳程序对应的原始程序的导入表,具体包括:在到达OEP的时刻之后记录的代码块信息中,获取调用第一个函数的内存地址;根据获取的内存地址,确定加壳程序对应的原始程度的导入地址表;从确定的导入地址表中获取运行加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;根据获取的函数库及每个函数库的函数重新建立加壳程序对应的原始程序的导入表。
在达到OEP时刻之后记录的代码块信息中,获取调用的第一个函数的内存地址,从这里开始,原始程序会访问导入地址表,例如:
mov edi,[0x01001020]//把0x1001020地址中的库函数地址给edi
call edi//调用函数。
所以0x01001020就是导入地址表中的一个地址,得到该地址后,确定加壳程序对应的原始程度的导入地址表;从确定的导入地址表中获取运行加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;根据获取的函数库及每个函数库的函数重新建立加壳程序对应的原始程序的导入表。
基于同一发明构思,本发明实施例提供一种程序脱壳装置,该装置的结构如图9所示,包括:
记录模块90,用于记录运行加壳程序过程中产生的数据改写信息和模块加载信息,数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,模块加载信息包括加壳程序映射到内存中的基地址和终止地址;
确定模块91,用于确定加壳程序对应的原始程序的入口点OEP;
修复模块92,用于修复加壳程序对应的原始程序的导入表和重定位表,其中修复重定位表的过程具体包括:在确定加壳程序对应的原始程序的OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表;若搜寻到待选重定位表,获取在到达OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为加壳程序对应的原始程序的重定位表;若搜寻不到待选重定位表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立加壳程序对应的原始程序的重定位表;
存储模块93,用于在文件中存储到达加壳程序对应的原始程序的OEP时内存中的原始程序。
具体的,上述修复模块92,具体用于:在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
具体的,上述修复模块92,具体用于:在所有改写数据的组合中搜寻符合下列条件的待选重定位表:所有重定位块的头部包括基地址和地址长度都落入模块加载信息中包括的基地址和终止地址范围内,并且地址长度为偶数;每个重定位块包含至少两个重定位项;每个重定位项指向的数据改写地址在到达OEP的时刻之前最后两次的改写数据的差值等于加壳程序的默认加载基地址与加壳程序映射到内存中的基地址之差;写入重定位项中的内存地址顺序排列。
具体的,上述修复模块92,具体用于:计算记录的数据改写信息中每个数据改写地址到达OEP的时刻之前最后两次的改写数据的差值;获取计算的差值等于加壳程序的默认加载基地址与加壳程序映射到内存中的基地址之差的数据改写地址;将获取的数据改写地址中对应的数据改写执行地址相同的数据改写地址分为一组;从所有分组中选取到达OEP的时刻之前最后两次数据改写的数据改写地址顺序排列、且包含的数据改写地址最多的分组;根据选取的分组中每条数据改写信息中包括的数据改写地址生成对应的重定位项;将内存中的原始程序写入文件后,在文件末尾添加一个节,在该节中组合生成的重定位项得到重定位表,并修改文件头部的重定位信息指向得到的重定位表。
具体的,上述确定模块91,具体用于:根据记录的数据改写信息确定加壳程序运行过程中进入后直到结束没有离开的内存区域;获取记录每条数据改写信息后内存区域中每个内存地址的数据,并根据获取的数据计算在对应的数据改写信息中包括的数据改写时间的内存区域的熵值;获取熵值开始大于等于设定阈值的数据改写时间对应的数据改写地址为加壳程序对应的原始程序的OEP。
具体的,上述确定模块91,具体用于:遍历记录的数据改写信息,获取在连续的数据改写时间对应的时间长度内,数据改写地址连续且连续的数据改写地址对应的内存地址范围大于等于设定长度的内存地址范围作为待选内存区域;根据数据改写信息中包括的数据改写执行地址,确定加壳程序运行过程中进入后直到结束没有离开的最后一个待选内存区域作为内存区域。
具体的,上述确定模块91,还用于:记录加壳程序运行过程中产生的模块加载信息,模块加载信息包括加壳程序映射到内存中的基地址和结束地址;以及根据记录的数据改写信息和模块加载信息确定加壳程序运行过程中进入后直到结束没有离开的内存区域。
具体的,上述确定模块91,具体用于:获取加壳程序运行过程中最后一条数据改写信息中包括的数据改写地址;将基地址与获取的最后一条数据改写信息中包括的数据改写地址之间的内存地址范围作为内存区域。
具体的,上述确定模块91,具体用于:若模块加载信息中包括加壳程序对应的原始程序的资源节,确定资源节映射到内存中的最小内存地址;将基地址与最小内存地址之间的内存地址范围作为内存区域。
具体的,上述确定模块91,具体用于:确定内存地址中的数据可能的种类;根据获取的数据统计确定出的每种数据出现的次数,以及获取的数据的总个数;用每种数据出现的次数除以获取的数据的总个数得到对应数据出现的频率,计算得到的频率的均值;计算得到的频率的方差,方差作为在对应的数据改写信息中包括的数据改写时间的内存区域的熵值。
具体的,上述修复模块92,具体用于:记录运行加壳程序过程中产生的数据改写信息和模块加载信息,数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,模块加载信息包括加壳程序映射到内存中的基地址和结束地址;在确定加壳程序对应的原始程序的OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表;若搜寻到待选导入表,确定每个待选导入表对应的导入地址表,获取在到达OEP的时刻存在于内存中、并且内存地址最小的导入地址表,将获取的导入地址表对应的待选导入表作为加壳程序对应的原始程序的导入表;若搜寻不到待选导入表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立加壳程序对应的原始程序的导入表。
具体的,上述修复模块92,具体用于:在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
具体的,上述修复模块92,具体用于:在所有改写数据的组合中搜寻符合下列条件的待选导入表:大小大于等于第一设定字节;OFT指向的内存地址不为零,且落入模块加载信息中包括的基地址和结束地址范围内;OFT指向的内存地址为零,FT指向的内存地址不为零且落入模块加载信息中包括的基地址和结束地址范围内;Name RVA与基地址的和指向的内存地址落入模块加载信息中包括的基地址和结束地址范围内,且Name RVA与基地址的和指向的内存地址中的模块包含在模块加载信息包括的加载模块的名称中;OFT和FT指向的内存地址中的函数包含在模块加载信息包括的加载模块对应的函数中。
具体的,上述修复模块92,具体用于:在到达OEP的时刻之前记录的数据改写信息中,获取改写数据为函数地址、改写长度为第二设定字节的数据改写信息;将获取的数据改写信息中包括的数据改写执行地址相同的数据改写信息分为一组;从所有分组中选取数据改写地址顺序排列、且包含的数据改写地址最多的分组,选取的分组中的数据改写信息中的改写数据指向的函数包含在模块加载信息包括的加载模块对应的函数中,选取的分组中的数据改写信息中的改写数据指向的函数中归属于同一加载模块的相邻;根据选取的分组中每条数据改写信息中包括的改写数据,确定加壳程序对应的原始程度的导入地址表;从确定的导入地址表中获取运行加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;根据获取的函数库及每个函数库的函数重新建立加壳程序对应的原始程序的导入表。
具体的,上述修复模块92,还用于:记录运行加壳程序过程中产生的代码块信息,代码块信息包括代码块的起始地址和结束地址;根据记录的代码块信息重新建立加壳程序对应的原始程序的导入表。
具体的,上述修复模块92,具体用于:在到达OEP的时刻之后记录的代码块信息中,获取调用第一个函数的内存地址;根据获取的内存地址,确定加壳程序对应的原始程度的导入地址表;从确定的导入地址表中获取运行加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;根据获取的函数库及每个函数库的函数重新建立加壳程序对应的原始程序的导入表。
显然,本领域的技术人员可以对本发明进行各种改动和变型而不脱离本发明的精神和范围。这样,倘若本发明的这些修改和变型属于本发明权利要求及其等同技术的范围之内,则本发明也意图包含这些改动和变型在内。
Claims (40)
1.一种重定位表的修复方法,其特征在于,包括:
记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和终止地址;
在确定所述加壳程序对应的原始程序的入口点OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表;
若搜寻到待选重定位表,获取在到达所述OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为所述加壳程序对应的原始程序的重定位表;
若搜寻不到待选重定位表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的重定位表。
2.如权利要求1所述的方法,其特征在于,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,具体包括:
在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,
在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
3.如权利要求1所述的方法,其特征在于,根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表,具体包括:
在所有改写数据的组合中搜寻符合下列条件的待选重定位表:
所有重定位块的头部包括基地址和地址长度都落入所述模块加载信息中包括的基地址和终止地址范围内,并且地址长度为偶数;
每个重定位块包含至少两个重定位项;
每个重定位项指向的数据改写地址在到达所述OEP的时刻之前最后两次的改写数据的差值等于所述加壳程序的默认加载基地址与所述加壳程序映射到内存中的基地址之差;
写入重定位项中的内存地址顺序排列。
4.如权利要求1所述的方法,其特征在于,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的重定位表,具体包括:
计算记录的数据改写信息中每个数据改写地址到达所述OEP的时刻之前最后两次的改写数据的差值;
获取计算的差值等于所述加壳程序的默认加载基地址与所述加壳程序映射到内存中的基地址之差的数据改写地址;
将获取的数据改写地址中对应的数据改写执行地址相同的数据改写地址分为一组;
从所有分组中选取到达所述OEP的时刻之前最后两次数据改写的数据改写地址顺序排列、且包含的数据改写地址最多的分组;
根据选取的分组中每条数据改写信息中包括的数据改写地址生成对应的重定位项;
将内存中的原始程序写入文件后,在所述文件末尾添加一个节,在该节中组合生成的重定位项得到重定位表,并修改所述文件头部的重定位信息指向得到的重定位表。
5.一种重定位表的修复装置,其特征在于,包括:
记录单元,用于记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和终止地址;
搜寻单元,用于在确定所述加壳程序对应的原始程序的入口点OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表;
确定单元,用于若所述搜寻单元搜寻到待选重定位表,获取在到达所述OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为所述加壳程序对应的原始程序的重定位表;若所述搜寻单元搜寻不到待选重定位表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的重定位表。
6.如权利要求5所述的装置,其特征在于,所述搜寻单元,具体用于:
在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,
在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
7.如权利要求5所述的装置,其特征在于,所述搜寻单元,具体用于:
在所有改写数据的组合中搜寻符合下列条件的待选重定位表:
所有重定位块的头部包括基地址和地址长度都落入所述模块加载信息中包括的基地址和终止地址范围内,并且地址长度为偶数;
每个重定位块包含至少两个重定位项;
每个重定位项指向的数据改写地址在到达所述OEP的时刻之前最后两次的改写数据的差值等于所述加壳程序的默认加载基地址与所述加壳程序映射到内存中的基地址之差;
写入重定位项中的内存地址顺序排列。
8.如权利要求5所述的装置,其特征在于,所述确定单元,具体用于:
计算记录的数据改写信息中每个数据改写地址到达所述OEP的时刻之前最后两次的改写数据的差值;
获取计算的差值等于所述加壳程序的默认加载基地址与所述加壳程序映射到内存中的基地址之差的数据改写地址;
将获取的数据改写地址中对应的数据改写执行地址相同的数据改写地址分为一组;
从所有分组中选取到达所述OEP的时刻之前最后两次数据改写的数据改写地址顺序排列、且包含的数据改写地址最多的分组;
根据选取的分组中每条数据改写信息中包括的数据改写地址生成对应的重定位项;
将内存中的原始程序写入文件后,在所述文件末尾添加一个节,在该节中组合生成的重定位项得到重定位表,并修改所述文件头部的重定位信息指向得到的重定位表。
9.一种程序脱壳方法,其特征在于,包括:
记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和终止地址;
确定所述加壳程序对应的原始程序的入口点OEP;
修复所述加壳程序对应的原始程序的导入表和重定位表,其中修复重定位表的过程具体包括:在确定所述加壳程序对应的原始程序的OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表;若搜寻到待选重定位表,获取在到达所述OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为所述加壳程序对应的原始程序的重定位表;若搜寻不到待选重定位表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的重定位表;
在文件中存储到达所述加壳程序对应的原始程序的OEP时内存中的原始程序。
10.如权利要求9所述的方法,其特征在于,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,具体包括:
在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,
在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
11.如权利要求9所述的方法,其特征在于,根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表,具体包括:
在所有改写数据的组合中搜寻符合下列条件的待选重定位表:
所有重定位块的头部包括基地址和地址长度都落入所述模块加载信息中包括的基地址和终止地址范围内,并且地址长度为偶数;
每个重定位块包含至少两个重定位项;
每个重定位项指向的数据改写地址在到达所述OEP的时刻之前最后两次的改写数据的差值等于所述加壳程序的默认加载基地址与所述加壳程序映射到内存中的基地址之差;
写入重定位项中的内存地址顺序排列。
12.如权利要求9所述的方法,其特征在于,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的重定位表,具体包括:
计算记录的数据改写信息中每个数据改写地址到达所述OEP的时刻之前最后两次的改写数据的差值;
获取计算的差值等于所述加壳程序的默认加载基地址与所述加壳程序映射到内存中的基地址之差的数据改写地址;
将获取的数据改写地址中对应的数据改写执行地址相同的数据改写地址分为一组;
从所有分组中选取到达所述OEP的时刻之前最后两次数据改写的数据改写地址顺序排列、且包含的数据改写地址最多的分组;
根据选取的分组中每条数据改写信息中包括的数据改写地址生成对应的重定位项;
将内存中的原始程序写入文件后,在所述文件末尾添加一个节,在该节中组合生成的重定位项得到重定位表,并修改所述文件头部的重定位信息指向得到的重定位表。
13.如权利要求9所述的方法,其特征在于,确定所述加壳程序对应的原始程序的OEP,具体包括:
根据记录的数据改写信息确定所述加壳程序运行过程中进入后直到结束没有离开的内存区域;
获取记录每条数据改写信息后所述内存区域中每个内存地址的数据,并根据获取的数据计算在对应的数据改写信息中包括的数据改写时间的所述内存区域的熵值;
获取熵值开始大于等于设定阈值的数据改写时间对应的数据改写地址为所述加壳程序对应的原始程序的OEP。
14.如权利要求13所述的方法,其特征在于,根据记录的数据改写信息确定所述加壳程序运行过程中进入后直到结束没有离开的内存区域,具体包括:
遍历记录的数据改写信息,获取在连续的数据改写时间对应的时间长度内,数据改写地址连续且连续的数据改写地址对应的内存地址范围大于等于设定长度的内存地址范围作为待选内存区域;
根据所述数据改写信息中包括的数据改写执行地址,确定所述加壳程序运行过程中进入后直到结束没有离开的最后一个待选内存区域作为所述内存区域。
15.如权利要求13所述的方法,其特征在于,还包括:
记录所述加壳程序运行过程中产生的模块加载信息,所述模块加载信息包括所述加壳程序映射到内存中的基地址和结束地址;以及
根据记录的数据改写信息和模块加载信息确定所述加壳程序运行过程中进入后直到结束没有离开的内存区域。
16.如权利要求15所述的方法,其特征在于,根据记录的数据改写信息和模块加载信息确定所述加壳程序运行过程中进入后直到结束没有离开的内存区域,具体包括:
获取所述加壳程序运行过程中最后一条数据改写信息中包括的数据改写地址;
将所述基地址与获取的最后一条数据改写信息中包括的数据改写地址之间的内存地址范围作为所述内存区域。
17.如权利要求13所述的方法,其特征在于,根据记录的数据改写信息和模块加载信息确定所述加壳程序运行过程中进入后直到结束没有离开的内存区域,具体包括:
若所述模块加载信息中包括加壳程序对应的原始程序的资源节,确定所述资源节映射到内存中的最小内存地址;
将所述基地址与所述最小内存地址之间的内存地址范围作为所述内存区域。
18.如权利要求13-17任一所述的方法,其特征在于,根据获取的数据计算在对应的数据改写信息中包括的数据改写时间的所述内存区域的熵值,具体包括:
确定内存地址中的数据可能的种类;
根据获取的数据统计确定出的每种数据出现的次数,以及获取的数据的总个数;
用每种数据出现的次数除以获取的数据的总个数得到对应数据出现的频率,计算得到的频率的均值;
计算得到的频率的方差,所述方差作为在对应的数据改写信息中包括的数据改写时间的所述内存区域的熵值。
19.如权利要求9所述的方法,其特征在于,修复所述加壳程序对应的原始程序的导入表,具体包括:
记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和结束地址;
在确定所述加壳程序对应的原始程序的入口点OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表;
若搜寻到待选导入表,确定每个待选导入表对应的导入地址表,获取在到达所述OEP的时刻存在于内存中、并且内存地址最小的导入地址表,将获取的导入地址表对应的待选导入表作为所述加壳程序对应的原始程序的导入表;
若搜寻不到待选导入表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的导入表。
20.如权利要求19所述的方法,其特征在于,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,具体包括:
在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,
在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
21.如权利要求19所述的方法,其特征在于,所述模块加载信息还包括加载模块的名称,根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表,具体包括:
在所有改写数据的组合中搜寻符合下列条件的待选导入表:
大小大于等于第一设定字节;
原始第一存根OFT指向的内存地址不为零,且落入所述模块加载信息中包括的基地址和结束地址范围内;
OFT指向的内存地址为零,第一存根FT指向的内存地址不为零且落入所述模块加载信息中包括的基地址和结束地址范围内;
模块名称虚拟地址偏移Name RVA与所述基地址的和指向的内存地址落入所述模块加载信息中包括的基地址和结束地址范围内,且Name RVA与所述基地址的和指向的内存地址中的模块包含在所述模块加载信息包括的加载模块的名称中;
OFT和FT指向的内存地址中的函数包含在所述模块加载信息包括的加载模块对应的函数中。
22.如权利要求19所述的方法,其特征在于,所述数据改写信息还包括改写长度,根据记录的数据改写信息重新建立所述加壳程序对应的原始程序的导入表,具体包括:
在到达所述OEP的时刻之前记录的数据改写信息中,获取改写数据为函数地址、改写长度为第二设定字节的数据改写信息;
将获取的数据改写信息中包括的数据改写执行地址相同的数据改写信息分为一组;
从所有分组中选取数据改写地址顺序排列、且包含的数据改写地址最多的分组,选取的分组中的数据改写信息中的改写数据指向的函数包含在所述模块加载信息包括的加载模块对应的函数中,选取的分组中的数据改写信息中的改写数据指向的函数中归属于同一加载模块的相邻;
根据选取的分组中每条数据改写信息中包括的改写数据,确定所述加壳程序对应的原始程度的导入地址表;
从确定的导入地址表中获取运行所述加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;
根据获取的函数库及每个函数库的函数重新建立所述加壳程序对应的原始程序的导入表。
23.如权利要求19所述的方法,其特征在于,还包括:
记录运行加壳程序过程中产生的代码块信息,所述代码块信息包括代码块的起始地址和结束地址;
根据记录的代码块信息重新建立所述加壳程序对应的原始程序的导入表。
24.如权利要求23所述的方法,其特征在于,根据记录的代码块信息重新建立所述加壳程序对应的原始程序的导入表,具体包括:
在到达所述OEP的时刻之后记录的代码块信息中,获取调用第一个函数的内存地址;
根据获取的内存地址,确定所述加壳程序对应的原始程度的导入地址表;
从确定的导入地址表中获取运行所述加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;
根据获取的函数库及每个函数库的函数重新建立所述加壳程序对应的原始程序的导入表。
25.一种程序脱壳装置,其特征在于,包括:
记录模块,用于记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和终止地址;
确定模块,用于确定所述加壳程序对应的原始程序的入口点OEP;
修复模块,用于修复所述加壳程序对应的原始程序的导入表和重定位表,其中修复重定位表的过程具体包括:在确定所述加壳程序对应的原始程序的OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和重定位表格式在组合后的改写数据中搜寻待选重定位表;若搜寻到待选重定位表,获取在到达所述OEP的时刻所有重定位项指向内存地址的数据都存在于内存中、并且包含指向的内存地址最小的重定位项的待选重定位表为所述加壳程序对应的原始程序的重定位表;若搜寻不到待选重定位表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的重定位表;
存储模块,用于在文件中存储到达所述加壳程序对应的原始程序的OEP时内存中的原始程序。
26.如权利要求25所述的装置,其特征在于,所述修复模块,具体用于:
在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,
在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
27.如权利要求25所述的装置,其特征在于,所述修复模块,具体用于:
在所有改写数据的组合中搜寻符合下列条件的待选重定位表:
所有重定位块的头部包括基地址和地址长度都落入所述模块加载信息中包括的基地址和终止地址范围内,并且地址长度为偶数;
每个重定位块包含至少两个重定位项;
每个重定位项指向的数据改写地址在到达所述OEP的时刻之前最后两次的改写数据的差值等于所述加壳程序的默认加载基地址与所述加壳程序映射到内存中的基地址之差;
写入重定位项中的内存地址顺序排列。
28.如权利要求25所述的装置,其特征在于,所述修复模块,具体用于:
计算记录的数据改写信息中每个数据改写地址到达所述OEP的时刻之前最后两次的改写数据的差值;
获取计算的差值等于所述加壳程序的默认加载基地址与所述加壳程序映射到内存中的基地址之差的数据改写地址;
将获取的数据改写地址中对应的数据改写执行地址相同的数据改写地址分为一组;
从所有分组中选取到达所述OEP的时刻之前最后两次数据改写的数据改写地址顺序排列、且包含的数据改写地址最多的分组;
根据选取的分组中每条数据改写信息中包括的数据改写地址生成对应的重定位项;
将内存中的原始程序写入文件后,在所述文件末尾添加一个节,在该节中组合生成的重定位项得到重定位表,并修改所述文件头部的重定位信息指向得到的重定位表。
29.如权利要求25所述的装置,其特征在于,所述确定模块,具体用于:
根据记录的数据改写信息确定所述加壳程序运行过程中进入后直到结束没有离开的内存区域;
获取记录每条数据改写信息后所述内存区域中每个内存地址的数据,并根据获取的数据计算在对应的数据改写信息中包括的数据改写时间的所述内存区域的熵值;
获取熵值开始大于等于设定阈值的数据改写时间对应的数据改写地址为所述加壳程序对应的原始程序的OEP。
30.如权利要求29所述的装置,其特征在于,所述确定模块,具体用于:
遍历记录的数据改写信息,获取在连续的数据改写时间对应的时间长度内,数据改写地址连续且连续的数据改写地址对应的内存地址范围大于等于设定长度的内存地址范围作为待选内存区域;
根据所述数据改写信息中包括的数据改写执行地址,确定所述加壳程序运行过程中进入后直到结束没有离开的最后一个待选内存区域作为所述内存区域。
31.如权利要求29所述的装置,其特征在于,所述确定模块,还用于:
记录所述加壳程序运行过程中产生的模块加载信息,所述模块加载信息包括所述加壳程序映射到内存中的基地址和结束地址;以及
根据记录的数据改写信息和模块加载信息确定所述加壳程序运行过程中进入后直到结束没有离开的内存区域。
32.如权利要求31所述的装置,其特征在于,所述确定模块,具体用于:
获取所述加壳程序运行过程中最后一条数据改写信息中包括的数据改写地址;
将所述基地址与获取的最后一条数据改写信息中包括的数据改写地址之间的内存地址范围作为所述内存区域。
33.如权利要求29所述的装置,其特征在于,所述确定模块,具体用于:
若所述模块加载信息中包括加壳程序对应的原始程序的资源节,确定所述资源节映射到内存中的最小内存地址;
将所述基地址与所述最小内存地址之间的内存地址范围作为所述内存区域。
34.如权利要求29-33任一所述的装置,其特征在于,所述确定模块,具体用于:
确定内存地址中的数据可能的种类;
根据获取的数据统计确定出的每种数据出现的次数,以及获取的数据的总个数;
用每种数据出现的次数除以获取的数据的总个数得到对应数据出现的频率,计算得到的频率的均值;
计算得到的频率的方差,所述方差作为在对应的数据改写信息中包括的数据改写时间的所述内存区域的熵值。
35.如权利要求25所述的装置,其特征在于,所述修复模块,具体用于:
记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和结束地址;
在确定所述加壳程序对应的原始程序的入口点OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表;
若搜寻到待选导入表,确定每个待选导入表对应的导入地址表,获取在到达所述OEP的时刻存在于内存中、并且内存地址最小的导入地址表,将获取的导入地址表对应的待选导入表作为所述加壳程序对应的原始程序的导入表;
若搜寻不到待选导入表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的导入表。
36.如权利要求35所述的装置,其特征在于,所述修复模块,具体用于:
在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,
在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
37.如权利要求35所述的装置,其特征在于,所述修复模块,具体用于:
在所有改写数据的组合中搜寻符合下列条件的待选导入表:
大小大于等于第一设定字节;
原始第一存根OFT指向的内存地址不为零,且落入所述模块加载信息中包括的基地址和结束地址范围内;
OFT指向的内存地址为零,第一存根FT指向的内存地址不为零且落入所述模块加载信息中包括的基地址和结束地址范围内;
模块名称虚拟地址偏移Name RVA与所述基地址的和指向的内存地址落入所述模块加载信息中包括的基地址和结束地址范围内,且Name RVA与所述基地址的和指向的内存地址中的模块包含在所述模块加载信息包括的加载模块的名称中;
OFT和FT指向的内存地址中的函数包含在所述模块加载信息包括的加载模块对应的函数中。
38.如权利要求35所述的装置,其特征在于,所述修复模块,具体用于:
在到达所述OEP的时刻之前记录的数据改写信息中,获取改写数据为函数地址、改写长度为第二设定字节的数据改写信息;
将获取的数据改写信息中包括的数据改写执行地址相同的数据改写信息分为一组;
从所有分组中选取数据改写地址顺序排列、且包含的数据改写地址最多的分组,选取的分组中的数据改写信息中的改写数据指向的函数包含在所述模块加载信息包括的加载模块对应的函数中,选取的分组中的数据改写信息中的改写数据指向的函数中归属于同一加载模块的相邻;
根据选取的分组中每条数据改写信息中包括的改写数据,确定所述加壳程序对应的原始程度的导入地址表;
从确定的导入地址表中获取运行所述加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;
根据获取的函数库及每个函数库的函数重新建立所述加壳程序对应的原始程序的导入表。
39.如权利要求35所述的装置,其特征在于,所述修复模块,还用于:
记录运行加壳程序过程中产生的代码块信息,所述代码块信息包括代码块的起始地址和结束地址;
根据记录的代码块信息重新建立所述加壳程序对应的原始程序的导入表。
40.如权利要求39所述的装置,其特征在于,所述修复模块,具体用于:
在到达所述OEP的时刻之后记录的代码块信息中,获取调用第一个函数的内存地址;
根据获取的内存地址,确定所述加壳程序对应的原始程度的导入地址表;
从确定的导入地址表中获取运行所述加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;
根据获取的函数库及每个函数库的函数重新建立所述加壳程序对应的原始程序的导入表。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201210587721.8A CN103019739B (zh) | 2012-12-28 | 2012-12-28 | 重定位表的修复方法、程序脱壳方法及相关装置 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201210587721.8A CN103019739B (zh) | 2012-12-28 | 2012-12-28 | 重定位表的修复方法、程序脱壳方法及相关装置 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN103019739A true CN103019739A (zh) | 2013-04-03 |
CN103019739B CN103019739B (zh) | 2015-07-29 |
Family
ID=47968377
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201210587721.8A Active CN103019739B (zh) | 2012-12-28 | 2012-12-28 | 重定位表的修复方法、程序脱壳方法及相关装置 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN103019739B (zh) |
Cited By (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN108038376A (zh) * | 2017-12-21 | 2018-05-15 | 中国人民解放军战略支援部队信息工程大学 | 基于混合分析的加壳程序通用脱壳方法及装置 |
CN108108617A (zh) * | 2017-12-21 | 2018-06-01 | 中国人民解放军战略支援部队信息工程大学 | 基于静态指令流跟踪的导入表修复方法及装置 |
CN109145638A (zh) * | 2018-07-20 | 2019-01-04 | 武汉斗鱼网络科技有限公司 | 一种获取自加载模块函数的方法及装置 |
CN112631672A (zh) * | 2020-12-08 | 2021-04-09 | 龙芯中科技术股份有限公司 | 一种重定位方法、装置、电子设备及可读介质 |
Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101154259A (zh) * | 2007-08-27 | 2008-04-02 | 电子科技大学 | 通用自动化脱壳引擎与方法 |
US20110035731A1 (en) * | 2009-07-29 | 2011-02-10 | Tomislav Pericin | Automated Unpacking of Portable Executable Files |
CN102184103A (zh) * | 2011-05-12 | 2011-09-14 | 电子科技大学 | 软件保护壳的壳特征提取方法 |
CN102184363A (zh) * | 2011-05-21 | 2011-09-14 | 电子科技大学 | 基于综合处理的软件壳自动脱壳方法 |
-
2012
- 2012-12-28 CN CN201210587721.8A patent/CN103019739B/zh active Active
Patent Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101154259A (zh) * | 2007-08-27 | 2008-04-02 | 电子科技大学 | 通用自动化脱壳引擎与方法 |
US20110035731A1 (en) * | 2009-07-29 | 2011-02-10 | Tomislav Pericin | Automated Unpacking of Portable Executable Files |
CN102184103A (zh) * | 2011-05-12 | 2011-09-14 | 电子科技大学 | 软件保护壳的壳特征提取方法 |
CN102184363A (zh) * | 2011-05-21 | 2011-09-14 | 电子科技大学 | 基于综合处理的软件壳自动脱壳方法 |
Cited By (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN108038376A (zh) * | 2017-12-21 | 2018-05-15 | 中国人民解放军战略支援部队信息工程大学 | 基于混合分析的加壳程序通用脱壳方法及装置 |
CN108108617A (zh) * | 2017-12-21 | 2018-06-01 | 中国人民解放军战略支援部队信息工程大学 | 基于静态指令流跟踪的导入表修复方法及装置 |
CN108108617B (zh) * | 2017-12-21 | 2019-10-08 | 中国人民解放军战略支援部队信息工程大学 | 基于静态指令流跟踪的导入表修复方法及装置 |
CN109145638A (zh) * | 2018-07-20 | 2019-01-04 | 武汉斗鱼网络科技有限公司 | 一种获取自加载模块函数的方法及装置 |
CN112631672A (zh) * | 2020-12-08 | 2021-04-09 | 龙芯中科技术股份有限公司 | 一种重定位方法、装置、电子设备及可读介质 |
CN112631672B (zh) * | 2020-12-08 | 2023-07-04 | 龙芯中科技术股份有限公司 | 一种重定位方法、装置、电子设备及可读介质 |
Also Published As
Publication number | Publication date |
---|---|
CN103019739B (zh) | 2015-07-29 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US9256515B2 (en) | Stack trace compression | |
CN110059020B (zh) | 扩展内存的访问方法、设备以及系统 | |
US10175983B2 (en) | Branch trace compression | |
CN103413073B (zh) | 一种保护java可执行程序的方法及设备 | |
US20120209895A1 (en) | Method and device for dynamically loading relocatable file | |
CN104133780A (zh) | 一种跨页预取方法、装置及系统 | |
US20220091890A1 (en) | Identifying memory devices for swapping virtual machine memory pages | |
CN103019739B (zh) | 重定位表的修复方法、程序脱壳方法及相关装置 | |
US9304898B2 (en) | Hardware-based array compression | |
US20120284688A1 (en) | System and method for blurring instructions and data via binary obfuscation | |
WO2018164975A1 (en) | Indexing a trace by insertion of reverse lookup data structures | |
CN104750620A (zh) | 一种内存迁移方法及装置 | |
CN103019884A (zh) | 基于虚拟机快照的内存页去重方法及装置 | |
US9104402B2 (en) | Branch trace compression | |
US8775826B2 (en) | Counteracting memory tracing on computing systems by code obfuscation | |
CN104238962A (zh) | 向缓存中写入数据的方法及装置 | |
CN104267978A (zh) | 一种生成差分包的方法及装置 | |
CN112445729B (zh) | 操作地址确定方法、PCIe系统、电子设备及存储介质 | |
CN103197942A (zh) | 一种补丁的生成方法、打补丁的方法及装置 | |
CN101311901B (zh) | 程序重写装置 | |
CN112579595A (zh) | 数据处理方法、装置、电子设备及可读存储介质 | |
CN111104158A (zh) | 一种软件打包的方法、装置、计算机设备及存储介质 | |
CN101808141B (zh) | 一种基于虚拟化平台的宿主客户机协同换页的方法 | |
CN109165201B (zh) | 日志的归并方法及终端设备 | |
US20180088948A1 (en) | Efficient vectorization techniques for operands in non-sequential memory locations |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C14 | Grant of patent or utility model | ||
GR01 | Patent grant | ||
CP01 | Change in the name or title of a patent holder | ||
CP01 | Change in the name or title of a patent holder |
Address after: 100089 Beijing city Haidian District Road No. 4 North wa Yitai three storey building Patentee after: NSFOCUS Technologies Group Co.,Ltd. Patentee after: NSFOCUS TECHNOLOGIES Inc. Address before: 100089 Beijing city Haidian District Road No. 4 North wa Yitai three storey building Patentee before: NSFOCUS INFORMATION TECHNOLOGY Co.,Ltd. Patentee before: NSFOCUS TECHNOLOGIES Inc. |