![]() |
由于Acpr把ImageSize作为“敏感”数据,因此这一步就不能完全交给ImportRec了,当然,这么好的工具还是要用的。这里分为两步,第一是常规修复 IAT;第二就是移植Import Table。 |
这其中第一步的确很简单,除了一个地方,Acpr对原来的入口地址仅仅分解为两个值的异或运算结果。找 IAT也很容易,因为是Delphi程序,所以406EE8这行就应该是调用GetModuleHandle函数了,鼠标选中该行后回车,见到: 00406E18 JMP DWORD PTR DS:[691234] ; ACProtec.006D42A7 再回车,又见: 006D42A7 PUSH 66D2D09B 006D42AC XOR DWORD PTR SS:[ESP],11358640 006D42B3 RETN 呵呵,异或后转到 api(这也算加密?有点晕) OK,根据这里的[691234],知道这应该是Thunk值表的位置,将Dump窗口转到这里稍作调整看到这个表: 00691140 10 40 6D 00 1D 40 6D 00 2A 40 6D 00 37 40 6D 00 始于691140 00691150 44 40 6D 00 51 40 6D 00 5E 40 6D 00 6B 40 6D 00 00691160 78 40 6D 00 85 40 6D 00 92 40 6D 00 9F 40 6D 00 ........ ...... 00691800 28 26 79 71 5A 8A 79 71 B7 42 79 71 E9 15 78 71 00691810 00 00 00 00 72 C3 5F 77 00 00 00 00 E6 A4 AF 76 00691820 CD A5 AF 76 00 00 00 00 00 00 00 00 00 00 00 00 止于691824 利用异或还原数据吧,程序中空闲处键入: pusha mov esi,691140 mov edi,esi again: lodsd ;这里的行标在od中是地址,下面有行标处一样 test eax,eax je OK cmp eax,70000000 ja OK mov edx,eax mov eax,[edx+1] ;[edx+1]指向push 的数据 xor eax,[edx+8] ;[edx+8]处是原来xor的数据 cmp eax,70000000 ;应该大于70000000 jb check_it OK: stosd cmp esi,691824 jbe again jmp over check_it: nop ; <-- 这里设断,若停在这里,记下edi和eax的值。并在 eax处设断。 over : popa ; <-- 这里设断 以上代码与tDasm的不同之处在于1.还原的是Thunk表以保证所有的api无遗漏;2.有一个是Acpr借用了的Api,必须找出来。 好,执行这程序段吧。过程中两次停在check_it,其edi和eax的值分别是: edi eax 6911FC 6E084D 691588 6E084D 记下这两组数据(注意eax都一样)修复程序时使用。 下面轮到ImportRec上场了,启动它选中目标后RVA处设为291140,Size处设为700,GetImports! 乖乖,除了有两处外全部OK!这两处就是刚才记下的啦,这个函数无论你用追踪层次几都无济于事。看看吧,都位于user32组中,特别是291588处附近的Api函数以“姓氏笔画为序”,很整齐的。这个未解析出来的函数排在MessageBeep的上方哦,是不是...它?一个商品化的程序不可能没有它!把结果存为文本文件放到记事本中搜索一下,果然没有它---MessageBoxA啊!!!多半是了。也许你要说“又在猜了!”,好吧,刚才不是设断了吗,跟一下那个断点就清楚了,如果这样你会发现这个函数有四个参数(当然咯),跟到最后看到函数有两个出口1.retn 2.jmp eax,这个时候eax的值正好指向MessageBox,至此恢复完毕。(注意,这个就是Acpr借用的“Api”入口,运行时还要填入6E084D这个值的。)这时用ImportRec以通常方式修复IAT(修复后的程序丧失加密功能),结果就是dumped_.exe了。 第二步,利用上面的dumped_.exe移植Impotr Table。这一步操作起来有点考耐心的。 用LordPe查一下Impotr Table的RVA---2F6000,记下后关闭LordPe,od载入dumped_.exe,把Hex dump窗口转到6F6000,把6F6000~6F6130的数据复制到691000~691130,再把6F6140~6F7EF0处的数据复制到691840~6935F0,记下位置差6F6140-691840=64900,用Winhex打开dumped_exe把291140~291830的数据块复制下来,用Winhex的RamEditor把它(以ASCII-Hex方式)粘贴到od载入的dumped_.exe,位置:691140~691830。(希望不要说昏了) 关闭Winhex,在od中找“空地”键入: pusha mov esi,691000 mov edi,esi again: lodsd ;这里的行标在od中是地址,下面有行标处一样 cmp eax,2F0000 jb OK sub eax,64900 ;64900是位置差哦 OK: stosd cmp esi,691824 jb again popa over: nop ;<- 这里设断,执行这段代码 呵呵,移植完毕。 现在,你可以把内存中的dumped_.exe再dump一次就啦,(dump前最好清除自己的工作代码),然后用LordPe打开新dump的文件把Import Table的RVA改成291000,Save后检查Import Table的内容,会发现最后一个api“看不见”,这是因为文件头中定义该段的RSize小了一点的缘故,用LordPe修改一下就好,RSize和VSize都从25D4改成2600吧。再次Save后检查,allright! 最后轮到去掉ImportRec添加的段了,这用LordPe就可简单搞定。用OD载入试试,是不是有点爽! |