A的70限制版插件的脱壳方法(Zt)
HsGyNkr?r
HsGyNkr?r A的70限制版插件的脱壳方法
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r 1,首先要A的70限制版就要搞清楚他的程序是用什么加的壳。
HsGyNkr?r 使用工具:PEiD (属于查壳工具)
HsGyNkr?r 2,经过查看:属于EncryptPE V1加过的壳
HsGyNkr?r (注)“EncryptPE”是老王的加壳工具,其论坛地址:http://www.encryptpe.com/bbs/
HsGyNkr?r 有兴趣的可以在里面研究一下加壳解壳的要领。
HsGyNkr?r 3,下一步,也是关键的一步,就是脱EncryptPE的壳。
HsGyNkr?r 如果是新版本EncryptPE加壳的DLL,就搞不定了。但是A的是EncryptPE V1.2003.5.18旧版加壳,所以可以利用Ollydbg手动脱EncryptPE V1.2003.5.18加壳的DLL。
HsGyNkr?r 4,举例脱壳过程:
HsGyNkr?r 大家可以自己用EncryptPE V1.2003.5.18免费版把EdrLib.dll加壳看看。
HsGyNkr?r
HsGyNkr?r —————————————————————————————————
HsGyNkr?r 一、避开IAT加密
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r 设置Ollydbg忽略所有的异常选项。用IsDebug 1.4插件去掉Ollydbg的调试器标志。
HsGyNkr?r 添加“同时忽略0EEDFADE、C0000008、009B25C、00953D74”异常。
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r 代码:--------------------------------------------------------------------------------
HsGyNkr?r 00877000 60 pushad//进入OD后停在这
HsGyNkr?r 00877001 9C pushfd
HsGyNkr?r 00877002 64:FF35 00000000 push dword ptr fs:[0]
HsGyNkr?r 00877009 E8 79010000 call EdrLib.00877187
HsGyNkr?r --------------------------------------------------------------------------------
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r 下断:BP IsDebuggerPresent 断下后取消断点
HsGyNkr?r 现在我们Ctrl+G:711A0000
HsGyNkr?r 为何用这个地址?因为V12003518.EPE是相同的。呵呵,钻了个旧版的空子。
HsGyNkr?r
HsGyNkr?r 其实可以再BP GetProcAddress,根据返回地址来判断。如果返回地址是711XXXXX,说明这是V12003518.EPE的调用,就可以取消断点Ctrl+F9返回了。具体情况以堆栈的返回地址为准。
HsGyNkr?r
HsGyNkr?r 现在Ctrl+S 在“整个区段”搜索命令序列:
HsGyNkr?r
HsGyNkr?r 代码:--------------------------------------------------------------------------------
HsGyNkr?r mov eax,edi
HsGyNkr?r mov edx,dword ptr ss:[ebp-8]
HsGyNkr?r mov dword ptr ds:[eax],edx
HsGyNkr?r xor eax,eax
HsGyNkr?r --------------------------------------------------------------------------------
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r 找到在711A339F处,我们在711A339F处下个 硬件执行 断点。
HsGyNkr?r 现在我们关闭Ollydbg,重新载入这个dll,直接Shift+F9运行,中断在711A339F处
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r 代码:--------------------------------------------------------------------------------
HsGyNkr?r 711A339F 8BC7 mov eax,edi
HsGyNkr?r 711A33A1 8B55 F8 mov edx,dword ptr ss:[ebp-8]
HsGyNkr?r //改为: mov edx,dword ptr ss:[ebp-4] ★ 正确函数写入
HsGyNkr?r 711A33A4 8910 mov dword ptr ds:[eax],edx
HsGyNkr?r 711A33A6 33C0 xor eax,eax
HsGyNkr?r 711A33A8 5A pop edx
HsGyNkr?r 711A33A9 59 pop ecx
HsGyNkr?r 711A33AA 59 pop ecx
HsGyNkr?r 711A33AB 64:8910 mov dword ptr fs:[eax],edx
HsGyNkr?r 711A33AE EB 0A jmp short V1200351.711A33BA
HsGyNkr?r --------------------------------------------------------------------------------
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r 把711A33A1处修改好之后,取消以前下的711A339F处的断点。
HsGyNkr?r 再Ctrl+S搜索命令序列:
HsGyNkr?r
HsGyNkr?r 代码:--------------------------------------------------------------------------------
HsGyNkr?r add ebx,4
HsGyNkr?r mov eax,dword ptr ss:[ebp-4C]
HsGyNkr?r add eax,4
HsGyNkr?r --------------------------------------------------------------------------------
HsGyNkr?r
HsGyNkr?r 找到在711A43C2处,我们在下面xor eax,eax的711A4401下断。Shift+F9运行
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r 代码:--------------------------------------------------------------------------------
HsGyNkr?r 711A43C2 83C3 04 add ebx,4
HsGyNkr?r 711A43C5 8B45 B4 mov eax,dword ptr ss:[ebp-4C]
HsGyNkr?r 711A43C8 83C0 04 add eax,4
HsGyNkr?r 711A43CB 8945 B4 mov dword ptr ss:[ebp-4C],eax
HsGyNkr?r 711A43CE 8B03 mov eax,dword ptr ds:[ebx]
HsGyNkr?r 711A43D0 85C0 test eax,eax
HsGyNkr?r 711A43D2 0F87 39FDFFFF ja V1200351.711A4111
HsGyNkr?r 711A43D8 A1 74C71B71 mov eax,dword ptr ds:[711BC774]
HsGyNkr?r 711A43DD 8038 00 cmp byte ptr ds:[eax],0
HsGyNkr?r 711A43E0 75 1F jnz short V1200351.711A4401
HsGyNkr?r 711A43E2 8B45 C4 mov eax,dword ptr ss:[ebp-3C]
HsGyNkr?r 711A43E5 83C0 14 add eax,14
HsGyNkr?r 711A43E8 8945 C4 mov dword ptr ss:[ebp-3C],eax
HsGyNkr?r 711A43EB 8B45 C4 mov eax,dword ptr ss:[ebp-3C]
HsGyNkr?r 711A43EE 8378 0C 00 cmp dword ptr ds:[eax+C],0
HsGyNkr?r 711A43F2 76 0D jbe short V1200351.711A4401
HsGyNkr?r 711A43F4 8B45 C4 mov eax,dword ptr ss:[ebp-3C]
HsGyNkr?r 711A43F7 8378 10 00 cmp dword ptr ds:[eax+10],0
HsGyNkr?r 711A43FB 0F87 38FCFFFF ja V1200351.711A4039//循环处理IAT
HsGyNkr?r 711A4401 33C0 xor eax,eax//此处下断! ★
HsGyNkr?r --------------------------------------------------------------------------------
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r 当我们中断在711A4401处时IAT已经处理完毕,此时就可以用ImportREC得到正确的输入表了。
HsGyNkr?r 因为EncryptPE后面有自校验,所以我们返回711A33A1处,点右键->撤销选择,恢复原来的代码。
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r —————————————————————————————————
HsGyNkr?r 二、得到重定位表信息、获得OEP
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r Ctrl+S 在“整个区段”搜索命令序列:
HsGyNkr?r
HsGyNkr?r 代码:--------------------------------------------------------------------------------
HsGyNkr?r mov edx,dword ptr ss:[ebp-24]
HsGyNkr?r sub edx,dword ptr ds:[eax+34]
HsGyNkr?r mov dword ptr ss:[ebp-54],edx
HsGyNkr?r --------------------------------------------------------------------------------
HsGyNkr?r
HsGyNkr?r 找到在711A4428处,下断,Shift+F9运行,中断下来
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r 代码:--------------------------------------------------------------------------------
HsGyNkr?r 711A4428 8B55 DC mov edx,dword ptr ss:[ebp-24] ; EdrLib.00870000
HsGyNkr?r 711A442B 2B50 34 sub edx,dword ptr ds:[eax+34]//算是一种比较方式吧
HsGyNkr?r 711A442E 8955 AC mov dword ptr ss:[ebp-54],edx
HsGyNkr?r 711A4431 8B45 D8 mov eax,dword ptr ss:[ebp-28]
HsGyNkr?r 711A4434 8B40 3C mov eax,dword ptr ds:[eax+3C]
HsGyNkr?r 711A4437 0345 D8 add eax,dword ptr ss:[ebp-28]
HsGyNkr?r 711A443A 8B90 A0000000 mov edx,dword ptr ds:[eax+A0]
HsGyNkr?r //[eax+A0]=[008E7D80]=00006000 ★ 这个00006000就是重定位表的RVA!原来放在这里 :-)
HsGyNkr?r 711A4440 8955 C8 mov dword ptr ss:[ebp-38],edx
HsGyNkr?r 711A4443 8B90 A4000000 mov edx,dword ptr ds:[eax+A4]
HsGyNkr?r //[eax+A4]=[008E7D84]=000003B0 ★ 这个000003B0就是重定位表的Size!
HsGyNkr?r --------------------------------------------------------------------------------
HsGyNkr?r
HsGyNkr?r
HsGyNkr?r OK,我们已经得到了我们想得到的信息。我们可以Dump出重定位表了,现在的重定位表是完好的。
HsGyNkr?r 用LordPE选择这个dll,部分脱壳:地址=00870000+00006000=00876000,大小=3B0,存为00876000.dmp
HsGyNkr?r
[ d`m)MW- 略去重定位过程,我们在这里寻找OEP!
[ d`m)MW- Ctrl+F在当前位置下搜索命令:sub edx,dword ptr ss:[ebp-24] 找到在711A450D处:
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- 代码:--------------------------------------------------------------------------------
[ d`m)MW- 711A4504 83F0 FF xor eax,FFFFFFFF
[ d`m)MW- 711A4507 8B55 F0 mov edx,dword ptr ss:[ebp-10]
[ d`m)MW- 711A450A 83F2 FF xor edx,FFFFFFFF
[ d`m)MW- //EDX=FF78EE36 XOR FFFFFFFF=008711C9
[ d`m)MW- 711A450D 2B55 DC sub edx,dword ptr ss:[ebp-24]
[ d`m)MW- //EDX=008711C9 ★ 这是什么?呵呵,OEP啦
[ d`m)MW- 711A4510 33C2 xor eax,edx
[ d`m)MW- 711A4512 0345 AC add eax,dword ptr ss:[ebp-54]
[ d`m)MW- 711A4515 8945 FC mov dword ptr ss:[ebp-4],eax
[ d`m)MW- 711A4518 EB 13 jmp short V1200351.711A452D
[ d`m)MW- --------------------------------------------------------------------------------
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- 下面每处理1次就清零掉重定位表数据。
[ d`m)MW- Ctrl+F在当前位置下搜索命令:mov word ptr ds:[ebx],0 找到在711A4600处:
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- 代码:--------------------------------------------------------------------------------
[ d`m)MW- 711A4600 66:C703 0000 mov word ptr ds:[ebx],0//重定位表清0!
[ d`m)MW- 711A4605 FF4D E0 dec dword ptr ss:[ebp-20]
[ d`m)MW- 711A4608 837D E0 00 cmp dword ptr ss:[ebp-20],0
[ d`m)MW- 711A460C 0F8F B6FEFFFF jg V1200351.711A44C8
[ d`m)MW- 711A4612 8B45 E8 mov eax,dword ptr ss:[ebp-18]
[ d`m)MW- --------------------------------------------------------------------------------
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- 如果壳加密了跳转表,则在这段代码中间处理,可以修改代码避开跳转表的加密。
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- —————————————————————————————————
[ d`m)MW- 三、DUMP
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- 去OEP吧。Ctrl+S 在“整个区段”搜索命令序列:
[ d`m)MW-
[ d`m)MW- 代码:--------------------------------------------------------------------------------
[ d`m)MW- mov eax,dword ptr ds:[edx+28]
[ d`m)MW- mov dword ptr ds:[ebx+0B0],eax
[ d`m)MW- --------------------------------------------------------------------------------
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- 找到在7119CF0E处,在7119CF11处下 硬件执行 断点,Shift+F9运行
[ d`m)MW-
[ d`m)MW- 代码:--------------------------------------------------------------------------------
[ d`m)MW- 7119CF0E 8B42 28 mov eax,dword ptr ds:[edx+28]
[ d`m)MW- 7119CF11 8983 B0000000 mov dword ptr ds:[ebx+B0],eax; EdrLib.008711C9
[ d`m)MW- --------------------------------------------------------------------------------
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- 我们会在7119CF11处中断2次,第2次就是OEP的值了。
[ d`m)MW- BP 008711C9 Shift+F9运行就来到OEP了。
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- 代码:--------------------------------------------------------------------------------
[ d`m)MW- 008711C9 55 push ebp//OEP ★
[ d`m)MW- 008711CA 8BEC mov ebp,esp
[ d`m)MW- 008711CC 53 push ebx
[ d`m)MW- 008711CD 8B5D 08 mov ebx,dword ptr ss:[ebp+8]
[ d`m)MW- 008711D0 56 push esi
[ d`m)MW- 008711D1 8B75 0C mov esi,dword ptr ss:[ebp+C]
[ d`m)MW- 008711D4 57 push edi
[ d`m)MW- 008711D5 8B7D 10 mov edi,dword ptr ss:[ebp+10]
[ d`m)MW- 008711D8 85F6 test esi,esi
[ d`m)MW- 008711DA 75 09 jnz short EdrLib.008711E5
[ d`m)MW- 008711DC 833D 60538700 00 cmp dword ptr ds:[875360],0
[ d`m)MW- 008711E3 EB 26 jmp short EdrLib.0087120B
[ d`m)MW- --------------------------------------------------------------------------------
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- 现在就可以DUMP了。用LordPE选中Ollydbg的loaddll.exe的进程,在下面的列表里选择EdrLib.dll,然后完整脱壳,得到dumped.dll。
[ d`m)MW-
[ d`m)MW- 小提示:EncryptPE V1.2003.5.18都用的是V12003518.EPE
[ d`m)MW- 所以,以上避开IAT加密和得到重定位信息的代码地址是相同的,呵呵。
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- —————————————————————————————————
[ d`m)MW- 四、输入表
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- 因为已经避开了IAT加密,所以现在可以得到完整的输入表。随便从程序找个API调用:
[ d`m)MW- 008710FD FF15 20408700 call dword ptr ds:[874020]; kernel32.GetVersion
[ d`m)MW- 在转存中跟随874020,上下看到许多函数地址,很明显的可以找到IAT开始和结束的地址:
[ d`m)MW-
[ d`m)MW- 代码:--------------------------------------------------------------------------------
[ d`m)MW- ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
[ d`m)MW- IAT:
[ d`m)MW- 00873FF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
[ d`m)MW- 00874000 1D 51 C4 77 1C 3A C4 77 3E E7 C4 77 CC D2 C4 77 Q膚:膚>缒w桃膚
[ d`m)MW-
[ d`m)MW- 008740B0 CE 7C E5 77 05 74 E5 77 F9 81 E5 77 EB 41 E4 77 蝲鍂t鍂鶃鍂階鋡
[ d`m)MW- 008740C0 66 C8 E5 77 3E 18 F6 77 00 00 00 00 00 00 00 00 f儒w>鰓........
[ d`m)MW- ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
[ d`m)MW- --------------------------------------------------------------------------------
[ d`m)MW-
[ d`m)MW- 开始地址=00874000
[ d`m)MW- 结束地址=008740C9
[ d`m)MW-
[ d`m)MW- 运行ImportREC,去掉“使用来自磁盘的PE部首”的选项!选中Ollydbg的loaddll.exe的进程,然后点“选取DLL”,选择EdrLib.dll,填入填入RVA=00004000、大小=C8、OEP=000011C9 ,点“Get Import”,得到输入表,FixDump!
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- —————————————————————————————————
[ d`m)MW- 五、PE修正
[ d`m)MW-
[ d`m)MW-
[ d`m)MW- 用LordPE修正dumped_.dll的基址为00870000。
[ d`m)MW- 用WinHex把00876000.dmp全部复制写入进dumped_.dll的00006000处。
[ d`m)MW- 用LordPE修正dumped_.dll的重定位表RVA=00006000、大小=000003B0,保存之。
[ d`m)MW- OK,脱壳完成啦。
[ d`m)MW- [此贴子已经被作者于2005-4-23 7:06:28编辑过]