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

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 19429|回复: 16
收起左侧

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

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

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


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

UnPackMe自效验.rar

12 KB, 下载次数: 628, 下载积分: 吾爱币 -1 CB

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

pcfans 发表于 2008-10-11 22:29
脱壳过程:

用单步跟踪法

OD载入

0040763A >/$55PUSH EBP;程序入口一路单步f8
0040763B|.8BECMOV EBP,ESP
0040763D|.83EC 64 SUB ESP,64
00407640|.53PUSH EBX
00407641|.56PUSH ESI
00407642|.57PUSH EDI
00407643|.EB 0C JMP SHORT UnPackMe.00407651

………………………………省略N多代码

00407CDB|.6A 00 PUSH 0 ; |Size = 0
00407CDD|.FF75 FC PUSH DWORD PTR SS:[EBP-4]; |Address
00407CE0|.FF15 C0744000 CALL DWORD PTR DS:[<&KERNEL32.VirtualFre>; \VirtualFree
00407CE6|.68 00800000 PUSH 8000; /FreeType = MEM_RELEASE
00407CEB|.6A 00 PUSH 0 ; |Size = 0
00407CED|.FF75 EC PUSH DWORD PTR SS:[EBP-14] ; |Address
00407CF0|.FF15 C0744000 CALL DWORD PTR DS:[<&KERNEL32.VirtualFre>; \VirtualFree
00407CF6|.8B45 C8 MOV EAX,DWORD PTR SS:[EBP-38]
00407CF9|.5FPOP EDI
00407CFA|.5EPOP ESI
00407CFB|.5BPOP EBX
00407CFC|.83C4 64 ADD ESP,64
00407CFF|.5DPOP EBP
00407D00|.- FFE0JMP EAX;单步到这里,一个jmp大跳转,跳向了OEP

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

004012A068 582E4000 PUSH UnPackMe.00402E58;这里就是梦寐以求的OEP了
004012A5E8 F0FFFFFF CALL UnPackMe.0040129A; JMP 到 MSVBVM60.ThunRTMain
004012AA0000ADD BYTE PTR DS:[EAX],AL
004012AC0000ADD BYTE PTR DS:[EAX],AL
004012AE0000ADD BYTE PTR DS:[EAX],AL
004012B03000XOR BYTE PTR DS:[EAX],AL
004012B20000ADD BYTE PTR DS:[EAX],AL
004012B440INC EAX
004012B50000ADD BYTE PTR DS:[EAX],AL

----------------------------------
脱壳修复过程:

LoadPE脱壳,IR修复,指针完好,抓取脱壳文件,脱壳完成,程序点击无反映,既然是自校验的程序那么下面开始破

除这个自校验了:

载入脱壳的程序

004012A0 >68 582E4000 push00402E58 ;停在程序OEP
004012A5E8 F0FFFFFF call<jmp.&msvbvm60.ThunRTMain>
004012AA0000add byte ptr [eax], al
004012AC0000add byte ptr [eax], al
004012AE0000add byte ptr [eax], al
----------------------------------
下__vbaStrCmp断点 这个是程序比较两个字符串的函数,F9运行

733B4813 >FF7424 08 PUSH DWORD PTR SS:[ESP+8];运行后断在这里,F8单步往下跟
733B4817FF7424 08 PUSH DWORD PTR SS:[ESP+8]
733B481B6A 00 PUSH 0
733B481DE8 03000000 CALL msvbvm60.__vbaStrComp
733B4822C2 0800 RETN 8 ;程序跳转返回
733B4825 >837C24 04 02CMP DWORD PTR SS:[ESP+4],2

----------------------------------
上段程序返回,继续F8

00403E5252PUSH EDX
00403E5368 8C384000 PUSH dumped_.0040388C; UNICODE "20081005120830"
00403E58FF15 54104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaStrCm>; msvbvm60.__vbaStrCmp
00403E5EF7D8NEG EAX;返回到这里,向上看看上面发现文件创建日期,估计比较的是这串
00403E601BC0SBB EAX,EAX ;继续f8单步跟踪
00403E62F7D8NEG EAX
00403E6448DEC EAX
00403E658945 E4 MOV DWORD PTR SS:[EBP-1C],EAX
…………………………省略代码N多
00403EC85EPOP ESI
00403EC966:8908 MOV WORD PTR DS:[EAX],CX
00403ECC8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10]
00403ECF33C0XOR EAX,EAX
00403ED164:890D 0000000>MOV DWORD PTR FS:[0],ECX
00403ED85BPOP EBX
00403ED98BE5MOV ESP,EBP
00403EDB5DPOP EBP
00403EDCC2 0800 RETN 8 ;程序单步到这里返回

----------------------------------
来到关键地方了,注意看了这里是第一处的校验,应该是日期型校验

00403F3566:395D E4CMP WORD PTR SS:[EBP-1C],BX ;上段程序返回到这里,将寄存器bx的值与堆栈中的

值进行比较
00403F3975 56 JNZ SHORT dumped_.00403F91;如果不相等就跳转,这里改成je或jmp否则跳过就

死了
00403F3B391D E0524000 CMP DWORD PTR DS:[4052E0],EBX
00403F4175 10 JNZ SHORT dumped_.00403F53
00403F4368 E0524000 PUSH dumped_.004052E0
00403F4868 2C384000 PUSH dumped_.0040382C
00403F4DFF15 8C104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaNew2>>; msvbvm60.__vbaNew2
00403F538B35 E0524000 MOV ESI,DWORD PTR DS:[4052E0]
00403F598D4D E8 LEA ECX,DWORD PTR SS:[EBP-18]
00403F5C57PUSH EDI

----------------------------------
我们继续寻找下一处校验,这次是文件大小的校验,下rtcFileLen断点F9运行

7346E967 >55PUSH EBP ;程序断在这里了,alt+F9返回程序领空去
7346E9688BECMOV EBP,ESP
7346E96A81EC 40010000 SUB ESP,140
7346E9708D85 C0FEFFFF LEA EAX,DWORD PTR SS:[EBP-140]
7346E97650PUSH EAX
7346E977FF75 08 PUSH DWORD PTR SS:[EBP+8]
7346E97AE8 E9000000 CALL msvbvm60.7346EA68
7346E97F85C0TEST EAX,EAX
----------------------------------
alt+F9后程序来到这里,F8单步跟

004044C18D4D D4 LEA ECX,DWORD PTR SS:[EBP-2C] ;程序返回停在这里,F8单步注意看OD的几个窗口
004044C48945 D8 MOV DWORD PTR SS:[EBP-28],EAX ;将eax寄存器中的脱壳后的大小放入堆栈中
004044C7FF15 D8104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaFreeS>; msvbvm60.__vbaFreeStr
004044CD68 1C454000 PUSH dumped_.0040451C
004044D2EB 35 JMP SHORT dumped_.00404509
004044D48D4D C8 LEA ECX,DWORD PTR SS:[EBP-38]
004044D78D55 CC LEA EDX,DWORD PTR SS:[EBP-34]
004044DA51PUSH ECX
004044DB8D45 D0 LEA EAX,DWORD PTR SS:[EBP-30]
004044DE52PUSH EDX
………………………………省略代码N多
004045268B4D F0 MOV ECX,DWORD PTR SS:[EBP-10]
0040452933C0XOR EAX,EAX
0040452B64:890D 0000000>MOV DWORD PTR FS:[0],ECX
004045325BPOP EBX
004045338BE5MOV ESP,EBP
004045355DPOP EBP
00404536C2 0800 RETN 8 ;程序到这里返回

-----------------------------------
这里又返回到了关键代码处

00404295817D E4 C05D000>CMP DWORD PTR SS:[EBP-1C],5DC0 ;将5dc0的大小和脱壳后程序大小进行比较,这

里也可以将5dc0改成大于脱壳的文件大小的数字,注意是16进制的数字
0040429C7E 54 JLE SHORT dumped_.004042F2 ;如果小于等于就跳,这里要改成jge或jmp进行

跳转,如果不跳,程序就自动关闭了。
0040429E391D E0524000 CMP DWORD PTR DS:[4052E0],EBX
004042A475 10 JNZ SHORT dumped_.004042B6
004042A668 E0524000 PUSH dumped_.004052E0
004042AB68 2C384000 PUSH dumped_.0040382C
004042B0FF15 8C104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaNew2>>; msvbvm60.__vbaNew2
004042B68B35 E0524000 MOV ESI,DWORD PTR DS:[4052E0]
004042BC8D4D E8 LEA ECX,DWORD PTR SS:[EBP-18]

特别注意,00404295和0040429C是两种改法,可以任改一处,不可两处都改
-----------------------------------

好了程序改到这里,所有的校验都被去掉了,将修改后的文件保存,试运行,完全成功。程序脱壳去校验完成。
wgz001 发表于 2008-10-11 22:06
今天终于出差回来了 又去那个鬼地方-----上海金山汗没网络我郁闷啊

回来后搞了下自校验的题目 下面说说我的思路:

1.到达OEP用的是ESP定律 到这里
00407D00- FFE0jmp eax; UnPackMe.004012A0
00407D025Fpop edi
00407D035Epop esi
00407D045Bpop ebx
00407D05C9leave

单步F8就来到了OEP
004012A068 582E4000 push UnPackMe.00402E58
004012A5E8 F0FFFFFF call UnPackMe.0040129A ; jmp to MSVBVM60.ThunRTMain
004012AA0000add byte ptr ds:[eax],al
004012AC0000add byte ptr ds:[eax],al
004012AE0000add byte ptr ds:[eax],al

2. 接着就DUMP 修复运行 郁闷没反应(正常哦本来就考察自校验么呵呵)

3.去自校验共有两处

首先下断点 bp __vbaStrCmp来到此处


734793DA msv>FF7424 08push dword ptr ss:[esp+8]
734793DE FF7424 08push dword ptr ss:[esp+8]
734793E2 6A 00push 0
734793E4 E8 44E6FFFFcall msvbvm60.__vbaStrComp

ALT+F9返回到这里

00403E5E F7D8 neg eax
00403E60 1BC0 sbb eax,eax
00403E62 F7D8 neg eax
00403E64 48 dec eax
00403E65 8945 E4mov dword ptr ss:[ebp-1C],eax
00403E68 68 C03E4000push dumped_.00403EC0

接下来单步走到这里

00403F35 66:395D E4 cmp word ptr ss:[ebp-1C],bx
00403F39 75 56jnz short dumped_.00403F91

将此跳转改为JUMP(用两个OD对比下) 并保存文件

运行程序一闪而过 还有校验[s:17]

因为是VB的程序就用VBExplore 查找按钮事件吧可以查看到TIME事件 地址:00404240

OD载入修改后的程序去上面的地址下断点

0040424055push ebp
004042418BECmov ebp,esp
0040424383EC 0C sub esp,0C
0040424668 56114000 push <jmp.&msvbvm60.__vbaExceptHandler>; SE 句柄安装
0040424B64:A1 00000000mov eax,dword ptr fs:[0]
0040425150push eax
0040425264:8925 0000000>mov dword ptr fs:[0],esp

单步往下面走 看到下面一个跳转

00404295817D E4 C05D000>cmp dword ptr ss:[ebp-1C],5DC0
0040429C7E 54 jle short 1.004042F2

可疑(怀疑是大小比较,5DC0=24K)修改成JUMP

可以了 [s:40]

(开始写的时候糊涂了 第一出校验没写不好意思)


个人思路 不正确的地方还请多多指教

OK1223733870528.rar
QQ截图未命名.jpg
 楼主| 小生我怕怕 发表于 2008-10-11 00:49
首先我们来脱壳
0040763A >55push ebp //OD载入
0040763B8BECmov ebp,esp//在此执行ESP定律
0040763D83EC 64 sub esp,64
0040764053push ebx
━━━━━━━━━━━━━━━━━━━━━━━━━━
00407D00- FFE0jmp eax//程序停在这里
00407D025Fpop edi//然后我们单步F8一步就飞向我们OEP
00407D035Epop esi
00407D045Bpop ebx
00407D05C9leave
━━━━━━━━━━━━━━━━━━━━━━━━━━
004012A068 582E4000 push UnPackMe.00402E58//标准的VB入口
004012A5E8 F0FFFFFF call UnPackMe.0040129A//运行lordPE把程序dump,在用importRCE修复
004012AA0000add byte ptr ds:[eax],al
004012AC0000add byte ptr ds:[eax],al
━━━━━━━━━━━━━━━━━━━━━━━━━━
呵呵,运行我们的程序发现鼠标一转,老规矩标题也写名的自效验
好通常朋友们玩自效验方法都是下比较段点,而我今天就用另类一
点的方法去过了这个自效验,从新加载脱壳后的程序
━━━━━━━━━━━━━━━━━━━━━━━━━━
004012A0 > $68 582E4000 push dumped_.00402E58 //程序停在这里
004012A5 .E8 F0FFFFFF call <jmp.&msvbvm60.ThunRTMain> //我们在命令处下段 bpx papa
004012AA .0000add byte ptr ds:[eax],al//此时会打开我们的模块间调用的窗口
004012AC .0000add byte ptr ds:[eax],al
004012AE .0000add byte ptr ds:[eax],al
━━━━━━━━━━━━━━━━━━━━━━━━━━
如下图:
1.JPG

━━━━━━━━━━━━━━━━━━━━━━━━━━
然后我们寻找一个VB函数,.__vbaNew2,右键选择设置每次调用__vbaNew2的断点
然后点一下顶部的目标
如下图:

2.jpg
━━━━━━━━━━━━━━━━━━━━━━━━━━
现在我们会发现一共有7处调用到了这个函数,好我们逐一双击进去看看
00403CC3 .895D 9C mov dword ptr ss:[ebp-64],ebx
00403CC6 .895D 8C mov dword ptr ss:[ebp-74],ebx
00403CC9 .75 10 jnz short dumped_.00403CDB //第一处这个跳转跳过
00403CCB .68 E0524000 push dumped_.004052E0//而很明显他上面没有比较的语句
00403CD0 .68 2C384000 push dumped_.0040382C//所以排除他是的可能性
00403CD5 .FF15 8C104000 call dword ptr ds:[<&msvbvm60.__vbaNew2>>;msvbvm60.__vbaNew2
━━━━━━━━━━━━━━━━━━━━━━━━━━
在一次点回我们的模块间调用,选择第2句
00403D2A > \391D E0524000 cmp dword ptr ds:[4052E0],ebx //这里是第2处
00403D30 .75 10 jnz short dumped_.00403D42//但是很明显他上面就是调用了我们的第一句
00403D32 .68 E0524000 push dumped_.004052E0 //而他的比较是不成立的
00403D37 .68 2C384000 push dumped_.0040382C //通常上下一看即可得出结论
00403D3C .FF15 8C104000 call dword ptr ds:[<&msvbvm60.__vbaNew2>>;msvbvm60.__vbaNew2
00403D42 >8B35 E0524000 mov esi,dword ptr ds:[4052E0]
━━━━━━━━━━━━━━━━━━━━━━━━━━
在一次点回我们的模块间调用,选择第3句
00403F2F .FF92 FC060000 call dword ptr ds:[edx+6FC] //这里是第3处调用
00403F35 .66:395D E4cmp word ptr ss:[ebp-1C],bx //而这句比较是和BX比较,大家都知道我们的寄存器里并无BX这个值,所以可疑
00403F39 .75 56 jnz short dumped_.00403F91//这里即第一处效验,改JMP跳走
00403F3B .391D E0524000 cmp dword ptr ds:[4052E0],ebx //以上比较大家可单步跟踪到此是绝对不会跳的,所以上面必须改JMP
00403F41 .75 10 jnz short dumped_.00403F53
00403F43 .68 E0524000 push dumped_.004052E0
00403F48 .68 2C384000 push dumped_.0040382C
00403F4D .FF15 8C104000 call dword ptr ds:[<&msvbvm60.__vbaNew2>>;msvbvm60.__vbaNew2
00403F53 >8B35 E0524000 mov esi,dword ptr ds:[4052E0]
━━━━━━━━━━━━━━━━━━━━━━━━━━
在一次点回我们的模块间调用,选择第4句
00404022 . /75 4E jnz short dumped_.00404072 //向上看了看,上面的比较语句离得太远,所以排出自效验的可能
00404024 . |3905 E0524000 cmp dword ptr ds:[4052E0],eax//继续寻找我们的第5句吧
0040402A . |75 10 jnz short dumped_.0040403C
0040402C . |68 E0524000 push dumped_.004052E0
00404031 . |68 2C384000 push dumped_.0040382C
00404036 . |FF15 8C104000 call dword ptr ds:[<&msvbvm60.__vbaNew2>>;msvbvm60.__vbaNew2
━━━━━━━━━━━━━━━━━━━━━━━━━━
在一次点回我们的模块间调用,选择第5句
0040428C .895D E4 mov dword ptr ss:[ebp-1C],ebx //我们向下看一下
0040428F .FF92 0C070000 call dword ptr ds:[edx+70C]
00404295 .817D E4 C05D0>cmp dword ptr ss:[ebp-1C],5DC0//这里是比较语句并且是和5DC0比,大家应该反映过来了吧
0040429C .7E 54 jle short dumped_.004042F2//这里即是我们的大效验的地址,所以这里也是JMP
0040429E .391D E0524000 cmp dword ptr ds:[4052E0],ebx //继续简单下我们的其他函数还有自效验没有
004042A4 .75 10 jnz short dumped_.004042B6
004042A6 .68 E0524000 push dumped_.004052E0
004042AB .68 2C384000 push dumped_.0040382C
004042B0 .FF15 8C104000 call dword ptr ds:[<&msvbvm60.__vbaNew2>>;msvbvm60.__vbaNew2
━━━━━━━━━━━━━━━━━━━━━━━━━━
在一次点回我们的模块间调用,选择第6句
0040437D . /75 10 jnz short dumped_.0040438F //以上没有比较函数,所以排除自效验可能
0040437F . |68 E0524000 push dumped_.004052E0//继续寻找我们的下一句
00404384 . |68 2C384000 push dumped_.0040382C
00404389 . |FF15 8C104000 call dword ptr ds:[<&msvbvm60.__vbaNew2>>;msvbvm60.__vbaNew2
0040438F > \8B35 E0524000 mov esi,dword ptr ds:[4052E0]
━━━━━━━━━━━━━━━━━━━━━━━━━━
在一次点回我们的模块间调用,选择第7句
004043DE > \391D E0524000 cmp dword ptr ds:[4052E0],ebx//此比较并未触发任何退出函数,所以排除自效验可能性
004043E4 .75 10 jnz short dumped_.004043F6 //到此保存我们的程序,选择右键复制到可执行文件---所有修改
004043E6 .68 E0524000 push dumped_.004052E0//此时大家就会发现程序已经可运行,我们成功啦
004043EB .68 2C384000 push dumped_.0040382C
004043F0 .FF15 8C104000 call dword ptr ds:[<&msvbvm60.__vbaNew2>>;msvbvm60.__vbaNew2
004043F6 >8B35 E0524000 mov esi,dword ptr ds:[4052E0]

以上.__vbaNew2此函数经常被利用在调用某些字程序,或者子函数上,所以得出此调用退出的原理

去效验.rar

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

nv21 发表于 2008-10-11 01:00
首先OD载入 程序停在
0040763A >55push ebp
0040763B8BECmov ebp,esp
0040763D83EC 64 sub esp,64
0040764053push ebx
0040764156push esi
0040764257push edi
00407643EB 0C jmp short UnPackMe.00407651
0040764545inc ebp
0040764678 50 js short UnPackMe.00407698
0040764872 2D jb short UnPackMe.00407677
0040764A76 2E jbe short UnPackMe.0040767A

单步F8 打断向上的跳转来到00407CF0FF15 C0744000 call dword ptr ds:[<&KERNEL32.VirtualFre>; kernel32.VirtualFree
00407CF68B45 C8 mov eax,dword ptr ss:[ebp-38]
00407CF95Fpop edi
00407CFA5Epop esi
00407CFB5Bpop ebx
00407CFC83C4 64 add esp,64
00407CFF5Dpop ebp
00407D00- FFE0jmp eax; UnPackMe.004012A0

F8一次到程序的OEP

004012A068 582E4000 push UnPackMe.00402E58
004012A5E8 F0FFFFFF call UnPackMe.0040129A ; jmp 到 MSVBVM60.ThunRTMain
004012AA0000add byte ptr ds:[eax],al
004012AC0000add byte ptr ds:[eax],al
004012AE0000add byte ptr ds:[eax],al
004012B03000xor byte ptr ds:[eax],al
004012B20000add byte ptr ds:[eax],al
004012B440inc eax
004012B50000add byte ptr ds:[eax],al
004012B70000add byte ptr ds:[eax],al
004012B90000add byte ptr ds:[eax],al
004012BB00C2add dl,al
004012BD9Esahf
直接OD方式1脱壳
脱壳后运行程序 没有反应说明程序有自校验(在加上楼主已有过提示)
所以接下来就找自校验的位置
通过查找按钮事件的方法在每个按钮事件上下断
0040352A .816C24 04 470>sub dword ptr ss:[esp+4],47
00403532 .E9 19060000 jmp 1.00403B50
00403537 .816C24 04 FFF>sub dword ptr ss:[esp+4],0FFFF
0040353F .E9 2C070000 jmp 1.00403C70
00403544 .816C24 04 370>sub dword ptr ss:[esp+4],37
0040354C .E9 8F090000 jmp 1.00403EE0
00403551 .816C24 04 370>sub dword ptr ss:[esp+4],37
00403559 .E9 720A0000 jmp 1.00403FD0
0040355E .816C24 04 4F0>sub dword ptr ss:[esp+4],4F
00403566 .E9 D50C0000 jmp 1.00404240
0040356B .816C24 04 FFF>sub dword ptr ss:[esp+4],0FFFF
00403573 .E9 B80D0000 jmp 1.00404330
0040357800db 00
0040357900db 00

然后F9运行
查找 按钮异常
异常出现在
00403559 . /E9 720A0000 jmp 1.00403FD0 到这一句程序就不往下运行
所以自校验就在这个按钮事件里
选中这一句 右键跟随
来到段首00403FD055push ebp----改为RETN
00403FD1 .8BECmov ebp,esp
00403FD3 .83EC 0C sub esp,0C
00403FD6 .68 56114000 push <jmp.&MSVBVM60.__vbaExceptHandler>;SE 处理程序安装
00403FDB .64:A1 0000000>mov eax,dword ptr fs:[0]
00403FE1 .50push eax
00403FE2 .64:8925 00000>mov dword ptr fs:[0],esp
00403FE9 .83EC 74 sub esp,74
00403FEC .53push ebx
00403FED .56push esi
00403FEE .57push edi

段首改为retn
OK保存文件
程序正常运行

去校验.rar

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

枫笑九洲 发表于 2008-10-11 06:50
交作业
------------------------------------------
载入OD停在
0040763A U>/$55push ebp
0040763B |.8BECmov ebp,esp
0040763D |.83EC 64 sub esp,64
00407640 |.53push ebx
00407641 |.56push esi
00407642 |.57push edi

F8单步,走一步,esp定律下断,F9运行
00407D00 |.- FFE0jmp eax //跳向OEP
00407D02 |>5Fpop edi
00407D03 |.5Epop esi
00407D04 |.5Bpop ebx

然后dump即可,
下面接着自检验
OD载入脱壳后文件,右键,查找Find Unicode,在每个字符串处下断,F9运行,3次F9后,我们来到.
00403DEF 52push edx
00403DF0 50push eax
00403DF1 FF15 A0104000 call dword ptr ds:[<&MSVBVM60.rtcFileDateT>; MSVBVM60.rtcFileDateTime
00403DF7 8D55 8C lea edx,dword ptr ss:[ebp-74]
00403DFA 8D4D AC lea ecx,dword ptr ss:[ebp-54]
00403DFD C745 94 68384000mov dword ptr ss:[ebp-6C],111.00403868 ;;停在这里
00403E04 C745 8C 08000000mov dword ptr ss:[ebp-74],8
00403E0B FF15 B8104000 call dword ptr ds:[<&MSVBVM60.__vbaVarDup>>; MSVBVM60.__vbaVarDup

代码向上走下,可以看到MSVBVM60.rtcFileDateTime,这个函数(文件建立时间),

再次F9
00403E53 68 8C384000 push 111.0040388C; UNICODE "20081005120830"
00403E58 FF15 54104000 call dword ptr ds:[<&MSVBVM60.__vbaStrCmp>>; MSVBVM60.__vbaStrCmp
00403E5E F7D8neg eax

可以看到20081005120830(小生UnpackMe建立时间)入栈,下面一个MSVBVM60.__vbaStrCmp比较函数,初步估计,如果不等,就挂了.F8单步
来到
00403F35 66:395D E4cmp word ptr ss:[ebp-1C],bx
00403F39 75 56 jnz short 111.00403F91 ;;不跳就挂.
00403F3B 391D E0524000 cmp dword ptr ds:[4052E0],ebx
00403F41 75 10 jnz short 111.00403F53
00403F43 68 E0524000 push 111.004052E0

把jnz改成jmp,另存,退出..

再次运行,发现还是只会一闪,就挂了,可能还有文件大小的比较,再次载入OD
11次F9后,程序退出
再次载入OD,10次F9后,F8单步.
........
004044B4 FF15 84104000 call dword ptr ds:[<&MSVBVM60.__vbaStrVarVal>]; MSVBVM60.__vbaStrVarVal
004044BA 50push eax
004044BB FF15 A8104000 call dword ptr ds:[<&MSVBVM60.rtcFileLen>]; ;获取文件大小.
004044C1 8D4D D4 lea ecx,dword ptr ss:[ebp-2C]
004044C4 8945 D8 mov dword ptr ss:[ebp-28],eax
004044C7 FF15 D8104000 call dword ptr ds:[<&MSVBVM60.__vbaFreeStr>]; MSVBVM60.__vbaFreeStr
...........
F8单步,来到.
00404295 817D E4 C05D0000cmp dword ptr ss:[ebp-1C],5DC0
0040429C 7E 54 jle short 1234.004042F2;;比较,符合条件就跳,不跳就走向死亡.
0040429E 391D E0524000 cmp dword ptr ds:[4052E0],ebx
004042A4 75 10 jnz short 1234.004042B6
004042A6 68 E0524000 push 1234.004052E0

把jnz改成jmp,另存,运行别存后文件,可以正常运行,收工...

UnPack.rar (10 KB, 下载次数: 1)
lynn 发表于 2008-10-11 09:43
这壳一点花都没有。。
00407D00|.FFE0jmp eax
直接找这句,或者CTRL+B从开始处搜索FF E0
jmp eax后就到了OEP了,看了下IAT也是完好的,直接lordpe加importREC脱壳
直接运行dump_.exe的不行,od载入跑,提示什么SEH链递归错误
纳闷了一阵子,直接对所有函数下断点也断不下来,后来干脆用ximo教的办法直接对VB关键事件下断点
即CTRL+B,二进制搜索81 6C 24
0040352A816C24 04 47000>sub dword ptr [esp+4], 47
00403532E9 19060000 jmp 00403B50
00403537816C24 04 FFFF0>sub dword ptr [esp+4], 0FFFF
0040353FE9 2C070000 jmp 00403C70
00403544816C24 04 37000>sub dword ptr [esp+4], 37
0040354CE9 8F090000 jmp 00403EE0
00403551816C24 04 37000>sub dword ptr [esp+4], 37
00403559E9 720A0000 jmp 00403FD0
0040355E816C24 04 4F000>sub dword ptr [esp+4], 4F
00403566E9 D50C0000 jmp 00404240
0040356B816C24 04 FFFF0>sub dword ptr [esp+4], 0FFFF
00403573E9 B80D0000 jmp 00404330
把jmp那些句子全部给断了,OK,F9运行OD
0040354C /E9 8F090000 jmp 00403EE0 ; 第1次中断
第1次中断跟进去没发现什么
0040353F /E9 2C070000 jmp 00403C70 ; 第2次中断
第2次中断就有发现啦~~
比如
00403DF1FF15 A0104000 calldword ptr [<&msvbvm60.rtcFileDat>; msvbvm60.rtcFileDateTime
00403DF78D55 8C lea edx, dword ptr [ebp-74]
00403DFA8D4D AC lea ecx, dword ptr [ebp-54]
00403DFDC745 94 6838400>mov dword ptr [ebp-6C], 00403868 ; UNICODE "YYYYMMDDHHMMSS"

00403E5368 8C384000 push0040388C ; UNICODE "20081005120830"
00403E58FF15 54104000 calldword ptr [<&msvbvm60.__vbaStrCm>; msvbvm60.__vbaStrCmp

这些是很可疑的!
好了,猜也猜得出是__vbaStrCmp是关键判断,在00403E58处下断,断下后看堆栈:
0012F88C 0040388CUNICODE "20081005120830"
0012F890 0014C9D4UNICODE "20081011085359"
是比较文件的修改时间来做判断的

00403E58FF15 54104000 calldword ptr [<&msvbvm60.__vbaStrCm>; msvbvm60.__vbaStrCmp
00403E5EF7D8neg eax
00403E601BC0sbb eax, eax
00403E62F7D8neg eax
00403E6448dec eax
00403E658945 E4 mov dword ptr [ebp-1C], eax
如果不相同,那么最后将给[ebp-1C]赋值成0,而我们载入原文件定位到这里则给[ebp-1C]赋值成0xFFFFFFFF,好了,那么我们就patch成直接给[ebp-1C]赋值成0xffffffff,最后是下面的形式:
00403E58FF15 54104000 calldword ptr [<&msvbvm60.__vbaStrCm>; msvbvm60.__vbaStrCmp
00403E5EC745 E4 FFFFFFF>mov dword ptr [ebp-1C], -1
00403E6590nop
00403E6690nop
00403E6790nop
C7 45 E4 FF FF FF FF 90 90 90

试着保存程序再运行,发现窗口一闪而过,还有自校验!
在跟踪VB关键事件的那几个jmp,发现了这个比较可疑:
0040407EBF B0384000 mov edi, 004038B0; UNICODE "VB.TIMER"
是设置定时器的,估计是定时检查的。我们就慢慢F8,最后找到
004044BBFF15 A8104000 calldword ptr [<&msvbvm60.rtcFileLen>; msvbvm60.rtcFileLen
但这句下面没有明显的比较语句,那就慢慢F8吧,到了这里:
00404295817D E4 C05D000>cmp dword ptr [ebp-1C], 5DC0
0040429C7E 54 jle short 004042F2
0040429E391D E0524000 cmp dword ptr [4052E0], ebx
004042A475 10 jnz short 004042B6
这几句不好判断了,直接载入原程序在这里对比,发现下面这句是跳过的
0040429C /7E 54 jle short 004042F2 ; 跳过
好了,直接改为jmp保存即可,试运行,正常!

OK,总结下,这个自校验有两处,一处是判断文件时间,一处是设置定时器,在定时器的回调过程里判断文件大小,patch共有两处,用二进制粘贴:
1.00403E5E
C7 45 E4 FF FF FF FF 90 90 90
2.0040429C
EB

脱壳后的样本:
http://www.禁止使用网挣网盘/space/show/qiannao/上传分享/2008/10/11/unpacked.rar/.page
lqiulu 发表于 2008-10-11 10:43
一.脱壳
OD载入停在这里:
0040763A >55push ebp
0040763B8BECmov ebp,esp// HR ESP 下断点执行esp定律
0040763D83EC 64 sub esp,64
0040764053push ebx
-------------------------------------------------------------------------------------
00407D00- FFE0jmp eax//程序停在这里,单步跳向程序OEP
00407D025Fpop edi
----------------------------------------------------------------------------------
004012A068 582E4000 push UnPackMe.00402E58//这里就是程序的OEP,标准的VB入口,DUMP修复。
004012A5E8 F0FFFFFF call UnPackMe.0040129A//
004012AA0000add byte ptr ds:[eax],al
004012AC0000add byte ptr ds:[eax],al
===================================================================================================
二、去自校验
自校验一般就是对文件大小,创建时间等进行比较来校验文件是否进行了改动,我们就从这方面入手。
OD载入脱壳后的文件。查找所有模块间的调用。会发现如下:

00403DF1CALL DWORD PTR DS:[<&msvbvm60.rtcFileDateTime>]msvbvm60.rtcFileDateTime
004044BBCALL DWORD PTR DS:[<&msvbvm60.rtcFileLen>]msvbvm60.rtcFileLen


这两个函数不就是获取文件时间和大小的么,在这两个函数的每个调用下断,shift + f9运行。
00403DF1FF15 A0104000 CALL DWORD PTR DS:[<&msvbvm60.rtcFileDateTime>] ;
首先断在这里
00403DF78D55 8C LEA EDX,DWORD PTR SS:[EBP-74]
00403DFA8D4D AC LEA ECX,DWORD PTR SS:[EBP-54]
00403DFDC745 94 6838400>MOV DWORD PTR SS:[EBP-6C],unpackme.00403868 ; YYYYMMDDHHMMSS
00403E04C745 8C 0800000>MOV DWORD PTR SS:[EBP-74],8
00403E0BFF15 B8104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaVarDup>] ; msvbvm60.__vbaVarDup
00403E116A 01 PUSH 1
00403E138D4D AC LEA ECX,DWORD PTR SS:[EBP-54]
00403E166A 01 PUSH 1
00403E188D55 BC LEA EDX,DWORD PTR SS:[EBP-44]
00403E1B51PUSH ECX
00403E1C8D45 9C LEA EAX,DWORD PTR SS:[EBP-64]
00403E1F52PUSH EDX
00403E2050PUSH EAX
00403E21FF15 28104000 CALL DWORD PTR DS:[<&msvbvm60.rtcVarFromFormatVar>];
00403E278D4D 9C LEA ECX,DWORD PTR SS:[EBP-64]
00403E2A51PUSH ECX
00403E2BFF15 10104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaStrVarMove>];
获取脱壳文件时间
00403E318BD0MOV EDX,EAX ;
eax为子程序调用返回值,20081011085348
00403E338D4D E8 LEA ECX,DWORD PTR SS:[EBP-18]
00403E36FFD6CALL ESI
00403E388D55 9C LEA EDX,DWORD PTR SS:[EBP-64]
00403E3B8D45 AC LEA EAX,DWORD PTR SS:[EBP-54]
00403E3E52PUSH EDX
00403E3F8D4D BC LEA ECX,DWORD PTR SS:[EBP-44]
00403E4250PUSH EAX
00403E4351PUSH ECX
00403E446A 03 PUSH 3
00403E46FF15 14104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaFreeVarList>]
00403E4C8B55 E8 MOV EDX,DWORD PTR SS:[EBP-18] ;
脱壳文件的时间
00403E4F83C4 10 ADD ESP,10
00403E5252PUSH EDX;
脱壳文件时间入栈
00403E5368 8C384000 PUSH unpackme.0040388C;
20081005120830原文件时间
00403E58FF15 54104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaStrCmp>] ;
比较两个时间,不等返回1
00403E5EF7D8NEG EAX;
返回值在eax中,为1
00403E601BC0SBB EAX,EAX
00403E62F7D8NEG EAX
00403E6448DEC EAX //NOP掉 ;
减1,nop掉就可以了
00403E658945 E4 MOV DWORD PTR SS:[EBP-1C],EAX;
使eax为1就是两个时间相等,eax为0为两时间不等。
00403E6868 C03E4000 PUSH unpackme.00403EC0
00403E6DEB 40 JMP SHORT unpackme.00403EAF
-----------------------------------------------------------------------------------------------------------------

上面就处理完了时间校验,再F9运行。
004044BBFF15 A8104000 CALL DWORD PTR DS:[<&msvbvm60.rtcFileLen>];
停在这里,函数返回值在eax中。
004044C18D4D D4 LEA ECX,DWORD PTR SS:[EBP-2C]
004044C48945 D8 MOV DWORD PTR SS:[EBP-28],EAX

脱壳后的文件大小十六进制:E000(十进制:57344)
004044C7FF15 D8104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaFreeStr>] ;
004044CD68 1C454000 PUSH unpackme.0040451C
F8单步向下直到程序返回
。。。。。。。。。。。
------------------------------------------------------------------------------------
返回到这里:
00404295817D E4 C05D0000CMP DWORD PTR SS:[EBP-1C],5DC0 ;
内存地址值与5DC0(24000)进行比较。值为:E000,十进制的57344。脱壳文件的大小。
0040429C7E 54 JLE SHORT unpackme.004042F2 //改为jmp004042F2 ;
小于等于就跳。脱壳前的文件大小为16836,小于24000,而脱壳后的文件大小24000,所以这里一定要跳的不然就OVER。
==============================================================================================
修改两字节:
00403E6448 =>90
0040429C7E =>EB
unpc.rar



经过以上处理后程序就可以正常运行了。保存文件。OK。
小糊涂虫 发表于 2008-10-11 11:00
00407CF95F pop edi
00407CFA5E pop esi
00407CFB5B pop ebx
00407CFC83C4 64add esp,64
00407CFF5D pop ebp 一直F8到这里,有向上跳的F4
00407D00FFE0 jmp eax这里应该就是跳向......................
00407D025F pop edi
00407D035E pop esi
00407D045B pop ebx
00407D05C9 leave

004012A068 582E4000push UnPackMe.00402E58
004012A5E8 F0FFFFFFcall UnPackMe.0040129A
004012AA0000 add byte ptr ds:[eax],al
004012AC0000 add byte ptr ds:[eax],al
004012AE0000 add byte ptr ds:[eax],al

然后脱壳.修复,指针全部有效....但是运行不起来的.....
拿没脱壳的文件一比较...这里发现有点问题...
00403F3566:395D E4 cmp word ptr ss:[ebp-1C],bx
00403F3975 56jnz short UnPackMe.00403F91 把这里改为JMP....
00403F3B391D E0524000cmp dword ptr ds:[4052E0],ebx
00403F4175 10jnz short UnPackMe.00403F53
00403F4368 E0524000push UnPackMe.004052E0
保存后运行...程序一闪而过....
下BP rtcFileLen这个断点..........OK断下来了,返回到
004044C18D4D D4lea ecx,dword ptr ss:[ebp-2C]
004044C48945 D8mov dword ptr ss:[ebp-28],eax
004044C7FF15 D8104000call dword ptr ds:[<&msvbvm60.__vbaFreeStr>]
004044CD68 1C454000push 1.0040451C
004044D2EB 35jmp short 1.00404509
004044D48D4D C8lea ecx,dword ptr ss:[ebp-38]
004044D78D55 CClea edx,dword ptr ss:[ebp-34]
一直往下走来到..
0040428FFF92 0C070000call dword ptr ds:[edx+70C]
00404295817D E4 C05D00>cmp dword ptr ss:[ebp-1C],5DC0这里好像有问题(换成10进制看一下就明白..).......
0040429C7E 54jle short 1.004042F2 把这里改为JMP...
0040429E391D E0524000cmp dword ptr ds:[4052E0],ebx
004042A475 10jnz short 1.004042B6

要不把5DC0改为...E000(前面要加个0) 这样也可以的...自己机子上测试过...
然后就OK了.....
shayu 发表于 2008-10-11 12:30
VB自效验的处理

PEID查壳为eXPressor 1.3.0 -> CGSoftLabs

第一步脱壳

OD载入程序停在程序入口点 如下代码

0040763A >55PUSH EBP
0040763B8BECMOV EBP,ESP
0040763D83EC 64 SUB ESP,64
0040764053PUSH EBX
0040764156PUSH ESI
0040764257PUSH EDI

脱壳的思路源自于当ESP不能用时秒用EBP

看到头两句代码了没有 看过那篇文章的朋友就知道原理了

0040763A >55PUSH EBP
0040763B8BECMOV EBP,ESP

单步来到这之后在命令里面下硬件访问断点:hr 0012ffc0

0040763B8BECMOV EBP,ESP

Shift+F9运行程序 程序跑到这里

00407D00- FFE0JMP EAX; UnPackMe.004012A0
00407D025FPOP EDI
00407D035EPOP ESI
00407D045BPOP EBX

单步步过来到此处

004012A068DB 68;CHAR &#39;h&#39;
004012A158DB 58;CHAR &#39;X&#39;
004012A22EDB 2E;CHAR &#39;.&#39;
004012A340DB 40;CHAR &#39;@&#39;
004012A400DB 00

从模块中删除分析 在往上看看代码

00401288- FF25 80104000 JMP DWORD PTR DS:[401080]; MSVBVM60.GetMemEvent
0040128E- FF25 B0104000 JMP DWORD PTR DS:[4010B0]; MSVBVM60.PutMemEvent
00401294- FF25 BC104000 JMP DWORD PTR DS:[4010BC]; MSVBVM60.SetMemEvent
0040129A- FF25 AC104000 JMP DWORD PTR DS:[4010AC]; MSVBVM60.ThunRTMain
004012A068 582E4000 PUSH UnPackMe.00402E58
004012A5E8 F0FFFFFF CALL UnPackMe.0040129A ; JMP 到 MSVBVM60.ThunRTMain

VB的入口特征 到这里用OD插件脱壳 脱壳后运行出错 打开ImportREC进行修复

OEP为000012A0->自动查找IAT->获取输入表->检查无效函数(都有效)->修复脱壳出来的文件

运行程序没有反应 程序有自校验 脱壳到此结束 进行下一部 去除自校验


第二步 去除校验

校验1)

OD载入脱壳修复的程序 停留在VB入口

004012A0 > $68 582E4000 PUSH UnPack_.00402E58
004012A5 .E8 F0FFFFFF CALL <JMP.&msvbvm60.ThunRTMain>
004012AA .0000ADD BYTE PTR DS:[EAX],AL

我尝试使用两个OD同时单步下去 结果没有什么有用的信息

先查看一下Unicode吧 可能里面有些有用的信息

超级字串参考, 项目 7

地址=00403DFD
反汇编=MOV DWORD PTR SS:[EBP-6C],UnPack_.00403868
文本字串=YYYYMMDDHHMMSS

超级字串参考, 项目 8
地址=00403E53
反汇编=PUSH UnPack_.0040388C
文本字串=20081005120830

看到这两个地方我觉得有点奇怪 自校验应该根据这个校验的吧

分别对这两处下断点进行调试 F9运行程序 程序中断在

00403DFD .C745 94 68384>MOV DWORD PTR SS:[EBP-6C],UnPack_.004038>;YYYYMMDDHHMMSS
00403E04 .C745 8C 08000>MOV DWORD PTR SS:[EBP-74],8

单步走下去 走过到这里

00403E2B .FF15 10104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaStrVa>;msvbvm60.__vbaStrVarMove
00403E31 .8BD0MOV EDX,EAX

寄存器里面的EAX显示 EAX 0015E3F4 UNICODE "20081011012018"

这个UNICODE应该是一个有用的信息 先保留下来 继续单步往下走

00403E53 .68 8C384000 PUSH UnPack_.0040388C;20081005120830
00403E58 .FF15 54104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaStrCm>;msvbvm60.__vbaStrCmp

看到这里有一个vbaStrCmp 这个是字符比较 偶汇编不好 所以就不进去分析了 单步继续往下

00403F39 . /75 56 JNZ SHORT UnPack_.00403F91
00403F3B . |391D E0524000 CMP DWORD PTR DS:[4052E0],EBX
00403F41 . |75 10 JNZ SHORT UnPack_.00403F53
00403F43 . |68 E0524000 PUSH UnPack_.004052E0
00403F48 . |68 2C384000 PUSH UnPack_.0040382C
00403F4D . |FF15 8C104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaNew2>>;msvbvm60.__vbaNew2

来到此处遇到第两个条件跳转 有点可疑 但是还没有确定 所以在第一个JNZ处下F2断点 以便走错在调试

第一个JNZ跳转没有实现 先不管它 走到第二个JNZ跳转 这个实现了 在看看这条代码 主要这个__vbaNew2

00403F4D .FF15 8C104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaNew2>>;msvbvm60.__vbaNew2

看过天草的教程里面有讲解到这个是做什么用的 这里我COPY天草里面的原话 大家先不让它跳看看运行会出现什么

__vbaNew2调用显示一个对话框,类似 Windows&#39; API Dialogboxparam/a

F9运行程序 提示“您没有适当的许可使用该功能”确定后程序直接退出了 这样差不多可以确定自校验就在这里的附近了

但是这个不是关键的跳转 所以没有必要去修改这个 那我们继续来到第一个JNZ跳转处 重新载入跳转 因为刚才已经下断了

载入程序后直接运行程序 程序断在 我们来看看这个跳转实现后跳到哪里(跟随)

00403F39 . /75 56 JNZ SHORT UnPack_.00403F91
00403F3B . |391D E0524000 CMP DWORD PTR DS:[4052E0],EBX
00403F41 |75 10 JNZ SHORT UnPack_.00403F53

跳转要是实现的话跳转到这里的代码 看到一个关键的东西__vbaFreeObj 这个作用是引用天草的原话

“__vbafreeobj 释放出VB一个对象(一个窗口,一个对话框)所占的内存,也就是把内存某个位置的一个窗口,一个对话框抹掉”

结合这个JNZ实现的跳转走到00403F9F这里的直接跳过__vbafreeobj 到了这里的话 我们应该明白了吧 所以第一个跳就是要关键跳

00403F91 > \66:C747 34 FF>MOV WORD PTR DS:[EDI+34],0FFFF
00403F97 >895D FC MOV DWORD PTR SS:[EBP-4],EBX
00403F9A .68 AC3F4000 PUSH UnPack_.00403FAC
00403F9F .EB 0A JMP SHORT UnPack_.00403FAB
00403FA1 .8D4D E8 LEA ECX,DWORD PTR SS:[EBP-18]
00403FA4 .FF15 DC104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaFreeO>;msvbvm60.__vbaFreeObj

把00403F39处的JNZ修改为JMP 保存一下文件 不要关闭OD 运行一下保存的程序 发现程序闪了一下又关了 说明还有别的自校验

校验2)

OD载入文件 下bp rtcFileLen这个断点 F9运行程序 程序中断下来了

660D5D72 >55PUSH EBP
660D5D738BECMOV EBP,ESP
660D5D7581EC 40010000 SUB ESP,140
660D5D7B8D85 C0FEFFFF LEA EAX,DWORD PTR SS:[EBP-140]
660D5D8150PUSH EAX
660D5D82FF75 08 PUSH DWORD PTR SS:[EBP+8]
660D5D85E8 E9000000 CALL msvbvm60.660D5E73

Alt+F9返回到程序领空

004044BB .FF15 A8104000 CALL DWORD PTR DS:[<&msvbvm60.rtcFileLen>;msvbvm60.rtcFileLen
004044C1 .8D4D D4 LEA ECX,DWORD PTR SS:[EBP-2C]
004044C4 .8945 D8 MOV DWORD PTR SS:[EBP-28],EAX
004044C7 .FF15 D8104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaFreeS>;msvbvm60.__vbaFreeStr
004044CD .68 1C454000 PUSH UnPack_2.0040451C

很明显在这里校验了文件的大小 单步往下走就可以找到校验关键跳了 单步走到这里之后看到校验的关键跳

0040429C . /7E 54 JLE SHORT UnPack_2.004042F2
0040429E . |391D E0524000 CMP DWORD PTR DS:[4052E0],EBX
004042A4 . |75 10 JNZ SHORT UnPack_2.004042B6
004042A6 . |68 E0524000 PUSH UnPack_2.004052E0 ;d吾
004042AB . |68 2C384000 PUSH UnPack_2.0040382C
004042B0 . |FF15 8C104000 CALL DWORD PTR DS:[<&msvbvm60.__vbaNew2>>;msvbvm60.__vbaNew2

从形式上来看和第一个校验差不多是一样的比较 只不过这里用的JLE条件跳转 第一个校验用的是JNZ条件跳转

修改0040429C处的JLE为JMP即可 保存程序可以正常运行 去除自校验完成
脱壳去校验.rar (10 KB, 下载次数: 9)
blgzs 发表于 2008-10-11 15:04
0040763A UnPackMe.<Mod>55push ebp; OD载入
0040763B 8BECmov ebp,esp ; 使用OEP定律
0040763D 83EC 64 sub esp,64
00407640 53push ebx
00407641 56push esi
00407642 57push edi
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
按F9运行至OEP
004012A0 68 582E4000 push UnPackMe.00402E58; OEP所在,用OD的插件脱壳
004012A5 E8 F0FFFFFF call UnPackMe.0040129A; jmp to MSVBVM60.ThunRTMain
004012AA 0000add byte ptr ds:[eax],al
004012AC 0000add byte ptr ds:[eax],al
004012AE 0000add byte ptr ds:[eax],al
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

再用OD载入脱壳后的文件,找出校验的位置,修改跳转位置,下面是操作过程

004012A0 1.<ModuleEntr>68 582E4000 push 1.00402E58 ; OD载入
004012A5 E8 F0FFFFFF call <jmp.&MSVBVM60.ThunRTMain>
004012AA 0000add byte ptr ds:[eax],al
004012AC 0000add byte ptr ds:[eax],al
004012AE 0000add byte ptr ds:[eax],al
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
接下来查找字符串
通过Find ASCII发现没有所需要的信息
再通过Find Unicode发现如下:
Ultra String Reference
AddressDisassembly Text String
004012A0 push 1.00402E58 (Initial CPU selection)
004037AF push 1.0040378C l7@|7@
00403BE3 push 1.004037E0 http://www.52pojie.cn
00403D8D push 1.00403850 \
00403DB0 push 1.00403858 .exe
00403DFD mov dword ptr ss:[ebp-6C],1.00403868YYYYMMDDHHMMSS
00403E53 push 1.0040388C 20081005120830
0040407E mov edi,1.004038B0VB.TIMER
004040D1 push 1.004038E0 Add
004040DE mov eax,1.004038C8mytimetest
00404441 push 1.00403850 \
00404464 push 1.00403858 .exe
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
发现可疑处,有两个字符串是".exe",一般的校验都出现在这个位置,双击这两个到代码,在这两处按F2设断点
如下:
00403DB0 68 58384000 push 1.00403858 ; UNICODE ".exe"
00403DB5 FFD7call edi
00403DB7 8BD0mov edx,eax
00403DB9 8D4D EC lea ecx,dword ptr ss:[ebp-14]
00403DBC FFD6call esi

00404464 68 58384000 push 1.00403858 ; UNICODE ".exe"
00404469 FFD6call esi
0040446B 8D55 B0 lea edx,dword ptr ss:[ebp-50]
0040446E 8D4D E0 lea ecx,dword ptr ss:[ebp-20]
00404471 8945 B8 mov dword ptr ss:[ebp-48],eax
00404474 C745 B0 08000000mov dword ptr ss:[ebp-50],8
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
F9运行,发现先到第一个断点处
00403DB0 68 58384000 push 1.00403858 ; UNICODE ".exe"
00403DB5 FFD7call edi
00403DB7 8BD0mov edx,eax
00403DB9 8D4D EC lea ecx,dword ptr ss:[ebp-14]
00403DBC FFD6call esi
00403DBE 8D55 D4 lea edx,dword ptr ss:[ebp-2C]
00403DC1 8D45 DC lea eax,dword ptr ss:[ebp-24]
F8单步运行,直至
00403F35 66:395D E4cmp word ptr ss:[ebp-1C],bx
00403F39/EB 56 jmp short 1.00403F91 ; 关键跳,这里我修改成了jmp
00403F3B 391D E0524000 cmp dword ptr ds:[4052E0],ebx
00403F41 75 10 jnz short 1.00403F53
00403F43 68 E0524000 push 1.004052E0
00403F48 68 2C384000 push 1.0040382C
为什么这样修改呢,我是对照着原程序修改的,另开一个OD载入带壳的程序,发现他运行到这里之后实现了跳转,而脱了壳的
这里就不跳转了,说明问题出在这里,所以这么改了
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
再次F9运行,发现到了第二个断点处
00404464 68 58384000 push 1.00403858 ; UNICODE ".exe"
00404469 FFD6call esi
0040446B 8D55 B0 lea edx,dword ptr ss:[ebp-50]
0040446E 8D4D E0 lea ecx,dword ptr ss:[ebp-20]
00404471 8945 B8 mov dword ptr ss:[ebp-48],eax
同样的道理,仍然单步运行至
00404295 817D E4 C05D0000cmp dword ptr ss:[ebp-1C],5DC0
0040429C EB 54 jmp short 1.004042F2; 这里我也改成了jmp
0040429E 391D E0524000 cmp dword ptr ds:[4052E0],ebx
004042A4 75 10 jnz short 1.004042B6
004042A6 68 E0524000 push 1.004052E0
为什么这样改,和上面的情况一下,和原程序对比。其实也不难看出,这里和5DC0比较了一下,如果文件大小小于等于这
个值就跳,而我们脱壳的程序是大于这个大小的。同样,你也可以将这个5DC0改成FFFF也行。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
再次F9,发现又到了第二个断点,说明程序是循环检测,这里不用管他了,将第二个断点取消,再次F9,发现程序运行
起来了。
最后修改保存,OK,完成









unpack.rar
unpack 发表于 2008-10-11 19:30
在此之前,用PEID查得壳为eXPressor V1.3 -> CGSoftLabs * Sign.By.fly *

首先OD载入程序,忽略所以异常,程序停在
0040763A >/$55pushebp;//壳的开始处0040763B|.8BECmov ebp, esp ;//ESP定律,下断点hr 0012FFC00040763D|.83EC 64 sub esp, 6400407640|.53pushebx00407641|.56pushesi00407642|.57pushedi00407643|.EB 0C jmp short 00407651
下完断点后,F9运行!来到
00407D00|.- FFE0jmp eax;UnPackMe.004012A000407D02|>5Fpop edi00407D03|.5Epop esi00407D04|.5Bpop ebx00407D05|.C9leave00407D06\.C3retn
呵呵这个jmp就是一个很大的跳转了,我们再F8一步就到OEP了
004012A068 582E4000 push00402E58 ; //OEP004012A5E8 F0FFFFFF call0040129A004012AA0000add [eax], al004012AC0000add [eax], al004012AE0000add [eax], al004012B03000xor [eax], al004012B20000add [eax], al004012B440inc eax004012B50000add [eax], al004012B70000add [eax], al004012B90000add [eax], al004012BB00C2add dl, al
很典型的vb程序吧

我用LordPE将其dump下来,然后用ImpREC修复,没有无效指针!用PEID查得:Microsoft Visual Basic 5.0 / 6.0

下面就是关键了,我们运行脱壳后的程序,发现怎么点都没有办法运行起来!
O(∩_∩)O哈哈~这就是今天的关键了,有自校验!好开始我的想法了,当然说了不能用比较两个OD,我也就不用,而且麻烦

我想了下,一般有自校验都是进行比较,我就先下vb专业断点 _vbaStrCmp、_vbaStrComp、_vbaStrCompVar、_rtcFileLen、_rtcFileLength等:
由于我跟踪过了,所以知道只有两个有用,我就不多下断点了,直接下_vbaStrCmp、_rtcFileLen
我们载入脱壳后的程序,然后先下断点 bpx _vbaStrCmp,发现只有一个这个断点,看来一处就要出来了!下好后我们F9运行
00403E5368 8C384000push0040388C ; UNICODE "20081005120830"00403E58FF15 54104000call[<&msvbvm60.#406>] ; msvbvm60.__vbaStrCmp00403E5EF7D8 neg eax; //F9断下后,停在上一行的call,我们F8进入看看00403E601BC0 sbb eax, eax00403E62F7D8 neg eax00403E6448 dec eax00403E658945 E4mov [ebp-1C], eax00403E6868 C03E4000push00403EC000403E6DEB 40jmp short 00403EAF
是不是,有个比较,看样子是要比较软件的日期了!
我们F8试试进去看看什么情况
73528A03 >FF7424 08pushdword ptr [esp+8]; //F8来到这儿,我们看堆栈73528A07FF7424 08pushdword ptr [esp+8]73528A0B6A 00push073528A0DE8 B426F3FFcall__vbaStrComp ; //这里就是堆栈那里的比较了,比较日期73528A12C2 0800retn8
再看看堆栈
0012F888 00403E5E返回到 dumped_.00403E5E 来自 msvbvm60.__vbaStrCmp0012F88C 0040388CUNICODE "20081005120830"//这个是软件的修改日期0012F890 00151534UNICODE "20081011165530"//这个是脱壳后程序的修改日期
所以毫无疑问肯定是比较程序的修改日期了!

那个下面一行
73528A0DE8 B426F3FFcall__vbaStrComp
就是进行比较,然后给eax赋值了
我们就不进入跟踪了,直接到

73528A12C2 0800retn8

发现寄存器窗口的eax变成了1,也就是说他们日期不同就会给eax赋值为1,否则就赋值为0,这个我们怎么知道呢
呵呵,我是这样的,
73528A03 >FF7424 08pushdword ptr [esp+8]73528A07FF7424 08pushdword ptr [esp+8]
这两句不是要压栈吗,我们看看在73528A03的时候,我们在信息窗口显示
堆栈 ss:[0012F890]=00151534, (UNICODE "20081011165530")我们右键----修改数据----将数据00151534赋值下来,也就是说存放的啥了(忘了),然后F8来到73528A07,在信息窗口显示:堆栈 ss:[0012F88C]=0040388C (dumped_.0040388C), UNICODE "20081005120830"所以我们右键----修改数据---将00151534替换0040388C,然后在到73528A12C2 0800retn8
这句,我们就可以看到EAX变成0了,证明我们的猜测是正确的!
sshot-1.gif sshot-2.gif


好了,过了这个RETN后回来了
00403E5EF7D8 neg eax; //00403E601BC0 sbb eax, eax00403E62F7D8 neg eax00403E6448 dec eax00403E658945 E4mov [ebp-1C], eax; //然后将eax的值给[ebp-1c]00403E6868 C03E4000push00403EC000403E6DEB 40jmp short 00403EAF
然后经过上面的这几句计算,我们得到EAX==0,这个跳转跳后,我们一直单步;
然后retn返回后,就是关键点了
00403F3566:395D E4 cmp [ebp-1C], bx ; //这就关键比较了,bx是为0的,还记得刚刚eax==0的值赋给了[ebp-1c]00403F3975 56jnz short 00403F91 ; //所以这个跳一定要跳了,改成jmp00403F3B391D E0524000cmp [4052E0], ebx00403F4175 10jnz short 00403F5300403F4368 E0524000push004052E0 ; ASCII "d芜"00403F4868 2C384000push0040382C00403F4DFF15 8C104000call[<&msvbvm60.#340>] ; msvbvm60.__vbaNew2
这样就去了一处自校验了,如果我们这时候保存的话,程序运行会一闪而过!所以看来还有自自校验,我就没有保存直接来看看下个自校验吧!

下断点bpx _rtcFileLen(也只有这一个断点),F9运行:
004044BA50 pusheax; //来到下一句断下!004044BBFF15 A8104000call[<&msvbvm60.#578>] ; msvbvm60.rtcFileLen004044C18D4D D4lea ecx, [ebp-2C]; 这里比较程度,没有看出来,我们F8单步走下去!004044C48945 D8mov [ebp-28], eax004044C7FF15 D8104000call[<&msvbvm60.#130>] ; msvbvm60.__vbaFreeStr004044CD68 1C454000push0040451C004044D2EB 35jmp short 00404509

我们一直单步来到
00404295817D E4 C05D0000 cmp dword ptr [ebp-1C], 5DC0 ; //来到这儿,看到了比较了吧0040429C7E 54jle short 004042F20040429E391D E0524000cmp [4052E0], ebx004042A475 10jnz short 004042B6004042A668 E0524000push004052E0 ; ASCII "d芜"004042AB68 2C384000push0040382C004042B0FF15 8C104000call[<&msvbvm60.#340>] ; msvbvm60.__vbaNew2

我们现在是停在

00404295817D E4 C05D0000 cmp dword ptr [ebp-1C], 5DC0

这句了,我们用计算器算的0x5DC0=24000
而原程序大小是 16,836个字节比它小当然就会跳,我们再看脱壳后的程序有 57,344==0xE000,看堆栈就知道了
堆栈 ss:[0012FB5C]=0000E000
明显大,所以就不会跳了,我们同样要修改跳,将
0040429C7E 54jle short 004042F2改为0040429C /EB 54jmp short 004042F2
这样修改后把两处的修改全部复制保存,然后在看看保存后的程序,O(∩_∩)O哈哈~终于能运行了!

【总结下】可能大家下自校验的方式不一样,我开始脱壳后,放入OD中试着运行,什么信息也没有的到,只有下BPX 断点进入看看有什么下断的函数,O(∩_∩)O哈哈~,还是比较少的,所以,我开始也猜到用一般的下断方法全部下断,然后运行,看看是哪个断点断下了,也就是上面那几处试验出来的,不过建议还是看看这个程序有那些下断的函数,这样知己知彼,那么下断点也能更快了!
修改方法,我用了两种:
1、修改跳转
第一处:00403F3975 56jnz short 00403F91 改为00403F39 /EB 56 JMP SHORT dumped_.00403F91第二处:0040429C . /7E 54 JLE SHORT dumped_.004042F2改为0040429C /EB 54jmp short 004042F2
2、修改算法:
第一处:只要保证eax!=0即可00403E6448DEC EAX改为00403E6440INC EAX然后第二处跟第一种一样0040429C . /7E 54 JLE SHORT dumped_.004042F2改为0040429C /EB 54jmp short 004042F2我们其实也可以修改:00404295 .817D E4 C05D0>CMP DWORD PTR SS:[EBP-1C],5DC0为00404295817D E4 00E00>CMP DWORD PTR SS:[EBP-1C],0E000
呵呵一样的,修改的方法很多,还是讲究最精简修改为最好,两个字节就OK了 O(∩_∩)O哈哈~
就分析到这儿了!!!
dumped_3.rar
您需要登录后才可以回帖 登录 | 注册[Register]

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

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

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

GMT+8, 2024-4-30 22:51

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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