吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 15759|回复: 20
收起左侧

[原创] 吾爱破解脱壳练习----ACProtector系列保护

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

12.本期看点:需要注意熟悉语言入口特征,及代码分析,对编写语言要有一定的认识,从教程中吸收套路,贯通使用



公告:
由于前期让大家对此壳有了一定的了解,所以本期大家只需要去了解如何还原本混淆后的OEP


紧急通知:
由于凌晨0点时发的版本,经过测试难度过底,经过我测试3个多小时后,由凌晨3.44分改发,请昨天下载的朋友从新下载,对次给你带来的不便仅以在此说声抱歉,谢谢合作

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

UnPackMe.rar

107 KB, 下载次数: 519, 下载积分: 吾爱币 -1 CB

免费评分

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

查看全部评分

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

 楼主| 小生我怕怕 发表于 2008-10-20 04:24
OD设置除内存访问外的所有异常,并隐藏好OD
━━━━━━━━━━━━━━━━━━━━━━━━━━
00409000 >60pushad //OD载入
00409001E8 01000000 call UnPackMe.00409007 //我们F9直接运行
00409006- 73 83 jnb short UnPackMe.00408F8B
00409008C40485 F546E801 les eax,fword ptr ds:[eax*4+1E846F5]
0040900F0000add byte ptr ds:[eax],al
━━━━━━━━━━━━━━━━━━━━━━━━━━
0041A74DCD 01 int 1 //程序停在这里
0041A74F40inc eax //由于个人版本OD不一样所以有些朋友OD不一定是一次停下,可多试几次
0041A75040inc eax //停下后我们注意堆栈窗口
0041A7510BC0or eax,eax
0041A75375 05 jnz short UnPackMe.0041A75A
0041A75590nop
━━━━━━━━━━━━━━━━━━━━━━━━━━
0012FF78 0012FFE0指针到下一个 SEH 记录
0012FF7C 0041A731SE 句柄 //我们在此SE句柄处,右键--数据窗口中跟随
0012FF80 00000001
0012FF84 00000035
━━━━━━━━━━━━━━━━━━━━━━━━━━
0041A7310C245C8B//此时我们是停在了这里
0041A73500B88383//我们在上面一句右键---断点---内存访问
0041A73933020000//下好断后我们shift+f9运行程序
0041A73D6764C3C0
0041A741000036FF
━━━━━━━━━━━━━━━━━━━━━━━━━━
0041A7318B5C24 0C mov ebx,dword ptr ss:[esp+C]//我们程序停在这里,此时F2设置访问中断
0041A7358383 B8000000 0>add dword ptr ds:[ebx+B8],2 //设置好断点后我们shift+f9运行程序
0041A73C33C0xor eax,eax
0041A73EC3retn
0041A73F64:67:FF36 0000 push dword ptr fs:[0]
0041A74564:67:8926 0000 mov dword ptr fs:[0],esp
0041A74B33C0xor eax,eax
━━━━━━━━━━━━━━━━━━━━━━━━━━
0041A7818B048Emov eax,dword ptr ds:[esi+ecx*4] //程序停在这里,此时F2设置访问中断
0041A7848B5C8E 04 mov ebx,dword ptr ds:[esi+ecx*4+4]//设置好断点后我们shift+f9运行程序
0041A78833C3xor eax,ebx
0041A78AC1C8 02 ror eax,2
━━━━━━━━━━━━━━━━━━━━━━━━━━
0041A79589048Emov dword ptr ds:[esi+ecx*4],eax//程序停在了这里,此时我们取消我们的断点
0041A79849dec ecx //我们右键--断点--清除内存访问断点
0041A799^ EB E1 jmp short UnPackMe.0041A77C //ait+b把我们的两个普通断点也取消
0041A79B61popad //断点清除后,在retn句执行F4运行到所选
0041A79C61popad
0041A79DC3retn//在这里执行F4运行到所选
0041A79E0000add byte ptr ds:[eax],al//我们ait+m打开内存镜像
0041A7A00000add byte ptr ds:[eax],al
━━━━━━━━━━━━━━━━━━━━━━━━━━
内存映射,项目 22//在此设置F2访问中断
地址=00401000
大小=00003000 (12288.)//断点设置好后,我们shift+f9运行程序
物主=UnPackMe 00400000
区段=.text
包含=code
类型=Imag 01001002
访问=R
初始访问=RWE
━━━━━━━━━━━━━━━━━━━━━━━━━━
004011A4- E9 846E0000 jmp UnPackMe.0040802D//此时我们停在了我们的OEP处
004011A9CCint3 //很明显OEP是被混淆了的
004011AACCint3 //我们单步开始寻找我们的OEP值
004011ABCCint3 //由于程序是VB写的,所以我们只要找到一个PUSH就可以啦
004011ACCCint3
004011ADCCint3
004011AE0000add byte ptr ds:[eax],al
004011B00000add byte ptr ds:[eax],al
━━━━━━━━━━━━━━━━━━━━━━━━━━
0040802D68 88804000 push UnPackMe.00408088 //单步之后我们到了这里
00408032E8 2DEBFFFF call UnPackMe.00406B64 //到这个CALL时我们F8直接让程序跑飞
0040803787AB 7794B488 xchg dword ptr ds:[ebx+88B49477],ebp //同时我们注意堆栈窗口
0040803DA4movs byte ptr es:[edi],byte ptr ds:[esi]//这个数字是在不知道飞了多少次之后才发现的
0040803E98cwde//每次程序起飞都会读取到他
0040803FA8 9C test al,9C
0040804184B0 ACBC9018 test byte ptr ds:[eax+1890BCAC],dh
━━━━━━━━━━━━━━━━━━━━━━━━━━
0012FFC0 00402D40UnPackMe.00402D40 //这里就是我们的PUSH 00402D40
0012FFC4 7C816FD7返回到 kernel32.7C816FD7//我们把程序从新载入OD
0012FFC8 7C930738ntdll.7C930738
0012FFCC FFFFFFFF
0012FFD0 7FFDA000
━━━━━━━━━━━━━━━━━━━━━━━━━━
下面开始我们的正规脱壳啦,上面只是为了寻找到我们的OEP的前奏,而此时我们的OEP
是已经找到的啦,所以就可以开始我们的后续步骤啦
━━━━━━━━━━━━━━━━━━━━━━━━━━
00409000 >60pushad //程序从载后
00409001E8 01000000 call UnPackMe.00409007 //我们F9直接运行
00409006- 73 83 jnb short UnPackMe.00408F8B
00409008C40485 F546E801 les eax,fword ptr ds:[eax*4+1E846F5]
0040900F0000add byte ptr ds:[eax],al
━━━━━━━━━━━━━━━━━━━━━━━━━━
0041A74DCD 01 int 1 //程序停在这里
0041A74F40inc eax //由于个人版本OD不一样所以有些朋友OD不一定是一次停下,可多试几次
0041A75040inc eax //停下后我们注意堆栈窗口
0041A7510BC0or eax,eax
0041A75375 05 jnz short UnPackMe.0041A75A
0041A75590nop
━━━━━━━━━━━━━━━━━━━━━━━━━━
0012FF78 0012FFE0指针到下一个 SEH 记录
0012FF7C 0041A731SE 句柄 //我们在此SE句柄处,右键--数据窗口中跟随
0012FF80 00000001
0012FF84 00000035
━━━━━━━━━━━━━━━━━━━━━━━━━━
0041A7310C245C8B//此时我们是停在了这里
0041A73500B88383//我们在上面一句右键---断点---内存访问
0041A73933020000//下好断后我们shift+f9运行程序
0041A73D6764C3C0
0041A741000036FF
━━━━━━━━━━━━━━━━━━━━━━━━━━
0041A7318B5C24 0C mov ebx,dword ptr ss:[esp+C]//我们程序停在这里,此时F2设置访问中断
0041A7358383 B8000000 0>add dword ptr ds:[ebx+B8],2 //设置好断点后我们shift+f9运行程序
0041A73C33C0xor eax,eax
0041A73EC3retn
0041A73F64:67:FF36 0000 push dword ptr fs:[0]
0041A74564:67:8926 0000 mov dword ptr fs:[0],esp
0041A74B33C0xor eax,eax
━━━━━━━━━━━━━━━━━━━━━━━━━━
0041A7818B048Emov eax,dword ptr ds:[esi+ecx*4] //程序停在这里,此时F2设置访问中断
0041A7848B5C8E 04 mov ebx,dword ptr ds:[esi+ecx*4+4]//设置好断点后我们shift+f9运行程序
0041A78833C3xor eax,ebx
0041A78AC1C8 02 ror eax,2
━━━━━━━━━━━━━━━━━━━━━━━━━━
0041A79589048Emov dword ptr ds:[esi+ecx*4],eax//程序停在了这里,此时我们取消我们的断点
0041A79849dec ecx //我们右键--断点--清除内存访问断点
0041A799^ EB E1 jmp short UnPackMe.0041A77C //ait+b把我们的两个普通断点也取消
0041A79B61popad //断点清除后,在retn句执行F4运行到所选
0041A79C61popad
0041A79DC3retn//在这里执行F4运行到所选
0041A79E0000add byte ptr ds:[eax],al//我们ait+m打开内存镜像
0041A7A00000add byte ptr ds:[eax],al
━━━━━━━━━━━━━━━━━━━━━━━━━━
内存映射,项目 22//在此设置F2访问中断
地址=00401000
大小=00003000 (12288.)//断点设置好后,我们shift+f9运行程序
物主=UnPackMe 00400000
区段=.text
包含=code
类型=Imag 01001002
访问=R
初始访问=RWE
━━━━━━━━━━━━━━━━━━━━━━━━━━
00401192- FF25 30104000 jmp dword ptr ds:[401030]; MSVBVM60.EVENT_SINK_AddRef
00401198- FF25 3C104000 jmp dword ptr ds:[40103C]; MSVBVM60.EVENT_SINK_Release
0040119E- FF25 78104000 jmp dword ptr ds:[401078]; MSVBVM60.ThunRTMain
004011A4- E9 846E0000 jmp UnPackMe.0040802D //把这里改为PUSH 00402D40
004011A9CCint3//这里改CALL 0040119E
004011AACCint3//对VB入口了解的人都应该知道的VB在被抽OEP的情况下我们只需要找PUSH就好
004011ABCCint3//改好后直接把程序DUMP,修复既可
004011ACCCint3
004011ADCCint3
004011AE0000add byte ptr ds:[eax],al

