各为先辈,我最近刚开始学习脱壳,遇到这么一个壳,用PEid显示为
ASProtect V2.X Registered -> Alexey Solodovnikov *
用OllyIce载入后,如果不使用OllyIce,直接按F9,提示有调试器,如果使用HideOI,使用全部选项隐藏,不设任何断点,直接按f9,会执行出Winxp系统的发送报告错误的提示框。但如果不使用调试器直接运行是可以的..
用OllyICE加载后,头几行代码如下:
00401000 >/$ 68 01204E00 push 004E2001
00401005 |. E8 01000000 call 0040100B
0040100A \. C3 retn
0040100B $ C3 retn
我使用本论坛提供的教程,慢慢地跟综,发现程序一共用了5个步骤依次生成自己执行代码,并从内存总申请到一个区快,并在最后写了很多执行代码在这个区.最后用以下代码转移到过去
00BCE0EB F3:A4 rep movs byte ptr es:[edi], byte ptr [esi] ; 这段代码填写了下面的00BCE107的push eax代码
00BCE0ED 8B85 75294400 mov eax, [ebp+442975] ;这里一定要先设断点一次
00BCE0F3 68 00800000 push 8000
00BCE0F8 6A 00 push 0
00BCE0FA 50 push eax
00BCE0FB FF95 7D294400 call [ebp+44297D]
00BCE101 8D85 512C4400 lea eax, [ebp+442C51]
00BCE107 50 push eax
00BCE108 C3 retn
跳转之后的代码有申请了一块新的内存,填写了代码后利用下面的代码跳转过去..(ps.让我感觉好象是两层代码,因为再下去的代码就是另外一种非常难读懂的形式出现了,跟到这里,哦还觉得不是很难,虽然我只是个初学者...)
00BCE5AB 8B85 652A4400 mov eax, [ebp+442A65]
00BCE5B1 50 push eax
00BCE5B2 0385 D8304400 add eax, [ebp+4430D8]
00BCE5B8 5B pop ebx
00BCE5B9 0BDB or ebx, ebx
00BCE5BB 8985 112F4400 mov [ebp+442F11], eax
00BCE5C1 61 popad
00BCE5C2 75 08 jnz short 00BCE5CC
00BCE5C4 B8 01000000 mov eax, 1
00BCE5C9 C2 0C00 retn 0C
00BCE5CC 68 B0E5BB00 push 0BBE5B0
00BCE5D1 C3 retn ;程序跳转到00BBE5B0的位置
跳转之后的新的代码如下:
00BBE5B0 55 push ebp ; 004E2492
00BBE5B1 8BEC mov ebp, esp
00BBE5B3 83C4 B4 add esp, -4C
00BBE5B6 B8 B8E2BB00 mov eax, 0BBE2B8
00BBE5BB E8 C877FCFF call 00B85D88
00BBE5C0 E8 FB4FFCFF call 00B835C0 ;假的Call.实际上是跳转..
00BBE5C5 8D40 00 lea eax, [eax]
00BBE5C8 0000 add [eax], al
00BBE5CA 0000 add [eax], al
00B835C0处的代码如下:
00B835C0 53 push ebx
00B835C1 56 push esi
00B835C2 57 push edi
00B835C3 55 push ebp
00B835C4 BB 9C04BC00 mov ebx, 0BC049C
00B835C9 BE 3000BC00 mov esi, 0BC0030
00B835CE BF 3400BC00 mov edi, 0BC0034
00B835D3 807B 24 00 cmp byte ptr [ebx+24], 0
00B835D7 75 16 jnz short 00B835EF
00B835D9 833F 00 cmp dword ptr [edi], 0
00B835DC 74 11 je short 00B835EF
00B835DE 8B17 mov edx, [edi]
00B835E0 89D0 mov eax, edx
00B835E2 33D2 xor edx, edx
00B835E4 8917 mov [edi], edx
00B835E6 8BE8 mov ebp, eax
00B835E8 FFD5 call ebp
00B835EA 833F 00 cmp dword ptr [edi], 0
00B835ED ^ 75 EF jnz short 00B835DE
00B835EF 833D 3800BC00 00 cmp dword ptr [BC0038], 0
00B835F6 74 47 je short 00B8363F
00B835F8 E8 3FFFFFFF call 00B8353C
00B835FD 803D 4000BC00 00 cmp byte ptr [BC0040], 0
00B83604 74 16 je short 00B8361C
00B83606 BA 28F0BB00 mov edx, 0BBF028 ; ASCII "Runtime error at 00000000"
00B8360B B8 1402BC00 mov eax, 0BC0214
00B83610 E8 FB1E0000 call 00B85510
00B83615 E8 791E0000 call 00B85493
00B8361A EB 1C jmp short 00B83638
00B8361C 803D 0CF0BB00 00 cmp byte ptr [BBF00C], 0
00B83623 75 13 jnz short 00B83638
00B83625 6A 00 push 0
00B83627 68 48F0BB00 push 0BBF048 ; ASCII "Error"
00B8362C 68 28F0BB00 push 0BBF028 ; ASCII "Runtime error at 00000000"
00B83631 6A 00 push 0
00B83633 E8 A0DAFFFF call 00B810D8 ; jmp 到 user32.MessageBoxA
00B83638 33C0 xor eax, eax
00B8363A A3 3800BC00 mov [BC0038], eax
00B8363F 807B 24 02 cmp byte ptr [ebx+24], 2
00B83643 75 0A jnz short 00B8364F
00B83645 833E 00 cmp dword ptr [esi], 0
00B83648 75 05 jnz short 00B8364F
00B8364A 33C0 xor eax, eax
00B8364C 8943 0C mov [ebx+C], eax
00B8364F E8 48FDFFFF call 00B8339C
00B83654 807B 24 01 cmp byte ptr [ebx+24], 1
00B83658 76 05 jbe short 00B8365F
00B8365A 833E 00 cmp dword ptr [esi], 0
00B8365D 74 1D je short 00B8367C
00B8365F 8B43 10 mov eax, [ebx+10]
00B83662 85C0 test eax, eax
00B83664 74 16 je short 00B8367C
00B83666 E8 E9170000 call 00B84E54
00B8366B 8B43 10 mov eax, [ebx+10]
00B8366E 8B50 10 mov edx, [eax+10]
00B83671 3B50 04 cmp edx, [eax+4]
00B83674 74 06 je short 00B8367C
00B83676 52 push edx
00B83677 E8 74DAFFFF call 00B810F0 ; jmp 到 kernel32.FreeLibrary
00B8367C E8 F3FCFFFF call 00B83374 ; ;BlowFreeLibray
00B83681 807B 24 01 cmp byte ptr [ebx+24], 1
00B83685 75 03 jnz short 00B8368A
00B83687 FF53 28 call [ebx+28]
00B8368A 807B 24 00 cmp byte ptr [ebx+24], 0
00B8368E 74 05 je short 00B83695
00B83690 E8 F7FEFFFF call 00B8358C ; 似乎关键代码在这里,这个Call 实际上也是跳转,这以后的代码其实不会被执行,我在下一行上设断点,根本就不会被执行到...
00B83695 833B 00 cmp dword ptr [ebx], 0
00B83698 75 08 jnz short 00B836A2
00B8369A 8B06 mov eax, [esi]
00B8369C 50 push eax
00B8369D E8 2EDAFFFF call 00B810D0 ; jmp 到 kernel32.ExitProcess
00B836A2 8B03 mov eax, [ebx]
00B836A4 56 push esi
00B836A5 8BF0 mov esi, eax
00B836A7 8BFB mov edi, ebx
00B836A9 B9 0B000000 mov ecx, 0B
00B836AE F3:A5 rep movs dword ptr es:[edi], dword ptr [esi]
00B836B0 5E pop esi
00B836B1 ^ EB 8C jmp short 00B8363F
在往下的代码就是本上用Call做跳转,其中在一个Call的过程里,通过调用真正假假的大量call过程,通过修改ESP,来实现循环,甚至还跑道数据区里面执行代码,然后有用retn回到那个大循环的call里面,而且还有一点,如果用F7或F8跟踪,就是一不小心就会执行到0000的代码,(到现在我还没看明白他是如何搞成这样一来的,一个jmp 跳到的地址里都是000000 add [eax],al;eax的为0)导致内存写入错误,但如果用f4比较大段的执行倒是可以跳过这种陷阱的..
上面说的那个恶心的call大循环迷阵我基本上找到出口了,但又遇到了windows异常..
我在论坛搜了一阵,没有找到大家有谈论类似的壳的..
想问一下各位先行,这个是什么壳啊?有没有脱的窍门?我现在是基本晕掉了..
[课程]Linux pwn 探索篇!