吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 16826|回复: 13
收起左侧

[原创] 吾爱破解脱壳练习----Armadillo 4.40

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

12.本期看点:分析magic jump详细过程,了解加密的环节执行,了解magic jump的由来,网上诸多分析望大家多多借鉴(绝对不是去套用,因为那样只会被束缚),从而结合自己的思考出最佳解释!



公告:
暂无


紧急通知:
本期练习由于交作业的情况不是非常满意,特决定将本期练习延期一天,让更多的朋友有充裕的时间去进行整理分析,争取拿出更好的答案


练习一:(结果已经公布)
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

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

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

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

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

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

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

UnPackMe.rar

434 KB, 下载次数: 655, 下载积分: 吾爱币 -1 CB

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

 楼主| 小生我怕怕 发表于 2008-10-24 00:25
首先忽略异常选项里的所有异常选项

脱壳部分
━━━━━━━━━━━━━━━━━━━━━━━━━━
00454000 >60pushad//OD载入
00454001E8 00000000 call UnPackMe.00454006//在命令行下断 bp GetModuleHandleA+5
004540065Dpop ebp //shift+f9运行程序
0045400750push eax
0045400851push ecx
━━━━━━━━━━━━━━━━━━━━━━━━━━
以下为程序每运行一次后堆栈窗口的变化
0012FF0C 0012FF98 //运行第一次
0012FF10 00440D0B返回到 UnPackMe.00440D0B 来自 kernel32.GetModuleHandleA
0012FF14 00000000
0012FF18 00000000
━━━━━━━━━━━━━━━━━━━━━━━━━━
0012EE38/0012EE70 //运行第二次
0012EE3C|5D175324返回到 5D175324 来自 kernel32.GetModuleHandleA
0012EE40|5D175370ASCII "kernel32.dll"
0012EE44|5D1E3AB8
━━━━━━━━━━━━━━━━━━━━━━━━━━
0012EEF8/0012EF14//运行第三次
0012EEFC|77F45CD0返回到 SHLWAPI.77F45CD0 来自 kernel32.GetModuleHandleA
0012EF00|77F4501CASCII "KERNEL32.DLL"
0012EF04|00000001
━━━━━━━━━━━━━━━━━━━━━━━━━━
0012F710/0012F778//运行第四次
0012F714|0042B8F3返回到 UnPackMe.0042B8F3 来自 kernel32.GetModuleHandleA
0012F718|00000000
0012F71C|0000FFFF
━━━━━━━━━━━━━━━━━━━━━━━━━━
001294FC/0012EC44 //运行第五次
00129500|00AC7105返回到 00AC7105 来自 kernel32.GetModuleHandleA
00129504|00ADBC1CASCII "kernel32.dll"
00129508|00ADCEC4ASCII "VirtualAlloc"
━━━━━━━━━━━━━━━━━━━━━━━━━━
001294FC/0012EC44//运行第六次
00129500|00AC7122返回到 00AC7122 来自 kernel32.GetModuleHandleA
00129504|00ADBC1CASCII "kernel32.dll"
00129508|00ADCEB8ASCII "VirtualFree"
━━━━━━━━━━━━━━━━━━━━━━━━━━
00129260/00129500 //运行第七次
00129264|00AB5FC9返回到 00AB5FC9 来自 kernel32.GetModuleHandleA
00129268|001293B4ASCII "kernel32.dll" //与此同时我们ait+f9返回
0012926C|00000000
━━━━━━━━━━━━━━━━━━━━━━━━━━
00AB5FC98B0D AC40AE00 mov ecx,dword ptr ds:[AE40AC] //我们返回到了这里
00AB5FCF89040Emov dword ptr ds:[esi+ecx],eax
00AB5FD2A1 AC40AE00 mov eax,dword ptr ds:[AE40AC]
00AB5FD7391C06cmp dword ptr ds:[esi+eax],ebx
00AB5FDA75 16 jnz short 00AB5FF2
00AB5FDC8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C]
00AB5FE250push eax
00AB5FE3FF15 BC62AD00 call dword ptr ds:[AD62BC] ; kernel32.LoadLibraryA
00AB5FE98B0D AC40AE00 mov ecx,dword ptr ds:[AE40AC]
00AB5FEF89040Emov dword ptr ds:[esi+ecx],eax
00AB5FF2A1 AC40AE00 mov eax,dword ptr ds:[AE40AC]
00AB5FF7391C06cmp dword ptr ds:[esi+eax],ebx
00AB5FFA0F84 2F010000 je 00AB612F //这里改jmp就是我们的magic jump
00AB600033C9xor ecx,ecx //改好后我们ait+f9打开内存镜像
00AB60028B07mov eax,dword ptr ds:[edi]
00AB60043918cmp dword ptr ds:[eax],ebx
00AB600674 06 je short 00AB600E
━━━━━━━━━━━━━━━━━━━━━━━━━━
内存映射,项目 23 //我们在这里f2设置访问中断
地址=00401000//设置好断点后我们shift+f9
大小=00001000 (4096.)
物主=UnPackMe 00400000
区段=.text
类型=Imag 01001002
访问=R
初始访问=RWE
━━━━━━━━━━━━━━━━━━━━━━━━━━
00ACF9688B12mov edx,dword ptr ds:[edx]//程序停在了这里
00ACF96A8955 DC mov dword ptr ss:[ebp-24],edx //我们开始F8单步走
00ACF96D834D FC FFor dword ptr ss:[ebp-4],FFFFFFFF
00ACF971EB 11 jmp short 00ACF984//这里向下跳我们让他跳
00ACF9736A 01 push 1
00ACF97558pop eax
00ACF976C3retn
━━━━━━━━━━━━━━━━━━━━━━━━━━
00ACF9AF /75 18 jnz short 00ACF9C9 //这里向下跳我们让他跳
00ACF9B1 |FF77 18 push dword ptr ds:[edi+18]
00ACF9B4 |FF77 14 push dword ptr ds:[edi+14]
00ACF9B7 |FF77 10 push dword ptr ds:[edi+10]
00ACF9BA |8B50 60 mov edx,dword ptr ds:[eax+60]
00ACF9BD |3350 44 xor edx,dword ptr ds:[eax+44]
00ACF9C0 |3350 1C xor edx,dword ptr ds:[eax+1C]
00ACF9C3 |2BCAsub ecx,edx
00ACF9C5 |FFD1call ecx
00ACF9C7 |EB 1D jmp short 00ACF9E6
00ACF9C9 \83FA 01 cmp edx,1//跳到这里后我们继续F8单步走
00ACF9CC75 1B jnz short 00ACF9E9
00ACF9CEFF77 04 push dword ptr ds:[edi+4]
00ACF9D1FF77 08 push dword ptr ds:[edi+8]
00ACF9D46A 00 push 0
00ACF9D6FF77 0C push dword ptr ds:[edi+C]
00ACF9D98B50 60 mov edx,dword ptr ds:[eax+60]
00ACF9DC3350 44 xor edx,dword ptr ds:[eax+44]
00ACF9DF3350 1C xor edx,dword ptr ds:[eax+1C]
00ACF9E22BCAsub ecx,edx
00ACF9E4FFD1call ecx //这里F7跟进去后就是我们的OEP啦
00ACF9E68945 E4 mov dword ptr ss:[ebp-1C],eax
00ACF9E98B45 E4 mov eax,dword ptr ss:[ebp-1C]
00ACF9EC8B4D F0 mov ecx,dword ptr ss:[ebp-10]
━━━━━━━━━━━━━━━━━━━━━━━━━━
0040170055push ebp //我们的OEP现在可以运行importRCE看下
004017018BECmov ebp,esp//修复时有6个无效不管他剪切掉就好啦
004017036A FF push -1//运行lordPE把程序DUMP在运行importRCE修复下
0040170568 00254000 push UnPackMe.00402500
0040170A68 86184000 push UnPackMe.00401886 ; jmp to msvcrt._except_handler3
0040170F64:A1 00000000mov eax,dword ptr fs:[0]
0040171550push eax
━━━━━━━━━━━━━━━━━━━━━━━━━━
以下为IAT加密的分析和我们的magic jump的由来,首先我们OD直接不修改magic jump直接跑到OEP去
━━━━━━━━━━━━━━━━━━━━━━━━━━
以下为imporce输入表的情况
FThunk: 00002000NbFunc: 00000079
000002000?000000ABA785 //很明显这句被加密啦
100002004kernel32.dll01ADGetStartupInfoA
000002008?000000AB73AA//很明显这句也被加密啦
..................................................... //以下由于代码过多采用省略号代替
000002168?000000AB734A //这句被加密啦
10000216Cmsvcrt.dll0050_XcptFilter
100002170msvcrt.dll0291exit
100002174msvcrt.dll00A9_acmdln
100002178msvcrt.dll006F__getmainargs
10000217Cmsvcrt.dll013C_initterm
100002180msvcrt.dll009C__setusermatherr
100002184msvcrt.dll00B7_adjust_fdiv
100002188msvcrt.dll0082__p__commode
10000218Cmsvcrt.dll0087__p__fmode
100002190msvcrt.dll009A__set_app_type
100002194msvcrt.dll00EE_except_handler3
100002198msvcrt.dll00D7_controlfp
10000219Cmsvcrt.dll01B5_onexit
1000021A0msvcrt.dll006C__dllonexit
1000021A4msvcrt.dll0054__CxxFrameHandler
1000021A8msvcrt.dll01DF_setmbcp
1000021ACmsvcrt.dll00F7_exit
0000021B0?000000AB7400 //这句被加密啦
1000021B4shell32.dll0167ShellExecuteA
0000021B8?000000AB7405 //这句被加密啦
1000021BCuser32.dll0100GetClientRect
1000021C0user32.dll015DGetSystemMenu
1000021C4user32.dll01A7IsIconic
1000021C8user32.dll00C5EnableWindow
1000021CCuser32.dll0009AppendMenuA
1000021D0user32.dll015EGetSystemMetrics
1000021D4user32.dll00B7DrawIcon
1000021D8user32.dll01BCLoadIconA
1000021DCuser32.dll023CSendMessageA
0000021E0?000000AB7372//这句被加密啦

FThunk: 000021E8NbFunc: 00000001
0000021E8?000000401000 //这句被加密啦
━━━━━━━━━━━━━━━━━━━━━━━━━━
通过上面的分析我们可以在第一个无效处双击,我们注意如下图:
1.jpg

我们看到这里只是00002000但是要记住这里是没有加上我们的基址计算的
所以我们ait+m打开内存镜像后查看下我们的程序的基址是多少
内存映射,项目 22
地址=00400000//这里就是我们的基址
大小=00001000 (4096.)
物主=UnPackMe 00400000 (自身)
区段=
类型=Imag 01001002
访问=R
初始访问=RWE
00400000+00002000=00402000
此时我们从新载入程序后在命令提示栏输入D 00402000去跟踪
━━━━━━━━━━━━━━━━━━━━━━━━━━
00454000 >60pushad //从新载入程序后
00454001E8 00000000 call UnPackMe.00454006 //在命令提示行输入 bp GetModuleHandleA+5下断
004540065Dpop ebp//下好断点后我们在命令行输入 D 00402000
0045400750push eax //跟踪后同时注意一下我们的数据窗口
━━━━━━━━━━━━━━━━━━━━━━━━━━
0040200000000000 //此时数据窗口显示
0040200400000000 //我们右键在上面一句--断点--硬件断点
0040200800000000 //检查好两个断点后我们shift+f9运行程序
0040200C00000000
0040201000000000
━━━━━━━━━━━━━━━━━━━━━━━━━━
同样注意下我们的寄存器变化和数据窗口和堆栈窗口变化
注意我们的IAT有没有发生突变,在突变前返回到程序去,
然后开始单步跟,由于步骤比较多,这里我就只复制关键时刻的代码
━━━━━━━━━━━━━━━━━━━━━━━━━━
EAX 001293B4 ASCII "kernel32.dll" //第七次时寄存器出现两个DLL
ECX 001293C0//而第六次时我们显示的是我们的IAT的指针
EDX 001293B4 ASCII "kernel32.dll"
EBX 00000000
ESP 00129260
EBP 00129260
ESI 00000000
EDI 00ADB0F4
EIP 7C80B6A6 kernel32.7C80B6A6
━━━━━━━━━━━━━━━━━━━━━━━━━━
0040200000ABA785//当程序运行到第十一次时我们的IAT出现加密
004020040000291C//在数据窗口可以看到这三行都是被加密的
0040200800000000//从而我们就可以分析出在IAT消失时我们返回
0040200C73D98D67MFC42.#4486_CWinApp::OnDDECommand
0040201073D35EF1MFC42.#2554_CWinApp::DoWaitCursor
0040201473D497A0MFC42.#2512_CWinApp::DoMessageBox
0040201873D4224EMFC42.#5731_CWinApp::SaveAllModified
0040201C73DC9FEDMFC42.#3922_CWinApp::InitApplication
━━━━━━━━━━━━━━━━━━━━━━━━━━
00AB5FC98B0D AC40AE00 mov ecx,dword ptr ds:[AE40AC]//现在我们是在我们IAT指针消失后返回的
00AB5FCF89040Emov dword ptr ds:[esi+ecx],eax //也可以根据寄存器出现kernel32.dll时返回
00AB5FD2A1 AC40AE00 mov eax,dword ptr ds:[AE40AC]//我们单步来进行一下简单的分析
00AB5FD7391C06cmp dword ptr ds:[esi+eax],ebx
━━━━━━━━━━━━━━━━━━━━━━━━━━
00AB5FC98B0D AC40AE00 mov ecx,dword ptr ds:[AE40AC]//把我们的AE40AC传送给ECX
00AB5FCF89040Emov dword ptr ds:[esi+ecx],eax //把EAX的执行传送给esi+ecx
00AB5FD2A1 AC40AE00 mov eax,dword ptr ds:[AE40AC]
00AB5FD7391C06cmp dword ptr ds:[esi+eax],ebx //比较esi+asx是否和ebx相等,等于则跳
00AB5FDA75 16 jnz short 00AB5FF2 //这里是相等的所以执行了跳
00AB5FDC8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C]
00AB5FE250push eax
00AB5FE3FF15 BC62AD00 call dword ptr ds:[AD62BC] ; kernel32.LoadLibraryA
00AB5FE98B0D AC40AE00 mov ecx,dword ptr ds:[AE40AC]
00AB5FEF89040Emov dword ptr ds:[esi+ecx],eax
00AB5FF2A1 AC40AE00 mov eax,dword ptr ds:[AE40AC]//我们跳到这里后在次执行传送
00AB5FF7391C06cmp dword ptr ds:[esi+eax],ebx //紧接着马上一个比较esi+eax是否和ebx相等则跳,不等则取反
00AB5FFA0F84 2F010000 je 00AB612F//所以这里没有跳
00AB600033C9xor ecx,ecx//这里异或
00AB60028B07mov eax,dword ptr ds:[edi] //在一次把edi的指令传送给eax
━━━━━━━━━━━━━━━━━━━━━━━━━━
00AB6006 /74 06 je short 00AB600E
00AB6008 |41inc ecx//这里为ECX执行加1指令
00AB6009 |83C0 0C add eax,0C //把eax与0c相加
00AB600C^|EB F6 jmp short 00AB6004 //循环执行计算
00AB600E \8BD9mov ebx,ecx//把ecx指令传送去ebx
00AB6010C1E3 02 shl ebx,2
00AB601353push ebx //把我们的ebx的地址压栈
00AB6014E8 45F20100 call 00AD525E; jmp to msvcrt.operator new
00AB60198B0D A440AE00 mov ecx,dword ptr ds:[AE40A4]
00AB601F89040Emov dword ptr ds:[esi+ecx],eax
00AB602253push ebx
━━━━━━━━━━━━━━━━━━━━━━━━━━
00AB606250push eax //到这里时ascii码显示为:ExitProcess
00AB6063A1 AC40AE00 mov eax,dword ptr ds:[AE40AC]//传送ae40ac给eax
00AB6068FF3406push dword ptr ds:[esi+eax]//把esi+eax进行压栈
00AB606BFF15 B862AD00 call dword ptr ds:[AD62B8] ; kernel32.GetProcAddress
00AB60718BD8mov ebx,eax//当取上面的call时堆栈窗口显示为 ExitProcess
00AB6073B9 98FAAD00 mov ecx,0ADFA98
00AB6078E8 AD3A0000 call 00AB9B2A
00AB607D33D8xor ebx,eax//在次进行异或
━━━━━━━━━━━━━━━━━━━━━━━━━━
00AB610B85C0test eax,eax
00AB610D^ 0F85 34FFFFFF jnz 00AB6047 //这里开始返回继续处理我们的IAT加密
00AB61138BBD 78FDFFFF mov edi,dword ptr ss:[ebp-288]
00AB6119A1 AC40AE00 mov eax,dword ptr ds:[AE40AC]//相反如果我们有跳可以跳过这一段也就是所谓的magic jump
00AB611E8D1C06lea ebx,dword ptr ds:[esi+eax] //以上分析中不难发现多次转换我们的eac里的指令
00AB6121B9 98FAAD00 mov ecx,0ADFA98//从而可以象上寻找一个能跳过的计算加密指令的地址修改即可修改为我们的magic jump
00AB6126E8 EC390000 call 00AB9B17
━━━━━━━━━━━━━━━━━━━━━━━━━━
00AB604768 00010000 push 100 //在一次从下面的JNZ返回后我们来到这里
00AB604C8D8D A8FDFFFF lea ecx,dword ptr ss:[ebp-258] //很明显是进行循环加密处理
00AB605251push ecx
00AB605350push eax
━━━━━━━━━━━━━━━━━━━━━━━━━━
00AB603F /0F84 D4000000 je 00AB6119//此跳跳过了我们所有的加密指令即我们的magic jump
00AB6045 |33FFxor edi,edi//只要把上面的je改jmp即可以避免开我们的IAT加密
00AB6047 |68 00010000 push 100
00AB604C |8D8D A8FDFFFF lea ecx,dword ptr ss:[ebp-258]
00AB6052 |51push ecx