dumped_.rar

37 KB, 下载次数: 10, 下载积分: 吾爱币 -1 CB

yunfeng 发表于 2008-10-20 06:59
是不是跟我的系统有关,常用的方法在我这里行不通了,只好旁门左道了
先运行UnPackMe.exe,打开OD,附加-选中要附加的进程UnPackMe.exe,载入
7C92120FC3retn
7C9212108BFFmov edi,edi
7C921212 >CCint3
7C921213C3retn
ATL+F9返回
7C92E4F4 >C3retn
7C92E4F58DA424 00000000 lea esp,dword ptr ss:[esp]
7C92E4FC8D6424 00 lea esp,dword ptr ss:[esp]
7C92E500 >8D5424 08 lea edx,dword ptr ss:[esp+8]
7C92E504CD 2E int 2E

我们到右下角窗口看一看有没有好的发现
往下拖,看到了这里有一处值得怀疑
0012FFA8 0012FFE0指向下一个 SEH 记录的指针
0012FFAC 7347BAFDSE处理程序
0012FFB0 733A97D0MSVBVM60.733A97D0
0012FFB4 00000000
0012FFB8 0012FFF0
0012FFBC 00408079UnPackMe.00408079 ----->这里是什么??
0012FFC0 00402D40UnPackMe.00402D40 ------>这里又会是什么???
在00408079右键反汇编窗口中跟随
004080680Edb 0E
0040806955db 55;CHAR 'U'
0040806AAE114000dd UnPackMe.004011AE
0040806E2Cdb 2C;CHAR ','
0040806F30db 30;CHAR '0'
0040807004db 04
004080711Cdb 1C
0040807228db 28;CHAR '('
0040807318db 18
0040807424db 24;CHAR '$'
0040807508db 08
0040807634db 34;CHAR '4'
0040807714db 14
0040807875db 75;CHAR 'u'
0040807968db 68;CHAR 'h'
0040807A3A804000dd UnPackMe.0040803A
在004011ae跟随
0040118C- FF25 44104000 jmp dword ptr ds:[401044]; MSVBVM60.EVENT_SINK_QueryInterface
00401192- FF25 30104000 jmp dword ptr ds:[401030]; MSVBVM60.EVENT_SINK_AddRef
00401198- FF25 3C104000 jmp dword ptr ds:[40103C]; MSVBVM60.EVENT_SINK_Release
0040119E- FF25 78104000 jmp dword ptr ds:[401078]; MSVBVM60.ThunRTMain
004011A4- E9 846E0000 jmp UnPackMe.0040802D
004011A9CCint3
004011AACCint3
004011ABCCint3
004011ACCCint3
004011ADCCint3
这里被偷了代码,熟悉VB的都知道开头代码不是这样的
我们来到上面提到怀疑的地方在00402D40
右键点击数据窗口跟随
00402D4056 42 35 21 1C 23 76 62 36 63 68 73 2E 64 6C 6CVB5!#vb6chs.dll ,这不是我们被偷窃的代码吗?
我们去看一看代码
00402D4056db 56;CHAR 'V'
00402D4142db 42;CHAR 'B'
00402D4235db 35;CHAR '5'
00402D4321db 21;CHAR '!'
00402D441Cdb 1C
00402D45 .23 76 62 36 6>ascii "#vb6chs.dll",0
00402D5100db 00
00402D5200db 00
00402D5300db 00
原来就在这里,被偷窃的代码都找到了
004011A468 402D4000 push UnPackMe.00402D40
004011A9E8 F0FFFFFF call UnPackMe.0040119E ; jmp 到 MSVBVM60.ThunRTMain
004011AE0000add byte ptr ds:[eax],al
004011B00000add byte ptr ds:[eax],al
004011B20000add byte ptr ds:[eax],al
004011B43000xor byte ptr ds:[eax],al
004011B60000add byte ptr ds:[eax],al
004011B83800cmp byte ptr ds:[eax],al
004011BA0000add byte ptr ds:[eax],al
004011BC0000add byte ptr ds:[eax],al
在004011a4 此处新建EIP
到这里还没有结束
我们重新载入
00409000 >60pushad
00409001E8 01000000 call UnPackMe.00409007
00409006- 73 83 jnb short UnPackMe.00408F8B
00409008C40485 F546E801 les eax,fword ptr ds:[eax*4+1E846F5]
0040900F0000add byte ptr ds:[eax],al
0040901100E8add al,ch
0040901383C4 04 add esp,4
004090160F88 03000000 js UnPackMe.0040901F
ALT+M打开内存镜像
在data段下F2内存断点
F9 运行
断下后,我们CTRL+G 直接输入004011A4
把004011A468 402D4000 push UnPackMe.00402D40
004011A9E8 F0FFFFFF call UnPackMe.0040119E
这两处补丁
并在004011a4 处新建EIP
用LODEPE把程序DUMP出来,最后再用ImportREC修复一下填入11A4,没有无效指针
保存一下,脱壳完毕.运行一下,正常。只有38K

