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