简介:
Petite2.2具有10级的压缩级别,可以同时压缩 PE 文件的输入/输出表,去除重定位表,并且加上检测病毒的功能,即可以用来给 PE 文件减肥,也可以用来保护自己的程序。评价:压缩级别选9级很费时间,压缩比同Upx和Aspack差不多,优点是具备病毒检测功能,病毒修改未脱壳后会有发现病毒警告,使用了结构化异常处理SEH反跟踪调试,正常运行时没影响。属入门级加密壳,关于SEH知识参考相关文章,本论坛有两篇简介。
脱壳目标,Petite2.2加壳Win98的记事本。
下载地址
http://www.live-share.com/files/332657/Notepad_PEtite_2.2.rar.html
本地下载
软件后用Fi测Notepad.exe的壳为PEtite 2.2 -> Ian Luck
手动脱壳建议大家用Ollydbg,工作平台Win2000,WinXp,Win9x不推荐。
手动脱壳时,用Olldbg载入程序,脱壳程序里面会有有好多循环。对付循环时,只能让程序往前运行,基本不能让它往回跳,要想法跳出循环圈。不要用Peid查入口,单步跟踪,提高手动找入口能力。
从本文开始,我们把Od中的选项-调试选项-异常选项卡中
除了忽略在KERNEL32 中的内存访问异常打勾,其余一个勾都不打,请检查自己的Od设置。
用OD载入程序后。
确定一个入口警告,Od提示程序加壳,选不继续分析。
0040D042 > B8 00D04000 mov eax, Notepad.0040D000 中断在这里。
0040D047 68 4C584000 push Notepad.0040584C 填充ERR结构的Hander,当发生异常时系统会自动调用这里。
0040D04C 64:FF35 0000000>push dword ptr fs:[0] 填充ERR结构的Prev
0040D053 64:8925 0000000>mov dword ptr fs:[0], esp 建立SEH链,呵,异常后就会到40584C处的代码继续运行。
0040D05A 66:9C pushfw 关键字1
0040D05C 60 pushad 关键字2
0040D05D 50 push eax
0040D05E 68 00004000 push Notepad.00400000
0040D063 8B3C24 mov edi, dword ptr ss:[esp]
0040D066 8B30 mov esi, dword ptr ds:[eax]
0040D068 66:81C7 8007 add di, 780
0040D06D 8D7406 08 lea esi, dword ptr ds:[esi+eax+8]
0040D071 8938 mov dword ptr ds:[eax], edi
0040D073 8B5E 10 mov ebx, dword ptr ds:[esi+10]
0040D076 50 push eax
0040D077 56 push esi
0040D078 6A 02 push 2
0040D07A 68 80080000 push 880
0040D07F 57 push edi
0040D080 6A 12 push 12
0040D082 6A 06 push 6
0040D084 56 push esi
0040D085 6A 04 push 4
.....................................................
0040D0AB 8B0A mov ecx, dword ptr ds:[edx]
0040D0AD 0FBAF1 1F btr ecx, 1F
0040D0B1 73 16 jnb short Notepad.0040D0C9
0040D0B3 8B0424 mov eax, dword ptr ss:[esp]
0040D0B6 FD std
0040D0B7 8BF0 mov esi, eax
0040D0B9 8BF8 mov edi, eax
0040D0BB 0372 04 add esi, dword ptr ds:[edx+4]
0040D0BE 037A 08 add edi, dword ptr ds:[edx+8]
0040D0C1 F3:A5 rep movs dword ptr es:[edi], dword ptr d>
0040D0C3 83C2 0C add edx, 0C
0040D0C6 FC cld
0040D0C7 ^ EB E2 jmp short Notepad.0040D0AB 循环。
0040D0C9 83C2 10 add edx, 10 F4到这里。
0040D0CC 8B5A F4 mov ebx, dword ptr ds:[edx-C]
0040D0CF 85DB test ebx, ebx
0040D0D1 ^\74 D8 je short Notepad.0040D0AB
0040D0D3 8B0424 mov eax, dword ptr ss:[esp]
0040D0D6 8B7A F8 mov edi, dword ptr ds:[edx-8]
0040D0D9 03F8 add edi, eax
0040D0DB 52 push edx
0040D0DC 8D3401 lea esi, dword ptr ds:[ecx+eax]
0040D0DF EB 17 jmp short Notepad.0040D0F8 跳。
0040D0F8 81FB 00000100 cmp ebx, 10000 到这里。
0040D0FE 73 0E jnb short Notepad.0040D10E
0040D100 68 60C0FFFF push -3FA0
0040D105 68 60FCFFFF push -3A0
0040D10A B6 05 mov dh, 5
0040D10C EB 22 jmp short Notepad.0040D130 跳。
0040D130 6A 00 push 0 到这里。
0040D132 32D2 xor dl, dl
0040D134 4B dec ebx
0040D135 A4 movs byte ptr es:[edi], byte ptr ds:[esi>
0040D136 33C9 xor ecx, ecx
0040D138 83FB 00 cmp ebx, 0
0040D13B ^ 7E A4 jle short Notepad.0040D0E1
0040D13D E8 AAFFFFFF call Notepad.0040D0EC F8步过。
0040D142 72 17 jb short Notepad.0040D15B
0040D144 A4 movs byte ptr es:[edi], byte ptr ds:[esi>
0040D145 305F FF xor byte ptr ds:[edi-1], bl
0040D148 4B dec ebx
0040D149 ^ EB ED jmp short Notepad.0040D138 循环。
0040D14B 41 inc ecx F4到这里。
0040D14C E8 9BFFFFFF call Notepad.0040D0EC
0040D151 13C9 adc ecx, ecx
0040D153 E8 94FFFFFF call Notepad.0040D0EC
0040D158 ^ 72 F2 jb short Notepad.0040D14C
0040D15A C3 retn
0040D162 83E9 03 sub ecx, 3 到这里。
0040D165 73 06 jnb short Notepad.0040D16D 跳。
0040D16D 8BC1 mov eax, ecx 到这里。
0040D16F 0FB6CE movzx ecx, dh
0040D172 E8 75FFFFFF call Notepad.0040D0EC
0040D177 13C0 adc eax, eax
0040D179 49 dec ecx
0040D17A ^ 75 F6 jnz short Notepad.0040D172 循环。
0040D17C 83F0 FF xor eax, FFFFFFFF F4下来。
0040D17F 3B4424 04 cmp eax, dword ptr ss:[esp+4]
0040D183 83D5 01 adc ebp, 1
0040D186 3B4424 08 cmp eax, dword ptr ss:[esp+8]
.....................................................
0040D19E /75 08 jnz short Notepad.0040D1A8 跳。
0040D1A8 03CD add ecx, ebp 到这里。
0040D1AA 56 push esi
0040D1AB 2BD9 sub ebx, ecx
0040D1AD 8D3438 lea esi, dword ptr ds:[eax+edi]
0040D1B0 F3:A4 rep movs byte ptr es:[edi], byte ptr ds:>
0040D1B2 5E pop esi
0040D1B3 ^ EB 83 jmp short Notepad.0040D138 回跳。
0040D1B5 2E:8BC0 mov eax, eax 当我们想F4到这里,却....Od提示40D135处内存发生异常。
0040D135 A4 movs byte ptr es:[edi], byte ptr ds:[esi>
呵,这里是一个SEH暗桩,外壳代码对加密过的区段数据解压后就产生异常,让你无法继续跟综调试。
我们看信息框处的esi和edi的值都是400000,Movs指令是将esi指向的数据段中一个字节传递到由edi指向的附加段中去,此时Movs指令将向文件头写数据,因此产生一个异常SEH,系统将自动调用40584C处的代码继续执行。
0040D136 33C9 xor ecx, ecx
0040D138 83FB 00 cmp ebx, 0
0040D13B ^ 7E A4 jle short Notepad.0040D0E1
0040D13D E8 AAFFFFFF call Notepad.0040D0EC
如果里这时掌握了SEH结构知识,你这时可以Ctrl+g,输入40584C,回车,然后F2下断点,F9运行然后取消40584C断点。不过我这时还刚开始学SEH,让我们照Od的提示,Shift+7运行,将迷失在系统代码里。
77FB4DB3 8B1C24 mov ebx, dword ptr ss:[esp]
77FB4DB6 51 push ecx
77FB4DB7 53 push ebx
77FB4DB8 E8 ACBDFAFF call ntdll.77F60B69 F7跟进
77F60B69 55 push ebp 到这里
77F60B6A 8BEC mov ebp, esp
77F60B6C 83EC 60 sub esp, 60
77F60B6F 56 push esi
77F60B70 FF75 0C push dword ptr ss:[ebp+C]
77F60B73 8B75 08 mov esi, dword ptr ss:[ebp+8]
77F60B76 56 push esi
77F60B77 E8 AA000000 call ntdll.77F60C26 无特别提示一律F8步过。
.....................................................
77F60BC5 8B43 04 mov eax, dword ptr ds:[ebx+4] ; Notepad.0040584C 还是看到40584C
77F60BC8 3B45 FC cmp eax, dword ptr ss:[ebp-4]
77F60BCB 72 09 jb short ntdll.77F60BD6
.....................................................
77F60BEF E8 528F0100 call ntdll.77F79B46 F7跟。
77F60BF4 F605 4A32FC77 8>test byte ptr ds:[77FC324A], 80
77F60BFB 8BF8 mov edi, eax
77F79B46 BA B89BF777 mov edx, ntdll.77F79BB8 到这里。
77F79B4B EB 07 jmp short ntdll.77F79B54
77F79B4D BA DF9BF777 mov edx, ntdll.77F79BDF
77F79B52 8D09 lea ecx, dword ptr ds:[ecx]
77F79B54 53 push ebx
77F79B55 56 push esi
77F79B56 57 push edi
77F79B57 33C0 xor eax, eax
77F79B59 33DB xor ebx, ebx
77F79B5B 33F6 xor esi, esi
77F79B5D 33FF xor edi, edi
77F79B5F FF7424 20 push dword ptr ss:[esp+20]
77F79B63 FF7424 20 push dword ptr ss:[esp+20]
77F79B67 FF7424 20 push dword ptr ss:[esp+20]
77F79B6B FF7424 20 push dword ptr ss:[esp+20]
77F79B6F FF7424 20 push dword ptr ss:[esp+20]
77F79B73 E8 06000000 call ntdll.77F79B7E F7跟。
77F79B7E 55 push ebp 到这里。
77F79B7F 8BEC mov ebp, esp
77F79B81 FF75 0C push dword ptr ss:[ebp+C]
77F79B84 52 push edx
77F79B85 64:FF35 0000000>push dword ptr fs:[0]
77F79B8C 64:8925 0000000>mov dword ptr fs:[0], esp
77F79B93 FF75 14 push dword ptr ss:[ebp+14]
77F79B96 FF75 10 push dword ptr ss:[ebp+10]
77F79B99 FF75 0C push dword ptr ss:[ebp+C]
77F79B9C FF75 08 push dword ptr ss:[ebp+8]
77F79B9F 8B4D 18 mov ecx, dword ptr ss:[ebp+18] Ecx放入40584C
77F79BA2 FFD1 call ecx 进这个Call我们将回到40584C,昏,如果你熟悉SEH,就可以直接下断点,害我们在系统领空中徘徊半天。另外,论坛限制发布文章大小,所以不重要的代码省去一些,请读者见谅
77F79BA4 64:8B25 0000000>mov esp, dword ptr fs:[0]
77F79BAB 64:8F05 0000000>pop dword ptr fs:[0]
77F79BB2 8BE5 mov esp, ebp
77F79BB4 5D pop ebp
77F79BB5 C2 1400 retn 14
004058E5 5A pop edx 终于回到程序领空,真高兴。
004058E6 64:8F05 0000000>pop dword ptr fs:[0]
004058ED 58 pop eax
004058EE 6A 00 push 0
004058F0 53 push ebx
004058F1 33DB xor ebx, ebx
004058F3 68 3D030000 push 33D
004058F8 8B0C24 mov ecx, dword ptr ss:[esp]
004058FB 0FBAE3 00 bt ebx, 0
004058FF /72 16 jb short Notepad.00405917
00405901 |64:8B35 1C00000>mov esi, dword ptr fs:[1C]
00405908 |0FBAF6 00 btr esi, 0
0040590C |64:0335 2200000>add esi, dword ptr fs:[22]
00405913 |46 inc esi
00405914 |66:33DE xor bx, si
00405917 \321C11 xor bl, byte ptr ds:[ecx+edx]
0040591A C1C3 07 rol ebx, 7
0040591D 49 dec ecx
0040591E ^ 7D DB jge short Notepad.004058FB 循环。
00405920 8D48 37 lea ecx, dword ptr ds:[eax+37] F4下来。
00405923 3119 xor dword ptr ds:[ecx], ebx
00405925 3159 04 xor dword ptr ds:[ecx+4], ebx
00405928 3159 08 xor dword ptr ds:[ecx+8], ebx
0040592B 3159 0C xor dword ptr ds:[ecx+C], ebx
0040592E 59 pop ecx
0040592F 315C11 01 xor dword ptr ds:[ecx+edx+1], ebx
00405933 33DB xor ebx, ebx
00405935 8BF2 mov esi, edx
00405937 81BA 71A8FFFF 4>cmp dword ptr ds:[edx+FFFFA871], 0D042
00405941 75 21 jnz short Notepad.00405964
00405964 83C4 2A add esp, 2A 到这里。
00405967 - E9 A9760000 jmp Notepad.0040D015 跳走
0040596C BE 00600000 mov esi, 6000
00405971 03F5 add esi, ebp
00405973 8D8D 00080000 lea ecx, dword ptr ss:[ebp+800]
00405979 8BD8 mov ebx, eax
0040597B 833E 00 cmp dword ptr ds:[esi], 0
0040597E 0F84 0E020000 je Notepad.00405B92
00405984 51 push ecx
00405985 51 push ecx
00405986 FF95 90070000 call dword ptr ss:[ebp+790]
0040598C 85C0 test eax, eax
0040598E 0F84 DF000000 je Notepad.00405A73
0040D015 83C4 08 add esp, 8 我们被带到这里。
0040D018 6A 10 push 10
0040D01A 8BD8 mov ebx, eax
0040D01C 66:05 2D00 add ax, 2D
0040D020 50 push eax
0040D021 52 push edx
0040D022 6A 00 push 0
0040D024 8B1B mov ebx, dword ptr ds:[ebx] ebx中被放入40d047
0040D026 FF13 call dword ptr ds:[ebx] 再次单步异常。
0040D028 6A FF push -1
0040D02A FF53 0C call dword ptr ds:[ebx+C]
0040D047 0000 add byte ptr ds:[eax], al 到哪里一看,空地址无代码,陷阱。
0040D049 0000 add byte ptr ds:[eax], al
0040D04B 0000 add byte ptr ds:[eax], al
0040D04D 0000 add byte ptr ds:[eax], al
0040D04F 0000 add byte ptr ds:[eax], al
0040D051 0000 add byte ptr ds:[eax], al
可以Shift+F7继续迷失在系统领空,我选择Ctrl+F2重来。
先F9运行,提示异常,这时加密的区段解压完毕,我们Ctrl+g,填入00405941,回车。
Shift+F9继续运行,提示单步异常。Shift+F9继续,呵顺利通过单步异常,F2取消断点。
00405941 /75 21 jnz short Notepad.00405964 到这里,F8慢慢往下运行。
00405943 |81EE B7570000 sub esi, 57B7
00405949 |0FB64E 06 movzx ecx, byte ptr ds:[esi+6]
0040594D |6BC9 0A imul ecx, ecx, 0A
00405950 |66:81C1 3E00 add cx, 3E
00405955 |331E xor ebx, dword ptr ds:[esi]
00405957 |D3C3 rol ebx, cl
00405959 |83C6 04 add esi, 4
0040595C |49 dec ecx
0040595D ^|75 F6 jnz short Notepad.00405955
0040595F |3958 04 cmp dword ptr ds:[eax+4], ebx
00405962 |74 08 je short Notepad.0040596C
00405964 \83C4 2A add esp, 2A
00405967 - E9 A9760000 jmp Notepad.0040D015 这里这次没运行,被处理掉了。(这儿看不懂,怎么进行的处理让这句不执行呢?)
0040596C BE 00600000 mov esi, 6000
00405971 03F5 add esi, ebp
00405973 8D8D 00080000 lea ecx, dword ptr ss:[ebp+800]
00405979 8BD8 mov ebx, eax
0040597B 833E 00 cmp dword ptr ds:[esi], 0
0040597E 0F84 0E020000 je Notepad.00405B92 大跳转,可能是循环出口。
00405984 51 push ecx
00405985 51 push ecx
00405986 FF95 90070000 call dword ptr ss:[ebp+790]
0040598C 85C0 test eax, eax
0040598E 0F84 DF000000 je Notepad.00405A73 大跳转,可能是循环出口。
00405994 8BF8 mov edi, eax ; SHELL32.#584
00405996 0340 3C add eax, dword ptr ds:[eax+3C]
00405999 8B40 78 mov eax, dword ptr ds:[eax+78]
0040599C FF7438 18 push dword ptr ds:[eax+edi+18]
004059A0 8B4C38 24 mov ecx, dword ptr ds:[eax+edi+24]
004059A4 03CF add ecx, edi
004059A6 51 push ecx
004059A7 8B4C38 20 mov ecx, dword ptr ds:[eax+edi+20]
004059AB 03CF add ecx, edi
004059AD 51 push ecx
004059AE FF7438 10 push dword ptr ds:[eax+edi+10]
004059B2 FF7438 14 push dword ptr ds:[eax+edi+14]
004059B6 8B4438 1C mov eax, dword ptr ds:[eax+edi+1C]
.....................................................
004059C6 /0F84 81000000 je Notepad.00405A4D
004059CC |0FBAE0 1F bt eax, 1F
004059D0 |73 2B jnb short Notepad.004059FD 跳走。
004059FD 03C5 add eax, ebp 到这里。
004059FF 50 push eax
00405A00 50 push eax
00405A01 57 push edi
00405A02 FF95 94070000 call dword ptr ss:[ebp+794]
00405A08 85C0 test eax, eax
00405A0A 74 7F je short Notepad.00405A8B
00405A0C FF4C24 28 dec dword ptr ss:[esp+28]
00405A10 7D 1F jge short Notepad.00405A31
.....................................................
00405A33 873C24 xchg dword ptr ss:[esp], edi
00405A36 83C9 FF or ecx, FFFFFFFF
00405A39 33C0 xor eax, eax
00405A3B F2:AE repne scas byte ptr es:[edi]
00405A3D FD std
00405A3E F7D1 not ecx
00405A40 4F dec edi
00405A41 F3:AA rep stos byte ptr es:[edi]
00405A43 5F pop edi
00405A44 FC cld
00405A45 83C6 04 add esi, 4
00405A48 ^ E9 75FFFFFF jmp Notepad.004059C2 想往回跳。
00405A4D 5E pop esi F4下来。
00405A4E 83C4 18 add esp, 18
00405A51 8B16 mov edx, dword ptr ds:[esi]
00405A53 03D5 add edx, ebp
00405A55 8D43 43 lea eax, dword ptr ds:[ebx+43]
00405A58 8B4C24 04 mov ecx, dword ptr ss:[esp+4]
00405A5C 833A 00 cmp dword ptr ds:[edx], 0
00405A5F 74 12 je short Notepad.00405A73
00405A61 3B1A cmp ebx, dword ptr ds:[edx]
00405A63 8318 00 sbb dword ptr ds:[eax], 0
00405A66 390A cmp dword ptr ds:[edx], ecx
00405A68 8318 00 sbb dword ptr ds:[eax], 0
00405A6B 83C2 04 add edx, 4
00405A6E C108 03 ror dword ptr ds:[eax], 3
00405A71 ^ EB E9 jmp short Notepad.00405A5C 往回跳。
00405A73 C706 00000000 mov dword ptr ds:[esi], 0 F4下来。
00405A79 5F pop edi
00405A7A 83C9 FF or ecx, FFFFFFFF
00405A7D 33C0 xor eax, eax
00405A7F F2:AE repne scas byte ptr es:[edi]
00405A81 8BCF mov ecx, edi
00405A83 83C6 04 add esi, 4
00405A86 ^ E9 F0FEFFFF jmp Notepad.0040597B 往回跳。
00405A8B 59 pop ecx 试图F4到这里,程序跑飞。
看0040597E和0040598E两个大循环出口,选择0040597E处跳转下断点,它跳的远些。
我们直接下 00405B92 处的断点,看过我前面的文章的读者不难知道如何到这里。
00405B92 59 pop ecx 这里。
00405B93 5E pop esi
00405B94 FD std
00405B95 33C0 xor eax, eax
00405B97 B9 56030000 mov ecx, 356
00405B9C E8 98740000 call Notepad.0040D039 F7进去,不然跑飞。
00405BA1 0000 add byte ptr ds:[eax], al 无代码
00405BA3 0000 add byte ptr ds:[eax], al
00405BA5 0000 add byte ptr ds:[eax], al
00405BA7 0000 add byte ptr ds:[eax], al
0040D039 5F pop edi 到这里
0040D03A F3:AA rep stos byte ptr es:[edi]
0040D03C 61 popad 关键字1,与开始处完全对应。
0040D03D 66:9D popfw 关键字2,与开始处完全对应。
0040D03F 83C4 08 add esp, 8
0040D042 >- E9 8540FFFF jmp Notepad.004010CC 跨段跳跃到入口。
004010CC 55 push ebp
程序跨段,并且经过了PoPad和popfw两个关键字。我们再这里用Od的Dump插件直接脱壳。
004010CD 8BEC mov ebp, esp
004010CF 83EC 44 sub esp, 44
004010D2 56 push esi
004010D3 FF15 E4634000 call dword ptr ds:[4063E4] ; kernel32.GetCommandLineA
004010D9 8BF0 mov esi, eax
004010DB 8A00 mov al, byte ptr ds:[eax]
004010DD 3C 22 cmp al, 22
004010DF 75 1B jnz short Notepad.004010FC
004010E1 56 push esi
004010E2 FF15 F4644000 call dword ptr ds:[4064F4] ; Notepad.0040D0BA
重建输入表时,插件有两个选项。Method2重建输入表很快,脱壳后运行率高。Method1重建输入表慢,脱壳后运行率较低。不过本程序用Method2重建输入表无法运行,Method1重建输入表后程序可直接运行。
总结:
第一次见识SEH,还好不是很多,你只要能从这两个陷阱中出来就能顺利到达Oep处。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课