ddddddd_.rar

38 KB, 下载次数: 2, 下载积分: 吾爱币 -1 CB

pcfans 发表于 2008-10-20 10:35
脱壳过程:

脱壳方法:内存镜像法

OD载入程序,忽略所有异常,alt+m,在地址为0406000的.vmp0段,下f2断点F9运行

Memory map, 项目 25
地址=00406000
大小=00003000 (12288.)
属主=UnPackMe 00400000
区段=.vmp0
包含=代码
类型=映像 01001002
访问=R
初始访问=RWE

-----------------------

0040802D 68 88804000 PUSH UnPackMe.00408088;断下后程序挺在这里
00408032 E8 2DEBFFFF CALL UnPackMe.00406B64
00408037 87AB 7794B488 XCHG DWORD PTR DS:[EBX+88B49477],EBP
0040803D A4 MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
0040803E 98 CWDE
0040803F A8 9C TEST AL,9C
00408041 84B0 ACBC9018 TEST BYTE PTR DS:[EAX+1890BCAC],DH
00408047 24 08 AND AL,8
00408049 1C FC SBB AL,0FC
0040804B 14 66 ADC AL,66
0040804D ^ 7E 90 JLE SHORT UnPackMe.00407FDF
-----------------------
再一次alt+m,在地址为00401000的.text段,下f2断点F9运行

