吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 22499|回复: 24
收起左侧

[原创] 吾爱破解脱壳练习-----delphi自效验的处理

 关闭 [复制链接]
小生我怕怕 发表于 2008-10-13 00:12
一转眼我们的脱壳练习已经第12期啦,在这其中我相信许多的朋友也学习到了东西
必能脱掉此壳
本期考核主题为:delphi自效验的处理
1.脱壳后的文件大家以千脑形式上传,目的是为了便于隐藏文件和节约论坛空间
2.脱壳后的文件,请大家以脱文附带脱壳后程序打包压缩传于千脑网盘
3.对于回帖过程中千万不要出现灌水,否则BAN了ID
4.对于有优秀脱文或优秀脱壳方法的朋友,给于适当威望奖励
5.鉴于此练习是针对论坛的所有人,请大家踊跃参加,如果不是脱了壳教作业的,请不要顶帖子,方便管理查阅,及时给出评分
6.以下为需要设置威望的格式
7.脱壳一以周期计算,(周期=等于二天)
8.脱壳周期一结束,就开始公布答案让大家能有更充分的学习环境,让不懂脱的朋友去寻找你失误的地方争取早日赶上论坛的积极份子
9.我们要的是脱文,并不是脱壳机去脱的,如果用脱机脱了别拿来,请一定附带上脱文
10.我们讲对每次脱壳练习选择一个最好的脱壳分析过程,方便大家学习,每次脱壳练习结束后会说出楼数,对于被选种的朋友,我们会酌情给予CB或者威望进行奖励

11.本期看点:前一期的题目过于难,本期看点在于寻找最快最有效的方法去突破这个自效验,了解delphi程序的难点,尽量分析delphi函数,由函数做突破口



练习一:(结果已经公布)
http://www.52pojie.cn/thread-10496-1-1.html
最佳分析:第10楼unpack

练习二:(结果已经公布)
http://www.52pojie.cn/thread-10607-1-1.html
最佳分析:第9楼lqiulu

练习三:(结果已经公布)
http://www.52pojie.cn/thread-10688-1-1.html
最佳分析:第11楼傻人有傻福

练习四:(结果已经公布)
http://www.52pojie.cn/thread-10850-1-1.html
最佳分析:第11楼维护世界和平

练习五:(结果已经公布)
http://www.52pojie.cn/thread-10990-1-1.html
最佳分析:第3楼维护世界和平

练习六:(结果已经公布)
http://www.52pojie.cn/thread-11112-1-1.html
最佳分析:第12楼ximo

练习七:(结果已经公布)
http://www.52pojie.cn/thread-11244-1-1.html
最佳分析:第14楼傻人有傻福

练习八:(结果已经公布)
http://www.52pojie.cn/thread-11306-1-1.html
最佳分析: 第15楼unpack

练习九:(结果已经公布)
http://www.52pojie.cn/thread-11446-1-1.html
最佳分析: 第1楼小生我怕怕

练习十:(结果已经公布)
http://www.52pojie.cn/thread-11585-1-1.html
最佳分析:第10楼unpack

练习十一:(结果已经公布)
http://www.52pojie.cn/thread-11747-1-1.html
最佳分析:第9楼unpack

UnPackMe自效验.rar

182 KB, 下载次数: 718, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 1热心值 +1 收起 理由
min-gong + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

A-new 发表于 2008-10-13 08:57
这个是常见的大小校验
脱壳是FSG不是重点,这里不说了

载入脱完壳的,下断点 ExitProcess 和PostQuitMessage(PS:一般就是这两个退出函数了)
或者Ctrl+N找到对应的API下断点。

Shift+F9,运行程序,停在这里
7C81CAFA >8BFFmov edi, edi ; 123_.00451CD47C81CAFC55pushebp7C81CAFD8BECmov ebp, esp7C81CAFF6A FF push-17C81CB0168 B0F3E877 push77E8F3B07C81CB06FF75 08 pushdword ptr [ebp+8]
看堆栈
0012FDDC 004523BB/CALL 到 ExitProcess 来自 123_.004523B60012FDE0 00000000\ExitCode = 00012FDE4 0012FDF0指向下一个 SEH 记录的指针0012FDE8 004523C5SE处理程序0012FDEC 0012FE0C0012FDF0 0012FE14指向下一个 SEH 记录的指针
Ctrl+G到004523B6
004523AF .01D8add eax, ebx004523B1 .89C3mov ebx, eax004523B3 .58pop eax004523B4 .6A 00 push0; /ExitCode = 0004523B6 .E8 F540FBFF call<jmp.&kernel32.ExitProcess>; \ExitProcess004523BB >33C0xor eax, eax ;Case 2E4E9 of switch 00451FB8
看到最后一行没,有跳转过来,我们跟随到最远那个
00452080 . /E9 21030000 jmp 004523A600452085 |3D E9E40200 cmp eax, 2E4E90045208A . |7F 6A jgshort 004520F60045208C . |0F84 29030000 je004523BB就是这个了00452092 . |3D 8BFC0000 cmp eax, 0FC8B00452097 . |7F 37 jgshort 004520D0
看到了吧 cmp eax, 2E4E9,这一句,看一下原文件的属性,大小正好是2E4E9(16进制哦),
现在easy了,OD修改有点麻烦,拿出Hex WorkShop 载入脱壳文件,搜索Hex ValuesE9E40200,
把它修改为你脱壳后文件大小,我这里替换为00B00900,保存一下就OK了
 楼主| 小生我怕怕 发表于 2008-10-13 01:58
00400154 >8725 AC824900 xchg dword ptr ds:[4982AC],esp//OD载入
0040015A61popad
0040015B94xchg eax,esp//单步F8到此,注意堆栈窗口
0040015C55push ebp
0040015DA4movs byte ptr es:[edi],byte ptr ds:[esi]
━━━━━━━━━━━━━━━━━━━━━━━━━━
004982B0 004001E8UnPackMe.004001E8
004982B4 004001DCUnPackMe.004001DC
004982B8 004001DEUnPackMe.004001DE//下面即我们OEP地址0045271C
004982BC 0045271CUnPackMe.0045271C//在这行我们右键,反汇编窗口跟随
004982C0 > 7C801D77kernel32.LoadLibraryA
004982C4 > 7C80ADA0kernel32.GetProcAddress
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045271C00db 00//右键从模块中删除分析
0045271D00db 00//删除后如下面的分析
0045271E00db 00
0045271F00db 00
0045272000db 00
0045272100db 00
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045271C0000 add byte ptr ds:[eax],al//在此右键断点,设置硬件访问断点
0045271E0000 add byte ptr ds:[eax],al//ctrl+f2从新加载程序
004527200000 add byte ptr ds:[eax],al
004527220000 add byte ptr ds:[eax],al
004527240000 add byte ptr ds:[eax],al
━━━━━━━━━━━━━━━━━━━━━━━━━━
00400154 >8725 AC824900xchg dword ptr ds:[4982AC],esp//从新加载后在这里
0040015A61 popad //F9直接运行程序
0040015B94 xchg eax,esp
0040015C55 push ebp
0040015DA4 movs byte ptr es:[edi],byte ptr ds:[esi]
0040015EB6 80mov dh,80
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045271C55 push ebp//程序直接停在我们的OEP上
0045271D8BEC mov ebp,esp //运行lordPE把程序DUMP
0045271F83C4 ECadd esp,-14 //运行importRCE修复程序
0045272233C0 xor eax,eax
004527248945 ECmov dword ptr ss:[ebp-14],eax
00452727B8 34254500mov eax,UnPackMe.00452534
0045272CE8 673BFBFFcall UnPackMe.00406298
━━━━━━━━━━━━━━━━━━━━━━━━━━
在修复时,会发现只有3个指针,这种情况是不可能有的,所以我们要开始手动来查找我们的IAT指针
当然如果有CHimpREC这个工具就可以避免手动查找IAT的痛苦,好啦废话就不多说啦,我们开始找我
们的IAT指针
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045271C55 push ebp //这里是我们的OEP处
0045271D8BEC mov ebp,esp
0045271F83C4 ECadd esp,-14
0045272233C0 xor eax,eax
004527248945 ECmov dword ptr ss:[ebp-14],eax
00452727B8 34254500mov eax,UnPackMe.00452534
0045272CE8 673BFBFFcall UnPackMe.00406298
0045273133C0 xor eax,eax
0045273355 push ebp
0045273468 9E274500push UnPackMe.0045279E
0045273964:FF30push dword ptr fs:[eax]
0045273C64:8920mov dword ptr fs:[eax],esp
0045273FA1 E03F4500mov eax,dword ptr ds:[453FE0]//注意453FE0这个值
004527448B00 mov eax,dword ptr ds:[eax] //我们在命令栏输入 d 453fe0
00452746E8 91DEFFFFcall UnPackMe.004505DC
━━━━━━━━━━━━━━━━━━━━━━━━━━
00453FE000455BB0UnPackMe.00455BB0 //此时数据窗口如下
00453FE400453014UnPackMe.00453014 //我们向下拉着找有IAT指针的地址
00453FE800407138ASCII "dVE"
00453FEC0041ADD0ASCII "dVE"
00453FF00041ADF0ASCII "dVE"
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045611C00000000
0045612000000000
0045612400000000
0045612800000000
0045612C7C93188Antdll.RtlDeleteCriticalSection //找到这里,在上去就是空代码啦,所以我们的RVA就为5612C
004561307C9210EDntdll.RtlLeaveCriticalSection//我们的大小就不用去计算啦,就直接填1000
004561347C921005ntdll.RtlEnterCriticalSection//填上我们的OEP:5271C,RVA:5612C 大小:1000直接获取输入表
004561387C809EF1kernel32.InitializeCriticalSection //会发现有616个指针无效,直接剪切掉就可以啦,抓取下文件就可以啦
0045613C7C809AE4kernel32.VirtualFree
004561407C809A51kernel32.VirtualAlloc
004561447C80992Fkernel32.LocalFree
004561487C80998Dkernel32.LocalAlloc
━━━━━━━━━━━━━━━━━━━━━━━━━━
运行了一下我们的脱壳程序会发现程序无法运行,很明显是有自效验,好我们把脱壳的载入OD