在一种修改法
━━━━━━━━━━━━━━━━━━━━━━━━━━
cmp dword ptr ds:[esi+eax],ebx改为cmp esi,ebx
此时我们的
esi===00000000
eax===00C93FF0
ebx===00000000
如果上面不相等那么我们下面的je则不跳,我们也可以修改为
cmp esi,ebx从而让下面的JE执行跳转
00AB5FFA /0F84 2F010000 je 00AB612F
00AB6000 |33C9xor ecx,ecx
00AB6002 |8B07mov eax,dword ptr ds:[edi]
00AB6004 |3918cmp dword ptr ds:[eax],ebx
00AB6006 |74 06 je short 00AB600E
00AB6008 |41inc ecx
00AB6009 |83C0 0C add eax,0C

unpackme_dump_.rar

261 KB, 下载次数: 14, 下载积分: 吾爱币 -1 CB

nv21 发表于 2008-10-24 00:53

OD载入下断点he GetModuleHandleA+5
获取模块句柄至于为什么要下这个断点只要明白函数的属性不难理解
这个函数的作用是获取模块句柄
注意堆栈变化
001294FC/0012EC44
00129500|00AE7105返回到 00AE7105 来自 kernel32.GetModuleHandleA
00129504|00AFBC1CASCII "kernel32.dll"
00129508|00AFCEC4ASCII "VirtualAlloc"---------------分配内存空间
0012950C|00AFFA98
00129510|7C9210E0ntdll.RtlLeaveCriticalSection
001294FC/0012EC44
00129500|00AE7122返回到 00AE7122 来自 kernel32.GetModuleHandleA
00129504|00AFBC1CASCII "kernel32.dll"
00129508|00AFCEB8ASCII "VirtualFree"--------------释放分配内存
0012950C|00AFFA98
00129510|7C9210E0ntdll.RtlLeaveCriticalSection

00129260/00129500
00129264|00AD5FC9返回到 00AD5FC9 来自 kernel32.GetModuleHandleA
00129268|001293B4ASCII "kernel32.dll"----装入上面两个函数以后开始处理程序IAT 返回
0012926C|00000000
00129270|EC440000
返回到这里
00AD5FC3FF15 B860AF00 call dword ptr ds:[AF60B8] ; kernel32.GetModuleHandleA
00AD5FC98B0D AC40B000 mov ecx,dword ptr ds:[B040AC]
00AD5FCF89040Emov dword ptr ds:[esi+ecx],eax
00AD5FD2A1 AC40B000 mov eax,dword ptr ds:[B040AC]
00AD5FD7391C06cmp dword ptr ds:[esi+eax],ebx
00AD5FDA75 16 jnz short 00AD5FF2
00AD5FDC8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C]
00AD5FE250push eax
00AD5FE3FF15 BC62AF00 call dword ptr ds:[AF62BC] ; kernel32.LoadLibraryA////装入DLL
00AD5FE98B0D AC40B000 mov ecx,dword ptr ds:[B040AC]////////
00AD5FEF89040Emov dword ptr ds:[esi+ecx],eax
00AD5FF2A1 AC40B000 mov eax,dword ptr ds:[B040AC]
00AD5FF7391C06cmp dword ptr ds:[esi+eax],ebx
00AD5FFA0F84 2F010000 je 00AD612F///////////////////////////////////这里EBX等于0当EAX=ds:B040AC=00CB3FF0
也就是说当00CB3FF0等于0时跳过加密把这里改为JMP
00AD600033C9xor ecx,ecx
00AD60028B07mov eax,dword ptr ds:[edi]
00AD60043918cmp dword ptr ds:[eax],ebx
00AD600674 06 je short 00AD600E
00AD600841inc ecx
00AD600983C0 0C add eax,0C
00AD600C^ EB F6 jmp short 00AD6004
00AD600E8BD9mov ebx,ecx
00AD6010C1E3 02 shl ebx,2
00AD601353push ebx
00AD6014E8 45F20100 call 00AF525E; jmp 到 msvcrt.operator new
00AD60198B0D A440B000 mov ecx,dword ptr ds:[B040A4]
00AD601F89040Emov dword ptr ds:[esi+ecx],eax
00AD602253push ebx
00AD6023E8 36F20100 call 00AF525E; jmp 到 msvcrt.operator new
00AD602859pop ecx
00AD602959pop ecx
00AD602A8B0D A840B000 mov ecx,dword ptr ds:[B040A8]
00AD603089040Emov dword ptr ds:[esi+ecx],eax

下断点bp GetCurrentThreadId 获取当前线程ID的标识
SHIFT+F9运行

堆栈变化
00129260/00129500
00129264|00AD5FC9返回到 00AD5FC9 来自 kernel32.GetModuleHandleA
00129268|001293B4ASCII "user32.dll"
0012926C|00000000


00129260/00129500
00129264|00AD5FC9返回到 00AD5FC9 来自 kernel32.GetModuleHandleA
00129268|001293B4ASCII "MSVBVM60.DLL"
0012926C|00000000


00128B24 73391E46/CALL 到 GetCurrentThreadId 来自 73391E40
00128B28 00000001
00128B2C 73391C2A返回到 73391C2A 来自 73391DF2
00128B30 73391B70返回到 73391B70 来自 73391B9C

00128B18/00128B6C
00128B1C|7339282A返回到 7339282A 来自 kernel32.GetModuleHandleA
00128B20|7339F80CASCII "KERNEL32"
00128B24|733927DA返回到 733927DA 来自 7339281F
00128B28|733927AB返回到 733927AB

00128B0C/00128B2C
00128B10|733931DC返回到 733931DC 来自 kernel32.GetModuleHandleA
00128B14|00000000
00128B18|73390000
00128B1C|73393144返回到 73393144 来自 733931C9
00128B20|73390000


00128B04 7339352D/CALL 到 GetCurrentThreadId 来自 73393527
00128B08 00000000
00128B0C 7349E470
00128B10 7349E4D8
00128B14/00128B2C
00128B18|73393507返回到 73393507 来自 73393513


00129260/00129500
00129264|00AD5FC9返回到 00AD5FC9 来自 kernel32.GetModuleHandleA------------------------------
00129268|001293B4ASCII "advapi32.dll"
0012926C|00000000
00129270|EC440000
这里返回程序领空 ALT+F9返回

00AD63D450push eax
00AD63D5FF75 FC push dword ptr ss:[ebp-4]
00AD63D8E8 05000000 call 00AD63E2
00AD63DD83C4 0C add esp,0C
00AD63E0C9leave



单步F8跟踪 00AEF9C983FA 01 cmp edx,1
00AEF9CC75 1B jnz short 00AEF9E9
00AEF9CEFF77 04 push dword ptr ds:[edi+4]
00AEF9D1FF77 08 push dword ptr ds:[edi+8]
00AEF9D46A 00 push 0
00AEF9D6FF77 0C push dword ptr ds:[edi+C]; UnPackMe.00400000
00AEF9D98B50 60 mov edx,dword ptr ds:[eax+60]
00AEF9DC3350 44 xor edx,dword ptr ds:[eax+44]
00AEF9DF3350 1C xor edx,dword ptr ds:[eax+1C]
00AEF9E22BCAsub ecx,edx
00AEF9E4FFD1call ecx /////////////F7进入到OEP
00AEF9E68945 E4 mov dword ptr ss:[ebp-1C],eax
00AEF9E98B45 E4 mov eax,dword ptr ss:[ebp-1C]
00AEF9EC8B4D F0 mov ecx,dword ptr ss:[ebp-10]
00AEF9EF64:890D 0000000>mov dword ptr fs:[0],ecx
00AEF9F65Fpop edi

到OEP
0040170055push ebp
004017018BECmov ebp,esp
004017036A FF push -1
0040170568 00254000 push UnPackMe.00402500
0040170A68 86184000 push UnPackMe.00401886 ; jmp 到 msvcrt._except_handler3
0040170F64:A1 00000000mov eax,dword ptr fs:[0]
0040171550push eax
0040171664:8925 0000000>mov dword ptr fs:[0],esp
0040171D83EC 68 sub esp,68
0040172053push ebx
0040172156push esi
0040172257push edi
004017238965 E8 mov dword ptr ss:[ebp-18],esp
0040172633DBxor ebx,ebx
00401728895D FC mov dword ptr ss:[ebp-4],ebx
0040172B6A 02 push 2
0040172DFF15 90214000 call dword ptr ds:[402190] ; msvcrt.__set_app_type
0040173359pop ecx