Memory map, 项目 23
地址=00401000
大小=00003000 (12288.)
属主=UnPackMe 00400000
区段=.text
包含=代码
类型=映像 01001002
访问=R
初始访问=RWE

-----------------------
程序再次断下后,来到很接近OEP的一个地址,称之为伪OEP吧

0040119E - FF25 78104000 JMP DWORD PTR DS:[401078] ; 伪OEP
004011A4 - E9 846E0000 JMP UnPackMe.0040802D;这是真正OEP的地址,代码被抽取掉了
004011A9 CC INT3
004011AA CC INT3
004011AB CC INT3
004011AC CC INT3
004011AD CC INT3
004011AE 0000 ADD BYTE PTR DS:[EAX],AL
004011B0 0000 ADD BYTE PTR DS:[EAX],AL

-----------------------

找个VB程序对比一下,就会发现,程序的两行代码被抽取了,我们就找回这两行吧

首先我们要知道VB程序的OEP的入口特征
push xxxxxxxxx ;关键是找这个地址
call yyyyyyyyy ;这行的地址是固定的,一般call到MSVBVM60.ThunRTMain这个函数
-----------------------

怎么样找回这个地址呢,很简单,我们知道push的作用是压栈,既然是压栈,那么push

的地址肯定是放在堆栈里了,从我们的这个程序看,内存镜像法后,程序运行到的地址

正好是入口call到的的地址,那么call的地址就很明显了yyyyyyyyy地址就是0040119E这

个刚才伪OEP的地址,那么反推,程序已经运行到了call地址了,那么push xxxxx的地址

应该已经在堆栈里了,来看下堆栈情况。

----------------------
堆栈情况:
0013FFBC 00408079 UnPackMe.00408079
0013FFC0 00402D40 UnPackMe.00402D40 ;这个00402D40就是我要找的push的地址
0013FFC4 7C816FD7 返回到 kernel32.7C816FD7
0013FFC8 7C930738 ntdll.7C930738

-----------------------

到这里,我们就找齐了两句被抽取的代码了
push 00402D40
call0040119E
-----------------------
还等什么把他们004011A4处填回去吧,完成的效果:

0040119E - FF25 78104000 JMP DWORD PTR DS:[401078] ;原伪OEP
004011A4 68 402D4000 PUSH UnPackMe.00402D40;在此新建EIP,真正的OEP
004011A9 E8 F0FFFFFF CALL UnPackMe.0040119E
004011AE 0000 ADD BYTE PTR DS:[EAX],AL
004011B0 0000 ADD BYTE PTR DS:[EAX],AL
004011B2 0000 ADD BYTE PTR DS:[EAX],AL

-----------------------

接下来都是大家最拿手的了,LoadPE dump,ImprotREC修复,OEP填写11A4,获取输入表

,全部有效,抓取程序,运行正常,功能完好,脱壳完毕了,哈哈
小糊涂虫 发表于 2008-10-20 12:38
来到OEP的方法和上期一样的..所以就不复制代码了..
来到假OEP处....
我来讲一下我自己的方法.......
因为这个程序是VB写的...VB程度开头一般都是
PUSH XXXXXX至于找这句嘛......
CALLXXXXXX相信这句都不难找.....就是OEP上面那个JMP地址.

右键分析代码...
然后CTRL+b 查找 56 42 35 21
00402D3F00db 00
00402D4056db 56;CHAR 'V'这里就是了...
00402D4142db 42;CHAR 'B'
00402D4235db 35;CHAR '5'
00402D4321db 21;CHAR '!'
00402D441Cdb 1C
00402D45 .23 76 62 36 6>ascii "#vb6chs.dll",0
00402D5100db 00


00401192- FF25 30104000 jmp dword ptr ds:[401030]; MSVBVM60.EVENT_SINK_AddRef
00401198- FF25 3C104000 jmp dword ptr ds:[40103C]; MSVBVM60.EVENT_SINK_Release
0040119E- FF25 78104000 jmp dword ptr ds:[401078]; MSVBVM60.ThunRTMain
004011A468 402D4000 push UnPackMe.00402D40这样修改好后,脱壳......修复...OK
004011A9E8 F0FFFFFF call UnPackMe.0040119E ; jmp 到
004011AE0000add byte ptr ds:[eax],al
004011B00000add byte ptr ds:[eax],al
004011B20000add byte ptr ds:[eax],al

