CN103077029B - 一种导入表的修复方法及装置 - Google Patents
一种导入表的修复方法及装置 Download PDFInfo
- Publication number
- CN103077029B CN103077029B CN201210592469.XA CN201210592469A CN103077029B CN 103077029 B CN103077029 B CN 103077029B CN 201210592469 A CN201210592469 A CN 201210592469A CN 103077029 B CN103077029 B CN 103077029B
- Authority
- CN
- China
- Prior art keywords
- address
- data rewriting
- importing
- data
- 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.)
- Active
Links
Abstract
本发明公开了一种导入表的修复方法及装置,该方法包括:记录运行加壳程序过程中产生的数据改写信息和模块加载信息;在确定加壳程序对应的原始程序的OEP后,根据数据改写时间、数据改写地址和设定组合规则将改写数据进行组合,根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表;若搜到,确定每个待选导入表对应的导入地址表,获取在到达OEP的时刻存在于内存中、且内存地址最小的导入地址表,将获取的导入地址表对应的待选导入表作为加壳程序对应的原始程序的导入表;若搜不到,根据记录的数据改写信息重建加壳程序对应的原始程序的导入表。该方案可以适用于修复各种加壳程序对应的原始程序的导入表,方法简单,修复效率高。
Description
技术领域
本发明涉及计算机技术领域,尤指一种导入表的修复方法及装置。
背景技术
加壳是可执行程序资源压缩的简称,是保护文件的常用手段,其原理是利用特殊的算法,对可执行程序里的资源进行压缩、加密。加壳程序可以直接运行,但是不能获取原始程序,要经过脱壳才可以获取。脱壳的过程主要为三步:第一步,确定原始程序的入口点(OriginalEntryPoint,OEP);第二步,修复导入表和重定位表;第三步,将内存中的原始程序写入文件,更改程序的新入口地址为OEP,这一步通常称为转储(Dump)。修复导入表是脱壳过程中重要的步骤。
下面介绍导入表和导入地址表的概念。
在windows上,运行可执行程序时通常会调用很多函数,这些函数是由windows上的函数库导出的,每个函数库可以称为一个模块。windows加载可执行程序时,会定位该可执行程序的导入表和导入地址表,导入表中包括该可执行程序需要加载的所有函数库的名字,以及需要从每个函数库里导入的函数的名字,导入地址表中包括这些函数需要填充的内存地址,当这些函数全部填充到内存地址后,导入表就没有用了,运行可执行程序要调用函数时,直接从导入地址表中获取函数地址,然后到获取的函数地址中调用函数。
导入地址表的结构很特殊,假设导入地址表的起始地址是0x01001020,可执行程序为32位,则导入地址表的结构如下表所示:
可执行程序中采用类似如下代码调用函数:
movedi,[0x01001020]//把0x1001020地址中的函数地址给edi;
calledi//调用函数,如上表,调用的是函数kernel32.GetModuleHandleA。
可执行程序加壳后,新的导入表是壳的导入表,加壳程序加载后,系统会填充需要的函数地址到壳的导入地址表中,但是原始程序的导入地址表并不会被系统自动填充,这个工作由壳来完成,壳负责填充函数地址到原始程序的导入地址表中。
当加壳程序运行到OEP后,此时加壳程序的导入地址表虽然已经被壳填充了正确的函数地址,但是导入表却不一定正确,这样即便dump,下次运行加壳程序时,系统仍然找不到需要的函数库和函数,导致加壳程序崩溃。所以要想完成脱壳,还必须修复程序的导入表。
目前,在修复导入表时,通常会采用特征定位法,根据已知类型壳的特征对加壳程序对应的原始程序的导入表进行修复,现有的产品有针对具体壳的脱壳脚本或自动脱壳机等。这种方法在修复导入表时成功率很高,修复得完美,但是一旦已知类型壳升级可能导致特征定位失效,并且对于使用未知类型壳的加壳程序对应的原始程序的导入表不能使用。因此,现有的导入表修复方法并不能普遍适用于修复各种加壳程度对应的原始程序的导入表。
发明内容
本发明实施例提供一种导入表的修复方法及装置,用以解决现有的导入表修复方法不能普遍适用于修复各种加壳程序对应的原始程序的导入表的问题。
一种导入表的修复方法,包括:
记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和结束地址;
在确定所述加壳程序对应的原始程序的入口点OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表;
若搜寻到待选导入表,确定每个待选导入表对应的导入地址表,获取在到达所述OEP的时刻存在于内存中、并且内存地址最小的导入地址表,将获取的导入地址表对应的待选导入表作为所述加壳程序对应的原始程序的导入表;
若搜寻不到待选导入表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的导入表。
一种导入表的修复装置,包括:
记录单元,用于记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和结束地址;
搜寻单元,用于在确定所述加壳程序对应的原始程序的入口点OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表;
确定单元,用于若所述搜寻单元搜寻到待选导入表,确定每个待选导入表对应的导入地址表,获取在到达所述OEP的时刻存在于内存中、并且内存地址最小的导入地址表,将获取的导入地址表对应的待选导入表作为所述加壳程序对应的原始程序的导入表;若所述搜寻单元搜寻不到待选导入表,根据记录的数据改写信息重新建立所述加壳程序对应的原始程序的导入表。
本发明有益效果如下:
本发明实施例提供的导入表的修复方法及装置,通过记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和结束地址;在确定所述加壳程序对应的原始程序的入口点OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表;若搜寻到待选导入表,确定每个待选导入表对应的导入地址表,获取在到达所述OEP的时刻存在于内存中、并且内存地址最小的导入地址表,将获取的导入地址表对应的待选导入表作为所述加壳程序对应的原始程序的导入表;若搜寻不到待选导入表,根据记录的数据改写信息中包括数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的导入表。该方案可以适用于修复各种加壳程序对应的原始程序的导入表,方法简单,修复效率高。
附图说明
图1为本发明实施例中导入表的修复方法的流程图;
图2为本发明实施例中的导入表的结构示意图;
图3为本发明实施例中导入表的修复装置的结构示意图。
具体实施方式
针对用以解决现有的导入表修复方法不能普遍适用于修复各种加壳程序对应的原始程序的导入表的问题,本发明实施例提供一种导入表的修复方法,该方法的流程如图1所示,执行步骤如下:
S10:记录运行加壳程序过程中产生的数据改写信息和模块加载信息,数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,模块加载信息包括加壳程序映射到内存中的基地址和结束地址。
可以使用虚拟机或者调试器等运行加壳程序,并记录运行过程中产生的数据改写信息和模块加载信息。
S11:在确定加壳程序对应的原始程序的OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合。
S12:根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表,若搜寻到,执行S13;若搜寻不到,执行S14。
S13:确定每个待选导入表对应的导入地址表,获取在到达OEP的时刻存在于内存中、并且内存地址最小的导入地址表,将获取的导入地址表对应的待选导入表为加壳程序对应的原始程序的导入表。
这种情况是导入表未完全破坏的情况,也就是说壳在还原原始程序过程中,原始程序的的导入表会在某一时刻出现在内存地址的数据中,甚至在一开始加壳程序就保留原始程序的导入表在可执行程序中。壳解析原始程序的导入表,然后填充原始程序的导入地址表后,可以选择清除或者不清除这份导入表。
由于导入表会在内存地址的数据中出现,所以如果那时将导入表的数据保存起来,然后在到达OEP后,将保存的导入表数据填充回去,并更新可执行程序的头部指向的导入表地址,则成功实现了导入表的修复,dump后再次运行,可执行程序就能找到所需的函数库和函数。
如果搜寻到多个待选导入表,可以对搜寻到的待选导入表进行筛选,确定每个待选导入表对应的导入地址表,获取在到达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,这样就可以减少改写数据组合的数量。
当然也可以将第一种方案和第二中方案综合起来考虑。
具体的,模块加载信息还包括加载模块的名称,上述S12中的根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表,具体包括:
在所有改写数据的组合中搜寻符合下列条件的待选导入表:
大小大于等于第一设定字节;
原始第一换长(OriginalFirstThunk,OFT)指向的内存地址不为零,且落入模块加载信息中包括的基地址和结束地址范围内;
OFT指向的内存地址为零,第一换长(FirstThunk,FT)指向的内存地址不为零且落入模块加载信息中包括的基地址和结束地址范围内;
模块名称虚拟地址偏移NameRVA与基地址的和指向的内存地址落入模块加载信息中包括的基地址和结束地址范围内,且NameRVA与基地址的和指向的内存地址中的模块包含在模块加载信息包括的加载模块的名称中;
OFT和FT指向的内存地址中的函数包含在模块加载信息包括的加载模块对应的函数中。
对于32位可执行程序来说,导入表中的每个导入描述符IMAGE_IMPORT_DESCRIPTOR大小是20个字节,通常最后还有一个20字节的值全部为0的IMAGE_IMPORT_DESCRIPTOR,所以一个导入表至少40个字节,那么可以先排除大小小于40个字节的改写数据的组合。第一设定字节是根据可执行程序的类型确定的,例如对于32位可执行程序来说,第一设定字节为40个字节。
导入表的结构如图2所示,可以在改写数据的组合中查找OFT指向的内存地址,若不为0,则必须落入加载模块信息中包括的基地址和结束地址范围内,若为0,则查找FT指向的内存地址,若FT也为0,则不符合导入表格式,跳过该内存地址,若FT不为0,也必须落入加载模块信息中包括的基地址和结束地址范围内,才符合导入表的格式。
NameRVA指向的内存地址可以是需要加载模块的内存地址,加载模块可以是dll,也必须落入加载模块信息中包括的基地址和结束地址范围内,并且该内存地址中的模块包含在模块加载信息包括的加载模块的名称中。
导入表的格式要求OFT或FT指向的内存地址中的函数包含在模块加载信息包括的加载模块对应的函数中,例如图2中,可以看到描述KERNEL32.dll的LoadLibraryA和GetProcAddress两个函数,这两个函数都属于KERNEL32.dll的函数,这个IMAGE_IMPORT_DESCRIPTOR符合导入表格式,反之,则不符合,所以肯定不是导入表。
根据上面的格式查找,可能找到多个符合条件的导入表然后可以进一步筛选出真正的导入表。
具体的,数据改写信息还包括改写长度,上述S14中的根据记录的数据改写信息重新建立加壳程序对应的原始程序的导入表,具体包括:
在到达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时刻之后记录的代码块信息中,获取调用的第一个函数的内存地址,从这里开始,原始程序会访问导入地址表,例如:
movedi,[0x01001020]//把0x1001020地址中的库函数地址给edi
calledi//调用函数。
所以0x01001020就是导入地址表中的一个地址,得到该地址后,确定加壳程序对应的原始程度的导入地址表;从确定的导入地址表中获取运行加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;根据获取的函数库及每个函数库的函数重新建立加壳程序对应的原始程序的导入表。
基于同一发明构思,本发明实施例提供一种导入表的修复装置,该装置的结构如图3所示,包括:
记录单元30,用于记录运行加壳程序过程中产生的数据改写信息和模块加载信息,数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,模块加载信息包括加壳程序映射到内存中的基地址和结束地址。
搜寻单元31,用于在确定加壳程序对应的原始程序的入口点OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表。
确定单元32,用于若搜寻单元31搜寻到待选导入表,确定每个待选导入表对应的导入地址表,获取在到达OEP的时刻存在于内存中、并且存地址最小的导入地址表,将获取的导入地址表对应的待选导入表作为加壳程序对应的原始程序的导入表;若搜寻单元31搜寻不到待选导入表,根据记录的数据改写信息重新建立加壳程序对应的原始程序的导入表。
具体的,上述搜寻单元31,具体用于:在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合。
具体的,上述搜寻单元31,具体用于:在所有改写数据的组合中搜寻符合下列条件的待选导入表:大小大于等于第一设定字节;OFT指向的内存地址不为零,且落入模块加载信息中包括的基地址和结束地址范围内;OFT指向的内存地址为零,FT指向的内存地址不为零且落入模块加载信息中包括的基地址和结束地址范围内;NameRVA与基地址的和指向的内存地址落入模块加载信息中包括的基地址和结束地址范围内,且NameRVA与基地址的和指向的内存地址中的模块包含在模块加载信息包括的加载模块的名称中;OFT和FT指向的内存地址中的函数包含在模块加载信息包括的加载模块对应的函数中。
具体的,上述确定单元,具体用于:在到达OEP的时刻之前记录的数据改写信息中,获取改写数据为函数地址、改写长度为第二设定字节的数据改写信息;将获取的数据改写信息中包括的数据改写执行地址相同的数据改写信息分为一组;从所有分组中选取数据改写地址顺序排列、且包含的数据改写地址最多的分组,选取的分组中的数据改写信息中的改写数据指向的函数包含在模块加载信息包括的加载模块对应的函数中,选取的分组中的数据改写信息中的改写数据指向的函数中归属于同一加载模块的相邻;根据选取的分组中每条数据改写信息中包括的改写数据,确定加壳程序对应的原始程度的导入地址表;从确定的导入地址表中获取运行加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;根据获取的函数库及每个函数库的函数重新建立加壳程序对应的原始程序的导入表。
较佳的,上述记录单元30,还用于记录运行加壳程序过程中产生的代码块信息,代码块信息包括代码块的起始地址和结束地址。
上述确定单元32,还用于根据记录的代码块信息重新建立加壳程序对应的原始程序的导入表。
具体的,上述确定单元32,具体用于:在到达OEP的时刻之后记录的代码块信息中,获取调用第一个函数的内存地址;根据获取的内存地址,确定加壳程序对应的原始程度的导入地址表;从确定的导入地址表中获取运行加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;根据获取的函数库及每个函数库的函数重新建立加壳程序对应的原始程序的导入表。
显然,本领域的技术人员可以对本发明进行各种改动和变型而不脱离本发明的精神和范围。这样,倘若本发明的这些修改和变型属于本发明权利要求及其等同技术的范围之内,则本发明也意图包含这些改动和变型在内。
Claims (8)
1.一种导入表的修复方法,其特征在于,包括:
记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和结束地址;
在确定所述加壳程序对应的原始程序的入口点OEP后,在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合,并,
根据模块加载信息和导入表格式在所有改写数据的组合中搜寻符合下列条件的待选导入表:
大小大于等于第一设定字节;
原始第一换长OFT指向的内存地址不为零,且落入所述模块加载信息中包括的基地址和结束地址范围内;或,OFT指向的内存地址为零,第一换长FT指向的内存地址不为零且落入所述模块加载信息中包括的基地址和结束地址范围内;
模块名称虚拟地址偏移NameRVA与所述基地址的和指向的内存地址落入所述模块加载信息中包括的基地址和结束地址范围内,且NameRVA与所述基地址的和指向的内存地址中的模块的名称包含在所述模块加载信息包括的加载模块的名称中;
OFT和FT指向的内存地址中的函数包含在所述模块加载信息包括的加载模块的名称对应的函数中;
若搜寻到待选导入表,确定每个待选导入表对应的导入地址表,获取在到达所述OEP的时刻存在于内存中、并且内存地址最小的导入地址表,将获取的导入地址表对应的待选导入表作为所述加壳程序对应的原始程序的导入表;
若搜寻不到待选导入表,根据记录的数据改写信息中包括的数据改写执行地址、数据改写地址、改写数据和数据改写时间重新建立所述加壳程序对应的原始程序的导入表。
2.如权利要求1所述的方法,其特征在于,所述数据改写信息还包括改写长度,根据记录的数据改写信息重新建立所述加壳程序对应的原始程序的导入表,具体包括:
在到达所述OEP的时刻之前记录的数据改写信息中,获取改写数据为函数地址、改写长度为第二设定字节的数据改写信息;
将获取的数据改写信息中包括的数据改写执行地址相同的数据改写信息分为一组;
从所有分组中选取数据改写地址顺序排列、且包含的数据改写地址最多的分组,选取的分组中的数据改写信息中的改写数据指向的函数包含在所述模块加载信息包括的加载模块的名称对应的函数中,选取的分组中的数据改写信息中的改写数据指向的函数中归属于同一加载模块的相邻;
根据选取的分组中每条数据改写信息中包括的改写数据,确定所述加壳程序对应的原始程度的导入地址表;
从确定的导入地址表中获取运行所述加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;
根据获取的函数库及每个函数库的函数重新建立所述加壳程序对应的原始程序的导入表。
3.如权利要求1所述的方法,其特征在于,还包括:
记录运行加壳程序过程中产生的代码块信息,所述代码块信息包括代码块的起始地址和结束地址;
根据记录的代码块信息重新建立所述加壳程序对应的原始程序的导入表。
4.如权利要求3所述的方法,其特征在于,根据记录的代码块信息重新建立所述加壳程序对应的原始程序的导入表,具体包括:
在到达所述OEP的时刻之后记录的代码块信息中,获取调用第一个函数的内存地址;
根据获取的内存地址,确定所述加壳程序对应的原始程度的导入地址表;
从确定的导入地址表中获取运行所述加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;
根据获取的函数库及每个函数库的函数重新建立所述加壳程序对应的原始程序的导入表。
5.一种导入表的修复装置,其特征在于,包括:
记录单元,用于记录运行加壳程序过程中产生的数据改写信息和模块加载信息,所述数据改写信息包括数据改写执行地址、数据改写地址、改写数据和数据改写时间,所述模块加载信息包括所述加壳程序映射到内存中的基地址和结束地址;
搜寻单元,用于在确定所述加壳程序对应的原始程序的入口点OEP后,根据数据改写时间、数据改写地址和设定的组合规则将记录的数据改写信息中的改写数据进行组合,并根据模块加载信息和导入表格式在组合后的改写数据中搜寻待选导入表;所述搜寻单元,具体用于:在记录的数据改写信息中,将数据改写时间连续且数据改写地址连续的数据改写信息所对应的改写数据进行组合;和/或,在记录的数据改写信息中,将数据改写时间连续、至少两个连续的数据改写地址循环的数据改写信息所对应的改写数据进行组合;
所述模块加载信息还包括加载模块的名称,所述搜寻单元,具体用于:
在所有改写数据的组合中搜寻符合下列条件的待选导入表:
大小大于等于第一设定字节;
原始第一换长OFT指向的内存地址不为零,且落入所述模块加载信息中包括的基地址和结束地址范围内;或,OFT指向的内存地址为零,第一换长FT指向的内存地址不为零且落入所述模块加载信息中包括的基地址和结束地址范围内;
模块名称虚拟地址偏移NameRVA与所述基地址的和指向的内存地址落入所述模块加载信息中包括的基地址和结束地址范围内,且NameRVA与所述基地址的和指向的内存地址中的模块的名称包含在所述模块加载信息包括的加载模块的名称中;
OFT和FT指向的内存地址中的函数包含在所述模块加载信息包括的加载模块的名称对应的函数中;
确定单元,用于若所述搜寻单元搜寻到待选导入表,确定每个待选导入表对应的导入地址表,获取在到达所述OEP的时刻存在于内存中、并且内存地址最小的导入地址表,将获取的导入地址表对应的待选导入表作为所述加壳程序对应的原始程序的导入表;若所述搜寻单元搜寻不到待选导入表,根据记录的数据改写信息重新建立所述加壳程序对应的原始程序的导入表。
6.如权利要求5所述的装置,其特征在于,所述数据改写信息还包括改写长度,所述确定单元,具体用于:
在到达所述OEP的时刻之前记录的数据改写信息中,获取改写数据为函数地址、改写长度为第二设定字节的数据改写信息;
将获取的数据改写信息中包括的数据改写执行地址相同的数据改写信息分为一组;
从所有分组中选取数据改写地址顺序排列、且包含的数据改写地址最多的分组,选取的分组中的数据改写信息中的改写数据指向的函数包含在所述模块加载信息包括的加载模块的名称对应的函数中,选取的分组中的数据改写信息中的改写数据指向的函数中归属于同一加载模块的相邻;
根据选取的分组中每条数据改写信息中包括的改写数据,确定所述加壳程序对应的原始程度的导入地址表;
从确定的导入地址表中获取运行所述加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;
根据获取的函数库及每个函数库的函数重新建立所述加壳程序对应的原始程序的导入表。
7.如权利要求5所述的装置,其特征在于,所述记录单元,还用于记录运行加壳程序过程中产生的代码块信息,所述代码块信息包括代码块的起始地址和结束地址;
所述确定单元,还用于根据记录的代码块信息重新建立所述加壳程序对应的原始程序的导入表。
8.如权利要求7所述的装置,其特征在于,所述确定单元,具体用于:
在到达所述OEP的时刻之后记录的代码块信息中,获取调用第一个函数的内存地址;
根据获取的内存地址,确定所述加壳程序对应的原始程度的导入地址表;
从确定的导入地址表中获取运行所述加壳程序对应的原始程序时所需的函数库及每个函数库中的函数;
根据获取的函数库及每个函数库的函数重新建立所述加壳程序对应的原始程序的导入表。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201210592469.XA CN103077029B (zh) | 2012-12-28 | 2012-12-28 | 一种导入表的修复方法及装置 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201210592469.XA CN103077029B (zh) | 2012-12-28 | 2012-12-28 | 一种导入表的修复方法及装置 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN103077029A CN103077029A (zh) | 2013-05-01 |
CN103077029B true CN103077029B (zh) | 2016-07-13 |
Family
ID=48153567
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201210592469.XA Active CN103077029B (zh) | 2012-12-28 | 2012-12-28 | 一种导入表的修复方法及装置 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN103077029B (zh) |
Families Citing this family (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN108108617B (zh) * | 2017-12-21 | 2019-10-08 | 中国人民解放军战略支援部队信息工程大学 | 基于静态指令流跟踪的导入表修复方法及装置 |
Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101154259A (zh) * | 2007-08-27 | 2008-04-02 | 电子科技大学 | 通用自动化脱壳引擎与方法 |
CN102004884A (zh) * | 2009-08-28 | 2011-04-06 | 华为技术有限公司 | 一种获取可执行文件输入表的方法及装置 |
CN102184103A (zh) * | 2011-05-12 | 2011-09-14 | 电子科技大学 | 软件保护壳的壳特征提取方法 |
Family Cites Families (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
EP2460113B1 (en) * | 2009-07-29 | 2017-07-05 | Reversinglabs Corporation | Automated unpacking of portable executable files |
-
2012
- 2012-12-28 CN CN201210592469.XA patent/CN103077029B/zh active Active
Patent Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101154259A (zh) * | 2007-08-27 | 2008-04-02 | 电子科技大学 | 通用自动化脱壳引擎与方法 |
CN102004884A (zh) * | 2009-08-28 | 2011-04-06 | 华为技术有限公司 | 一种获取可执行文件输入表的方法及装置 |
CN102184103A (zh) * | 2011-05-12 | 2011-09-14 | 电子科技大学 | 软件保护壳的壳特征提取方法 |
Non-Patent Citations (1)
Title |
---|
程序自动脱壳数据采集技术研究;曾勇军 等;《计算机应用》;20090331;第29卷(第3期);第813-816页 * |
Also Published As
Publication number | Publication date |
---|---|
CN103077029A (zh) | 2013-05-01 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US9858072B2 (en) | Portable executable file analysis | |
CN103995784B (zh) | 快闪存储器控制器与存储装置以及快闪存储器控制方法 | |
US20080222215A1 (en) | Method for Deleting Virus Program and Method to Get Back the Data Destroyed by the Virus | |
CN103019884A (zh) | 基于虚拟机快照的内存页去重方法及装置 | |
CN107203331B (zh) | 写数据的方法及装置 | |
CN104809178A (zh) | 一种键值数据库内存日志的写入方法 | |
CN112579595A (zh) | 数据处理方法、装置、电子设备及可读存储介质 | |
CN103019739B (zh) | 重定位表的修复方法、程序脱壳方法及相关装置 | |
CN103077029B (zh) | 一种导入表的修复方法及装置 | |
CN107632880B (zh) | 导出excel数据的方法、存储介质及电子设备 | |
CN110851437A (zh) | 一种存储方法、装置及设备 | |
CN111143182B (zh) | 一种进程行为的分析方法、装置及存储介质 | |
CN110795247B (zh) | 一种应用于mcu的高效动态内存管理方法 | |
CN107608825A (zh) | 一种云备份快照数据的方法及装置 | |
CN111602121B (zh) | 利用所应用的存储器区域生命期的比特精确跟踪分析 | |
CN103019740B (zh) | 一种获取导入表和重定位表的方法及装置 | |
CN113590044A (zh) | 电池测试数据存储方法 | |
CN116738382A (zh) | 代码处理方法、装置、计算机设备和存储介质 | |
JP2004030505A (ja) | プログラムトレースデータ記録方法およびトレースメモリ |
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 |
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. |
|
CP01 | Change in the name or title of a patent holder |