0045271C >/$55push ebp //载入脱壳后的文件
0045271D|.8BECmov ebp,esp//我们在命令栏输入bpx papa
0045271F|.83C4 EC add esp,-14
00452722|.33C0xor eax,eax
00452724|.8945 EC mov [local.5],eax
00452727|.B8 34254500 mov eax,dumped_.00452534
0045272C|.E8 673BFBFF call dumped_.00406298
━━━━━━━━━━━━━━━━━━━━━━━━━━
我们找到ExitProcess退出函数
然后右键-----设置每次调用到ExitProcess的断点,如下图

1.jpg
━━━━━━━━━━━━━━━━━━━━━━━━━━
接着当然是逐一点击进去查看
004043A3|.FF15 24504500 |call dword ptr ds:[455024] //第一句排除
004043A9|>A1 00304500 |mov eax,dword ptr ds:[453000]
004043AE|.50|push eax; /ExitCode => 0
004043AF|.E8 70CEFFFF |call <jmp.&kernel32.ExitProcess>; \ExitProcess
━━━━━━━━━━━━━━━━━━━━━━━━━━
00451F0E8BC0mov eax,eax //第二句排除
00451F10/$6A 00 push 0 ; /ExitCode = 0
00451F12\.E8 9945FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
00451F17 .C3retn
━━━━━━━━━━━━━━━━━━━━━━━━━━
00452140 . /74 51 je short dumped_.00452193 //来到第三句时,我们向上找我们的关键位置
00452142 . |E9 5F020000 jmp dumped_.004523A6
00452147 > |6A 00 push 0 ; /ExitCode = 0; Case 7B of switch 00451FB8
00452149 . |E8 6243FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
━━━━━━━━━━━━━━━━━━━━━━━━━━
00452085 > \3D E9E40200 cmp eax,2E4E9 //哈哈我们非常熟悉的2E4E9
0045208A .7F 6A jg short dumped_.004520F6 //这里改NOP
0045208C .0F84 29030000 je dumped_.004523BB //这里改JMP
00452092 .3D 8BFC0000 cmp eax,0FC8B
00452097 .7F 37 jg short dumped_.004520D0
00452099 .0F84 0A020000 je dumped_.004522A9
修改如下:
0045208A . 7F 6A jg short dumped_.004520F6 //这里改NOP
0045208C . 0F84 29030000 je dumped_.004523BB //这里改JMP
━━━━━━━━━━━━━━━━━━━━━━━━━━//第四句排除
00452174 . /E9 42020000 jmp dumped_.004523BB
00452179 > |6A 00 push 0 ; /ExitCode = 0; Case 8F of switch 00451FB8
0045217B . |E8 3043FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
━━━━━━━━━━━━━━━━━━━━━━━━━━
004521A6 . /E9 10020000 jmp dumped_.004523BB//第五句排除