关于查找56 42 35 21 还不知道是不是通用的...反正这期是搞定的.自己加壳的也是可以的....
dongmin20023 发表于 2008-10-20 13:40
OD载入目标程序
OD设置不忽略内存访问异常,
00409000 >60pushad 载入后停在这里
00409001E8 01000000 call UnPackMe.00409007
00409006- 73 83 jnb short UnPackMe.00408F8B
00409008C40485 F546E801 les eax,fword ptr ds:[eax*4+1E846F5]
0040900F0000add byte ptr ds:[eax],al
0040901100E8add al,ch
0040901383C4 04 add esp,4
004090160F88 03000000 js UnPackMe.0040901F
0040901C66:13DF adc bx,di
0040901FE8 01000000 call UnPackMe.00409025
004090247A 83 jpe short UnPackMe.00408FA9

隐藏下OD,F9运行,看堆栈
0012FF78 0012FFE0指针到下一个 SEH 记录
0012FF7C 0041A731SE 句柄 //注意这里SE 句柄
0012FF80 00000001
0012FF84 0000003A
0012FF88 00004F62

在汇编窗口CTRL+G 输入0041A731
在0041731右键设置内存访问断点,SHIFT+F9运行
0041A7318B5C24 0C mov ebx,dword ptr ss:[esp+C]
0041A7358383 B8000000 0>add dword ptr ds:[ebx+B8],2
0041A73C33C0xor eax,eax
0041A73EC3retn
0041A73F64:67:FF36 0000 push dword ptr fs:[0]
0041A74564:67:8926 0000 mov dword ptr fs:[0],esp
0041A74B33C0xor eax,eax

在0041731 F2下断,SHIFT+F9运行
0041A7818B048Emov eax,dword ptr ds:[esi+ecx*4]
0041A7848B5C8E 04 mov ebx,dword ptr ds:[esi+ecx*4+4]
0041A78833C3xor eax,ebx
0041A78AC1C8 02 ror eax,2
0041A78D2BC2sub eax,edx
0041A78F81F2 CC5F1FD5 xor edx,D51F5FCC
0041A79589048Emov dword ptr ds:[esi+ecx*4],eax

在0041A781 F2下断,SHIFT+F9运行

0041A79589048Emov dword ptr ds:[esi+ecx*4],eax
0041A79849dec ecx
0041A799^ EB E1 jmp short UnPackMe.0041A77C
0041A79B61popad
0041A79C61popad
0041A79DC3retn

取消断点和内存断点后,在0041A79D  F4运行到这里
ALT+M 在CODE段下断,在SHIFT+F9运行
内存映射,项目 23
地址=00401000
大小=00003000 (12288.)
物主=UnPackMe 00400000
区段=.text
包含=code
类型=Imag 01001002
访问=R
初始访问=RWE

到了这里,这里就是OEP了,记下OEP入口地址 004011A4
004011A4- E9 846E0000 jmp UnPackMe.0040802D
004011A9CCint3
004011AACCint3
004011ABCCint3
004011ACCCint3
004011ADCCint3
004011AE0000add byte ptr [eax], al
004011B00000add byte ptr [eax], al
004011B20000add byte ptr [eax], al
004011B43000xor byte ptr [eax], al

往上看看
0040118C- FF25 44104000 jmp dword ptr [401044] ; MSVBVM60.EVENT_SINK_QueryInterface
00401192- FF25 30104000 jmp dword ptr [401030] ; MSVBVM60.EVENT_SINK_AddRef
00401198- FF25 3C104000 jmp dword ptr [40103C] ; MSVBVM60.EVENT_SINK_Release
0040119E- FF25 78104000 jmp dword ptr [401078] ; MSVBVM60.ThunRTMain
004011A4- E9 846E0000 jmp UnPackMe.0040802D

看到这0040119E- FF25 78104000 jmp dword ptr [401078] ; MSVBVM60.ThunRTMain应该知道是VB的程序,典型的VB入口,但是在我们这里下面是被抽了代码

下面找被抽的代码
大家都知道,VB的入口是
Microsoft Visual Basic 5.0 / 6.0