然后LORDPE脱壳 REC修复 等级修复无效指针
CUT掉修复后的无效指针 正常运行~!
分析一下IAT的加密过程的MAJGC JMP的形成
00AD5FB6 /0F85 73010000 jnz 00AD612F
00AD5FBC |8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C]
00AD5FC2 |50push eax
00AD5FC3 |FF15 B860AF00 call dword ptr ds:[AF60B8] ;(kernel32.GetModuleHandleA)获取调用DLL模块句柄
00AD5FC9 |8B0D AC40B000 mov ecx,dword ptr ds:[B040AC]
00AD5FCF |89040Emov dword ptr ds:[esi+ecx],eax
00AD5FD2 |A1 AC40B000 mov eax,dword ptr ds:[B040AC]
00AD5FD7 |391C06cmp dword ptr ds:[esi+eax],ebx ; 判断是DLL是否为空
00AD5FDA |75 16 jnz short 00AD5FF2 ; DLL为空则开始把函数装入壳
00AD5FDC |8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C]
00AD5FE2 |50push eax
00AD5FE3 |FF15 BC62AF00 call dword ptr ds:[AF62BC] ; kernel32.LoadLibraryA
00AD5FE9 |8B0D AC40B000 mov ecx,dword ptr ds:[B040AC]
00AD5FEF |89040Emov dword ptr ds:[esi+ecx],eax
00AD5FF2 |A1 AC40B000 mov eax,dword ptr ds:[B040AC]
00AD5FF7 |391C06cmp dword ptr ds:[esi+eax],ebx ; 判断DLL是否为空 为空跳过加密过程
00AD5FFA |0F84 2F010000 je 00AD612F
00AD6000 |33C9xor ecx,ecx
00AD6002 |8B07mov eax,dword ptr ds:[edi]
00AD6004 |3918cmp dword ptr ds:[eax],ebx
00AD6006 |74 06 je short 00AD600E; 循环取当前DLL中函数的个数
00AD6008 |41inc ecx
00AD6009 |83C0 0C add eax,0C
00AD600C^|EB F6 jmp short 00AD6004
00AD600E |8BD9mov ebx,ecx
00AD6010 |C1E3 02 shl ebx,2
00AD6013 |53push ebx
00AD6014 |E8 45F20100 call 00AF525E; jmp 到 msvcrt.operator new
00AD6019 |8B0D A440B000 mov ecx,dword ptr ds:[B040A4]
00AD601F |89040Emov dword ptr ds:[esi+ecx],eax
00AD6022 |53push ebx
00AD6023 |E8 36F20100 call 00AF525E; jmp 到 msvcrt.operator new
00AD6028 |59pop ecx
00AD6029 |59pop ecx
00AD602A |8B0D A840B000 mov ecx,dword ptr ds:[B040A8]
00AD6030 |89040Emov dword ptr ds:[esi+ecx],eax
00AD6033 |8B07mov eax,dword ptr ds:[edi]
00AD6035 |8985 ACFEFFFF mov dword ptr ss:[ebp-154],eax
00AD603B |8B00mov eax,dword ptr ds:[eax]
00AD603D |85C0test eax,eax
00AD603F |0F84 D4000000 je 00AD6119
00AD6045 |33FFxor edi,edi
00AD6047 |68 00010000 push 100
00AD604C |8D8D A8FDFFFF lea ecx,dword ptr ss:[ebp-258] ;
00AD6052 |51push ecx
00AD6053 |50push eax
00AD6054 |E8 3FC6FEFF call 00AC2698; 取函数名
00AD6059 |83C4 0C add esp,0C ; 修正指针
00AD605C |8D85 A8FDFFFF lea eax,dword ptr ss:[ebp-258]
00AD6062 |50push eax
00AD6063 |A1 AC40B000 mov eax,dword ptr ds:[B040AC]
00AD6068 |FF3406push dword ptr ds:[esi+eax]
00AD606B |FF15 B862AF00 call dword ptr ds:[AF62B8] ; kernel32.GetProcAddress////取函数地址
00AD6071 |8BD8mov ebx,eax下面开始加密
00AD6073 |B9 98FAAF00 mov ecx,0AFFA98
00AD6078 |E8 AD3A0000 call 00AD9B2A; 地址加密
00AD607D |33D8xor ebx,eax
00AD607F |A1 A440B000 mov eax,dword ptr ds:[B040A4]
00AD6084 |8B0406mov eax,dword ptr ds:[esi+eax]
00AD6087 |891C38mov dword ptr ds:[eax+edi],ebx
00AD608A |6A 01 push 1
00AD608C |8D85 A8FDFFFF lea eax,dword ptr ss:[ebp-258]
00AD6092 |50push eax
00AD6093 |A1 AC40B000 mov eax,dword ptr ds:[B040AC]
00AD6098 |FF3406push dword ptr ds:[esi+eax]
00AD609B |E8 74050000 call 00AD6614
00AD60A0 |83C4 0C add esp,0C
00AD60A3 |8B0D A840B000 mov ecx,dword ptr ds:[B040A8]
00AD60A9 |8B0C0Emov ecx,dword ptr ds:[esi+ecx]
00AD60AC |890439mov dword ptr ds:[ecx+edi],eax
00AD60AF |A1 A840B000 mov eax,dword ptr ds:[B040A8]
00AD60B4 |8B0406mov eax,dword ptr ds:[esi+eax]
00AD60B7 |833C38 00 cmp dword ptr ds:[eax+edi],0
00AD60BB |75 25 jnz short 00AD60E2
00AD60BD |6A 00 push 0
00AD60BF |8D85 A8FDFFFF lea eax,dword ptr ss:[ebp-258]
00AD60C5 |50push eax
00AD60C6 |A1 AC40B000 mov eax,dword ptr ds:[B040AC]
00AD60CB |FF3406push dword ptr ds:[esi+eax]
00AD60CE |E8 41050000 call 00AD6614
00AD60D3 |83C4 0C add esp,0C
00AD60D6 |8B0D A840B000 mov ecx,dword ptr ds:[B040A8]
00AD60DC |8B0C0Emov ecx,dword ptr ds:[esi+ecx]
00AD60DF |890439mov dword ptr ds:[ecx+edi],eax
00AD60E2 |A1 A840B000 mov eax,dword ptr ds:[B040A8]
00AD60E7 |8B0406mov eax,dword ptr ds:[esi+eax]
00AD60EA |8D1C38lea ebx,dword ptr ds:[eax+edi]
00AD60ED |B9 98FAAF00 mov ecx,0AFFA98
00AD60F2 |E8 333A0000 call 00AD9B2A
00AD60F7 |3103xor dword ptr ds:[ebx],eax
00AD60F9 |8385 ACFEFFFF 0>add dword ptr ss:[ebp-154],0C
00AD6100 |83C7 04 add edi,4
00AD6103 |8B85 ACFEFFFF mov eax,dword ptr ss:[ebp-154]
00AD6109 |8B00mov eax,dword ptr ds:[eax]
00AD610B |85C0test eax,eax
00AD610D^|0F85 34FFFFFF jnz 00AD6047///////////循环对一个DLL中的函数进行加密
00AD6113 |8BBD 78FDFFFF mov edi,dword ptr ss:[ebp-288]
00AD6119 |A1 AC40B000 mov eax,dword ptr ds:[B040AC]
00AD611E |8D1C06lea ebx,dword ptr ds:[esi+eax]
00AD6121 |B9 98FAAF00 mov ecx,0AFFA98
00AD6126 |E8 EC390000 call 00AD9B17
00AD612B |3103xor dword ptr ds:[ebx],eax
00AD612D |33DBxor ebx,ebx
00AD612F \83C7 0C add edi,0C
00AD613289BD 78FDFFFF mov dword ptr ss:[ebp-288],edi
00AD613883C6 04 add esi,4
00AD613B395F FC cmp dword ptr ds:[edi-4],ebx ////////判断加密是否结束
00AD613E^ 0F85 49FEFFFF jnz 00AD5F8D ////////////////////跳向下一个DLL 这里是一个循环 对调用的DLL进行加密
00AD6144EB 03 jmp short 00AD6149
00AD6146D6salc
00AD6147D6salc
00AD61488F???; 未知命令
00AD61498B0D 6C8FB000 mov ecx,dword ptr ds:[B08F6C]
00AD614F3BCBcmp ecx,ebx
00AD615174 13 je short 00AD6166
00AD61538B01mov eax,dword ptr ds:[ecx]
00AD61553BC3cmp eax,ebx
00AD615774 0D je short 00AD6166
00AD61598B15 10A3B000 mov edx,dword ptr ds:[B0A310]
00AD615F2910sub dword ptr ds:[eax],edx
00AD616183C1 04 add ecx,4
00AD6164^ EB ED jmp short 00AD6153
00AD61666A 01 push 1
00AD6168FF35 28C3AF00 push dword ptr ds:[AFC328]
00AD616EA1 28C1AF00 mov eax,dword ptr ds:[AFC128]
00AD61738B0D F800B000 mov ecx,dword ptr ds:[B000F8]
00AD617903C8add ecx,eax
00AD617B51push ecx
00AD617CFF75 DC push dword ptr ss:[ebp-24]
00AD617FE8 28B3FEFF call 00AC14AC
00AD618483C4 10 add esp,10
00AD61878B0D 6C8FB000 mov ecx,dword ptr ds:[B08F6C]
00AD618D3BCBcmp ecx,ebx
00AD618F74 13 je short 00AD61A4
00AD61918B01mov eax,dword ptr ds:[ecx]
00AD61933BC3cmp eax,ebx
00AD619574 0D je short 00AD61A4
00AD61978B15 10A3B000 mov edx,dword ptr ds:[B0A310]
00AD619D0110add dword ptr ds:[eax],edx
00AD619F83C1 04 add ecx,4
00AD61A2^ EB ED jmp short 00AD6191
00AD61A468 A092B000 push 0B092A0
00AD61A98B35 6462AF00 mov esi,dword ptr ds:[AF6264]; ntdll.RtlLeaveCriticalSection
00AD61AFFFD6call esi
00AD61B168 8892B000 push 0B09288
00AD61B6FFD6call esi
00AD61B8E9 B1000000 jmp 00AD626E
00AD61BD803D 9C40B000 0>cmp byte ptr ds:[B0409C],0
00AD61C40F85 A4000000 jnz 00AD626E
00AD61CA83A5 9CFDFFFF 0>and dword ptr ss:[ebp-264],0
00AD61D18B85 9CFDFFFF mov eax,dword ptr ss:[ebp-264]
00AD61D73B05 B040B000 cmp eax,dword ptr ds:[B040B0]
00AD61DD73 36 jnb short 00AD6215
00AD61DF8365 FC 00and dword ptr ss:[ebp-4],0
00AD61E36A 00 push 0
00AD61E5A1 B840B000 mov eax,dword ptr ds:[B040B8]
00AD61EA8B8D 9CFDFFFF mov ecx,dword ptr ss:[ebp-264]
00AD61F0FF3488push dword ptr ds:[eax+ecx*4]
00AD61F3E8 58090000 call 00AD6B50
00AD61F859pop ecx
00AD61F959pop ecx
00AD61FAEB 0D jmp short 00AD6209
00AD61FC6A 01 push 1
00AD61FE58pop eax
00AD61FFC3retn
yunfeng 发表于 2008-10-24 07:11
分析IAT 加密过程
00ACBEC36A 01 push 1;IAT处理开始
00ACBEC558pop eax
00ACBEC685C0test eax,eax
00ACBEC80F84 C5080000 je 00ACC793
00ACBECE8B85 84D9FFFF mov eax,dword ptr ss:[ebp-267C] ;dll名送EAX
00ACBED48985 84D3FFFF mov dword ptr ss:[ebp-2C7C],eax
00ACBEDA6A 00 push 0
00ACBEDCFFB5 84D9FFFF push dword ptr ss:[ebp-267C]
00ACBEE2FF15 1463AD00 call dword ptr ds:[AD6314]; msvcrt.strchr
00ACBEE859pop ecx
00ACBEE959pop ecx
00ACBEEA40inc eax
00ACBEEB8985 84D9FFFF mov dword ptr ss:[ebp-267C],eax
00ACBEF18B85 84D3FFFF mov eax,dword ptr ss:[ebp-2C7C]
00ACBEF70FBE00movsx eax,byte ptr ds:[eax]
00ACBEFA85C0test eax,eax
00ACBEFC75 05 jnz short 00ACBF03
00ACBEFEE9 90080000 jmp 00ACC793
.....................................................................................省略代码
00ACBF486A 40 push 40
00ACBF4A59pop ecx
00ACBF4B33C0xor eax,eax
00ACBF4D8DBD 89D3FFFF lea edi,dword ptr ss:[ebp-2C77]
00ACBF53F3:AB rep stos dword ptr es:[edi]
00ACBF5566:AB stos word ptr es:[edi]
00ACBF57AAstos byte ptr es:[edi]
00ACBF58FFB5 84D3FFFF push dword ptr ss:[ebp-2C7C]
00ACBF5EE8 05B5FEFF call 00AB7468; 获取 DLL 基址
00ACBF638985 A0D4FFFF mov dword ptr ss:[ebp-2B60],eax; 基址送 [ebp-2B60] 保存
00ACBF6983BD A0D4FFFF 0>cmp dword ptr ss:[ebp-2B60],0
00ACBF700F85 9F000000 jnz 00ACC015
.....................................................................................省略代码
00ACC066FF15 1063AD00 call dword ptr ds:[AD6310] ; msvcrt.sprintf
00ACC06C83C4 10 add esp,10
00ACC06F33C0xor eax,eax
00ACC071E9 4A1A0000 jmp 00ACDAC0
00ACC076FFB5 A0D4FFFF push dword ptr ss:[ebp-2B60] ;Dll 基址进栈
00ACC07CE8 DB9CFEFF call 00AB5D5C
00ACC08159pop ecx
00ACC08283A5 9CD4FFFF 0>and dword ptr ss:[ebp-2B64],0
00ACC089A1 FC00AE00 mov eax,dword ptr ds:[AE00FC]
00ACC08E8985 F0A9FFFF mov dword ptr ss:[ebp+FFFFA9F0],eax;镜像基址送 [ebp+FFFFA9F0]
00ACC0948B85 A0D4FFFF mov eax,dword ptr ss:[ebp-2B60]; Dll 基址送 EAX
00ACC09A3B85 F0A9FFFF cmp eax,dword ptr ss:[ebp+FFFFA9F0]
00ACC0A075 0F jnz short 00ACC0B1
.....................................................................................省略代码
00ACC3CBFFB5 60C2FFFF push dword ptr ss:[ebp-3DA0]
00ACC3D1E8 D650FDFF call 00AA14AC ; 获取一个函数名
00ACC3D683C4 10 add esp,10
00ACC3D90FB685 70CAFFFF movzx eax,byte ptr ss:[ebp-3590]; 函数名首字母 ASCII 送到 EAX
00ACC3E03D FF000000 cmp eax,0FF
00ACC3E575 10 jnz short 00ACC3F7
00ACC3E766:8B85 71CAFFF>mov ax,word ptr ss:[ebp-358F]
00ACC3EE66:8985 6CCAFFF>mov word ptr ss:[ebp-3594],ax
00ACC3F5EB 20 jmp short 00ACC417
00ACC3F70FBE85 70CAFFFF movsx eax,byte ptr ss:[ebp-3590]; 函数名首字母 ASCII 送到 EAX
00ACC3FE85C0test eax,eax
00ACC40074 15 je short 00ACC417
00ACC4028D85 70CAFFFF lea eax,dword ptr ss:[ebp-3590] ;函数名送到 EAX 中保存
00ACC40850push eax
00ACC4098D85 68C2FFFF lea eax,dword ptr ss:[ebp-3D98] ; 函数地址送到 EAX 中保存
00ACC40F50push eax
00ACC410E8 D58E0000 call 00AD52EA ; jmp 到 msvcrt.strcpy
00ACC41559pop ecx
00ACC41659pop ecx
00ACC41783A5 68CAFFFF 0>and dword ptr ss:[ebp-3598],0
00ACC41E0FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594] ; EAX 清 0
00ACC42585C0test eax,eax
00ACC42774 6C je short 00ACC495
00ACC42983BD 9CD4FFFF 0>cmp dword ptr ss:[ebp-2B64],0
00ACC43074 51 je short 00ACC483
.....................................................................................省略代码
00ACC4950FBE85 68C2FFFF movsx eax,byte ptr ss:[ebp-3D98] ; 函数名首字母送 ASCII 码 EAX
00ACC49C85C0test eax,eax
00ACC49E0F84 8A000000 je 00ACC52E 空就跳走
00ACC4A483BD 9CD4FFFF 0>cmp dword ptr ss:[ebp-2B64],0
00ACC4AB74 72 je short 00ACC51F
00ACC4AD8B85 9CD4FFFF mov eax,dword ptr ss:[ebp-2B64]
00ACC4B38985 58C2FFFF mov dword ptr ss:[ebp-3DA8],eax
00ACC4B9EB 0F jmp short 00ACC4CA
00ACC4BB8B85 58C2FFFF mov eax,dword ptr ss:[ebp-3DA8] ;开始循环计算函数地址
00ACC4C183C0 0C add eax,0C
00ACC4C48985 58C2FFFF mov dword ptr ss:[ebp-3DA8],eax
00ACC4CA8B85 58C2FFFF mov eax,dword ptr ss:[ebp-3DA8]
00ACC4D08378 08 00cmp dword ptr ds:[eax+8],0
00ACC4D474 49 je short 00ACC51F
00ACC4D668 00010000 push 100
00ACC4DB8D85 58C1FFFF lea eax,dword ptr ss:[ebp-3EA8]
00ACC4E150push eax
00ACC4E28B85 58C2FFFF mov eax,dword ptr ss:[ebp-3DA8]
00ACC4E8FF30push dword ptr ds:[eax]
00ACC4EAE8 A961FDFF call 00AA2698
00ACC4EF83C4 0C add esp,0C
00ACC4F28D85 58C1FFFF lea eax,dword ptr ss:[ebp-3EA8]
00ACC4F850push eax
00ACC4F98D85 68C2FFFF lea eax,dword ptr ss:[ebp-3D98]
00ACC4FF50push eax
00ACC500FF15 8C63AD00 call dword ptr ds:[AD638C] ; msvcrt._stricmp
00ACC50659pop ecx
00ACC50759pop ecx
00ACC50885C0test eax,eax ;Magic Jmp
00ACC50A75 11 jnz short 00ACC51D ; 如果上面 EAX 值为 0 那么就加密 IAT
00ACC50C8B85 58C2FFFF mov eax,dword ptr ss:[ebp-3DA8]
00ACC5128B40 08 mov eax,dword ptr ds:[eax+8]
00ACC5158985 68CAFFFF mov dword ptr ss:[ebp-3598],eax
00ACC51BEB 02 jmp short 00ACC51F ;找到了就结束循环继续处理
00ACC51D^ EB 9C jmp short 00ACC4BB ;返回 00ACC4BB 继续循环
00ACC51F8B85 A8D4FFFF mov eax,dword ptr ss:[ebp-2B58];EAX 清 0
00ACC52540inc eax
00ACC5268985 A8D4FFFF mov dword ptr ss:[ebp-2B58],eax
00ACC52CEB 37 jmp short 00ACC565
00ACC52E8D8D 38D9FFFF lea ecx,dword ptr ss:[ebp-26C8]
00ACC534E8 074BFDFF call 00AA1040
00ACC5390FB6C0movzx eax,al
00ACC53C99cdq
00ACC53D6A 14 push 14
00ACC53F59pop ecx
00ACC540F7F9idiv ecx
00ACC5428B85 10D9FFFF mov eax,dword ptr ss:[ebp-26F0]
00ACC5488B8C95 94D7FFFF mov ecx,dword ptr ss:[ebp+edx*4-286C]
00ACC54F8908mov dword ptr ds:[eax],ecx
00ACC5518B85 10D9FFFF mov eax,dword ptr ss:[ebp-26F0]
00ACC55783C0 04 add eax,4
00ACC55A8985 10D9FFFF mov dword ptr ss:[ebp-26F0],eax
00ACC560E9 6C010000 jmp 00ACC6D1
00ACC56583BD 68CAFFFF 0>cmp dword ptr ss:[ebp-3598],0; [ebp-3598] 为 0 吗
00ACC56C75 42 jnz short 00ACC5B0 ; 跳就加密 IAT(如果上面没修改这里nop掉可避开加密)
00ACC56E0FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594] ;EAX 清 0
00ACC57585C0test eax,eax
00ACC57774 0F je short 00ACC588
00ACC5790FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594]
00ACC5808985 D8A8FFFF mov dword ptr ss:[ebp+FFFFA8D8],eax
00ACC586EB 0C jmp short 00ACC594
00ACC5888D85 68C2FFFF lea eax,dword ptr ss:[ebp-3D98];函数名送 EAX
00ACC58E8985 D8A8FFFF mov dword ptr ss:[ebp+FFFFA8D8],eax
00ACC5946A 01 push 1
00ACC596FFB5 D8A8FFFF push dword ptr ss:[ebp+FFFFA8D8] ;函数名进栈
00ACC59CFFB5 A0D4FFFF push dword ptr ss:[ebp-2B60] ; 函数名所在的 Dll 进栈
00ACC5A2E8 6DA0FEFF call 00AB6614
00ACC5A783C4 0C add esp,0C
00ACC5AA8985 68CAFFFF mov dword ptr ss:[ebp-3598],eax ;把处理好的 IAT 送到 [ebp-3598]
00ACC5B083BD 68CAFFFF 0>cmp dword ptr ss:[ebp-3598],0 ;送进去了吗?
00ACC5B775 42 jnz short 00ACC5FB; 送进去就跳到下面继续
00ACC5B90FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594]
00ACC5C085C0test eax,eax
00ACC5C274 0F je short 00ACC5D3
00ACC5C40FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594]
00ACC5CB8985 D4A8FFFF mov dword ptr ss:[ebp+FFFFA8D4],eax
00ACC5D1EB 0C jmp short 00ACC5DF
00ACC5D38D85 68C2FFFF lea eax,dword ptr ss:[ebp-3D98]
00ACC5D98985 D4A8FFFF mov dword ptr ss:[ebp+FFFFA8D4],eax
00ACC5DF6A 00 push 0
00ACC5E1FFB5 D4A8FFFF push dword ptr ss:[ebp+FFFFA8D4]
00ACC5E7FFB5 A0D4FFFF push dword ptr ss:[ebp-2B60]
00ACC5EDE8 22A0FEFF call 00AB6614
00ACC5F283C4 0C add esp,0C
00ACC5F58985 68CAFFFF mov dword ptr ss:[ebp-3598],eax
00ACC5FB83BD 68CAFFFF 0>cmp dword ptr ss:[ebp-3598],0 ; 送进去了吗?
00ACC6020F85 99000000 jnz 00ACC6A1; 送进去就跳到下面继续
00ACC6080FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594]
00ACC60F85C0test eax,eax
00ACC61174 54 je short 00ACC667
00ACC613FF15 C060AD00 call dword ptr ds:[AD60C0] ; ntdll.RtlGetLastWin32Error
00ACC61983F8 32 cmp eax,32
00ACC61C75 0C jnz short 00ACC62A
00ACC61EC785 68CAFFFF 0>mov dword ptr ss:[ebp-3598],0AB6609
00ACC628EB 3B jmp short 00ACC665
00ACC62A8B45 08 mov eax,dword ptr ss:[ebp+8]
00ACC62D8B00mov eax,dword ptr ds:[eax]
00ACC62FC700 03000000 mov dword ptr ds:[eax],3
00ACC635FF15 C060AD00 call dword ptr ds:[AD60C0] ; ntdll.RtlGetLastWin32Error
00ACC63B50push eax
00ACC63C0FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594]
00ACC64350push eax
00ACC644FFB5 84D3FFFF push dword ptr ss:[ebp-2C7C]
00ACC64A68 94CBAD00 push 0ADCB94 ; ASCII "File "%s", ordinal %d (error %d)"
00ACC64F8B45 08 mov eax,dword ptr ss:[ebp+8]
00ACC652FF70 04 push dword ptr ds:[eax+4]
00ACC655FF15 1063AD00 call dword ptr ds:[AD6310] ; msvcrt.sprintf
00ACC65B83C4 14 add esp,14
00ACC65E33C0xor eax,eax
00ACC660E9 5B140000 jmp 00ACDAC0
00ACC665EB 3A jmp short 00ACC6A1
00ACC6678B45 08 mov eax,dword ptr ss:[ebp+8]
00ACC66A8B00mov eax,dword ptr ds:[eax]
00ACC66CC700 03000000 mov dword ptr ds:[eax],3
00ACC672FF15 C060AD00 call dword ptr ds:[AD60C0] ; ntdll.RtlGetLastWin32Error
00ACC67850push eax
00ACC6798D85 68C2FFFF lea eax,dword ptr ss:[ebp-3D98]
00ACC67F50push eax
00ACC680FFB5 84D3FFFF push dword ptr ss:[ebp-2C7C]
00ACC68668 70CBAD00 push 0ADCB70 ; ASCII "File "%s", function "%s" (error %d)"
00ACC68B8B45 08 mov eax,dword ptr ss:[ebp+8]
00ACC68EFF70 04 push dword ptr ds:[eax+4]
00ACC691FF15 1063AD00 call dword ptr ds:[AD6310] ; msvcrt.sprintf
00ACC69783C4 14 add esp,14
00ACC69A33C0xor eax,eax
00ACC69CE9 1F140000 jmp 00ACDAC0
00ACC6A18B85 10D9FFFF mov eax,dword ptr ss:[ebp-26F0] ; 把刚才 IAT 所在的位置送到 EAX
00ACC6A73B85 64D9FFFF cmp eax,dword ptr ss:[ebp-269C] ;EAX 里现在是 FFFFFFFF 吗?
00ACC6AD73 1D jnb short 00ACC6CC
00ACC6AF8B85 10D9FFFF mov eax,dword ptr ss:[ebp-26F0] ;把刚才 IAT 所在的位置送到 EAX
00ACC6B58B8D 68CAFFFF mov ecx,dword ptr ss:[ebp-3598] ;把 IAT 送到 ECX
00ACC6BB8908mov dword ptr ds:[eax],ecx;写入 IAT,过了这句就可以在数据窗口中看到 IAT
00ACC6BD8B85 10D9FFFF mov eax,dword ptr ss:[ebp-26F0] ;把刚才 IAT 所在位置的地址送到 EAX 中
00ACC6C383C0 04 add eax,4 ;指针指向下一个要写入的 IAT 位置
00ACC6C68985 10D9FFFF mov dword ptr ss:[ebp-26F0],eax;获得下一个要写入的 IAT 的位置后 送到[ebp-26F0] 中保存
00ACC6CC^ E9 4DFCFFFF jmp 00ACC31E;回去继续循环
00ACC6D1FF15 7C62AD00 call dword ptr ds:[AD627C] ; kernel32.GetTickCount
00ACC6D72B85 A4D4FFFF sub eax,dword ptr ss:[ebp-2B5C]
00ACC6DD8B8D A8D4FFFF mov ecx,dword ptr ss:[ebp-2B58]
00ACC6E36BC9 32 imul ecx,ecx,32
00ACC6E681C1 D0070000 add ecx,7D0
00ACC6EC3BC1cmp eax,ecx
00ACC6EE76 07 jbe short 00ACC6F7
00ACC6F0C685 34D9FFFF 0>mov byte ptr ss:[ebp-26CC],1
00ACC6F783BD E4D7FFFF 0>cmp dword ptr ss:[ebp-281C],0
00ACC6FE0F85 8A000000 jnz 00ACC78E
00ACC7040FB685 94D4FFFF movzx eax,byte ptr ss:[ebp-2B6C]
00ACC70B85C0test eax,eax
00ACC70D74 7F je short 00ACC78E
00ACC70F6A 00 push 0
00ACC7118B85 98D4FFFF mov eax,dword ptr ss:[ebp-2B68]
00ACC717C1E0 02 shl eax,2
00ACC71A50push eax
00ACC71B8B85 0CD8FFFF mov eax,dword ptr ss:[ebp-27F4]
00ACC7210385 90D4FFFF add eax,dword ptr ss:[ebp-2B70]
00ACC72750push eax
00ACC728E8 0D1E0000 call 00ACE53A
00ACC72D83C4 0C add esp,0C
00ACC7308B85 98D4FFFF mov eax,dword ptr ss:[ebp-2B68]
00ACC736C1E0 02 shl eax,2
00ACC73950push eax
00ACC73AFFB5 6CD9FFFF push dword ptr ss:[ebp-2694]
00ACC7408B85 0CD8FFFF mov eax,dword ptr ss:[ebp-27F4]
00ACC7460385 90D4FFFF add eax,dword ptr ss:[ebp-2B70]
00ACC74C50push eax
00ACC74DE8 068B0000 call 00AD5258; jmp 到 msvcrt.memcpy
00ACC75283C4 0C add esp,0C
00ACC7556A 01 push 1
00ACC7578B85 98D4FFFF mov eax,dword ptr ss:[ebp-2B68]
00ACC75DC1E0 02 shl eax,2
00ACC76050push eax
00ACC7618B85 0CD8FFFF mov eax,dword ptr ss:[ebp-27F4]
00ACC7670385 90D4FFFF add eax,dword ptr ss:[ebp-2B70]
00ACC76D50push eax
00ACC76EE8 C71D0000 call 00ACE53A
00ACC77383C4 0C add esp,0C
00ACC7768B85 6CD9FFFF mov eax,dword ptr ss:[ebp-2694]
00ACC77C8985 A4ABFFFF mov dword ptr ss:[ebp+FFFFABA4],eax
00ACC782FFB5 A4ABFFFF push dword ptr ss:[ebp+FFFFABA4]
00ACC788E8 C58A0000 call 00AD5252; jmp 到 msvcrt.operator delete
00ACC78D59pop ecx; 跳回去继续处理 IAT
00ACC78E^ E9 30F7FFFF jmp 00ACBEC3 ; 到这里 IAT 已经全部处理完毕
总结一下:
1 把00ACC5B7的 jnz short 00ACC5B0 这句 nop 掉就可以避开 IAT 加密了。

