来源:安全中国
手工修复引入表是破解加壳软件最难的一道工序,一向是顶尖高手的专利,令我等菜鸟往往望而却步,而不敢奢望越雷池半步!那么有没有简单一些的方法呢?通过本人的实践,终于找到了这条捷径。我的做法可以分为以下几步:
1、确定程序的OEP,并脱壳。
2、使未脱壳程序处于正常运行态,使用ImportREC或LordPE检查是否所有的API都可识别,并记录下不可识别API的列表及其函数入口地址。
3、重新启动未脱壳程序,并使之中断在OEP,用前面记录到的资料在所有不可识别API的入口设执行断点,尽可能尝试软件所有的功能,通过跟踪查清每一个不可识别API的名称及实际入口地址,并加以记录。
4、再次启动未脱壳程序,并使之中断在OEP,用上一步确定的实际API的入口地址逐一替换相应的未识别API入口地址,然后使程序处于正常运行态,使用ImportREC或LordPE进行检查,这时所有的API就都能识别了。API识别完成后,对已脱壳的程序进行FixDump,整个修复过程就完成了。
下面让我们一起来亲手搞定目前比较凶悍的加壳保护软件之一--SVKP1.32(当前版本,看雪工具有介绍)。
使用工具:(1)、SoftICE 2.6 根据http://www.chat001.com/forum/crackforum/251195.html自行制作的修改版
(2)、ImportREC 1.6 (http://www.pediy.com/tools/PE_tools/Rebuilder/Import%20REC/ucfir16f.zip)
(3)、LordPE DLX(http://www.pediy.com/tools/PE_tools/Lordpe/LPE-DLX.ZIP)
(4)、UltraEdit 10.10a(http://www.ttdown.com/SoftDown.asp?ID=6718)
目标程序: SVK Protect 1.32 (http://www.anticracking.szm.sk/svkp_setup.exe)
安装目标程序,装载SoftICE。
1、下断点“bpint 1”,然后启动SVKP.EXE,程序中断于
001B:07BABC57 CD01 INT 01
下命令“bd 0”关闭断点,并使用命令“r eip 07BAEE11”修改指令指针,以便躲过SEH陷阱,再下命令“g 07D31FA5”,使程序中断于07D31FA5处(当然,你也可以使用命令“g 00401000”使程序直接停在OEP处),使用F8键单步跟踪,要不了几步就可以到达程序的OEP:00401000 处了。记录下此值,并记录下从OEP开始的几行指令及相应十六进制编码,下汇编命令“a eip”修改入口指令为“JMP EIP”然后用命令“x”使程序退出SoftICE并在OEP处进入死循环。
2、下面需要从内存中Dump出程序。启动LordPE,用鼠标指针点选SVKP.EXE进程,点鼠标右键,在弹出的菜单中点选“Correct Image Size”项前先修正映像尺寸。然后在相同的菜单中点选“Dump Full”以Dump出脱过壳的程序,命名为“SVKP_Dump.exe”。然后还在相同菜单下点选“Burn Process”杀死在内存之中处于死循环状态的程序。此后用LordPE的PE Editor功能调入脱过壳的SVKP_Dump.exe,修改其OEP的RVA为00001000,保存退出。 3、下面需要复原SVKP_Dump.exe在OEP处的指令。使用UltraEdit载入SVKP_Dump.exe,使用十六进制码搜索功能搜索以下字节串
eb fe f3 4b 00
找到后修改为:
68 1d f3 4b 00
改好后存盘退出。至此,脱壳程序SVKP_Dump.exe修改完毕,剩下的工作就是修复引入表IAT了。
4、启动ImpotREC,在进程列表中选取SVKP.EXE,修改相应OEP的RVA为00001000,点击“IAT Auto Search”按钮,再点击“Get Impots”按钮,逐一检查API的识别情况。最后发现,有5个API程序无法识别,对应的入口分别是:
(1) 07D37656
(2) 07D49E52
(3) 07D49E82
(4) 07D333DD
(5) 07D32070
5、重新启动加壳程序,使之停在OEP处,下断点:
(1)、“bpx 07D37656”
(2)、“bpx 07D49E52”
(3)、“bpx 07D49E82”
(4)、“bpx 07D333DD”
(5)、“bpx 07D32070”
然后让程序继续执行,分别从断点处开始跟踪,看看程序调用的究竟是哪个API,然后再返回到调用处看看:
(1) 00401005 CALL [004C521C] -- 07D37656 <-- SVKP API
(2) 00402F04 CALL [004C51A8] -- 07D49E52 <-- KERNEL32!CopyFileA
(2) 0040300B CALL [004C51A8] -- 07D49E52 <-- KERNEL32!CopyFileA
(3) 00402F58 CALL [004C51B0] -- 07D49E82 <-- KERNEL32!CreateFileMappingA
(3) 00403694 CALL [004C51B0] -- 07D49E82 <-- KERNEL32!CreateFileMappingA
(4) 00401086 CALL [004C51F8] -- 07D333DD <-- KERNEL32!GetModuleHandleA
(5) 004011A8 CALL [004C5200] -- 07D32070 <-- KERNEL32!ExitProcess
现在情况就比较清楚了,第一个API是用于为传入的地址装载固定的文本内容,只在程序开始时调用,不是很重要,我们为它指定一个调用形式相当的API--KERNEL32!GetVersionExA作为替代,其它的API已经清楚了。