004521AB > |6A 00 push 0 ; /ExitCode = 0; Case 40B5 of switch 00451FB8
004521AD . |E8 FE42FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
004521B2 . |50push eax
━━━━━━━━━━━━━━━━━━━━━━━━━━
004521D8 . /E9 DE010000 jmp dumped_.004523BB //第六句排除
004521DD > |6A 00 push 0 ; /ExitCode = 0; Case 84 of switch 00451FB8
004521DF . |E8 CC42FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
004521E4 . |50push eax
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045220A . /E9 AC010000 jmp dumped_.004523BB//第七句排除
0045220F > |6A 00 push 0 ; /ExitCode = 0; Case 529 of switch 00451FB8
00452211 . |E8 9A42FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
00452216 . |E9 A0010000 jmp dumped_.004523BB
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045220A . /E9 AC010000 jmp dumped_.004523BB//第八句排除
0045220F > |6A 00 push 0 ; /ExitCode = 0; Case 529 of switch 00451FB8
00452211 . |E8 9A42FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
00452216 . |E9 A0010000 jmp dumped_.004523BB
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045226A . /E9 4C010000 jmp dumped_.004523BB//第九句排除
0045226F > |6A 00 push 0 ; /ExitCode = 0; Case C8B of switch 00451FB8
00452271 . |E8 3A42FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
00452276 . |E9 40010000 jmp dumped_.004523BB
━━━━━━━━━━━━━━━━━━━━━━━━━━
00452298 . /E9 1E010000 jmp dumped_.004523BB//第十句排除
0045229D > |6A 00 push 0 ; /ExitCode = 0; Case 348C of switch 00451FB8
0045229F . |E8 0C42FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
━━━━━━━━━━━━━━━━━━━━━━━━━━
004522C6 . /E9 F0000000 jmp dumped_.004523BB //第十一句排除
004522CB > |6A 00 push 0 ; /ExitCode = 0; Case 563183 of switch 00451FB8
004522CD . |E8 DE41FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
━━━━━━━━━━━━━━━━━━━━━━━━━━
00452302 . /E9 B4000000 jmp dumped_.004523BB //第十二句排除
00452307 > |6A 00 push 0 ; /ExitCode = 0; Case 1F241 of switch 00451FB8
00452309 . |E8 A241FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
0045230E . |E9 A8000000 jmp dumped_.004523BB
━━━━━━━━━━━━━━━━━━━━━━━━━━
00452326 .E9 90000000 jmp dumped_.004523BB //第十三句排除
0045232B >6A 00 push 0 ; /ExitCode = 0; Case 4FB of switch 00451FB8
0045232D .E8 7E41FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045234A . /EB 6F jmp short dumped_.004523BB //第十四句排除
0045234C > |6A 00 push 0 ; /ExitCode = 0; Case 89D42 of switch 00451FB8
0045234E . |E8 5D41FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045236F . /EB 4A jmp short dumped_.004523BB //第十五句排除
00452371 > |6A 00 push 0 ; /ExitCode = 0; Case 1545 of switch 00451FB8
00452373 . |E8 3841FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045238D . /EB 2C jmp short dumped_.004523BB //第十六句排除
0045238F > |6A 00 push 0 ; /ExitCode = 0; Case D575 of switch 00451FB8
00452391 . |E8 1A41FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
━━━━━━━━━━━━━━━━━━━━━━━━━━
004523B3 .58pop eax//第十七句排除
004523B4 .6A 00 push 0 ; /ExitCode = 0
004523B6 .E8 F540FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
004523BB >33C0xor eax,eax;Case 2E4E9 of switch 00451FB8
━━━━━━━━━━━━━━━━━━━━━━━━━━
00452419|.3D E9E40200 cmp eax,2E4E9//这里不跳即挂
0045241E|.74 07 je short dumped_.00452427//所以修改为JMP
00452420|.6A 00 push 0 ; /ExitCode = 0
00452422|.E8 8940FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
━━━━━━━━━━━━━━━━━━━━━━━━━━
修改了以上两处后,我们保存会发现程序还是不能运行,我们载入我们已经修复了两处效验的程序
0045271C >/$55push ebp //OD载入
0045271D|.8BECmov ebp,esp//在命令行下断 bp FindFirstFileA
0045271F|.83C4 EC add esp,-14//下好断后,我们F9运行程序
00452722|.33C0xor eax,eax
00452724|.8945 EC mov [local.5],eax
00452727|.B8 34254500 mov eax,1.00452534
━━━━━━━━━━━━━━━━━━━━━━━━━━
7C8137D9 >8BFFmov edi,edi //程序停在这里,我们AIT+F9返回
7C8137DB55push ebp
7C8137DC8BECmov ebp,esp
7C8137DE81EC 6C020000 sub esp,26C
7C8137E4A1 CC46887C mov eax,dword ptr ds:[7C8846CC]
7C8137E956push esi
━━━━━━━━━━━━━━━━━━━━━━━━━━
00408848|.8BF0mov esi,eax //由于代码过多我就只复制关键啦
0040884A|.8973 14 mov dword ptr ds:[ebx+14],esi //我们F8单步走起
0040884D|.83FE FF cmp esi,-1
00408850|.74 16 je short 1.00408868
00408852|.8BC3mov eax,ebx
━━━━━━━━━━━━━━━━━━━━━━━━━━
00452768|.E8 7F06FBFF call 1.00402DEC
0045276D|.8B45 EC mov eax,[local.5]
00452770|.E8 0BFDFFFF call 1.00452480
00452775|.3D E9E40200 cmp eax,2E4E9 //很明显我们的这句还没有改
0045277A|.75 0C jnz short 1.00452788//所以这里改NOP既可过掉我们所有效验保存即可
0045277C|.A1 E03F4500 mov eax,dword ptr ds:[453FE0]
00452781|.8B00mov eax,dword ptr ds:[eax]
修改如下:
0045277A 75 0C jnz short dumped_.00452788 //这句改NOP
━━━━━━━━━━━━━━━━━━━━━━━━━━
其实自效验不单是体力活,有时对API函数和断点的了解可以让我们用脑力来进行替代
 楼主| 小生我怕怕 发表于 2008-10-13 01:13
00400154 >8725 AC824900 xchg dword ptr ds:[4982AC],esp//OD载入
0040015A61popad
0040015B94xchg eax,esp//单步F8到此,注意堆栈窗口
0040015C55push ebp
0040015DA4movs byte ptr es:[edi],byte ptr ds:[esi]
━━━━━━━━━━━━━━━━━━━━━━━━━━
004982B0 004001E8UnPackMe.004001E8
004982B4 004001DCUnPackMe.004001DC
004982B8 004001DEUnPackMe.004001DE//下面即我们OEP地址0045271C
004982BC 0045271CUnPackMe.0045271C//在这行我们右键,反汇编窗口跟随
004982C0 > 7C801D77kernel32.LoadLibraryA
004982C4 > 7C80ADA0kernel32.GetProcAddress
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045271C00db 00//右键从模块中删除分析
0045271D00db 00//删除后如下面的分析
0045271E00db 00
0045271F00db 00
0045272000db 00
0045272100db 00
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045271C0000 add byte ptr ds:[eax],al//在此右键断点,设置硬件访问断点
0045271E0000 add byte ptr ds:[eax],al//ctrl+f2从新加载程序
004527200000 add byte ptr ds:[eax],al
004527220000 add byte ptr ds:[eax],al
004527240000 add byte ptr ds:[eax],al
━━━━━━━━━━━━━━━━━━━━━━━━━━
00400154 >8725 AC824900xchg dword ptr ds:[4982AC],esp//从新加载后在这里
0040015A61 popad //F9直接运行程序
0040015B94 xchg eax,esp
0040015C55 push ebp
0040015DA4 movs byte ptr es:[edi],byte ptr ds:[esi]
0040015EB6 80mov dh,80
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045271C55 push ebp//程序直接停在我们的OEP上
0045271D8BEC mov ebp,esp //运行lordPE把程序DUMP
0045271F83C4 ECadd esp,-14 //运行importRCE修复程序
0045272233C0 xor eax,eax
004527248945 ECmov dword ptr ss:[ebp-14],eax
00452727B8 34254500mov eax,UnPackMe.00452534
0045272CE8 673BFBFFcall UnPackMe.00406298
━━━━━━━━━━━━━━━━━━━━━━━━━━
在修复时,会发现只有3个指针,这种情况是不可能有的,所以我们要开始手动来查找我们的IAT指针
当然如果有CHimpREC这个工具就可以避免手动查找IAT的痛苦,好啦废话就不多说啦,我们开始找我
们的IAT指针
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045271C55 push ebp //这里是我们的OEP处
0045271D8BEC mov ebp,esp
0045271F83C4 ECadd esp,-14
0045272233C0 xor eax,eax
004527248945 ECmov dword ptr ss:[ebp-14],eax
00452727B8 34254500mov eax,UnPackMe.00452534
0045272CE8 673BFBFFcall UnPackMe.00406298
0045273133C0 xor eax,eax
0045273355 push ebp
0045273468 9E274500push UnPackMe.0045279E
0045273964:FF30push dword ptr fs:[eax]
0045273C64:8920mov dword ptr fs:[eax],esp
0045273FA1 E03F4500mov eax,dword ptr ds:[453FE0]//注意453FE0这个值
004527448B00 mov eax,dword ptr ds:[eax] //我们在命令栏输入 d 453fe0
00452746E8 91DEFFFFcall UnPackMe.004505DC
━━━━━━━━━━━━━━━━━━━━━━━━━━
00453FE000455BB0UnPackMe.00455BB0 //此时数据窗口如下
00453FE400453014UnPackMe.00453014 //我们向下拉着找有IAT指针的地址
00453FE800407138ASCII "dVE"
00453FEC0041ADD0ASCII "dVE"
00453FF00041ADF0ASCII "dVE"
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045611C00000000
0045612000000000
0045612400000000
0045612800000000
0045612C7C93188Antdll.RtlDeleteCriticalSection //找到这里,在上去就是空代码啦,所以我们的RVA就为5612C
004561307C9210EDntdll.RtlLeaveCriticalSection//我们的大小就不用去计算啦,就直接填1000
004561347C921005ntdll.RtlEnterCriticalSection//填上我们的OEP:5271C,RVA:5612C 大小:1000直接获取输入表
004561387C809EF1kernel32.InitializeCriticalSection //会发现有616个指针无效,直接剪切掉就可以啦,抓取下文件就可以啦
0045613C7C809AE4kernel32.VirtualFree
004561407C809A51kernel32.VirtualAlloc
004561447C80992Fkernel32.LocalFree
004561487C80998Dkernel32.LocalAlloc
━━━━━━━━━━━━━━━━━━━━━━━━━━
运行了一下我们的脱壳程序会发现程序无法运行,很明显是有自效验,好我们把脱壳的载入OD
经过了前一次痛苦的分析,现在我们来个简化的流程,不难发现我们的3处比较都是以2E4E9来
进行比较,而比较方法也是一样的,所以简化出下面的方法,关键语句:cmp eax,2E4E9
0045271C >/$55push ebp //OD载入脱壳后的文件
0045271D|.8BECmov ebp,esp//我们右键----搜索----全部命令
0045271F|.83C4 EC add esp,-14//然后我们查找cmp eax,2E4E9
00452722|.33C0xor eax,eax
00452724|.8945 EC mov [local.5],eax
━━━━━━━━━━━━━━━━━━━━━━━━━━
我们会发现有三个同一样的命令,如下图
1.jpg