2 把00ACC50A的 jnz 改成 JMP 就可以避开 IAT 加密了。

两种方法任选其一,改好后到00ACC78E设置个硬件执行断点,然后 Shift+F9 运行程序

中断后把刚才改的还原回来这时候就可以用 ImportREC v1.6 Fix 修复输入表了

3 在 ImportREC 里填好 OEP 1700后,自动搜索IAT就可以了。
lqiulu 发表于 2008-10-24 08:35
观察一下为单进程, Armadillo Find Protected V1.8查壳为:
!- Protected Armadillo
Protection system (Professional)
!- <Protection Options>
Standard protection or Minimum protection
!- <Backup Key Options>
No Registry Keys at All
!- <Compression Options>
Better/Slower Compression
!- <Other Options>
!- Version 4.40 31October2005


传统方法:

开工,还是两个断点法脱壳:
bp GetModuleHandleA+9
bp CreateThread

OD载入:
00454000 >60PUSHAD
00454001E8 00000000 CALL UnPackMe.00454006
004540065DPOP EBP
0045400750PUSH EAX
0045400851PUSH ECX
004540090FCABSWAP EDX
0045400BF7D2NOT EDX


下第一个断点:bp GetModuleHandleA+9,SHIFT+F9运行,注意堆栈:
运行七次后(可能每个人的机子不一样):堆栈中为:


00129500|00AC7122RETURN to 00AC7122 from kernel32.GetModuleHandleA
00129504|00ADBC1CASCII "kernel32.dll"
00129508|00ADCEB8ASCII "VirtualFree"//这里就是标志
0012950C|00ADFA98
00129510|7C9210E0ntdll.RtlLeaveCriticalSection


再运行一次达到最佳返回时机。
寄存器中的内容如下:

EAX 001293B4 ASCII "kernel32.dll"
ECX 001293C0
EDX 001293B4 ASCII "kernel32.dll"
EBX 00000000
ESP 00129260
EBP 00129260
ESI 00000000
EDI 00ADB0F4
EIP 7C80B73A kernel32.7C80B73A


堆栈内容如下:

00129260/00129500
00129264|00AB5FC9RETURN to 00AB5FC9 from kernel32.GetModuleHandleA
00129268|001293B4ASCII "kernel32.dll"
0012926C|00000000
00129270|EC440000


取消断点,alt + F9返回。
00AB5FC98B0D AC40AE00 MOV ECX,DWORD PTR DS:[AE40AC] //返回到这里
00AB5FCF89040EMOV DWORD PTR DS:[ESI+ECX],EAX
00AB5FD2A1 AC40AE00 MOV EAX,DWORD PTR DS:[AE40AC]
00AB5FD7391C06CMP DWORD PTR DS:[ESI+EAX],EBX
00AB5FDA75 16 JNZ SHORT 00AB5FF2
00AB5FDC8D85 B4FEFFFF LEA EAX,DWORD PTR SS:[EBP-14C]
00AB5FE250PUSH EAX
00AB5FE3FF15 BC62AD00 CALL DWORD PTR DS:[AD62BC] ; kernel32.LoadLibraryA 标志
00AB5FE98B0D AC40AE00 MOV ECX,DWORD PTR DS:[AE40AC]
00AB5FEF89040EMOV DWORD PTR DS:[ESI+ECX],EAX
00AB5FF2A1 AC40AE00 MOV EAX,DWORD PTR DS:[AE40AC]
00AB5FF7391C06CMP DWORD PTR DS:[ESI+EAX],EBX
00AB5FFA0F84 2F010000 JE 00AB612F//这就是传说中的magic jump ,改为jump
00AB600033C9XOR ECX,ECX
00AB60028B07MOV EAX,DWORD PTR DS:[EDI]
00AB60043918CMP DWORD PTR DS:[EAX],EBX
00AB600674 06 JE SHORT 00AB600E //这个跳转小
00AB600841INC ECX
00AB600983C0 0C ADD EAX,0C
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

00AB612F83C7 0C ADD EDI,0C //MAGIC JUMP跳到这里。
00AB613289BD 78FDFFFF MOV DWORD PTR SS:[EBP-288],EDI
00AB613883C6 04 ADD ESI,4
00AB613B395F FC CMP DWORD PTR DS:[EDI-4],EBX
00AB613E^ 0F85 49FEFFFF JNZ 00AB5F8D //向回跳,不断处理IAT数据。
00AB6144EB 03 JMP SHORT 00AB6149 //在这里下断,运行到这里时IAT全部处理完毕。
00AB6146D6SALC //停在上边时返回恢复修改的magic跳代码以防壳的校验。
00AB6147D6SALC
00AB61488F???


下第二个断点:bp CreateThread,SHIFT+F9运行。停下后取消断点返回。
00ABC51E50PUSH EAX //返回到这里,F8单步
00ABC51FFF15 4C62AD00 CALL DWORD PTR DS:[AD624C] ; kernel32.CloseHandle
00ABC5255FPOP EDI
00ABC5265EPOP ESI
00ABC527C9LEAVE
00ABC528C3RETN
...............................................................
00ACF8DD59POP ECX //00ABC528返回到这里,继续单步走。
00ACF8DEBE 98FAAD00 MOV ESI,0ADFA98
00ACF8E38BCEMOV ECX,ESI
00ACF8E5E8 1693FDFF CALL 00AA8C00
00ACF8EA84C0TEST AL,AL
00ACF8EC75 09 JNZ SHORT 00ACF8F7
00ACF8EE6A 01 PUSH 1
............................................................
00ACF9C5FFD1CALL ECX
00ACF9C7EB 1D JMP SHORT 00ACF9E6
00ACF9C983FA 01 CMP EDX,1
00ACF9CC75 1B JNZ SHORT 00ACF9E9
00ACF9CEFF77 04 PUSH DWORD PTR DS:[EDI+4]
00ACF9D1FF77 08 PUSH DWORD PTR DS:[EDI+8]
00ACF9D46A 00 PUSH 0
00ACF9D6FF77 0C PUSH DWORD PTR DS:[EDI+C]
00ACF9D98B50 60 MOV EDX,DWORD PTR DS:[EAX+60]
00ACF9DC3350 44 XOR EDX,DWORD PTR DS:[EAX+44]
00ACF9DF3350 1C XOR EDX,DWORD PTR DS:[EAX+1C]
00ACF9E22BCASUB ECX,EDX
00ACF9E4FFD1CALL ECX //一直单步到这里,这里跳向程序OEP。
00ACF9E68945 E4 MOV DWORD PTR SS:[EBP-1C],EAX
00ACF9E98B45 E4 MOV EAX,DWORD PTR SS:[EBP-1C]
00ACF9EC8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10]
00ACF9EF64:890D 0000000>MOV DWORD PTR FS:[0],ECX
00ACF9F65FPOP EDI
00ACF9F75EPOP ESI
00ACF9F85BPOP EBX
00ACF9F9C9LEAVE
00ACF9FAC3RETN
---------------------------------------------------------------------------------
0040170055PUSH EBP //程序OEP.
004017018BECMOV EBP,ESP
004017036A FF PUSH -1
0040170568 00254000 PUSH UnPackMe.00402500
0040170A68 86184000 PUSH UnPackMe.00401886 ; JMP to msvcrt._except_handler3
0040170F64:A1 00000000MOV EAX,DWORD PTR FS:[0]
0040171550PUSH EAX
0040171664:8925 0000000>MOV DWORD PTR FS:[0],ESP
0040171D83EC 68 SUB ESP,68


dump程序,importREC进行复,填入程序OEP,1700,自动查找,获取,cut掉所有无效指针,修复dump程序。正常
运行。脱壳过程结束。

减肥,脱壳后的程序大小为736 KB,用cff explorer删除无用区段,只保留.text,.data,.rdata,.rsrc,.mackt几个区段。大小为32.0 KB。

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


下面分析一下,另一种方法。

bp CreateThread断点,直接到达OEP,dump下来,修复时有七个无效指针,
找到第一个加密的IAT函数。2000即00402000。下硬件写入断点。shift+f9 第一停在这里:

77C16FA3 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
77C16FA5 FF2495 B870C177 JMP DWORD PTR DS:[EDX*4+77C170B8]

与IAT函数无关,再F9运行。
停在这里:

00ACC6AD/73 1D JNB SHORT 00ACC6CC
00ACC6AF|8B85 10D9FFFF MOV EAX,DWORD PTR SS:[EBP-26F0]
00ACC6B5|8B8D 68CAFFFF MOV ECX,DWORD PTR SS:[EBP-3598]
00ACC6BB|8908MOV DWORD PTR DS:[EAX],ECX //这里给0040200写值了。
00ACC6BD|8B85 10D9FFFF MOV EAX,DWORD PTR SS:[EBP-26F0]//运行第二次停在这里。单步走。
00ACC6C3|83C0 04 ADD EAX,4
00ACC6C6|8985 10D9FFFF MOV DWORD PTR SS:[EBP-26F0],EAX
00ACC6CC ^\E9 4DFCFFFF JMP 00ACC31E //到这里跟回去。


00ACC31E 6A 01 PUSH 1 //跳到这里。下面单步走。
00ACC320 58POP EAX
00ACC321 85C0TEST EAX,EAX
00ACC323 0F84 A8030000 JE 00ACC6D1
00ACC329 8B85 84D9FFFF MOV EAX,DWORD PTR SS:[EBP-267C]
00ACC32F 66:8B00 MOV AX,WORD PTR DS:[EAX]
00ACC332 66:8985 64C2FFFFMOV WORD PTR SS:[EBP-3D9C],AX
00ACC339 8B85 84D9FFFF MOV EAX,DWORD PTR SS:[EBP-267C]
00ACC33F 40INC EAX
00ACC340 40INC EAX
00ACC341 8985 84D9FFFF MOV DWORD PTR SS:[EBP-267C],EAX
........................................................................

00ACC500FF15 8C63AD00 CALLDWORD PTR [AD638C]; msvcrt._stricmp
00ACC50659POP ECX
00ACC50759POP ECX
00ACC508 >85C0TESTEAX, EAX

00ACC50A /75 11 JNZ SHORT 00ACC51D //这里改为jmp就可以跳过加密。
00ACC50C |8B85 58C2FFFF MOV EAX, DWORD PTR [EBP-3DA8]
00ACC512 |8B40 08 MOV EAX, DWORD PTR [EAX+8]
00ACC515 |8985 68CAFFFF MOV DWORD PTR [EBP-3598], EAX //这里给[EBP-3598]赋值,

此时eax非零,赋值的话下面的00ACC56C处的跳就会实现。所以一定不能执行这个语句。
00ACC51B |EB 02 JMP SHORT 00ACC51F//这里跳过后就对IAT进行加密。
00ACC51D^\EB 9C JMP SHORT 00ACC4BB//跳回处理IAT函数,跳过这里就会加密
00ACC51F8B85 A8D4FFFF MOV EAX, DWORD PTR [EBP-2B58]
00ACC52540INC EAX
00ACC5268985 A8D4FFFF MOV DWORD PTR [EBP-2B58], EAX

......................................................................
00ACC54F 8908MOV DWORD PTR DS:[EAX],ECX
00ACC551 8B85 10D9FFFF MOV EAX,DWORD PTR SS:[EBP-26F0]
00ACC557 83C0 04 ADD EAX,4
00ACC55A 8985 10D9FFFF MOV DWORD PTR SS:[EBP-26F0],EAX
00ACC560 E9 6C010000 JMP 00ACC6D1
00ACC565 83BD 68CAFFFF 00CMP DWORD PTR SS:[EBP-3598],0 //这里比较[EBP-3598]是不是0,

不为0就跳,跳的话就跳过了得到正确API函数的CALL。
00ACC56C 75 42 JNZ SHORT 00ACC5B0 //这里跳过得到正确API函数。所以不能跳过。
这一段代码是解码得来的,所以找合适断点。当代码为以上形式的时候就可以下条件断点。
00ACC56E 0FB785 6CCAFFFF MOVZX EAX,WORD PTR SS:[EBP-3594]
00ACC575 85C0TEST EAX,EAX
00ACC577 74 0F JE SHORT 00ACC588
00ACC579 0FB785 6CCAFFFF MOVZX EAX,WORD PTR SS:[EBP-3594]
00ACC580 8985 D8A8FFFF MOV DWORD PTR SS:[EBP+FFFFA8D8],EAX
00ACC586 EB 0C JMP SHORT 00ACC594
00ACC588 8D85 68C2FFFF LEA EAX,DWORD PTR SS:[EBP-3D98]
00ACC58E 8985 D8A8FFFF MOV DWORD PTR SS:[EBP+FFFFA8D8],EAX
00ACC594 6A 01 PUSH 1
00ACC596 FFB5 D8A8FFFF PUSH DWORD PTR SS:[EBP+FFFFA8D8]
00ACC59C FFB5 A0D4FFFF PUSH DWORD PTR SS:[EBP-2B60]
00ACC5A2 E8 6DA0FEFF CALL 00AB6614//这里得到真正API函数。不能跳过,跳过就加密了。
00ACC5A7 83C4 0C ADD ESP,0C
00ACC5AA 8985 68CAFFFFMOV DWORD PTR SS:[EBP-3598],EAX//EAX就是API函数,00ACC5A2返回。
00ACC5B0 83BD 68CAFFFF 00CMP DWORD PTR SS:[EBP-3598],0
00ACC5B7 75 42 JNZ SHORT 00ACC5FB

00ACC5B9 0FB785 6CCAFFFF MOVZX EAX,WORD PTR SS:[EBP-3594]


重新运行程序,保留00402000的写入断点,并下HE LoadLibraryA断点运行。
三次后停在写入断点。



继续运行,断在LoadLibraryA断点,堆栈为:

001294EC 00AB75C8/CALL to LoadLibraryA from 00AB75C2
001294F0 00C04008\FileName = "MFC42.DLL"
001294F4 0012C0D0


crtl+G00ACC56C,NOP掉75 42JNZ SHORT 00ACC5B0。shift + f9运行
运行至断在硬件写入断点。


00ACC6BD 8B85 10D9FFFF MOV EAX,DWORD PTR SS:[EBP-26F0]; UnPackMe.00402000
00ACC6C3 83C0 04 ADD EAX,4


这时数据窗口,命令行 “D 00402000” 看到iat数据显示出来了。


004020007C80B731kernel32.GetModuleHandleA//这里原来被加密的。
004020047C801EF2kernel32.GetStartupInfoA
0040200800AB73AA



继续运行断下后看堆栈为:

001294EC 00AB75C8/CALL to LoadLibraryA from 00AB75C2
001294F0 00C04504\FileName = "USER32.dll"


返回00ACC56C恢复NOP掉的代码,防校验。取消所有硬件断点,下bp CreateThread断点来到程序OEP.
下面的跟传统的方法相同。不详述了。



总结如下:

下断点:HE LoadLibraryA SHIFT + F9运行,看堆栈

001294EC 00AB75C8/CALL to LoadLibraryA from 00AB75C2
001294F0 00C04008\FileName = "MFC42.DLL"
001294F4 0012C0D0


此时返回程序领空,查找:“75 ?? 0F B7 85 ?? ?? ?? ?? 85 C0

JNZ XXXX NOP掉,或改前面的jump继续运行断下后看堆栈为:

001294EC 00AB75C8/CALL to LoadLibraryA from 00AB75C2
001294F0 00C04504\FileName = "USER32.dll"


返回程序领空恢复更改的代码。再下断点:bp CreateThread到达OEP.

2.rar

8 KB, 下载次数: 0, 下载积分: 吾爱币 -1 CB

blgzs 发表于 2008-10-24 10:15
我的方法超级简单

OD载入,忽略全部异常,再添加忽略这个异常C000001E
在401000下内存断点F2,Shift+F9
00B0F9688B12mov edx,dword ptr ds:[edx];停在这里
00B0F96A8955 DC mov dword ptr ss:[ebp-24],edx;F8一下到这里后,再在401000下内存断点F2,Shift+F9

一下就到了OEP处
LoadPE转存,importREC修复,发现有7个无效指针,穿山甲壳一般是有6个无效
指针,也就意味着只有一个指针被加密了。
我们取第一个无效指针来找,看能否找到
OD重新载入
dd 402000,下硬件写入断点
shift+F9
77C16FA3F3:A5 rep movs dword ptr es:[edi],dword ptr ds>
77C16FA5FF2495 B870C177 jmp dword ptr ds:[edx*4+77C170B8]
77C16FAC8BC7mov eax,edi
发现堆栈和寄存器中没有要找的信息,再次shift+F9
00B0C6BD8B85 10D9FFFF mov eax,dword ptr ss:[ebp-26F0];停在这里
看堆栈和寄存器中都有GetModuleHandleA,可能这个无效指针就是它,我们来试一下

用刚才的方法找到OEP,LoadPE转存,importREC修复,将第一个无效指针改成
GetModuleHandleA,其它的cut掉,修复转存文件。运行成功。

嘎嘎...

没有分析IAT加密,不知道是不是符合小生的要求?
dumped_.rar
wesley 发表于 2008-10-24 12:14
从没有分析过小穿的IAT加密以前一直都是照着大牛的做法花了几个小时又看了好多破文。。。。才能搞成现在这把样子惭愧

查壳
<------- 24-10-2008 23:40:59 ------->
C:\Documents and Settings\wesley\Desktop\UnPackMe.exe
!- 目标为Armadillo保护
!- 保护系统级别为 (专业版)
!- <所用到的保护模式有>
标准保护 或 最小保护模式
!- <备份密钥设置>
没有发现注册密钥
!- <目标程序压缩设置>
较好 / 较慢 的压缩方式
!- <其它保护设置>
!- 版本号: 4.40 31October2005
!- 共使用的时间 00h 00m 00s 641ms


OD载入忽略所有异常 直接在CODE段下断shift+f9运行
00BFF9688B12mov edx,dword ptr ds:[edx]00BFF96A8955 DC mov dword ptr ss:[ebp-24],edx00BFF96D834D FC FFor dword ptr ss:[ebp-4],FFFFFFFF00BFF971EB 11 jmp short 00BFF98400BFF9736A 01 push 100BFF97558pop eax
单步几下直达OEP
0040170055push ebp004017018BECmov ebp,esp004017036A FF push -10040170568 00254000 push UnPackMe.004025000040170A68 86184000 push UnPackMe.00401886 ; jmp 到0040170F64:A1 00000000mov eax,dword ptr fs:[0]0040171550push eax0040171664:8925 0000000>mov dword ptr fs:[0],esp0040171D83EC 68 sub esp,680040172053push ebx
LordPe脱下来再说ImportREC修复 随便找一个IAT地址 我这里就找0040216c

重新载入程序

在数据窗口 Ctrl+G到0040216c
下硬件写入断点(BYTE)
Shift+F9 Twice

