用armgfindprotected工具检测内容如下:
!- Protected Armadillo
<Protection Options>
Debug-Blocker
CopyMem-II
Enable Memory-Patching Protections
<Backup Key Options>
Fixed Backup Keys
<Compression Options>
Better/Slower Compression !- Child detach
Child process ID: 00000D20
Entry point: 00736363
Original bytes: 558B
虽然有Enable Memory-Patching Protections,但是如果使用修改版的od,直接把它当做CopyMem-II来脱就行!这个没有code,只有iat,所以简单些
od载入,忽略所有异常,隐藏od
00736363 >/$ 55 PUSH EBP
00736364 |. 8BEC MOV EBP,ESP
00736366 |. 6A FF PUSH -1
00736368 |. 68 200B7600 PUSH fotobatc.00760B20
0073636D |. 68 A0607300 PUSH fotobatc.007360A0 ; SE 处理程序安装
00736372 |. 64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
00736378 |. 50 PUSH EAX
00736379 |. 64:8925 00000>MOV DWORD PTR FS:[0],ESP
00736380 |. 83EC 58 SUB ESP,58
00736383 |. 53 PUSH EBX
(1)查找OEP
在命令行中先下bp WaitForDebugEvent断点,这个函数有两个参数,其中一个指向接收调试事件信息DEBUG_ENENT的指针,Shift+F9运行
7C849128 > 8BFF MOV EDI,EDI 来到这里,注意此时的堆栈处
7C84912A 55 PUSH EBP
7C84912B 8BEC MOV EBP,ESP
7C84912D 83EC 68 SUB ESP,68
7C849130 56 PUSH ESI
堆栈处如下:
0012BCB8 007264DF /CALL 到 WaitForDebugEvent 来自 fotobatc.007264D9
0012BCBC 0012CD90 |pDebugEvent = 0012CD90 ;这个就是指针了,在数据窗口跟随,按F2键取消断点
0012BCC0 000003E8 \Timeout = 1000. ms
继续在命令行下bp WriteProcessMemory断点,Shift+F9运行
7C80226F > 8BFF MOV EDI,EDI 来到这里,看看堆栈处
7C802271 55 PUSH EBP
7C802272 8BEC MOV EBP,ESP
7C802274 51 PUSH ECX
7C802275 51 PUSH ECX
7C802276 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C]
7C802279 53 PUSH EBX
7C80227A 8B5D 14 MOV EBX,DWORD PTR SS:[EBP+14]
堆栈处如下:
0012BB58 0072A477 /CALL 到 WriteProcessMemory 来自 fotobatc.0072A471
0012BB5C 0000004C |hProcess = 0000004C (window)
0012BB60 006A9000 |Address = 6A9000 ;这里是欲写入区域的基地址
0012BB64 003EE6C8 |Buffer = 003EE6C8
0012BB68 00001000 |BytesToWrite = 1000 (4096.)
0012BB6C 0012BC74 \pBytesWritten = 0012BC74
现在我们看数据窗口
0012CD9C 80000001
0012CDA0 00000000
0012CDA4 00000000
0012CDA8 006A9E80 fotobatc.006A9E80
0012CDAC 00000002
0012CDB0 00000000
0012CDB4 006A9E80 fotobatc.006A9E80
0012CDB8 006A9E80 fotobatc.006A9E80
0012CDBC 00000001
看到OEP了吧。OEP=006a9e80
(2)dump
重新在OD中载入程序,重新下bp WaitForDebugEvent,Shift+F9运行,取消断点Alt+F9返回
007264DF . 85C0 TEST EAX,EAX 返回到这里
007264E1 . 0F84 2B270000 JE fotobatc.00728C12
007264E7 . 8B85 FCFDFFFF MOV EAX,DWORD PTR SS:[EBP-204]
007264ED . 25 FF000000 AND EAX,0FF
007264F2 . 85C0 TEST EAX,EAX
007264F4 . 74 13 JE SHORT fotobatc.00726509
007264F6 . 8B0D 441F7600 MOV ECX,DWORD PTR DS:[761F44]
007264FC . 8379 20 00 CMP DWORD PTR DS:[ECX+20],0
00726500 . 74 07 JE SHORT fotobatc.00726509
按CTRL+F键,输入按CTRL+F键,输入or eax,0fffffff8按查找。按查找。
00726A63 > \83BD CCF5FFFF>CMP DWORD PTR SS:[EBP-A34],0 ;找到这里,设置断点运行到这里
00726A6A . 0F8C A8020000 JL fotobatc.00726D18 注意这里
00726A70 . 8B8D CCF5FFFF MOV ECX,DWORD PTR SS:[EBP-A34] 注意这里
00726A76 . 3B0D 481F7600 CMP ECX,DWORD PTR DS:[761F48] 注意这里
00726A7C . 0F8D 96020000 JGE fotobatc.00726D18
00726A82 . 8B95 40F6FFFF MOV EDX,DWORD PTR SS:[EBP-9C0]
00726A88 . 81E2 FF000000 AND EDX,0FF
00726A8E . 85D2 TEST EDX,EDX
00726A90 . 0F84 AD000000 JE fotobatc.00726B43
00726A96 . 6A 00 PUSH 0
00726A98 . 8BB5 CCF5FFFF MOV ESI,DWORD PTR SS:[EBP-A34]
00726A9E . C1E6 04 SHL ESI,4
00726AA1 . 8B85 CCF5FFFF MOV EAX,DWORD PTR SS:[EBP-A34]
00726AA7 . 25 07000080 AND EAX,80000007
00726AAC . 79 05 JNS SHORT fotobatc.00726AB3
00726AAE . 48 DEC EAX
00726AAF . 83C8 F8 OR EAX,FFFFFFF8 ;找到这里。来到这里,向上翻
00726AB2 . 40 INC EAX
00726AB3 > 33C9 XOR ECX,ECX
在726A63处下断点,F9运行到726A63 处,取消断点,得到[0012CD7c]=000002a8,把0012cd7c的数据改为0,
代码窗口向下翻
00726B1D . 8B15 2C1F7600 MOV EDX,DWORD PTR DS:[761F2C]
00726B23 . 8D04B2 LEA EAX,DWORD PTR DS:[EDX+ESI*4]
00726B26 . 50 PUSH EAX
00726B27 . 8B8D CCF5FFFF MOV ECX,DWORD PTR SS:[EBP-A34]
00726B2D . 51 PUSH ECX
00726B2E . E8 2F210000 CALL fotobatc.00728C62
00726B33 . 83C4 0C ADD ESP,0C
00726B36 . 25 FF000000 AND EAX,0FF 从这里开始修改
00726B3B . 85C0 TEST EAX,EAX
00726B3D . 0F84 D5010000 JE fotobatc.00726D18
00726B43 > 837D D8 00 CMP DWORD PTR SS:[EBP-28],0
00726B47 . 75 27 JNZ SHORT fotobatc.00726B70
找到
00726B36 . 25 FF000000 AND EAX,0FF
00726B3B . 85C0 TEST EAX,EAX
00726B3D . 0F84 D5010000 JE fotobatc.00726D18
改为
00726B36 FF05 7CCD1200 INC DWORD PTR DS:[12CD7C]
00726B3C C705 4C1F7600>MOV DWORD PTR DS:[761F4C],1
00726B46 ^ E9 18FFFFFF JMP fotobatc.00726A63
接着在00726A63下一行处可看到
00726A6A . /0F8C A8020000 JL fotobatc.00726D18
跟随到00726D18处下断点,Shift+F9运行,取消断点,
这时所有代码都强制解压完成,运行LordPE,选择第二个进程完整脱壳,修改脱壳后的dumped的OEP为2a9e80,保存进入下一步。
重新把原程序载入OD,下断bp DebugActiveProcess,Shift+F9运行,注意堆栈处
0012BCBC 0072633A /CALL 到 DebugActiveProcess 来自 fotobatc.00726334
0012BCC0 000007F0 \ProcessId = 7F0 这个是子进程ID,你的不一定相同
另开一个OD,在附加处选择7f0这个进程,Alt+F9返回
00736363 >- EB FE JMP SHORT fotobatc.<模块入口点> 停在这里,修改为55 8B
00736365 EC IN AL,DX ; I/O 命令
00736366 6A FF PUSH -1
00736368 68 200B7600 PUSH fotobatc.00760B20
0073636D 68 A0607300 PUSH fotobatc.007360A0 ; SE 处理程序安装
然后运行双进程转单进程脚本。完毕后,下断BP GetModuleHandleA+5,Shift+F9,注意观察堆栈!
00126880 /0012CCE0
00126884 |01083637 返回到 01083637 来自 kernel32.GetModuleHandleA
00126888 |01097474 ASCII "kernel32.dll"
0012688C |01098744 ASCII "VirtualAlloc"
00126890 |00000001
00126880 /0012CCE0
00126884 |01083654 返回到 01083654 来自 kernel32.GetModuleHandleA
00126888 |01097474 ASCII "kernel32.dll"
0012688C |01098738 ASCII "VirtualFree"
001265F0 /00126884
001265F4 |0106ABB9 返回到 0106ABB9 来自 kernel32.GetModuleHandleA
001265F8 |00126738 ASCII "kernel32.dll"
001265FC |00000000
不断Shft+F9直到经过VirtualAlloc、VirtualFree再次在堆栈中看见kernel32.dll,是返回的时机了,取消断点,ALT+F9返回
0106ABB9 8B0D E4C90901 MOV ECX,DWORD PTR DS:[109C9E4]
0106ABBF 89040E MOV DWORD PTR DS:[ESI+ECX],EAX
0106ABC2 A1 E4C90901 MOV EAX,DWORD PTR DS:[109C9E4]
0106ABC7 391C06 CMP DWORD PTR DS:[ESI+EAX],EBX
0106ABCA 75 16 JNZ SHORT 0106ABE2
0106ABCC 8D85 B4FEFFFF LEA EAX,DWORD PTR SS:[EBP-14C]
0106ABD2 50 PUSH EAX
0106ABD3 FF15 E0200901 CALL DWORD PTR DS:[10920E0] ; kernel32.LoadLibraryA
0106ABD9 8B0D E4C90901 MOV ECX,DWORD PTR DS:[109C9E4]
0106ABDF 89040E MOV DWORD PTR DS:[ESI+ECX],EAX
0106ABE2 A1 E4C90901 MOV EAX,DWORD PTR DS:[109C9E4]
0106ABE7 391C06 CMP DWORD PTR DS:[ESI+EAX],EBX
0106ABEA 0F84 32010000 JE 0106AD22 修改为jmp 0106AD22
0106ABF0 33C9 XOR ECX,ECX
0106ABF2 8B07 MOV EAX,DWORD PTR DS:[EDI]
按一次F9直接运行
打开ImportREC选择7f0这个进程
OEP=2a9e80
RAV=2E7280
大小=930
直接点击获取输入表,CUT掉无效的指针修复dumped即可以了.
这里说说rva的找法
od载入dump.exe
006A9E80 dumped.<> 55 push ebp
006A9E81 8BEC mov ebp,esp
006A9E83 B9 13000000 mov ecx,13
006A9E88 6A 00 push 0
006A9E8A 6A 00 push 0
006A9E8C 49 dec ecx
006A9E8D ^ 75 F9 jnz short dumped.006A9E88
006A9E8F 53 push ebx
006A9E90 56 push esi
006A9E91 57 push edi
006A9E92 B8 90986A00 mov eax,dumped.006A9890
006A9E97 E8 B0CFD5FF call dumped.00406E4C 这里f7
006A9E9C 33C0 xor eax,eax
到这里
00406E4C 53 push ebx
00406E4D 8BD8 mov ebx,eax
00406E4F 33C0 xor eax,eax
00406E51 A3 ACB06A00 mov dword ptr ds:[6AB0AC],eax
00406E56 6A 00 push 0
00406E58 E8 2BFFFFFF call dumped.00406D88 这里f7
00406E5D A3 68A66C00 mov dword ptr ds:[6CA668],eax
到这里
00406D88 - FF25 78736E00 jmp dword ptr ds:[6E7378]
00406D8E 8BC0 mov eax,eax
00406D90 - FF25 74736E00 jmp dword ptr ds:[6E7374] ; kernel32.LocalAlloc
00406D96 8BC0 mov eax,eax
00406D98 - FF25 70736E00 jmp dword ptr ds:[6E7370] ; kernel32.TlsGetValue
00406D9E 8BC0 mov eax,eax
00406DA0 - FF25 6C736E00 jmp dword ptr ds:[6E736C] ; kernel32.TlsSetValue
在数据窗口,ctrl+G,输入006e7378
上下查找
006E727C 00000000
006E7280 7C96AE65 ntdll.RtlDeleteCriticalSection 这里开始的
006E7284 7C95F2FC ntdll.RtlLeaveCriticalSection
006E7288 7C95F337 ntdll.RtlEnterCriticalSection
006E728C 7C8284E0 kernel32.InitializeCriticalSection
006E7BA8 0105BF23
006E7BAC 77BDA69A GDI32.CreateDIBSection
006E7BB0 0105BF23 这里结束的
大小=006E7BB0-006E7280=930
运行,ok
脱壳后,程序仍然要求注册!od,载入,f9运行,到程序帮助菜单下,输入注册码,比如注册码为aabbccddeeffgg,点确定,没反映,不要紧,回到od下,alt+m,右键,搜索,asscii,输入aabbccddeeffgg,找到了吧,ctrl+L,观察下面的字符串,重新填入注册就是.