━━━━━━━━━━━━━━━━━━━━━━━━━━
我们选择第一个,双击进去
00452085 > \3D E9E40200 cmp eax,2E4E9 //这里就是我们刚分析的第一句比较
0045208A .7F 6A jg short dumped_.004520F6 //所以这里应该改NOP
0045208C .0F84 29030000 je dumped_.004523BB //这里改JMP不然程序就退出啦
修改如下:
0045208A . 7F 6A jg short dumped_.004520F6 //这里改NOP
0045208C . 0F84 29030000 je dumped_.004523BB //这里改JMP
━━━━━━━━━━━━━━━━━━━━━━━━━━
我们在来看看我们的第2处比较
00452419|.3D E9E40200 cmp eax,2E4E9 //这句就更明显啦,不跳就是退出
0045241E|.74 07 je short dumped_.00452427 //所以这里改JMP
00452420|.6A 00 push 0 ; /ExitCode = 0
00452422|.E8 8940FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
修改如下:
0045241E 74 07 je short dumped_.00452427 //这里改JMP
━━━━━━━━━━━━━━━━━━━━━━━━━━
我们在来看看我们的第3处比较
00452775|.3D E9E40200 cmp eax,2E4E9 //这里就是我们刚分析的第2处比较位置
0045277A|.75 0C jnz short dumped_.00452788//所以这里就应该改为NOP
0045277C|.A1 E03F4500 mov eax,dword ptr ds:[453FE0]
00452781|.8B00mov eax,dword ptr ds:[eax]
00452783|.E8 ECDEFFFF call dumped_.00450674
修改如下:
0045277A 75 0C jnz short dumped_.00452788 //这句改NOP
━━━━━━━━━━━━━━━━━━━━━━━━━━
修改后保存,就这样一分钟不到就过掉了我们的效验,当然这是建立在上面的痛苦分析上的
 楼主| 小生我怕怕 发表于 2008-10-13 01:02
00400154 > 8725 AC824900 xchg dword ptr ds:[4982AC],esp //OD载入
0040015A 61 popad
0040015B 94 xchg eax,esp //单步F8到此,注意堆栈窗口
0040015C 55 push ebp
0040015D A4 movs byte ptr es:[edi],byte ptr ds:[esi]
━━━━━━━━━━━━━━━━━━━━━━━━━━
004982B0 004001E8 UnPackMe.004001E8
004982B4 004001DC UnPackMe.004001DC
004982B8 004001DE UnPackMe.004001DE //下面即我们OEP地址0045271C
004982BC 0045271C UnPackMe.0045271C //在这行我们右键,反汇编窗口跟随
004982C0 > 7C801D77 kernel32.LoadLibraryA
004982C4 > 7C80ADA0 kernel32.GetProcAddress
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045271C 00 db 00 //右键从模块中删除分析
0045271D 00 db 00 //删除后如下面的分析
0045271E 00 db 00
0045271F 00 db 00
00452720 00 db 00
00452721 00 db 00
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045271C 0000 add byte ptr ds:[eax],al //在此右键断点,设置硬件访问断点
0045271E 0000 add byte ptr ds:[eax],al //ctrl+f2从新加载程序
00452720 0000 add byte ptr ds:[eax],al
00452722 0000 add byte ptr ds:[eax],al
00452724 0000 add byte ptr ds:[eax],al
━━━━━━━━━━━━━━━━━━━━━━━━━━
00400154 > 8725 AC824900 xchg dword ptr ds:[4982AC],esp //从新加载后在这里
0040015A 61 popad //F9直接运行程序
0040015B 94 xchg eax,esp
0040015C 55 push ebp
0040015D A4 movs byte ptr es:[edi],byte ptr ds:[esi]
0040015E B6 80 mov dh,80
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045271C 55 push ebp //程序直接停在我们的OEP上
0045271D 8BEC mov ebp,esp //运行lordPE把程序DUMP
0045271F 83C4 EC add esp,-14 //运行importRCE修复程序
00452722 33C0 xor eax,eax
00452724 8945 EC mov dword ptr ss:[ebp-14],eax
00452727 B8 34254500 mov eax,UnPackMe.00452534
0045272C E8 673BFBFF call UnPackMe.00406298
━━━━━━━━━━━━━━━━━━━━━━━━━━
在修复时,会发现只有3个指针,这种情况是不可能有的,所以我们要开始手动来查找我们的IAT指针
当然如果有CHimpREC这个工具就可以避免手动查找IAT的痛苦,好啦废话就不多说啦,我们开始找我
们的IAT指针
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045271C 55 push ebp //这里是我们的OEP处
0045271D 8BEC mov ebp,esp
0045271F 83C4 EC add esp,-14
00452722 33C0 xor eax,eax
00452724 8945 EC mov dword ptr ss:[ebp-14],eax
00452727 B8 34254500 mov eax,UnPackMe.00452534
0045272C E8 673BFBFF call UnPackMe.00406298
00452731 33C0 xor eax,eax
00452733 55 push ebp
00452734 68 9E274500 push UnPackMe.0045279E
00452739 64:FF30 push dword ptr fs:[eax]
0045273C 64:8920 mov dword ptr fs:[eax],esp
0045273F A1 E03F4500 mov eax,dword ptr ds:[453FE0] //注意453FE0这个值
00452744 8B00 mov eax,dword ptr ds:[eax] //我们在命令栏输入 d 453fe0
00452746 E8 91DEFFFF call UnPackMe.004505DC
━━━━━━━━━━━━━━━━━━━━━━━━━━
00453FE0 00455BB0 UnPackMe.00455BB0 //此时数据窗口如下
00453FE4 00453014 UnPackMe.00453014 //我们向下拉着找有IAT指针的地址
00453FE8 00407138 ASCII "dVE"
00453FEC 0041ADD0 ASCII "dVE"
00453FF0 0041ADF0 ASCII "dVE"
━━━━━━━━━━━━━━━━━━━━━━━━━━
0045611C 00000000
00456120 00000000
00456124 00000000
00456128 00000000
0045612C 7C93188A ntdll.RtlDeleteCriticalSection //找到这里,在上去就是空代码啦,所以我们的RVA就为5612C
00456130 7C9210ED ntdll.RtlLeaveCriticalSection //我们的大小就不用去计算啦,就直接填1000
00456134 7C921005 ntdll.RtlEnterCriticalSection //填上我们的OEP:5271C,RVA:5612C 大小:1000直接获取输入表
00456138 7C809EF1 kernel32.InitializeCriticalSection //会发现有616个指针无效,直接剪切掉就可以啦,抓取下文件就可以啦
0045613C 7C809AE4 kernel32.VirtualFree
00456140 7C809A51 kernel32.VirtualAlloc
00456144 7C80992F kernel32.LocalFree
00456148 7C80998D kernel32.LocalAlloc
━━━━━━━━━━━━━━━━━━━━━━━━━━
运行了一下我们的脱壳程序会发现程序无法运行,很明显是有自效验,好我们把脱壳的载入OD
0045271C >/$ 55 push ebp //从新载入后在这里
0045271D |. 8BEC mov ebp,esp //在命令行下断 bp FindFirstFileA
0045271F |. 83C4 EC add esp,-14 //下好断后,f9运行程序
00452722 |. 33C0 xor eax,eax
00452724 |. 8945 EC mov [local.5],eax
00452727 |. B8 34254500 mov eax,dumped_.00452534
━━━━━━━━━━━━━━━━━━━━━━━━━━
7C8137D9 > 8BFF mov edi,edi//F9运行到这里后
7C8137DB 55 push ebp//记住这个断点千万不能取消,后面还要用到
7C8137DC 8BEC mov ebp,esp
7C8137DE 81EC 6C020000 sub esp,26C
7C8137E4 A1 CC46887C mov eax,dword ptr ds:[7C8846CC]
━━━━━━━━━━━━━━━━━━━━━━━━━━
00408848 |. 8BF0 mov esi,eax //ait+f9返回到这里
0040884A |. 8973 14 mov dword ptr ds:[ebx+14],esi //开始单步f8走起
0040884D |. 83FE FF cmp esi,-1 //以下代码过多我就不复制啦,我尽量复制关键
00408850 |. 74 16 je short dumped_.00408868 //一路F8单步走就是啦
00408852 |. 8BC3 mov eax,ebx
00408854 |. E8 63FFFFFF call dumped_.004087BC
━━━━━━━━━━━━━━━━━━━━━━━━━━
00451FB8 . 3D D7330000 cmp eax,33D7 //哈哈到这里一定忽悠死不少人
00451FBD . 0F8F C2000000 jg dumped_.00452085 //我们只要注意他的跳向地址就可以闭开啦
00451FC3 . 0F84 1C030000 je dumped_.004522E5
00451FC9 . 3D FB040000 cmp eax,4FB //单步跳走
00451FCE . 7F 5E jg short dumped_.0045202E
00451FD0 . 0F84 55030000 je dumped_.0045232B
━━━━━━━━━━━━━━━━━━━━━━━━━━
00452085 > \3D E9E40200 cmp eax,2E4E9 //单步到这里会发现我们脱壳后的会大几倍,在向下拉看看。他是跳去退出
0045208A . 7F 6A jg short dumped_.004520F6 //这里改NOP
0045208C . 0F84 29030000 je dumped_.004523BB //这里向下看如果不跳,下面的地址将跳向退出,所以这里要改JMP
00452092 . 3D 8BFC0000 cmp eax,0FC8B
00452097 . 7F 37 jg short dumped_.004520D0
00452099 . 0F84 0A020000 je dumped_.004522A9
0045209F . 2D 8C340000 sub eax,348C
004520A4 . 0F84 F3010000 je dumped_.0045229D