It is broke in this place
00BFC6BD8B85 10D9FFFF mov eax,dword ptr ss:[ebp-26F0]; UnPackMe.0040216C00BFC6C383C0 04 add eax,400BFC6C68985 10D9FFFF mov dword ptr ss:[ebp-26F0],eax00BFC6CC^ E9 4DFCFFFF jmp 00BFC31E单步后到达下面的位置00BFC6D1FF15 7C62C000 call dword ptr ds:[C0627C] ; kernel32.GetTickCount
00C0C31E6A 01 push 1 ; IAT处理开始00C0C32058pop eax00C0C32185C0test eax,eax00C0C3230F84 A8030000 je 00C0C6D100C0C3298B85 84D9FFFF mov eax,dword ptr ss:[ebp-267C]00C0C32F66:8B00 mov ax,word ptr ds:[eax]00C0C33266:8985 64C2FFF>mov word ptr ss:[ebp-3D9C],ax00C0C3398B85 84D9FFFF mov eax,dword ptr ss:[ebp-267C]00C0C33F40inc eax00C0C34040inc eax00C0C3418985 84D9FFFF mov dword ptr ss:[ebp-267C],eax00C0C3470FB785 64C2FFFF movzx eax,word ptr ss:[ebp-3D9C]00C0C34E50push eax00C0C34FFFB5 84D9FFFF push dword ptr ss:[ebp-267C]00C0C3558D85 70CAFFFF lea eax,dword ptr ss:[ebp-3590]00C0C35B50push eax00C0C35CE8 F78E0000 call 00C15258; jmp 到00C0C36183C4 0C add esp,0C00C0C3640FB785 64C2FFFF movzx eax,word ptr ss:[ebp-3D9C]00C0C36B8B8D 84D9FFFF mov ecx,dword ptr ss:[ebp-267C]00C0C37103C8add ecx,eax00C0C373898D 84D9FFFF mov dword ptr ss:[ebp-267C],ecx00C0C37966:83A5 6CCAFFF>and word ptr ss:[ebp-3594],000C0C381A0 60ECC100 mov al,byte ptr ds:[C1EC60]00C0C3868885 68C2FFFF mov byte ptr ss:[ebp-3D98],al00C0C38CB9 FF010000 mov ecx,1FF00C0C39133C0xor eax,eax00C0C3938DBD 69C2FFFF lea edi,dword ptr ss:[ebp-3D97]00C0C399F3:AB rep stos dword ptr es:[edi]00C0C39B66:AB stos word ptr es:[edi]00C0C39DAAstos byte ptr es:[edi]00C0C39E0FB785 64C2FFFF movzx eax,word ptr ss:[ebp-3D9C]00C0C3A585C0test eax,eax00C0C3A774 6E je short 00C0C41700C0C3A98D8D 74D9FFFF lea ecx,dword ptr ss:[ebp-268C]00C0C3AFE8 4C4CFDFF call 00BE100000C0C3B48985 60C2FFFF mov dword ptr ss:[ebp-3DA0],eax00C0C3BA6A 00 push 000C0C3BC0FB785 64C2FFFF movzx eax,word ptr ss:[ebp-3D9C]00C0C3C350push eax00C0C3C48D85 70CAFFFF lea eax,dword ptr ss:[ebp-3590]00C0C3CA50push eax00C0C3CBFFB5 60C2FFFF push dword ptr ss:[ebp-3DA0]00C0C3D1E8 D650FDFF call 00BE14AC; 获取一个函数名00C0C3D683C4 10 add esp,1000C0C3D90FB685 70CAFFFF movzx eax,byte ptr ss:[ebp-3590] ; 函数名首字母 ASCII 送到 EAX00C0C3E03D FF000000 cmp eax,0FF00C0C3E575 10 jnz short 00C0C3F700C0C3E766:8B85 71CAFFF>mov ax,word ptr ss:[ebp-358F]00C0C3EE66:8985 6CCAFFF>mov word ptr ss:[ebp-3594],ax00C0C3F5EB 20 jmp short 00C0C41700C0C3F70FBE85 70CAFFFF movsx eax,byte ptr ss:[ebp-3590] ; 函数名首字母 ASCII 送到 EAX00C0C3FE85C0test eax,eax00C0C40074 15 je short 00C0C41700C0C4028D85 70CAFFFF lea eax,dword ptr ss:[ebp-3590]; 函数名送到 EAX 中保存00C0C40850push eax00C0C4098D85 68C2FFFF lea eax,dword ptr ss:[ebp-3D98]; 函数地址送到 EAX 中保存00C0C40F50push eax00C0C410E8 D58E0000 call 00C152EA; jmp 到00C0C41559pop ecx00C0C41659pop ecx00C0C41783A5 68CAFFFF 0>and dword ptr ss:[ebp-3598],000C0C41E0FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594]00C0C42585C0test eax,eax00C0C42774 6C je short 00C0C49500C0C42983BD 9CD4FFFF 0>cmp dword ptr ss:[ebp-2B64],000C0C43074 51 je short 00C0C48300C0C4328B85 9CD4FFFF mov eax,dword ptr ss:[ebp-2B64]00C0C4388985 5CC2FFFF mov dword ptr ss:[ebp-3DA4],eax00C0C43EEB 0F jmp short 00C0C44F00C0C4408B85 5CC2FFFF mov eax,dword ptr ss:[ebp-3DA4]00C0C44683C0 0C add eax,0C00C0C4498985 5CC2FFFF mov dword ptr ss:[ebp-3DA4],eax00C0C44F8B85 5CC2FFFF mov eax,dword ptr ss:[ebp-3DA4]00C0C4558378 08 00cmp dword ptr ds:[eax+8],000C0C45974 28 je short 00C0C48300C0C45B0FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594]00C0C4628B8D 5CC2FFFF mov ecx,dword ptr ss:[ebp-3DA4]00C0C4680FB749 04 movzx ecx,word ptr ds:[ecx+4]00C0C46C3BC1cmp eax,ecx00C0C46E75 11 jnz short 00C0C48100C0C4708B85 5CC2FFFF mov eax,dword ptr ss:[ebp-3DA4]00C0C4768B40 08 mov eax,dword ptr ds:[eax+8]00C0C4798985 68CAFFFF mov dword ptr ss:[ebp-3598],eax00C0C47FEB 02 jmp short 00C0C48300C0C481^ EB BD jmp short 00C0C44000C0C4838B85 A8D4FFFF mov eax,dword ptr ss:[ebp-2B58]00C0C48940inc eax00C0C48A8985 A8D4FFFF mov dword ptr ss:[ebp-2B58],eax00C0C490E9 D0000000 jmp 00C0C56500C0C4950FBE85 68C2FFFF movsx eax,byte ptr ss:[ebp-3D98]00C0C49C85C0test eax,eax ; 比较函数名首位是否为空00C0C49E0F84 8A000000 je 00C0C52E00C0C4A483BD 9CD4FFFF 0>cmp dword ptr ss:[ebp-2B64],000C0C4AB74 72 je short 00C0C51F00C0C4AD8B85 9CD4FFFF mov eax,dword ptr ss:[ebp-2B64]00C0C4B38985 58C2FFFF mov dword ptr ss:[ebp-3DA8],eax00C0C4B9EB 0F jmp short 00C0C4CA00C0C4BB8B85 58C2FFFF mov eax,dword ptr ss:[ebp-3DA8]00C0C4C183C0 0C add eax,0C00C0C4C48985 58C2FFFF mov dword ptr ss:[ebp-3DA8],eax00C0C4CA8B85 58C2FFFF mov eax,dword ptr ss:[ebp-3DA8]00C0C4D08378 08 00cmp dword ptr ds:[eax+8],000C0C4D474 49 je short 00C0C51F00C0C4D668 00010000 push 10000C0C4DB8D85 58C1FFFF lea eax,dword ptr ss:[ebp-3EA8]00C0C4E150push eax00C0C4E28B85 58C2FFFF mov eax,dword ptr ss:[ebp-3DA8]00C0C4E8FF30push dword ptr ds:[eax]00C0C4EAE8 A961FDFF call 00BE269800C0C4EF83C4 0C add esp,0C00C0C4F28D85 58C1FFFF lea eax,dword ptr ss:[ebp-3EA8]00C0C4F850push eax00C0C4F98D85 68C2FFFF lea eax,dword ptr ss:[ebp-3D98]00C0C4FF50push eax00C0C500FF15 8C63C100 call dword ptr ds:[C1638C] ; msvcrt._stricmp00C0C50659pop ecx00C0C50759pop ecx00C0C50885C0test eax,eax00C0C50A75 11 jnz short 00C0C51D00C0C50C8B85 58C2FFFF mov eax,dword ptr ss:[ebp-3DA8]00C0C5128B40 08 mov eax,dword ptr ds:[eax+8]00C0C5158985 68CAFFFF mov dword ptr ss:[ebp-3598],eax00C0C51BEB 02 jmp short 00C0C51F00C0C51D^ EB 9C jmp short 00C0C4BB00C0C51F8B85 A8D4FFFF mov eax,dword ptr ss:[ebp-2B58]00C0C52540inc eax00C0C5268985 A8D4FFFF mov dword ptr ss:[ebp-2B58],eax00C0C52CEB 37 jmp short 00C0C56500C0C52E8D8D 38D9FFFF lea ecx,dword ptr ss:[ebp-26C8]00C0C534E8 074BFDFF call 00BE104000C0C5390FB6C0movzx eax,al00C0C53C99cdq00C0C53D6A 14 push 1400C0C53F59pop ecx00C0C540F7F9idiv ecx00C0C5428B85 10D9FFFF mov eax,dword ptr ss:[ebp-26F0]00C0C5488B8C95 94D7FFFF mov ecx,dword ptr ss:[ebp+edx*4-286C]00C0C54F8908mov dword ptr ds:[eax],ecx00C0C5518B85 10D9FFFF mov eax,dword ptr ss:[ebp-26F0]00C0C55783C0 04 add eax,400C0C55A8985 10D9FFFF mov dword ptr ss:[ebp-26F0],eax00C0C560E9 6C010000 jmp 00C0C6D100C0C56583BD 68CAFFFF 0>cmp dword ptr ss:[ebp-3598],0关键00BFC56C /75 42 jnz short 00BFC5B0 majic jump 根据下面的简单分析 这里的跳转不实现 下面的IAT压栈等一系列操作才能完成 直接NOP掉00C0C56E0FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594] ; EAX清000C0C57585C0test eax,eax00C0C57774 0F je short 00C0C58800C0C5790FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594]00C0C5808985 D8A8FFFF mov dword ptr ss:[ebp+FFFFA8D8],eax00C0C586EB 0C jmp short 00C0C59400C0C5888D85 68C2FFFF lea eax,dword ptr ss:[ebp-3D98]; 函数名送EAX00C0C58E8985 D8A8FFFF mov dword ptr ss:[ebp+FFFFA8D8],eax00C0C5946A 01 push 100C0C596FFB5 D8A8FFFF push dword ptr ss:[ebp+FFFFA8D8] ; 函数名压栈00C0C59CFFB5 A0D4FFFF push dword ptr ss:[ebp-2B60] ; 这里应该是对应的DLL压栈?00C0C5A2E8 6DA0FEFF call 00BF661400C0C5A783C4 0C add esp,0C00C0C5AA8985 68CAFFFF mov dword ptr ss:[ebp-3598],eax; 处理好后送入[ebp-3598]保存00C0C5B083BD 68CAFFFF 0>cmp dword ptr ss:[ebp-3598],000C0C5B775 42 jnz short 00C0C5FB ; 检测该IAT是否已放入那个地址是的话跳走继续00C0C5B90FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594]00C0C5C085C0test eax,eax00C0C5C274 0F je short 00C0C5D300C0C5C40FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594]00C0C5CB8985 D4A8FFFF mov dword ptr ss:[ebp+FFFFA8D4],eax00C0C5D1EB 0C jmp short 00C0C5DF00C0C5D38D85 68C2FFFF lea eax,dword ptr ss:[ebp-3D98]00C0C5D98985 D4A8FFFF mov dword ptr ss:[ebp+FFFFA8D4],eax00C0C5DF6A 00 push 000C0C5E1FFB5 D4A8FFFF push dword ptr ss:[ebp+FFFFA8D4]00C0C5E7FFB5 A0D4FFFF push dword ptr ss:[ebp-2B60]00C0C5EDE8 22A0FEFF call 00BF661400C0C5F283C4 0C add esp,0C00C0C5F58985 68CAFFFF mov dword ptr ss:[ebp-3598],eax00C0C5FB83BD 68CAFFFF 0>cmp dword ptr ss:[ebp-3598],0; 再次确认是否放入00C0C6020F85 99000000 jnz 00C0C6A100C0C6080FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594]00C0C60F85C0test eax,eax00C0C61174 54 je short 00C0C66700C0C613FF15 C060C100 call dword ptr ds:[C160C0] ; ntdll.RtlGetLastWin32Error00C0C61983F8 32 cmp eax,3200C0C61C75 0C jnz short 00C0C62A00C0C61EC785 68CAFFFF 0>mov dword ptr ss:[ebp-3598],0BF660900C0C628EB 3B jmp short 00C0C66500C0C62A8B45 08 mov eax,dword ptr ss:[ebp+8]00C0C62D8B00mov eax,dword ptr ds:[eax]00C0C62FC700 03000000 mov dword ptr ds:[eax],300C0C635FF15 C060C100 call dword ptr ds:[C160C0] ; ntdll.RtlGetLastWin32Error00C0C63B50push eax00C0C63C0FB785 6CCAFFFF movzx eax,word ptr ss:[ebp-3594]00C0C64350push eax00C0C644FFB5 84D3FFFF push dword ptr ss:[ebp-2C7C]00C0C64A68 94CBC100 push 0C1CB94 ; ASCII "File ""%s"", ordinal %d (error %d)"00C0C64F8B45 08 mov eax,dword ptr ss:[ebp+8]00C0C652FF70 04 push dword ptr ds:[eax+4]00C0C655FF15 1063C100 call dword ptr ds:[C16310] ; msvcrt.sprintf00C0C65B83C4 14 add esp,1400C0C65E33C0xor eax,eax00C0C660E9 5B140000 jmp 00C0DAC000C0C665EB 3A jmp short 00C0C6A100C0C6678B45 08 mov eax,dword ptr ss:[ebp+8]00C0C66A8B00mov eax,dword ptr ds:[eax]00C0C66CC700 03000000 mov dword ptr ds:[eax],300C0C672FF15 C060C100 call dword ptr ds:[C160C0] ; ntdll.RtlGetLastWin32Error00C0C67850push eax00C0C6798D85 68C2FFFF lea eax,dword ptr ss:[ebp-3D98]00C0C67F50push eax00C0C680FFB5 84D3FFFF push dword ptr ss:[ebp-2C7C]00C0C68668 70CBC100 push 0C1CB70 ; ASCII "File ""%s"", function ""%s"" (error %d)"00C0C68B8B45 08 mov eax,dword ptr ss:[ebp+8]00C0C68EFF70 04 push dword ptr ds:[eax+4]00C0C691FF15 1063C100 call dword ptr ds:[C16310] ; msvcrt.sprintf00C0C69783C4 14 add esp,1400C0C69A33C0xor eax,eax00C0C69CE9 1F140000 jmp 00C0DAC000C0C6A18B85 10D9FFFF mov eax,dword ptr ss:[ebp-26F0]; 把该IAT的位置传EAX00C0C6A73B85 64D9FFFF cmp eax,dword ptr ss:[ebp-269C]00C0C6AD73 1D jnb short 00C0C6CC ; EAX值大于等于FFFFFFFF就跳 显然没跳00C0C6AF8B85 10D9FFFF mov eax,dword ptr ss:[ebp-26F0]; 再次把IAT位置写入EAX00C0C6B58B8D 68CAFFFF mov ecx,dword ptr ss:[ebp-3598]; IAT写入ECX00C0C6BB8908mov dword ptr ds:[eax],ecx ; 将IAT写入EAX对应的内存地址 可以在堆栈中看到已写入此IAT00C0C6BD8B85 10D9FFFF mov eax,dword ptr ss:[ebp-26F0]; 把IAT位置写入EAX00C0C6C383C0 04 add eax,4; 指向下一个要写入的IAT位置00C0C6C68985 10D9FFFF mov dword ptr ss:[ebp-26F0],eax; 将下一个要写入IAT的值 继续放入[ebp-26F0]00C0C6CC^ E9 4DFCFFFF jmp 00C0C31E ; 向上循环00C0C6D1FF15 7C62C100 call dword ptr ds:[C1627C] ; kernel32.GetTickCount
00C0C788E8 C58A0000 call 00C15252; jmp 到00C0C78D59pop ecx00C0C78E^ E9 30F7FFFF jmp 00C0BEC3 ; 继续循环00C0C7938B85 F0D7FFFF mov eax,dword ptr ss:[ebp-2810]; IAT处理完毕在此下F2断点 断下后 把上面的majic jump 改回来 以防壳检测00C0C7998985 A0ABFFFF mov dword ptr ss:[ebp+FFFFABA0],eax
然后在00401000处F2下断 shift+F9运行 来到这里好熟悉的地方
00C0F9688B12mov edx,dword ptr ds:[edx]00C0F96A8955 DC mov dword ptr ss:[ebp-24],edx00C0F96D834D FC FFor dword ptr ss:[ebp-4],FFFFFFFF00C0F971EB 11 jmp short 00C0F98400C0F9736A 01 push 100C0F97558pop eax00C0F976C3retn
一路单步
00C0F9D1FF77 08 push dword ptr ds:[edi+8]00C0F9D46A 00 push 000C0F9D6FF77 0C push dword ptr ds:[edi+C]00C0F9D98B50 60 mov edx,dword ptr ds:[eax+60]00C0F9DC3350 44 xor edx,dword ptr ds:[eax+44]00C0F9DF3350 1C xor edx,dword ptr ds:[eax+1C]00C0F9E22BCAsub ecx,edx00C0F9E4FFD1call ecx <<==OEP F7进入00C0F9E68945 E4 mov dword ptr ss:[ebp-1C],eax00C0F9E98B45 E4 mov eax,dword ptr ss:[ebp-1C]00C0F9EC8B4D F0 mov ecx,dword ptr ss:[ebp-10]00C0F9EF64:890D 0000000>mov dword ptr fs:[0],ecx00C0F9F65Fpop edi00C0F9F75Epop esi
先前已脱过壳了 这里直接修复就好删除几个无效指针。。。OK成功运行
maokecheng 该用户已被删除
maokecheng 发表于 2008-10-24 12:17
提示: 作者被禁止或删除 内容自动屏蔽
unpack 发表于 2008-10-24 12:43
首先,OD载入,隐藏OD,忽略所以异常!程序停在:
00454000 >60pushad00454001E8 00000000 call00454006004540065Dpop ebp0045400750pusheax0045400851pushecx

然后下断点:HE VirtualProtect
然后shift+f9运行~注意堆栈变化
当第一次出现下面堆栈显示情况的时候就停下:
001294F8 00ACC27C/CALL 到 VirtualProtect 来自 00ACC276001294FC 0040200C|Address = UnPackMe.0040200C00129500 00000160|Size = 160 (352.)00129504 00000004|NewProtect = PAGE_READWRITE00129508 0012C0D0\pOldProtect = 0012C0D00012950C 00ADFA9800129510 7C9210EDntdll.RtlLeaveCriticalSection
直到我们看到SIZE的大小小于1000,且NewProtect为PAGE_READWRITE
一共用了七次
我们就可以取消断点,然后ALT+F9返回,此时是停在:
7C801AD0 >8BFFmov edi, edi ; //停在这儿,取消断点,alt+f9返回7C801AD255pushebp7C801AD38BECmov ebp, esp7C801AD5FF75 14 pushdword ptr [ebp+14]7C801AD8FF75 10 pushdword ptr [ebp+10]7C801ADBFF75 0C pushdword ptr [ebp+C]7C801ADEFF75 08 pushdword ptr [ebp+8]7C801AE16A FF push-17C801AE3E8 75FFFFFF callVirtualProtectEx7C801AE85Dpop ebp7C801AE9C2 1000 retn10

然后返回
00ACC27550pusheax00ACC276FF15 1861AD00 call[AD6118] ; kernel32.VirtualProtect00ACC27C6A 14 push14 ; //返回到这儿00ACC27EE8 DB8F0000 call00AD525E ; jmp 到 msvcrt.operator new00ACC28359pop ecx00ACC2848985 A8ABFFFF mov [ebp+FFFFABA8], eax00ACC28A83BD A8ABFFFF 0>cmp dword ptr [ebp+FFFFABA8], 000ACC29174 58 jeshort 00ACC2EB

然后右键----查找命令-----PUSH 100,不要勾选整个块
00ACC4D668 00010000 push10000ACC4DB8D85 58C1FFFF lea eax, [ebp-3EA8]00ACC4E150pusheax00ACC4E28B85 58C2FFFF mov eax, [ebp-3DA8]00ACC4E8FF30pushdword ptr [eax]00ACC4EAE8 A961FDFF call00AA2698 ; //这个call跟随进入ENTER00ACC4EF83C4 0C add esp, 0C