00401166- FF25 6C104000 JMP DWORD PTR DS:[<&MSVBVM60.#100>]; MSVBVM60.ThunRTMain
0040116C >68 147C4000 PUSH PACKME.00407C14
00401171E8 F0FFFFFF CALL <JMP.&MSVBVM60.#100>
004011760000ADD BYTE PTR DS:[EAX],AL
004011780000ADD BYTE PTR DS:[EAX],AL
0040117A0000ADD BYTE PTR DS:[EAX],AL
0040117C3000XOR BYTE PTR DS:[EAX],AL

或省略第一行的JMP

00401FBC >68 D0D44000push dumped_.0040D4D0
00401FC1E8 EEFFFFFFcall <jmp.&msvbvm60.ThunRTMain>
00401FC60000 add byte ptr ds:[eax],al
00401FC80000 add byte ptr ds:[eax],al
00401FCA0000 add byte ptr ds:[eax],al
00401FCC3000 xor byte ptr ds:[eax],al
00401FCE0000 add byte ptr ds:[eax],al
这里有一个这样的方法,找到VB程序的这一句入口,
JMP DWORD PTR DS:[<&MSVBVM60.#100>]; MSVBVM60.ThunRTMain
在这个JUMP下断,在我这里是找到OEP上句就是了0040119E
F2在0040119E下断,SHIFT+F9运行,注意堆栈窗口
0012FFBC 00408079UnPackMe.00408079
0012FFC0 00402D40UnPackMe.00402D40
0012FFC4 7C816FF7返回到 kernel32.7C816FF7

我特意找了几个VB的程序看看它的入口特征,发现在堆栈窗口里的
"返回到 kernel32.7C816FF7" 这句的上一句就是push的地址,在这里的是00402d40
在堆栈窗口中的00402d40处点右键-数据窗口中跟随
用十六进制查看
00402D4056 42 35 21 1C 23 76 62 36 63 68 73 2E 64 6C 6CVB5!#vb6chs.dll
看到没有,被push的地址是VB5!#vb6chs.dll
感觉有点投机取巧,但是我查看了N个VB程序用了这种方法都可以找到被抽的字节
这应该算是一种规律吧
CTRL+G 输入 004011A4 回车,
回到原来的OEP入口,把下面的NOP掉
004011A4- E9 846E0000 jmp UnPackMe.0040802D
004011A9CCint3
004011AACCint3
004011ABCCint3
004011ACCCint3
004011ADCCint3

依次填上
push 00402D40
call0040119E

代码补回来了
004011A468 402D4000 pushUnPackMe.00402D40
004011A9E8 F0FFFFFF callUnPackMe.0040119E; jmp 到 MSVBVM60.ThunRTMain
004011AE0000add byte ptr [eax], al
004011B00000add byte ptr [eax], al
004011B20000add byte ptr [eax], al
004011B43000xor byte ptr [eax], al

取消所有断点后,用LOADPE把程序dump出来,ImportRec修复,OEP填上11A4 修复后,收工




UnPackMe16脱文与附件.rar
傻人有傻福 发表于 2008-10-20 14:37
00406000 >60PUSHAD ; OD载入到这里
0040600185D1TEST ECX,EDX
0040600342INC EDX
00406004D3EDSHR EBP,CL
00406006FCCLD
0040600771 01 JNO SHORT 0040600A ; UnPackMe.0040600A

异常设置里除了KERNEL32的那个异常保留外 其他的全部不忽略SHIFT+F9 2次

0040F5D890NOP;一次异常到这里
0040F5D964:67:8F06 0000 POP DWORD PTR FS:[0]
0040F5DF83C4 04 ADD ESP,4
0040F5E260PUSHAD
0040F5E3E8 00000000 CALL 0040F5E8; UnPackMe.0040F5E8

0040F386CD 01 INT 1;一次异常到这里
0040F38840INC EAX
0040F38940INC EAX
0040F38A0BC0OR EAX,EAX
0040F38C75 05 JNZ SHORT 0040F393 ; UnPackMe.0040F393
0040F38E90NOP

ALT+M在CODE段下段SHIFT+F9来到这里
0040119E- FF25 78104000 JMP DWORD PTR DS:[401078]; (Initial CPU
selection)(显示如下DS:[00401078]=7339DE3E (MSVBVM60.ThunRTMain))
004011A40EPUSH CS
004011A5C079 6E FCSAR BYTE PTR DS:[ECX+6E],0FC ; Shift constant out
of range 1..31
004011A973 1E JNB SHORT 004011C9 ; UnPackMe.004011C9
004011ABA5MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES>
004011AC37AAA
004011AD0100ADD DWORD PTR DS:[EAX],EAX
004011AF0000ADD BYTE PTR DS:[EAX],AL
004011B10000ADD BYTE PTR DS:[EAX],AL
004011B30030ADD BYTE PTR DS:[EAX],DH
004011B50000ADD BYTE PTR DS:[EAX],AL
004011B70038ADD BYTE PTR DS:[EAX],BH
004011B90000ADD BYTE PTR DS:[EAX],AL
004011BB0000ADD BYTE PTR DS:[EAX],AL
004011BD0000ADD BYTE PTR DS:[EAX],AL
004011BF001EADD BYTE PTR DS:[ESI],BL

这样看来是VB的程序,而且OEP被抽取了,VB的程序头是这样的
PUSH XXXXX
CALL (MSVBVM60.ThunRTMain)的地址
MSVBVM60.ThunRTMain的地址就是上面的0040119E- FF25 78104000 JMP DWORD PTR DS:[401078]
第一句PUSH的地址到堆栈中看一下:
0012FFBC 004156C0RETURN to UnPackMe.004156C0 from UnPackMe.0040119E
0012FFC0 00402D40UnPackMe.00402D40 ;要的就是这个
0012FFC4 7C816FD7RETURN to kernel32.7C816FD7

所以Stolen Code就是这样的
PUSH 00402D40
CALL 0040119E
代码从004011A4这里开始改起 改完之后在这里新建EIP,用LORDPE脱出来,IMPORTREC修复的时候指针是
全部有效的,转存修复一下程序是可以运行的。

说明一下:上面2个异常出现的顺序不一定,如果2次异常后在CODE下段没法直接到伪OEP的话再一次在
CODE段下段应该就可以到了。
wesley 发表于 2008-10-20 15:00
到OEP还跟上期一样就不多说了
到达被VM的OEP
0040119E- FF25 78104000 jmp dword ptr ds:[401078] ; MSVBVM60.ThunRTMain
004011A4- E9 846E0000 jmp UnPackMe.0040802D <<==OEP
004011A9CCint3
004011AACCint3
004011ABCCint3
004011ACCCint3
004011ADCCint3
004011AE0000add byte ptr ds:[eax],al
004011B00000add byte ptr ds:[eax],al
004011B20000add byte ptr ds:[eax],al
004011B43000xor byte ptr ds:[eax],al

单步3次
发现程序跑飞 此时堆栈窗口为
0012FFC0 00402D40UnPackMe.00402D40 对面的女孩看过来。。,,,[s:43]
0012FFC4 7C817067返回到 kernel32.7C817067
0012FFC8 7C800065ASCII "run in DOS mode.",CR,CR,LF,"$"

由于目标是VB程序
找个VB的对比一下不难发现开头只被VM了两句
push xxx
call xxx


程序跑飞时

堆栈中压入的是00402D40
OK 分析完毕

被VM的是
push 00402D40
call 0040119E
nv21 发表于 2008-10-20 15:42
首先OD载入看看哪个异常可以利用
试验证明 可以利用内存异常 忽略内存以外的所有异常~!F9运行

00406000 >60pushad
0040600185D1test ecx,edx
0040600342inc edx
00406004D3EDshr ebp,cl
00406006FCcld
0040600771 01 jno short UnPackMe.0040600A
00406009F9stc
0040600A87EAxchg edx,ebp
0040600C85F5test ebp,esi
0040600EF8clc
0040600FBE 407421D5 mov esi,D5217440
004060148BD8mov ebx,eax
0040601645inc ebp
0040601746inc esi
00406018F9stc
0040601981F6 D95B153C xor esi,3C155BD9

忽略内存以外的所有异常~!F9运行到这里
0040F386CD 01 int 1
0040F38840inc eax
0040F38940inc eax
0040F38A0BC0or eax,eax
0040F38C75 05 jnz short UnPackMe.0040F393
0040F38E90nop
0040F38F90nop
0040F39090nop
0040F39190nop
0040F39261popad
0040F39333C0xor eax,eax
0040F39564:8F00 pop dword ptr fs:[eax]
0040F39858pop eax
0040F39960pushad
0040F39AE8 00000000 call UnPackMe.0040F39F

打开内存境像
Memory map, 项目 22
地址=00401000F2下断SHIFT+F9运行
大小=00003000 (12288.)
属主=UnPackMe 00400000
区段=.text
包含=代码
类型=映像 01001002
访问=R
初始访问=RWE
00401180- FF25 7C104000 jmp dword ptr ds:[40107C]; MSVBVM60.__vbaStrToAnsi
00401186- FF25 18104000 jmp dword ptr ds:[401018]; MSVBVM60.__vbaHresultCheckObj
0040118C- FF25 44104000 jmp dword ptr ds:[401044]; MSVBVM60.EVENT_SINK_QueryInterface
00401192- FF25 30104000 jmp dword ptr ds:[401030]; MSVBVM60.EVENT_SINK_AddRef
00401198- FF25 3C104000 jmp dword ptr ds:[40103C]; MSVBVM60.EVENT_SINK_Release
0040119E- FF25 78104000 jmp dword ptr ds:[401078]; MSVBVM60.ThunRTMain////////停在这里看一下典型的VB入口
004011A40Epush cs
004011A5C079 6E FCsar byte ptr ds:[ecx+6E],0FC
004011A973 1E jnb short UnPackMe.004011C9
004011ABA5movs dword ptr es:[edi],dword ptr ds:[es>
004011AC37aaa
004011AD0100add dword ptr ds:[eax],eax
004011AF0000add byte ptr ds:[eax],al

接下来还原入口当然找到PUSH----------
此时看堆栈 向下找

0012FFBC 004156C0返回到 UnPackMe.004156C0 来自 UnPackMe.0040119E
0012FFC0 00402D40UnPackMe.00402D40---------------PUSH 的内容
0012FFC4 7C817067返回到 kernel32.7C817067

然后改入口
在伪OEP下面 修改代码
004011A468 402D4000 push UnPackMe.00402D40
004011A9E8 F0FFFFFF call UnPackMe.0040119E ; jmp 到 MSVBVM60.ThunRTMain

在004011A4 新建EIP
然后LORDPE 脱壳 REC修复 正常运行~!!!
jyxer 发表于 2008-10-20 18:41
先将程序运行,OD附加,探探敌情!!
7C92120FC3retn//停在这里,Alt+F9
7C9212108BFFmov edi,edi
7C921212 >CCint3
7C921213C3retn
————————————————————
7C92E4F4 >C3retn//停在这里
7C92E4F58DA424 00000000 lea esp,dword ptr ss:[esp]
7C92E4FC8D6424 00 lea esp,dword ptr ss:[esp]
7C92E500 >8D5424 08 lea edx,dword ptr ss:[esp+8]
7C92E504CD 2E int 2E
7C92E506C3retn
看堆栈,往下翻知道这里
0012FFA8 0012FFE0指针到下一个 SEH 记录
0012FFAC 7347BAFDSE 句柄
0012FFB0 733A97D0MSVBVM60.733A97D0
0012FFB4 00000000
0012FFB8 0012FFF0
0012FFBC 00408079UnPackMe.00408079
0012FFC0 00402D40UnPackMe.00402D40//记下这个值00402D40,等下修复代码要用!!
0012FFC4 7C817067返回到 kernel32.7C817067
关掉OD
正式开工::
忽略所有异常(内存异常除外)
隐藏OD
载入OD
00409000 >60pushad//载入后停在这里,记下ESP值:0012ffc4,后面有用
00409001E8 01000000 call UnPackMe.00409007
00409006- 73 83 jnb short UnPackMe.00408F8B
00409008C40485 F546E801 les eax,fword ptr ds:[eax*4+1E846F5]
0040900F0000add byte ptr ds:[eax],al
——————————————
F9运行
0041A74DCD 01 int 1//停在这里,看堆栈
0041A74F40inc eax
0041A75040inc eax
0041A7510BC0or eax,eax
0041A75375 05 jnz short UnPackMe.0041A75A
0041A75590nop
0041A75690nop
0041A75790nop
堆栈:
0012FF78 0012FFE0指针到下一个 SEH 记录
0012FF7C 0041A731SE 句柄//右键-》在数据中跟随
0012FF80 0041FDABUnPackMe.0041FDAB
0012FF84 01770376
0012FF88 DD7AEF4F
0012FF8C 0012FFA0
0012FF90 80000000
数据窗口
0041A7310C245C8B//右键-》断点-》内存访问
0041A73500B88383
0041A73933020000
0041A73D6764C3C0
0041A741000036FF
0041A74526896764
0041A749C0330000
0041A74D404001CD
——————————
shift+F9
0041A7318B5C24 0C mov ebx,dword ptr ss:[esp+C]//停在这里,F2,shift+F9
0041A7358383 B8000000 0>add dword ptr ds:[ebx+B8],2
0041A73C33C0xor eax,eax
0041A73EC3retn
0041A73F64:67:FF36 0000 push dword ptr fs:[0]
0041A74564:67:8926 0000 mov dword ptr fs:[0],esp
0041A74B33C0xor eax,eax
0041A74DCD 01 int 1
0041A74F40inc eax
0041A75040inc eax
————————————————————
0041A7818B048Emov eax,dword ptr ds:[esi+ecx*4]//停在这里,F2,shift+F9
0041A7848B5C8E 04 mov ebx,dword ptr ds:[esi+ecx*4+4]
0041A78833C3xor eax,ebx
0041A78AC1C8 02 ror eax,2
0041A78D2BC2sub eax,edx
0041A78F81F2 CC5F1FD5 xor edx,D51F5FCC
0041A79589048Emov dword ptr ds:[esi+ecx*4],eax////停在这里,取消三个断点
0041A79849dec ecx
0041A799^ EB E1 jmp short UnPackMe.0041A77C
0041A79B61popad
0041A79C61popad
0041A79DC3retn//在这里F4
——————————————
d 0012ffc0
(前面记下的ESP值0012ffc4减去4得到的!!至于原因,呵呵,请高手指点,我只是依葫芦画瓢罢了,本人小菜一个,表见怪!!)
——————————————
0012FFC000000000//右键-》设置硬件访问断点-》DWord,shift+F9
0012FFC47C817067返回到 kernel32.7C817067
0012FFC8005F6964
0012FFCC005F6950
0012FFD07FFD3000
0012FFD48054C6ED
————————————————
00420106 /EB 01 jmp short UnPackMe.00420109//停在这里,F8
00420108 |E8 FF254B01 call 018D270C
0042010D42inc edx
0042010E0060 E8 add byte ptr ds:[eax-18],ah
004201110000add byte ptr ds:[eax],al
004201130000add byte ptr ds:[eax],al

00420109- FF25 4B014200 jmp dword ptr ds:[42014B]; UnPackMe.004011A4//停在这里,F8,到达OEP
0042010F60pushad
00420110E8 00000000 call UnPackMe.00420115

————————————————————————
00401192- FF25 30104000 jmp dword ptr ds:[401030]; MSVBVM60.EVENT_SINK_AddRef
00401198- FF25 3C104000 jmp dword ptr ds:[40103C]; MSVBVM60.EVENT_SINK_Release
0040119E- FF25 78104000 jmp dword ptr ds:[401078]; MSVBVM60.ThunRTMain
004011A4- E9 846E0000 jmp UnPackMe.0040802D//停在这里,看代码的前前后后,知道是VB的程序,给偷了代码
004011A9CCint3
004011AACCint3
004011ABCCint3
004011ACCCint3
004011ADCCint3
004011AE0000add byte ptr ds:[eax],al
004011B00000add byte ptr ds:[eax],al
004011B20000add byte ptr ds:[eax],al
将下面两行代码从004011A4开始填充
0040802D68 88804000 push UnPackMe.00402D40
00408032E8 2DEBFFFF call UnPackMe.0040119E
好了,用LoadPE脱壳,ImportREC修复,指针全部有效,修复,可以运行
PS:晕,中午抽空写好了脱文要上来发的,没想到换了个UnpackMe,难度加大了,那啥,小生是不是要多加点钱咧!!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-12-23 15:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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