修改如下:
0045208A . 7F 6A jg short dumped_.004520F6 //这里改NOP
0045208C . 0F84 29030000 je dumped_.004523BB //这里改JMP

━━━━━━━━━━━━━━━━━━━━━━━━━━
004523BB > \33C0 xor eax,eax //修改后跳向这里
004523BD . 5A pop edx //继续单步F8走
004523BE . 59 pop ecx //由于代码过多我就不一样复制啦
004523BF . 59 pop ecx
004523C0 . 64:8910 mov dword ptr fs:[eax],edx
004523C3 . EB 0A jmp short dumped_.004523CF
━━━━━━━━━━━━━━━━━━━━━━━━━━
00452766 |. 33C0 xor eax,eax
00452768 |. E8 7F06FBFF call dumped_.00402DEC
0045276D |. 8B45 EC mov eax,[local.5]
00452770 |. E8 0BFDFFFF call dumped_.00452480 //在路过这个CALL时会跑去系统里如下
━━━━━━━━━━━━━━━━━━━━━━━━━━
7C8137D9 > 8BFF mov edi,edi //我们继续AIT+F9返回到用户代码
7C8137DB 55 push ebp
7C8137DC 8BEC mov ebp,esp
7C8137DE 81EC 6C020000 sub esp,26C
━━━━━━━━━━━━━━━━━━━━━━━━━━
00408848 |. 8BF0 mov esi,eax //继续F8单步走
0040884A |. 8973 14 mov dword ptr ds:[ebx+14],esi //由于代码过多我就不复制啦
0040884D |. 83FE FF cmp esi,-1
00408850 |. 74 16 je short dumped_.00408868
00408852 |. 8BC3 mov eax,ebx
━━━━━━━━━━━━━━━━━━━━━━━━━━
00452775 |. 3D E9E40200 cmp eax,2E4E9 //我们F8单步到达这里时注意他比较的值和我们上面一样
0045277A 75 0C jnz short dumped_.00452788 //这里改NOP就可以过掉第2处效验
0045277C |. A1 E03F4500 mov eax,dword ptr ds:[453FE0]
00452781 |. 8B00 mov eax,dword ptr ds:[eax]
00452783 |. E8 ECDEFFFF call dumped_.00450674

修改如下:
0045277A 75 0C jnz short dumped_.00452788 //这句改NOP

━━━━━━━━━━━━━━━━━━━━━━━━━━
0045277C |. A1 E03F4500 mov eax,dword ptr ds:[453FE0] //继续F8单步走
00452781 |. 8B00 mov eax,dword ptr ds:[eax] //由于代码过多我也不复制啦
00452783 |. E8 ECDEFFFF call dumped_.00450674 //路过这里时程序又跑去系统里啦
00452788 |> 33C0 xor eax,eax //此时会发现程序已经运行啦,但是这只是假象
0045278A |. 5A pop edx //所以我们还得继续寻找
━━━━━━━━━━━━━━━━━━━━━━━━━━
7C8137D9 > 8BFF mov edi,edi //我们AIT+F9返回到用户代码
7C8137DB 55 push ebp
7C8137DC 8BEC mov ebp,esp
7C8137DE 81EC 6C020000 sub esp,26C
7C8137E4 A1 CC46887C mov eax,dword ptr ds:[7C8846CC]
━━━━━━━━━━━━━━━━━━━━━━━━━━
00408848 |. 8BF0 mov esi,eax //我们返回到这里
0040884A |. 8973 14 mov dword ptr ds:[ebx+14],esi //由于代码过多我也就不一一复制
0040884D |. 83FE FF cmp esi,-1 //继续单步F8跟
00408850 |. 74 16 je short dumped_.00408868
00408852 |. 8BC3 mov eax,ebx
━━━━━━━━━━━━━━━━━━━━━━━━━━
00452419 |. 3D E9E40200 cmp eax,2E4E9 //当跟踪到这里时会发现出现第3处比较
0045241E 74 07 je short dumped_.00452427 //这里不跳就直接退出啦,所以这里改JMP
00452420 |. 6A 00 push 0 ; /ExitCode = 0
00452422 |. E8 8940FBFF call <jmp.&kernel32.ExitProcess> ; \ExitProcess
00452427 |> 33C0 xor eax,eax

修改如下:
0045241E 74 07 je short dumped_.00452427 //这里改JMP

━━━━━━━━━━━━━━━━━━━━━━━━━━
修改后,我们右键---复制到可执行文件,所有改动,然后保存一份
运行我们的程序,可以运行自效验已经排除

去效验.rar

338 KB, 下载次数: 20, 下载积分: 吾爱币 -1 CB

lqiulu 发表于 2008-10-13 09:37
PEID查壳
FSG 2.0 -> bart/xt
一、 脱壳:

查找特征代码,popad
xchg eax,esp即二进制代码“6194”
ctrl + G到400000,ctrl + B 查找“6194”到这里:

0040015A61POPAD
0040015B94XCHG EAX,ESP //这里下断,F9运行。断下后看堆栈:
0040015C55PUSH EBP
0040015DA4MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
0040015EB6 80 MOV DH,80
00400160FF13CALL DWORD PTR DS:[EBX]
-------------------------------------------------------------------------------------
堆栈情况:
004982B0 004001E8UnPackMe.004001E8
004982B4 004001DCUnPackMe.004001DC
004982B8 004001DEUnPackMe.004001DE
004982BC 0045271CUnPackMe.0045271C //这里就是程序的OEP,到OEP地址下硬件执行断点。F9运行。
004982C0 > 7C801D7Bkernel32.LoadLibraryA
004982C4 > 7C80AE30kernel32.GetProcAddress

