昨天看了csjwoman的那个双进程标准壳的NOTEPAD.EXE,说真的一开始还真不知如何下手,既不能用脱COPYMEMII(它没有用内存写入函数)的方法,也不能简单套用以前脱标准壳的方法(因为它还是有子进程的),后来仔细参考了下mysqladm的文章《试玩armadillo3.50a一点心得 》有了点启发(最近从他的这篇脱文中学到的东西可不少)。下面谈谈如何脱这种双进程的标准壳。
最近很懒,不愿写东西,所以也就不讲什么原理了(可以参考mysqladm的脱文),这里就简单说下方法。其实很简单就是不要让父进程生成子进程。所以我们可以这样做。
载入后隐藏OD,忽略所有异常,然后BP OpenMutexA,F9运行,断下后在一块空地输入如下代码,这里在401000输入,代码如下(抄来的)
00401000 60 PUSHAD
00401001 9C PUSHFD
00401002 68 B4FB1200 PUSH 12FBB4 (这里的12fbb4也就是MutexName,可以通过堆栈看到,也可以在某个寄存器器看到,我原来以为一直在EDX中,现更正一下。)
00401007 33C0 XOR EAX,EAX
00401009 50 PUSH EAX
0040100A 50 PUSH EAX
0040100B E8 E694A677 CALL KERNEL32.CreateMutexA
00401010 9D POPFD
00401011 61 POPAD
00401012 - E9 8F9FA777 JMP KERNEL32.OpenMutexA
在401000处新建起源。F9,程序又断回到OpenMutexA处,清除断点和刚才的工作代码。这时我们就完全可以象调试普通标准壳那样调试它了,因为它已经不会生成子进程而是把自己当作子进程运行起来。
这时我们下断bp VirtualProtect,F9运行,中断9-10次后清除断点,再bp GetCurrentThreadId,断下后几下ALT+F9返回,再F8几下就到那个CALL EDI了,如下
00DB455C C705 DCDBDB00 E>MOV DWORD PTR [DBDBDC], 0DBE6EC ; ASCII "RB"
00DB4566 FF15 1481DB00 CALL [DB8114] ; kernel32.GetCurrentThreadId
00DB456C A3 AC56DC00 MOV [DC56AC], EAX 返回到这里,
00DB4571 E8 1537FEFF CALL 00D97C8B
00DB4576 6A 00 PUSH 0
00DB4578 E8 648FFEFF CALL 00D9D4E1
00DB457D 6A 00 PUSH 0
00DB457F C705 DCDBDB00 E>MOV DWORD PTR [DBDBDC], 0DBE6E8 ; ASCII "RC"
00DB4589 E8 7231FEFF CALL 00D97700
00DB458E 59 POP ECX ; 0012FF2C
00DB458F 59 POP ECX ; 0012FF2C
00DB4590 E8 4A11FFFF CALL 00DA56DF
00DB4595 8BF8 MOV EDI, EAX
00DB4597 A1 9455DC00 MOV EAX, [DC5594]
00DB459C 8B48 70 MOV ECX, [EAX+70]
00DB459F 3348 40 XOR ECX, [EAX+40]
00DB45A2 3348 08 XOR ECX, [EAX+8]
00DB45A5 03F9 ADD EDI, ECX
00DB45A7 8B0E MOV ECX, [ESI]
00DB45A9 85C9 TEST ECX, ECX
00DB45AB 75 2F JNZ SHORT 00DB45DC
00DB45AD 8B78 70 MOV EDI, [EAX+70]
00DB45B0 E8 2A11FFFF CALL 00DA56DF
00DB45B5 8B0D 9455DC00 MOV ECX, [DC5594] ; NOTEPAD.0044D260
00DB45BB FF76 14 PUSH DWORD PTR [ESI+14]
00DB45BE 8B51 40 MOV EDX, [ECX+40]
00DB45C1 FF76 10 PUSH DWORD PTR [ESI+10]
00DB45C4 3351 08 XOR EDX, [ECX+8]
00DB45C7 FF76 0C PUSH DWORD PTR [ESI+C]
00DB45CA 33D7 XOR EDX, EDI
00DB45CC 03C2 ADD EAX, EDX
00DB45CE 8B51 68 MOV EDX, [ECX+68]
00DB45D1 3351 04 XOR EDX, [ECX+4]
00DB45D4 33D7 XOR EDX, EDI
00DB45D6 2BC2 SUB EAX, EDX
00DB45D8 FFD0 CALL EAX
00DB45DA EB 25 JMP SHORT 00DB4601
00DB45DC 83F9 01 CMP ECX, 1
00DB45DF 75 22 JNZ SHORT 00DB4603
00DB45E1 FF76 04 PUSH DWORD PTR [ESI+4]
00DB45E4 FF76 08 PUSH DWORD PTR [ESI+8]
00DB45E7 6A 00 PUSH 0
00DB45E9 E8 F110FFFF CALL 00DA56DF
00DB45EE 50 PUSH EAX
00DB45EF A1 9455DC00 MOV EAX, [DC5594]
00DB45F4 8B48 70 MOV ECX, [EAX+70]
00DB45F7 3348 68 XOR ECX, [EAX+68]
00DB45FA 3348 04 XOR ECX, [EAX+4]
00DB45FD 2BF9 SUB EDI, ECX
00DB45FF FFD7 CALL EDI ,这里F7,飞向光明之颠。
00DB4601 8BD8 MOV EBX, EAX
00DB4603 5F POP EDI ; 0012FF2C
00DB4604 8BC3 MOV EAX, EBX
00DB4606 5E POP ESI ; 0012FF2C
00DB4607 5B POP EBX ; 0012FF2C
00DB4608 C3 RETN
在那个CALL EDI处F7我们就到入口了,这时可以DUMP了。
至于IAT的修复,我不想多说了。