进入来到
00AA269855pushebp00AA26998BECmov ebp, esp00AA269B51pushecx00AA269CA1 30ECAD00 mov eax, [ADEC30]00AA26A153pushebx
然后找到一个大循环的一个跳转
00AA26E93BD6cmp edx, esi00AA26EB8BF8mov edi, eax00AA26ED73 14 jnb short 00AA2703 ; //这个就是魔法跳了,改成JUMP00AA26EF8B45 08 mov eax, [ebp+8]00AA26F28A18mov bl, [eax]00AA26F4321Fxor bl, [edi]00AA26F647inc edi00AA26F740inc eax00AA26F884DBtestbl, bl00AA26FA8819mov [ecx], bl00AA26FC74 05 jeshort 00AA270300AA26FE41inc ecx00AA26FF3BCEcmp ecx, esi00AA2701^ 72 EF jbshort 00AA26F200AA27038BC1mov eax, ecx00AA27055Fpop edi
改成魔法跳后,我们就可以下断
00AA26EB8BF8mov edi, eax00AA26EDEB 14 jmp short 00AA2703 ; //这个就是魔法跳了,改成JUMP00AA26EF8B45 08 mov eax, [ebp+8]00AA26F28A18mov bl, [eax]

然后在命令行下断:bp CreateThread,SHIFT+F9运行,停在
7C810657 >8BFFmov edi, edi7C81065955pushebp7C81065A8BECmov ebp, esp7C81065CFF75 1C pushdword ptr [ebp+1C]7C81065FFF75 18 pushdword ptr [ebp+18]7C810662FF75 14 pushdword ptr [ebp+14]7C810665FF75 10 pushdword ptr [ebp+10]7C810668FF75 0C pushdword ptr [ebp+C]7C81066BFF75 08 pushdword ptr [ebp+8]7C81066E6A FF push-17C810670E8 D7FDFFFF callCreateRemoteThread7C8106755Dpop ebp7C810676C2 1800 retn18
然后取消断点,alt+f9返回来到
00ABC51E50pusheax; //返回来到这儿,f8一直单步走00ABC51FFF15 4C62AD00 call[AD624C] ; kernel32.CloseHandle00ABC5255Fpop edi00ABC5265Epop esi00ABC527C9leave00ABC528C3retn
然后就会来到这个地方
00ACF9E22BCAsub ecx, edx ; //到下句的时候就要F7到OEP了00ACF9E4FFD1callecx; UnPackMe.0040170000ACF9E68945 E4 mov [ebp-1C], eax00ACF9E98B45 E4 mov eax, [ebp-1C]00ACF9EC8B4D F0 mov ecx, [ebp-10]

注意一定要用F7,否则就跑飞了
0040170055pushebp; //OEP004017018BECmov ebp, esp004017036A FF push-10040170568 00254000 push004025000040170A68 86184000 push00401886 ; jmp 到 msvcrt._except_handler30040170F64:A1 00000000mov eax, fs:[0]0040171550pusheax0040171664:8925 00000000mov fs:[0], esp0040171D83EC 68 sub esp, 680040172053pushebx0040172156pushesi0040172257pushedi004017238965 E8 mov [ebp-18], esp0040172633DBxor ebx, ebx00401728895D FC mov [ebp-4], ebx0040172B6A 02 push20040172DFF15 90214000 call[402190] ; msvcrt.__set_app_type
这就到了OEP了,这个就是vc++的程序了,但是用LordPE脱壳,用ImpREC修复的时候,还有六个指针,剪切掉,就可以运行了,但是PEiD查得为伪装的,其实也不是,好像是那个壳跟vc++的特征码差不多导致了,可以用FI等查查程序编写的语言就可以知道了



下面说说魔法跳的分析

按照上面的脱壳方法,不找IAT加密的地方的话,也就是先HE VirtualProtect七次,取消断点,然后下BP CreateThread断点,然后取消断点,alt+f9返回,一路F9到call ecx处,F7进入,用LordPE脱壳,用ImpREC修复的话,有七个无效,用等级一修复的话还是无效的,根本不能运行,也不能剪切掉,这时因为第一个函数是有效的,下面分析下这几个无效函数的地方
000020000000200800002168000021B0000021B8000021E0000021E8
在分析的时候都加上00400000

首先,根据跟踪得到,这个程序我暂且说成是五个函数库吧!!!!
kernel32.dllmfc42.dllmsvcrt.dllshell32.dlluser32.dll
这五个库的函数分别存在不同的连续的地址中,而这五个函数不可能连着一起的,所以要分割开,所以就会有函数见他们分开,而这些函数就是上面七个地址中的后面六个了

可以来看看数据窗口的信息

重新载入程序,跟随下 dd 00402000,可以看到此时数据窗口显示
0040200000000000004020040000000000402008000000000040200C00000000
注意看第二列的变化,按照正常的脱壳程序开始下HE VirtualProtect,SHIFT+F9 运行四次就有变化,为了下面叙述方便,直接7次,取消断点返回
00ACC276FF15 1861AD00 call[AD6118] ; kernel32.VirtualProtect00ACC27C6A 14 push14 ; //返回到这儿00ACC27EE8 DB8F0000 call00AD525E ; jmp 到 msvcrt.operator new00ACC28359pop ecx00ACC2848985 A8ABFFFF mov [ebp+FFFFABA8], eax
信息窗口显示的是
0040200000002908004020040000291C00402008000000000040200C80001186
其余的几个可以看看
004021648000062800402168000000000040216C00002856004021AC0000284E004021B000000000004021B4000029CE004021B800000000004021BC00002982004021DC00002948004021E000000000004021E400000000004021E800401000UnPackMe.00401000
可以看到基本上都是00000000在第二列的时候就是分割的地方了,但是004021E8也是无效的,且第二列的也不是全是0,但是感觉这个跟内存中经常说的00401000一样吧,估计是程序开始运行的内存地址段的开始了吧,这个不太清楚,但是可以清楚知道004021E0和004021E4都是00000000,也就是说程序到这两个地址的时候,都把函数重系统给入这个程序的相应地址了,所以下面的也就没有必要给入函数了吧~

这样分析后,再来看看程序给入函数的程序应该是mfc42.dll---msvcrt.dll---kernel32.dll---shell32.dll---user32.dll
后面的两个没有具体跟踪,可以先看看第一个dll库吧
00ACC39E0FB785 64C2FFFF movzx eax, word ptr [ebp-3D9C] ; //似乎是可以从数据窗口看到第二列的值给了eax比较00ACC3A585C0testeax, eax ; //如果等于零,表示用来分割函数库的,也就要跳00ACC3A774 6E jeshort 00ACC417 ; //也就是如果要修复函数的地址不是分割函数就不跳
00ACC3D90FB685 70CAFFFF movzx eax, byte ptr [ebp-3590] ; //这个就是给FF给eax了00ACC3E03D FF000000 cmp eax, 0FF ; //上面不跳,就给eax==FF了00ACC3E575 10 jnz short 00ACC3F7 ; //不跳00ACC3E766:8B85 71CAFFFFmov ax, [ebp-358F]00ACC3EE66:8985 6CCAFFFFmov [ebp-3594], ax00ACC3F5EB 20 jmp short 00ACC417
00ACC41E0FB785 6CCAFFFF movzx eax, word ptr [ebp-3594] ; //?给入一个值,好像是山脉那个地方给的,忘记似乎是获得的一个值00ACC42585C0testeax, eax ; //所以要是分割函数的话,下面就会跳00ACC42774 6C jeshort 00ACC495 ; //也就是如果要修复函数的地址不是分割函数就不跳00ACC42983BD 9CD4FFFF 00cmp dword ptr [ebp-2B64], 000ACC43074 51 jeshort 00ACC483 ; //跳
这不清楚这两个地址如何获得值,没有细跟,没有多大关系
00ACC48940inc eax00ACC48A8985 A8D4FFFF mov [ebp-2B58], eax00ACC490E9 D0000000 jmp 00ACC565
00ACC56583BD 68CAFFFF 00cmp dword ptr [ebp-3598], 000ACC56C75 42 jnz short 00ACC5B0 ; //不跳00ACC56E0FB785 6CCAFFFF movzx eax, word ptr [ebp-3594]00ACC57585C0testeax, eax00ACC57774 0F jeshort 00ACC588 ; //不跳00ACC5790FB785 6CCAFFFF movzx eax, word ptr [ebp-3594]00ACC5808985 D8A8FFFF mov [ebp+FFFFA8D8], eax00ACC586EB 0C jmp short 00ACC594
这个有一样了
00ACC59CFFB5 A0D4FFFF pushdword ptr [ebp-2B60] ; MFC42.#148900ACC5A2E8 6DA0FEFF call00AB6614 ; //获得函数了00ACC5A783C4 0C add esp, 0C00ACC5AA8985 68CAFFFF mov [ebp-3598], eax; MFC42.#4486_CWinApp::OnDDECommand00ACC5B083BD 68CAFFFF 00cmp dword ptr [ebp-3598], 000ACC5B775 42 jnz short 00ACC5FB ; //应为EAX有函数,所以不为零,就跳了
开始获取第一个dll库的函数了
00ACC5FB83BD 68CAFFFF 00cmp dword ptr [ebp-3598], 000ACC6020F85 99000000 jnz 00ACC6A1 ; //也跳了00ACC6A18B85 10D9FFFF mov eax, [ebp-26F0]; UnPackMe.0040200C00ACC6A73B85 64D9FFFF cmp eax, [ebp-269C]; //上面一句是把要传递函数的地址给eax,比较地址是否小于FFFFFFFF00ACC6AD73 1D jnb short 00ACC6CC ; //不跳00ACC6AF8B85 10D9FFFF mov eax, [ebp-26F0]; UnPackMe.0040200C00ACC6B58B8D 68CAFFFF mov ecx, [ebp-3598]; MFC42.#4486_CWinApp::OnDDECommand00ACC6BB8908mov [eax], ecx ; MFC42.#4486_CWinApp::OnDDECommand00ACC6BD8B85 10D9FFFF mov eax, [ebp-26F0]; UnPackMe.0040200C00ACC6C383C0 04 add eax, 4 ; //然后地址+4,开始下一个函数的传送了00ACC6C68985 10D9FFFF mov [ebp-26F0], eax; UnPackMe.0040201000ACC6CC^ E9 4DFCFFFF jmp 00ACC31E
这个地方不是我们的MAGIC JUMP,因为函数读取的地方不同,

下面分析了这个后,来到dd 004021AC

跟随下,因为经过分析了,就不分析其他的第二个的dll库,跟第一个相像,只是有一两个跳不要而已

然后下断点 hw 004012AC

shift+f9运行,停在
00ACC6BD8B85 10D9FFFF mov eax, [ebp-26F0]; UnPackMe.004021AC00ACC6C383C0 04 add eax, 4 ; //然后地址+4,开始下一个函数的传送了00ACC6C68985 10D9FFFF mov [ebp-26F0], eax00ACC6CC^ E9 4DFCFFFF jmp 00ACC31E
此时数据窗口显示
004021A477BF27FAmsvcrt.__CxxFrameHandler004021A877C0084Dmsvcrt._setmbcp004021AC77C09E9Amsvcrt._exit004021B000000000
然后再F8单步跟下
00ACC39E0FB785 64C2FFFF movzx eax, word ptr [ebp-3D9C] 00ACC3A585C0testeax, eax00ACC3A774 6E jeshort 00ACC417
因为004021B0是00000000,所以这些都跳了
00ACC427 /74 6C jeshort 00ACC49500ACC49E /0F84 8A000000 je00ACC52E00ACC52E8D8D 38D9FFFF lea ecx, [ebp-26C8]00ACC534E8 074BFDFF call00AA1040 ; //这个获得值给eax,而不是FF了00ACC5390FB6C0movzx eax, al00ACC5428B85 10D9FFFF mov eax, [ebp-26F0]; //给地址给eax了
信息窗口显示

堆栈 ss:[0012C554]=004021B0 (UnPackMe.004021B0)
eax=0000000B

然后接着走

00ACC560 /E9 6C010000 jmp 00ACC6D1

这个跳跳过了获取函数的地方

00ACC5A2E8 6DA0FEFF call00AB6614 ; //获得函数了

也就是说004032B0没有函数的了
00ACC6CC^\E9 4DFCFFFF jmp 00ACC31E00ACC6D1FF15 7C62AD00 call[AD627C] ; kernel32.GetTickCount
跳过了给地址函数的循环了
00ACC788E8 C58A0000 call00AD5252 ; jmp 到 msvcrt.operator delete00ACC78D59pop ecx00ACC78E^ E9 30F7FFFF jmp 00ACBEC3
这个跳返回去,开始下个dll的获取了
00ACBEC36A 01 push100ACBEC558pop eax00ACBEC685C0testeax, eax00ACBEC80F84 C5080000 je00ACC793
从这儿开始单步跟踪就要开始小心一点慢慢跟踪了,因为此时是00402000开始出现函数了
00ACBED48985 84D3FFFF mov [ebp-2C7C], eax00ACBEDA6A 00 push000ACBEDCFFB5 84D9FFFF pushdword ptr [ebp-267C]00ACBEE2FF15 1463AD00 call[AD6314] ; msvcrt.strchr
从寄存器和信息窗口显示这次是

堆栈 ss:[0012C5C8]=00CA14C1, (ASCII "KERNEL32.dll")

这个dll库,上面分析应该没有错了
00ACBF5EE8 05B5FEFF call00AB746800ACBF638985 A0D4FFFF mov [ebp-2B60], eax; kernel32.7C80000000ACBF6983BD A0D4FFFF 00cmp dword ptr [ebp-2B60], 000ACBF70 /0F85 9F000000 jnz 00ACC015

堆栈 ss:[0012C0E4]=7C800000 (kernel32.7C800000)

从信息窗口得到这个是要跳的了
00ACC01583BD A0D4FFFF 00cmp dword ptr [ebp-2B60], 000ACC01C75 58 jnz short 00ACC076
一样
00ACC076FFB5 A0D4FFFF pushdword ptr [ebp-2B60] ; kernel32.7C80000000ACC07CE8 DB9CFEFF call00AB5D5C00ACC08159pop ecx; kernel32.7C800000
继续走
00ACC08E8985 F0A9FFFF mov [ebp+FFFFA9F0], eax; UnPackMe.0040000000ACC0948B85 A0D4FFFF mov eax, [ebp-2B60]; kernel32.7C80000000ACC09A3B85 F0A9FFFF cmp eax, [ebp+FFFFA9F0]; UnPackMe.0040000000ACC0A0 /75 0F jnz short 00ACC0B1

不明白,似乎是内存的地址哦

中间跳过了
00ACC3D90FB685 70CAFFFF movzx eax, byte ptr [ebp-3590] ; //这个时候给eax不是FF了00ACC3E03D FF000000 cmp eax, 0FF ; 00ACC3E575 10 jnz short 00ACC3F7 ; //跳00ACC4028D85 70CAFFFF lea eax, [ebp-3590]; //这里开始给函数,出现在EAX中了00ACC40850pusheax00ACC4098D85 68C2FFFF lea eax, [ebp-3D98]00ACC40F50pusheax; //下面的call 进入还是获取函数给eax了,因为这个压栈了00ACC410E8 D58E0000 call00AD52EA ; jmp 到 msvcrt.strcpy00ACC41559pop ecx; 0012AEAC00ACC41659pop ecx; 0012B6B4


堆栈地址=0012AEAC
eax=0012B6B4, (ASCII "GetModuleHandleA")
00ACC41783A5 68CAFFFF 00and dword ptr [ebp-3598], 000ACC41E0FB785 6CCAFFFF movzx eax, word ptr [ebp-3594] ; 00ACC42585C0testeax, eax ; 00ACC42774 6C jeshort 00ACC495
;