-------------------------------------------------------------------------------------
断在这里:
0045271C55PUSH EBP; 断在这里,这里是程序的OEP.dump下修复。
0045271D8BECMOV EBP,ESP
0045271F83C4 EC ADD ESP,-14
0045272233C0XOR EAX,EAX
004527248945 EC MOV DWORD PTR SS:[EBP-14],EAX
00452727B8 34254500 MOV EAX,UnPackMe.00452534
0045272CE8 673BFBFF CALL UnPackMe.00406298

填入oep自动查找,发现rva大小为c太小,手动查找。
crtl+g到401000然后CRTL+b查找“FF 25”,
004011F4- FF25 B0614500 JMP DWORD PTR DS:[4561B0] ; kernel32.GetStdHandle
数据窗口跟随 --》内存地址。
0045612800000000
0045612C7C93135Antdll.RtlDeleteCriticalSection
004561307C9210E0ntdll.RtlLeaveCriticalSection
004561347C921000ntdll.RtlEnterCriticalSection
004561387C809F81kernel32.InitializeCriticalSection
0045613C7C809B74kernel32.VirtualFree
004561407C809AE1kernel32.VirtualAlloc
004561447C8099BFkernel32.LocalFree
004561487C809A1Dkernel32.LocalAlloc
。。。。。。。。。。。。。。。。。。。。。。。。。
0045672C5D180205comctl32.ImageList_Create
004567307FFFFFFF
004567347D611150shell32.ShellExecuteA
00456738FFFFFFFF

rav:5612c,size:56738-5612c=60C
cut掉无效指针。修复。

======================================================================================================

去自校验:

首先看是否是文件大小自校验:
原始文件打小为:189,673,也就是十六进制的,2E4E9
查找所有常量:2E4E9
查到三处:
References in dumped_: to constant 2E4E9
AddressDisassembly Comment
00452085 CMP EAX,2E4E9
00452419 CMP EAX,2E4E9
00452775 CMP EAX,2E4E9
都是比较大小的。

把原文件的大小统统改了脱壳后文件的大小
634880即十六进制的
9B000
保存修改。ok可以运行了。

2.rar
aisht 发表于 2008-10-13 10:01
查壳 FSG 2.0 -> bart/xt
载入
00400154 >8725 AC824900 xchg dword ptr ds:[4982AC],esp
0040015A61popad
0040015B94xchg eax,esp
0040015C55push ebp
0040015DA4movs byte ptr es:[edi],byte ptr ds:[esi]
0040015EB6 80 mov dh,80
00400160FF13call dword ptr ds:[ebx]
00400162^ 73 F9 jnb short UnPackMe.0040015D
0040016433C9xor ecx,ecx
00400166FF13call dword ptr ds:[ebx]

进行向下单步
004001C550push eax
004001C6FF53 10 call dword ptr ds:[ebx+10]
004001C995xchg eax,ebp
004001CA8B07mov eax,dword ptr ds:[edi]
004001CC40inc eax
004001CD^ 78 F3 js short UnPackMe.004001C2
004001CF75 03 jnz short UnPackMe.004001D4
004001D1FF63 0C jmp dword ptr ds:[ebx+C]//这里.FSG 2.0 的跳到OEP的特征
004001D450push eax
004001D555push ebp
004001D6FF53 14 call dword ptr ds:[ebx+14]
004001D9ABstos dword ptr es:[edi]
004001DA^ EB EE jmp short UnPackMe.004001CA
004001DC33C9xor ecx,ecx
004001DE41inc ecx
到这里可以发现有FSG 2.0 的跳到OEP的特征. F2 断下 F9运行 在F8进入到达OEP
0045271C/.55push ebp//OEP
0045271D|.8BECmov ebp,esp
0045271F|.83C4 EC add esp,-14
00452722|.33C0xor eax,eax
00452724|.8945 EC mov [local.5],eax
00452727|.B8 34254500 mov eax,UnPackMe.00452534
0045272C|.E8 673BFBFF call UnPackMe.00406298
00452731|.33C0xor eax,eax
00452733|.55push ebp

进行脱壳 修复 ,修复需要自己手动查找IAT. 修复完后 运行没有任何提示.
再根据题名判断为自校验.
我们继续OD载入修复好的文件.
载入后 下 ExitProcess 这个断点 原因为退出断点 bp ExitProcess下好后 F9运行

0012FDDC 004523BB/CALL 到 ExitProcess 来自 1_.004523B6
0012FDE0 00000000\ExitCode = 0
0012FDE4 0012FDF0指针到下一个 SEH 记录
0012FDE8 004523C5SE 句柄
0012FDEC 0012FE0C
0012FDF0 0012FE14指针到下一个 SEH 记录
堆栈显示
根据 CALL 到 ExitProcess 来自 1_.004523B6 我们双击看反汇编
004523AB .89C3mov ebx,eax
004523AD .89D8mov eax,ebx
004523AF .01D8add eax,ebx
004523B1 .89C3mov ebx,eax
004523B3 .58pop eax
004523B4 .6A 00 push 0 ; /ExitCode = 0
004523B6 .E8 F540FBFF call <jmp.&kernel32.ExitProcess>这个就是退出的CALL
004523BB >33C0xor eax,eax 那这个就是跳过退出CALL的
004523BD .5Apop edx
004523BE .59pop ecx
004523BF .59pop ecx
004523C0 .64:8910 mov dword ptr fs:[eax],edx
004523C3 .EB 0A jmp short 1_.004523CF
我们拉往段首下F2断 .
00451F5C .55push ebp//下断
00451F5D .8BECmov ebp,esp
00451F5F .6A 00 push 0
00451F61 .53push ebx
00451F62 .56push esi
00451F63 .57push edi
00451F64 .33C0xor eax,eax
00451F66 .55push ebp
00451F67 .68 E5234500 push 1_.004523E5
00451F6C .64:FF30 push dword ptr fs:[eax]
重新载入. F9运行我们单步跟踪.
00451FB8 .3D D7330000 cmp eax,33D7比较,但没有发现数值和33D7一样的.继续.
00451FBD .0F8F C2000000 jg 1_.00452085跳了.
00451FC3 .0F84 1C030000 je 1_.004522E5
00451FC9 .3D FB040000 cmp eax,4FB
跳到了下面这里.
00452085 > \3D E9E40200 cmp eax,2E4E9
0045208A .7F 6A jg short 1_.004520F6
0045208C .0F84 29030000 je 1_.004523BB
看 cmp eax,2E4E9把 2E4E9 转换成10进制 得出 189673
再发现原程序. 大小为 189,673字节
证明 校验处在这里我们改成我们脱壳修复后的大小. 大小 647,168转成16进 9E000
继续单步发现可以跳过之前的 Exit .
既然这样我们直接搜索命令cmp eax,2E4E9把 cmp eax,2E4E9 都改成 cmp eax,9E000
结束掉 大小的校验.
可以发现还有两处.修改好后保存.发现可以正常运行. 自校验去除完毕.
lynn 发表于 2008-10-13 12:57
1.脱壳。
脱壳不多说了,直接找FSG的特征码:
004001D1- FF63 0C jmp dword ptr [ebx+C]; oep
这里下断,断下后F8即到OEP,然后lordPE和ImportREC配合即可脱壳。

2.去自校验
脱了壳直接用dede反编译,看了下FormCreate和Timer1Timer绝对有可疑的

00451F5C来到FormCreate。看了下,后面有很多判断,很多判断跳转到ExitProcess调用,不管那么多了,delphi的FormCreate如果没啥特别要做的事的话,可以让它直接返回,所以我们直接让00451F5C返回,即retn
00451F5CC3retn ;retn

004523F4来到Timer1Timer,很明显的就是
0045241E /74 07 jeshort 00452427 ;jmp
00452420|. |6A 00 push0; /ExitCode = 0
00452422|. |E8 8940FBFF call<jmp.&kernel32.ExitProcess>; \ExitProcess
0045241E 那句改jmp即可

改了上述两个地方后,还不行,最后还有一处,OD停在OEP就可以看到
0045277A /75 0C jnz short 00452788 ;nop
0045277C|. |A1 E03F4500 mov eax, dword ptr [453FE0]
00452781|. |8B00mov eax, dword ptr [eax]
00452783|. |E8 ECDEFFFF call00450674
00452788|> \33C0xor eax, eax
0045277A 那行改nop即可,修改后运行成功。

OK,共三处patch:
1.00451F5C
C3

2.0045241E
EB 07

3.0045277A
90 90

附件就不用传了吧,比较大 [s:40]
小糊涂虫 发表于 2008-10-13 13:03
OD载入..
00400154 >8725 AC824900xchg dword ptr ds:[4982AC],esp
0040015A61 popad
0040015B94 xchg eax,esp ; UnPackMe.004982B0F8到这里.....
这时看堆栈..........
004982B8004001DE UnPackMe.004001DE
004982BC0045271C UnPackMe.0045271C这里应该就是所谓的...............
004982C0 <> 7C801D77 kernel32.LoadLibraryA
004982C4 <> 7C80ADA0 kernel32.GetProcAddress

然后脱壳..修复.....
修复时发现只三个指针,,,很明显的....这是不行的....看下面
0045612400000000
0045612800000000
0045612C7C93188Antdll.RtlDeleteCriticalSection应该是从这里开始的....
004561307C9210EDntdll.RtlLeaveCriticalSection
004561347C921005ntdll.RtlEnterCriticalSection
......................
004567285D1803D8comctl32.ImageList_Destroy
0045672C5D180205comctl32.ImageList_Create
004567307FFFFFFF
004567347D610EE0shell32.ShellExecuteA 到这里结束吧....
00456738FFFFFFFF

RAV填:5612C 大小填:734-12C
然后把无效的指针CUT....
发现还是运行不了的.....
然后载入修复的程序.....来到下面(和上期的方面差不多的...)
0045207A /0F84 41020000je UnPackMe.004522C1
00452080 |E9 21030000jmp UnPackMe.004523A6
00452085 |3D E9E40200cmp eax,2E4E9看到这个应该很明显了(换成十进制看)........
0045208A |7F 6Ajg short UnPackMe.004520F6直接改成JL
0045208C |0F84 29030000je UnPackMe.004523BB改成JMP
00452092 |3D 8BFC0000cmp eax,0FC8B

F8向下走....
来到这里后....
00452770E8 0BFDFFFFcall UnPackMe.00452480
004527753D E9E40200cmp eax,2E4E9 这里还有一处效验的.....
0045277A75 0Cjnz short UnPackMe.00452788改相反的....
0045277CA1 E03F4500mov eax,dword ptr ds:[453FE0]
004527818B00 mov eax,dword ptr ds:[eax]

这样保存以后还没完..程序运行一下就关闭了
..00452414E8 6BFAFFFFcall 1.00451E84
004524193D E9E40200cmp eax,2E4E9 这里还有效验...
0045241E74 07je short 1.00452427 把这里一改就OK了.....
004524206A 00push 0
00452422E8 8940FBFFcall <jmp.&kernel32.ExitProcess>

.到此结束了..OK............... [s:17]
pcfans 发表于 2008-10-13 13:09
脱壳过程

脱壳方法不知道叫什么方法好了,堆栈跟踪法?哈哈,不管了,看过程吧
OD载入


00400154 >8725 AC824900 XCHG DWORD PTR DS:[4982AC],ESP ;OD载入停在这里,F8单步一次,看堆栈
0040015A61POPAD
0040015B94XCHG EAX,ESP
0040015C55PUSH EBP
0040015DA4MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
0040015EB6 80 MOV DH,80

------------------------------
单步一次后的堆栈情况

00498290 00401000UnPackMe.00401000
00498294 0046B764UnPackMe.0046B764
00498298 00456000UnPackMe.00456000
0049829C 00000000
004982A0 004982B0UnPackMe.004982B0
004982A4 00000080
004982A8 00007D00
004982AC 0012FFC4
004982B0 004001E8UnPackMe.004001E8
004982B4 004001DCUnPackMe.004001DC
004982B8 004001DEUnPackMe.004001DE
004982BC 0045271CUnPackMe.0045271C ;看到这句了吧,在此行回车或右键跟随到反汇编窗口
004982C0 > 7C801D77kernel32.LoadLibraryA
004982C4 > 7C80AC28kernel32.GetProcAddress
004982C8 00000000
---------------------------------
来到反汇编窗口

0045271C00DB 00 ;程序停在这,全是零字节,在此行下硬件执行断点,F9运行
0045271D00DB 00
0045271E00DB 00
0045271F00DB 00
0045272000DB 00
0045272100DB 00
0045272200DB 00
---------------------------------
怎么样断下来后,这里就全解码了,右键分析一下

0045271C55PUSH EBP ;OEP就这样到了,看到这,那些还在单步跟的兄弟一定开始吐血了吧,哈


0045271D8BECMOV EBP,ESP
0045271F83C4 EC ADD ESP,-14
0045272233C0XOR EAX,EAX
004527248945 EC MOV DWORD PTR SS:[EBP-14],EAX
00452727B8 34254500 MOV EAX,UnPackMe.00452534
0045272CE8 673BFBFF CALL UnPackMe.00406298
0045273133C0XOR EAX,EAX
0045273355PUSH EBP
0045273468 9E274500 PUSH UnPackMe.0045279E
0045273964:FF30 PUSH DWORD PTR FS:[EAX]
0045273C64:8920 MOV DWORD PTR FS:[EAX],ESP
---------------------------------
接下来就开始脱壳吧,拿出法宝LoadPE脱掉,IR修复,我这里怎么才有三个指针,不知道是我工具的问题,还是程序

就是这样的,我只好手工输入查找到的IAT的起始位置56128,大小填1000,剪掉多余的指针,抓取脱壳文件修复。


下面就重新载入脱壳后的文件,来解除文件的自校验了


0045271C >/$55PUSH EBP ;OD载入停到了让很多人吐血的OEP
0045271D|.8BECMOV EBP,ESP
0045271F|.83C4 EC ADD ESP,-14
00452722|.33C0XOR EAX,EAX
00452724|.8945 EC MOV DWORD PTR SS:[EBP-14],EAX
00452727|.B8 34254500 MOV EAX,dumped_.00452534
0045272C|.E8 673BFBFF CALL dumped_.00406298
------------------------------
我们下程序退出的函数断点ExitProcess后F9运行

7C81CAA2 >8BFFMOV EDI,EDI ; 程序停在这里了,然后看堆栈
7C81CAA455PUSH EBP
7C81CAA58BECMOV EBP,ESP
7C81CAA76A FF PUSH -1
7C81CAA968 B0F3E877 PUSH 77E8F3B0
7C81CAAEFF75 08 PUSH DWORD PTR SS:[EBP+8]
7C81CAB1E8 46FFFFFF CALL kernel32.7C81C9FC
------------------------------
堆栈情况:

0012FDDC 004523BB/CALL 到 ExitProcess 来自 dumped_.004523B6 ;我们在这行回车跟随到反汇编窗口
0012FDE0 00000000\ExitCode = 0
0012FDE4 0012FDF0指向下一个 SEH 记录的指针
------------------------------
程序返回到一个退出函数的call的下面,我们向上翻,找到段首
004523B3 .58POP EAX
004523B4 .6A 00 PUSH 0 ; /ExitCode = 0
004523B6 .E8 F540FBFF CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
004523BB >33C0XOR EAX,EAX;返回到这里
004523BD .5APOP EDX
------------------------------
找到段首了,不要问什么段首啊,多看看教程就知道了