这个地方又不一样了,
这里的[]中的值在这个库的时候发生了变化,这个跳也就跳了
00ACC4950FBE85 68C2FFFF movsx eax, byte ptr [ebp-3D98]00ACC49C85C0testeax, eax00ACC49E0F84 8A000000 je00ACC52E; //不跳00ACC4A483BD 9CD4FFFF 00cmp dword ptr [ebp-2B64], 000ACC4AB74 72 jeshort 00ACC51F; //不跳00ACC4AD8B85 9CD4FFFF mov eax, [ebp-2B64]00ACC4B38985 58C2FFFF mov [ebp-3DA8], eax00ACC4B9EB 0F jmp short 00ACC4CA00ACC4BB8B85 58C2FFFF mov eax, [ebp-3DA8]00ACC4C183C0 0C add eax, 0C00ACC4C48985 58C2FFFF mov [ebp-3DA8], eax00ACC4CA8B85 58C2FFFF mov eax, [ebp-3DA8]00ACC4D08378 08 00cmp dword ptr [eax+8], 000ACC4D474 49 jeshort 00ACC51F; //不跳00ACC4D668 00010000 push10000ACC4DB8D85 58C1FFFF lea eax, [ebp-3EA8]00ACC4E150pusheax00ACC4E28B85 58C2FFFF mov eax, [ebp-3DA8]00ACC4E8FF30pushdword ptr [eax]00ACC4EAE8 A961FDFF call00AA2698; //这个call跟随进入ENTER00ACC4EF83C4 0C add esp, 0C ; //这个call过后,就会是寄存器中的函数变化了,成了EXITPROCESS00ACC4F28D85 58C1FFFF lea eax, [ebp-3EA8]00ACC4F850pusheax00ACC4F98D85 68C2FFFF lea eax, [ebp-3D98]00ACC4FF50pusheax00ACC500FF15 8C63AD00 call[AD638C]; msvcrt._stricmp00ACC50659pop ecx00ACC50759pop ecx00ACC50885C0testeax, eax00ACC50A75 11 jnz short 00ACC51D00ACC50C8B85 58C2FFFF mov eax, [ebp-3DA8]00ACC5128B40 08 mov eax, [eax+8]00ACC5158985 68CAFFFF mov [ebp-3598], eax00ACC51BEB 02 jmp short 00ACC51F00ACC51D^ EB 9C jmp short 00ACC4BB
看来那个call加密了哦
00AA269855pushebp00AA26998BECmov ebp, esp00AA269B51pushecx00AA269CA1 30ECAD00 mov eax, [ADEC30]00AA26A153pushebx00AA26A256pushesi00AA26A357pushedi00AA26A485C0testeax, eax00AA26A675 37 jnz short 00AA26DF00AA26A868 00010000 push10000AA26ADC745 FC 227014FCmov dword ptr [ebp-4], FC14702200AA26B4E8 A52B0300 call00AD525E; jmp 到 msvcrt.operator new00AA26B98DB0 00010000 lea esi, [eax+100]00AA26BF59pop ecx00AA26C03BC6cmp eax, esi00AA26C2A3 30ECAD00 mov [ADEC30], eax00AA26C78BF8mov edi, eax00AA26C973 14 jnb short 00AA26DF00AA26CB8D4D FC lea ecx, [ebp-4]00AA26CEE8 6DE9FFFF call00AA104000AA26D38807mov [edi], al00AA26D547inc edi00AA26D63BFEcmp edi, esi00AA26D8^ 72 F1 jbshort 00AA26CB00AA26DAA1 30ECAD00 mov eax, [ADEC30]00AA26DF8B55 0C mov edx, [ebp+C]00AA26E28B75 10 mov esi, [ebp+10]00AA26E503F2add esi, edx00AA26E78BCAmov ecx, edx00AA26E93BD6cmp edx, esi00AA26EB8BF8mov edi, eax00AA26ED73 14 jnb short 00AA2703; //这个就是魔法跳了,改成JUMP00AA26EF8B45 08 mov eax, [ebp+8]00AA26F28A18mov bl, [eax]00AA26F4321Fxor bl, [edi]00AA26F647inc edi00AA26F740inc eax00AA26F884DBtestbl, bl00AA26FA8819mov [ecx], bl00AA26FC74 05 jeshort 00AA270300AA26FE41inc ecx00AA26FF3BCEcmp ecx, esi00AA2701^ 72 EF jbshort 00AA26F2 ;//这个循环就是开始加密了,ecx不断减去一,然后和esi比较,00AA27038BC1mov eax, ecx00AA27055Fpop edi00AA27062BC6sub eax, esi00AA27085Epop esi00AA2709F7D8neg eax00AA270B1BC0sbb eax, eax00AA270D5Bpop ebx00AA270E23C2and eax, edx00AA2710C9leave00AA2711C3retn00AA27128BC1mov eax, ecx00AA2714C3retn
魔法跳找到了也就可以用此方法来脱壳了 关键找call上面的push 1000
然后ENTER 进入就可找到关键点就OK了
既然这个call是加密的call,我们直接跳过吧~~~
00ACC4D08378 08 00cmp dword ptr [eax+8], 000ACC4D474 49 jeshort 00ACC51F ; //不跳00ACC4D668 00010000 push100
这个跳就跳过那个加密call了,所以也可以认为这个跳是魔法跳,然后跳下去后
00ACC59CFFB5 A0D4FFFF pushdword ptr [ebp-2B60]00ACC5A2E8 6DA0FEFF call00AB6614 ; //获得函数了00ACC5A783C4 0C add esp, 0C
再次到这儿获取函数给地址了~~但是经过试验,这样是不行的,因为函数在这段中还要读取一些东西,具体什么不知道,反正如果这样的话,就会跳向终止了~~~

这个call加密后,然后会给EAX一个加密函数,然后在
00ACC4FF50pusheax; //下面的比较是否eax有函数00ACC500FF15 8C63AD00 call[AD638C] ; msvcrt._stricmp00ACC50659pop ecx00ACC50759pop ecx00ACC50885C0testeax, eax00ACC50A /75 11 jnz short 00ACC51D00ACC50C |8B85 58C2FFFF mov eax, [ebp-3DA8]00ACC512 |8B40 08 mov eax, [eax+8]00ACC515 |8985 68CAFFFF mov [ebp-3598], eax00ACC51B |EB 02 jmp short 00ACC51F00ACC51D^\EB 9C jmp short 00ACC4BB

然后就比较eax了

一个jmp一直循环知道
00ACC4D08378 08 00cmp dword ptr [eax+8], 000ACC4D474 49 jeshort 00ACC51F ; //不跳
[eax+8]==0
可以在这个跳下个条件断点,省去大量跟踪了~~~~


这个MAGIC JUMP就分析到这儿,由于是个小菜,所以很多地方并没有讲清楚,那个call如何加密,没有细跟,知道,那个jnb循环处一直在计算,所以跳过就行了


【总结】这个程序脱壳的大致流程是,先隐藏OD,然后下断点 he VirtualProtect断点,shift+f9运行七次,知道第一在堆栈窗口看到 SIZE的大小小于1000,且NewProtect为PAGE_READWRITE,然后就取消断点,alt+f9返回,搜索命令:push 100,找到它下面的call,enter跟入进去,然后在段首直接RETN改了(既然下面循环是加密,直接返回也一样了),或者搜索上面分析的那个magic jump了~~,然后在下断点 bp CreateThread,shift+f9运行,然后alt+f9返回,一直单步,知道出现 call ecx或者其他的EAX什么的时候F7进入就到OEP了
脱壳后,用FI查得为vc++的程序写的~~~

最后用LordPE进行删除无效区段,.text1、.adata、.data1、.pdata这四个区段,然后重建一下PE,查壳大小,只有18K了,也到的了减肥程序的目的!

1_.rar
 楼主| 小生我怕怕 发表于 2008-10-24 13:53
首先忽略OD异常选项的所有异常
00454000 >60pushad//OD载入程序
00454001E8 00000000 call UnPackMe.00454006//在命令行下断 BP VirtualProtect
004540065Dpop ebp //下好断点后shift+f9运行程序
0045400750push eax
0045400851push ecx
004540090FCAbswap edx
0045400BF7D2not edx
━━━━━━━━━━━━━━━━━━━━━━━━━━
7C801AD0 >8BFFmov edi,edi//中断后取消断点
7C801AD255push ebp //在命令行下断 BP CreateFileMappingA
7C801AD38BECmov ebp,esp//下好断点后shift+f9运行程序
7C801AD5FF75 14 push dword ptr ss:[ebp+14]
7C801AD8FF75 10 push dword ptr ss:[ebp+10]
7C801ADBFF75 0C push dword ptr ss:[ebp+C]
━━━━━━━━━━━━━━━━━━━━━━━━━━
7C80945C >8BFFmov edi,edi; kernel32.CreateFileMappingA
7C80945E55push ebp //中断后取消断点
7C80945F8BECmov ebp,esp//ctrl+G查找 GetModuleHandleA
7C80946151push ecx
7C80946251push ecx
7C80946356push esi
━━━━━━━━━━━━━━━━━━━━━━━━━━
7C80B6A1 >8BFFmov edi,edi//查找到了这里
7C80B6A355push ebp
7C80B6A48BECmov ebp,esp
7C80B6A6837D 08 00cmp dword ptr ss:[ebp+8],0
7C80B6AA74 18 je short kernel32.7C80B6C4
7C80B6ACFF75 08 push dword ptr ss:[ebp+8]
7C80B6AFE8 C0290000 call kernel32.7C80E074
7C80B6B485C0test eax,eax
7C80B6B674 08 je short kernel32.7C80B6C0
7C80B6B8FF70 04 push dword ptr ds:[eax+4]
7C80B6BBE8 7D2D0000 call kernel32.GetModuleHandleW
7C80B6C05Dpop ebp
7C80B6C1C2 0400 retn 4 //在retn处下断以防止程序检测断点
7C80B6C464:A1 18000000mov eax,dword ptr fs:[18]//程序停在retn处后注意堆栈窗口
7C80B6CA8B40 30 mov eax,dword ptr ds:[eax+30]
━━━━━━━━━━━━━━━━━━━━━━━━━━
以下为堆栈窗口的变化
第一次中断后堆栈如下:
我们在一次shift+f9运行程序
00129500 00AC7105返回到 00AC7105 来自 kernel32.GetModuleHandleA
00129504 00ADBC1CASCII "kernel32.dll"
00129508 00ADCEC4ASCII "VirtualAlloc"
0012950C 00ADFA98
00129510 7C9210EDntdll.RtlLeaveCriticalSection
━━━━━━━━━━━━━━━━━━━━━━━━━━
第二次中断后堆栈如下:
我们在一次shift+f9运行程序
00129500 00AC7122返回到 00AC7122 来自 kernel32.GetModuleHandleA
00129504 00ADBC1CASCII "kernel32.dll"
00129508 00ADCEB8ASCII "VirtualFree"
0012950C 00ADFA98
00129510 7C9210EDntdll.RtlLeaveCriticalSection
━━━━━━━━━━━━━━━━━━━━━━━━━━
第三次中断后堆栈如下:
00129264 00AB5FC9返回到 00AB5FC9 来自 kernel32.GetModuleHandleA
00129268 001293B4ASCII "kernel32.dll"
0012926C 00000000
00129270 EC440000
00129274 95A50012
━━━━━━━━━━━━━━━━━━━━━━━━━━
7C80B6BBE8 7D2D0000 call kernel32.GetModuleHandleW
7C80B6C05Dpop ebp
7C80B6C1C2 0400 retn 4//取消在retn处下的断点
7C80B6C464:A1 18000000mov eax,dword ptr fs:[18] //取消断点我们F7跟进到程序调用
7C80B6CA8B40 30 mov eax,dword ptr ds:[eax+30]
7C80B6CD8B40 08 mov eax,dword ptr ds:[eax+8]
━━━━━━━━━━━━━━━━━━━━━━━━━━
00AB5FC98B0D AC40AE00 mov ecx,dword ptr ds:[AE40AC] //返回到了这里
00AB5FCF89040Emov dword ptr ds:[esi+ecx],eax
00AB5FD2A1 AC40AE00 mov eax,dword ptr ds:[AE40AC]
00AB5FD7391C06cmp dword ptr ds:[esi+eax],ebx
00AB5FDA75 16 jnz short 00AB5FF2
00AB5FDC8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C]
00AB5FE250push eax
00AB5FE3FF15 BC62AD00 call dword ptr ds:[AD62BC] ; kernel32.LoadLibraryA
00AB5FE98B0D AC40AE00 mov ecx,dword ptr ds:[AE40AC]
00AB5FEF89040Emov dword ptr ds:[esi+ecx],eax
00AB5FF2A1 AC40AE00 mov eax,dword ptr ds:[AE40AC]
00AB5FF7391C06cmp dword ptr ds:[esi+eax],ebx //此magic jump是建立在上面分析过程中的
00AB5FFA0F84 2F010000 je 00AB612F//这里就是我们的magic jump
00AB600033C9xor ecx,ecx//把上面的je改jmp
00AB60028B07mov eax,dword ptr ds:[edi] //修改后把程序向下拉
00AB60043918cmp dword ptr ds:[eax],ebx
00AB600674 06 je short 00AB600E
━━━━━━━━━━━━━━━━━━━━━━━━━━
00AB613B395F FC cmp dword ptr ds:[edi-4],ebx //拉到这里后我们注意
00AB613E^ 0F85 49FEFFFF jnz 00AB5F8D //这个JNZ继续跳回去的
00AB6144EB 03 jmp short 00AB6149 //而这个jmp是向下跳,即跳出我们的加密
00AB6146D6salc //在上面的jmpF2设断,shift+f9运行程序
00AB6147D6salc //程序停下后,我们向上在拉回去找到我们修改后的指令,把他撤消修改,防止程序检测完整
00AB61488F???//还原后我们命令行下断 BP CreateThread
00AB61498B0D 6C8FAE00 mov ecx,dword ptr ds:[AE8F6C]//下好断点后我们shift+f9运行程序
00AB614F3BCBcmp ecx,ebx
━━━━━━━━━━━━━━━━━━━━━━━━━━
7C810637 >8BFFmov edi,edi//我们运行到了这里,取消断点
7C81063955push ebp //断点取消后,我们ait+f9返回到用户代码
7C81063A8BECmov ebp,esp
7C81063CFF75 1C push dword ptr ss:[ebp+1C]
7C81063FFF75 18 push dword ptr ss:[ebp+18]
7C810642FF75 14 push dword ptr ss:[ebp+14]
━━━━━━━━━━━━━━━━━━━━━━━━━━
00ABC51E50push eax//我们返回到了这里
00ABC51FFF15 4C62AD00 call dword ptr ds:[AD624C] ; kernel32.CloseHandle
00ABC5255Fpop edi //开始继续F8直接奔向我们的OEP
00ABC5265Epop esi
00ABC527C9leave
00ABC528C3retn//通过retn返回到下一段
00ABC52955push ebp
━━━━━━━━━━━━━━━━━━━━━━━━━━
00ACF8DD59pop ecx //返回到了这里后我们开始F8走吧
00ACF8DEBE 98FAAD00 mov esi,0ADFA98
00ACF8E38BCEmov ecx,esi
00ACF8E5E8 1693FDFF call 00AA8C00
00ACF8EA84C0test al,al
00ACF8EC75 09 jnz short 00ACF8F7
━━━━━━━━━━━━━━━━━━━━━━━━━━
00ACF9DF3350 1C xor edx,dword ptr ds:[eax+1C]
00ACF9E22BCAsub ecx,edx//到了这里时注意啦
00ACF9E4FFD1call ecx //这个CALL要F7跟进就到我们的OEP啦
00ACF9E68945 E4 mov dword ptr ss:[ebp-1C],eax//因为ecx此时的值正是我们的OEP,大家注意寄存器窗口
00ACF9E98B45 E4 mov eax,dword ptr ss:[ebp-1C]
━━━━━━━━━━━━━━━━━━━━━━━━━━
EAX 00464398 UnPackMe.00464398
ECX 00401700 UnPackMe.00401700 //此时ecx就是我们的oep的值
EDX 1B2B5480
EBX 00001000
ESP 0012F6FC
EBP 0012F774
ESI 00401000 UnPackMe.00401000
EDI 0046AEA0 UnPackMe.0046AEA0
EIP 00ACF9E4
━━━━━━━━━━━━━━━━━━━━━━━━━━
0040170055push ebp//运行lordPE把程序dump
004017018BECmov ebp,esp //在用importRCE修复时发现有6个无效,不管他剪切掉
004017036A FF push -1 //剪切掉后全部有效,直接抓取文件既可
0040170568 00254000 push UnPackMe.00402500
0040170A68 86184000 push UnPackMe.00401886 ; jmp to msvcrt._except_handler3
0040170F64:A1 00000000mov eax,dword ptr fs:[0]
0040171550push eax
0040171664:8925 0000000>mov dword ptr fs:[0],esp
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

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

GMT+8, 2024-4-25 19:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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