00451F5C .55PUSH EBP ;这里就是段首了,下个F2断点吧,重载后F9运行断在这里F8单步跟吧
00451F5D .8BECMOV EBP,ESP
00451F5F .6A 00 PUSH 0
00451F61 .53PUSH EBX
00451F62 .56PUSH ESI
00451F63 .57PUSH EDI
00451F64 .33C0XOR EAX,EAX
00451F66 .55PUSH EBP
……………………省略N行代码

00451FA7 .55PUSH EBP
00451FA8 .68 C5234500 PUSH dumped_.004523C5
00451FAD .64:FF30 PUSH DWORD PTR FS:[EAX]
00451FB0 .64:8920 MOV DWORD PTR FS:[EAX],ESP
00451FB3 .A1 D85B4500 MOV EAX,DWORD PTR DS:[455BD8]
00451FB8 .3D D7330000 CMP EAX,33D7 ;看到这里开始比较文件大小了,EAX中是我们脱壳后文件的大小

和某个数值比较
00451FBD .0F8F C2000000 JG dumped_.00452085 ;大于就跳
00451FC3 .0F84 1C030000 JE dumped_.004522E5 ;小于就跳
00451FC9 .3D FB040000 CMP EAX,4FB
00451FCE .7F 5E JG SHORT dumped_.0045202E
00451FD0 .0F84 55030000 JE dumped_.0045232B
00451FD6 .3D 9B000000 CMP EAX,9B
00451FDB .7F 2F JG SHORT dumped_.0045200C
00451FDD .0F84 38020000 JE dumped_.0045221B
00451FE3 .83E8 2D SUB EAX,2D
00451FE6 .0F84 A7020000 JE dumped_.00452293
………………………省略N行代码
0045217B .E8 3043FBFF CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
00452180 .50PUSH EAX
00452181 .89D8MOV EAX,EBX
00452183 .29D8SUB EAX,EBX
00452185 .89C3MOV EBX,EAX
00452187 .89D8MOV EAX,EBX
00452189 .01D8ADD EAX,EBX
0045218B .89C3MOV EBX,EAX
0045218D .58POP EAX
0045218E .E9 28020000 JMP dumped_.004523BB;注意看这里
00452193 >E8 78FDFFFF CALL dumped_.00451F10;案例 3ABC82A --> 分支 00451FB8
00452198 .50PUSH EAX
00452199 .89D8MOV EAX,EBX
0045219B .29D8SUB EAX,EBX
0045219D .89C3MOV EBX,EAX
0045219F .89D8MOV EAX,EBX
004521A1 .01D8ADD EAX,EBX
004521A3 .89C3MOV EBX,EAX
004521A5 .58POP EAX
004521A6 .E9 10020000 JMP dumped_.004523BB ;注意看这里,这些都是跳过校验的地址
004521AB >6A 00 PUSH 0 ; /ExitCode = 0; 案例 40B5 --> 分

支 00451FB8
004521AD .E8 FE42FBFF CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
………………………省略N行代码

004523AD .89D8MOV EAX,EBX
004523AF .01D8ADD EAX,EBX
004523B1 .89C3MOV EBX,EAX
004523B3 .58POP EAX
004523B4 .6A 00 PUSH 0 ; /ExitCode = 0
004523B6 .E8 F540FBFF CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
004523BB >33C0XOR EAX,EAX;刚才注意看上面的都知道,那些jmp都是跳到这里来了,这里就是跳

过校验的关键地址
004523BD .5APOP EDX
004523BE .59POP ECX
004523BF .59POP ECX
004523C0 .64:8910 MOV DWORD PTR FS:[EAX],EDX
004523C3 .EB 0A JMP SHORT dumped_.004523CF
004523C5 .^ E9 4217FBFF JMP dumped_.00403B0C
004523CA .E8 A51AFBFF CALL dumped_.00403E74
004523CF >33C0XOR EAX,EAX

-------------------------------
这次校验修改来点狠的

把这行
00451FBD .0F8F C2000000 JG dumped_.00452085 ;大于就跳
直接改成这样
00451FBD .0F8F C2000000 Jmp 004523BB ;直接就跳到我们过校验的地址004523BB,哈哈够狠吧

-------------------------------
改好后保存下文件,试运行,点击后还是无反应,应该有校验,载入刚去掉一个校验的文件,ctrl+G 去到004523BB

刚才跳转的那个位置,下F2断点,F9运行断下来了

004523BB >33C0XOR EAX,EAX;断在这里,我们继续F8单步跟一下
004523BD .5APOP EDX
004523BE .59POP ECX
004523BF .59POP ECX
004523C0 .64:8910 MOV DWORD PTR FS:[EAX],EDX
004523C3 .EB 0A JMP SHORT dumped_.004523CF
004523C5 .^ E9 4217FBFF JMP dumped_.00403B0C
004523CA .E8 A51AFBFF CALL dumped_.00403E74
004523CF >33C0XOR EAX,EAX
-------------------------------
经过几个retn,程序来到这里
00452763|.8D55 EC lea edx, dword ptr [ebp-14];单步跟到这里后往下看这里还有一个校验
00452766|.33C0xor eax, eax
00452768|.E8 7F06FBFF call00402DEC
0045276D|.8B45 EC mov eax, dword ptr [ebp-14]
00452770|.E8 0BFDFFFF call00452480
00452775|.3D E9E40200 cmp eax, 2E4E9;这里EAX中的值也是脱壳后文件的大小,和2E4E9这个数值比较
0045277A|.75 0C jnz short 00452788 ;这里不等就跳,把jnz这行nop掉
0045277C|.A1 E03F4500 mov eax, dword ptr [453FE0]
00452781|.8B00mov eax, dword ptr [eax]
00452783|.E8 ECDEFFFF call00450674
00452788|>33C0xor eax, eax
-------------------------------
好了,到这里两处自校验都改好了,保存文件试运行,哈哈,成功了,没来得急高兴几秒钟,程序又退出了,耐心耐

心,牛奶会有的,面包也会有的,离成功不远了,那就再载入去掉两处校验的的那个文件吧。

停在让某些人吐血的OEP后,再次祭出我们的法宝 ExitProcess断点,F9运行
-------------------------------
7C81CAA2 >8BFFmov edi, edi ;在程序启动后断在这里,看堆栈
7C81CAA455pushebp
7C81CAA58BECmov ebp, esp
7C81CAA76A FF push-1
7C81CAA968 B0F3E877 push77E8F3B0
7C81CAAEFF75 08 pushdword ptr [ebp+8]
7C81CAB1E8 46FFFFFF call7C81C9FC
7C81CAB6E9 29CF0100 jmp 7C8399E4
7C81CABB90nop
-------------------------------
堆栈情况:
0012FDCC 00452427/CALL 到 ExitProcess 来自 dumped_x.00452422;老办法,回车跟随到反汇编窗口
0012FDD0 00000000\ExitCode = 0
0012FDD4 0012FDF4指向下一个 SEH 记录的指针
0012FDD8 0045243DSE处理程序
-------------------------------
回到反汇编窗口
00452419|.3D E9E40200 cmp eax, 2E4E9;服了作者了,这里还藏着个比较
0045241E|.74 07 jeshort 00452427;这个跳转能够跳过下面那call退出函数的,改成jmp
00452420|.6A 00 push0; /ExitCode = 0
00452422|.E8 8940FBFF call<jmp.&kernel32.ExitProcess>; \ExitProcess
00452427|>33C0xor eax, eax ;程序返回到这里了,往上看看,竟然还有个退出函数作怪,
-------------------------------
改好了,保存修改的文件,怀着激动的心情运行这个文件,哈哈,成功了,程序运行一切正常,接下来要做的

知道是什么吗?那当然是感谢CCTV,感谢MTV,感谢LCGTV,感谢所有的TV了……
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 01:25

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表