一、破解目标: 联众台球圣手v4.7试用版
二、破解工具:OllyDbg v1.10,ImportREC 1.6 Final,LordPE
三、破解作者:csjwaman
四、破解过程:
1.寻找版本号:
用PEiD扫描,提示为Armadillo 1.xx - 2.xx -> Silicon Realms Toolworks [Overlay]。这其实是误报,实际应为ARM3.60双进程非标准壳。
因为是双进程的,先用以下脚本转换为单进程:
//转单进程脚本
msg "请忽略所有异常,并添加忽略C000001E异常,然后运行本脚本!"
gpa "OpenMutexA","kernel32.dll"
bp $RESULT
esto
exec
pushad
pushfd
push edx
xor eax,eax
push eax
push eax
call kernel32.CreateMutexA
popfd
popad
jmp kernel32.OpenMutexA
ende
bc eip
msg "现已转换成单进程!"
ret
运行脚本后停在:
77E62391 k> 55 push ebp///停在这里。
77E62392 8BEC mov ebp,esp
77E62394 51 push ecx
77E62395 51 push ecx
77E62396 837D 10 00 cmp dword ptr ss:[ebp+10],0
77E6239A 56 push esi
77E6239B 0F84 C2E30100 je 77E80763 ; 77E80763
77E623A1 64:A1 18000000 mov eax,dword ptr fs:[18]
77E623A7 FF75 10 push dword ptr ss:[ebp+10]
SHIFT+F9运行,出现异常:
00D306A7 A1 3857D400 mov eax,dword ptr ds:[D45738]
00D306AC 8B0D 9455D400 mov ecx,dword ptr ds:[D45594] ; Ball4.004EC260
00D306B2 8B04B0 mov eax,dword ptr ds:[eax+esi*4]///停在这里。
00D306B5 3341 54 xor eax,dword ptr ds:[ecx+54]
00D306B8 8B0D 9455D400 mov ecx,dword ptr ds:[D45594] ; Ball4.004EC260
00D306BE 3341 04 xor eax,dword ptr ds:[ecx+4]
00D306C1 8B0D 9455D400 mov ecx,dword ptr ds:[D45594] ; Ball4.004EC260
00D306C7 3341 74 xor eax,dword ptr ds:[ecx+74]
00D306CA 8B0D 9455D400 mov ecx,dword ptr ds:[D45594] ; Ball4.004EC260
00D306D0 3341 30 xor eax,dword ptr ds:[ecx+30]
00D306D3 8B0D 9455D400 mov ecx,dword ptr ds:[D45594] ; Ball4.004EC260
00D306D9 3341 20 xor eax,dword ptr ds:[ecx+20]
出现上述,说明这是非标准加壳方式。现在搜索所有参考文本串,然后查找字符“armVersion”,找到后在上一行就可以看到字符“3.60”。这就是版本号了。
2.寻找OEP和DUMP进程
重新加载程序,下断BP WaitForDebugEvent,断下后堆栈如下:
0012DAC0 004C1D67 /CALL 到 WaitForDebugEvent 来自 Ball4.004C1D61
0012DAC4 0012EB84 |pDebugEvent = 0012EB84///进数据窗口。
0012DAC8 000003E8 \Timeout = 1000. ms
取消断点,然后bp WriteProcessMemory 再F9,内存窗口数据如下:
0012EB84 01 00 00 00 E4 0A 00 00 ...?..
0012EB8C E8 0A 00 00 01 00 00 80 ?....?
0012EB94 00 00 00 00 00 00 00 00 ........
0012EB9C 38 77 49 00 02 00 00 00 8wI....
0012EBA4 00 00 00 00 38 77 49 00 ....8wI.
0012EBAC 38 77 49 00 00 00 00 00 8wI.....
0012EBB4 01 C7 4F E1 00 00 00 00 窍?...
其中497738就是OEP地址了。
ALT+F9返回:
004C5C6E . 85C0 test eax,eax///返回这里。
004C5C70 . 75 4B jnz short 004C5CBD ; 004C5CBD
004C5C72 . 50 push eax
004C5C73 . F7D0 not eax
004C5C75 . 0FC8 bswap eax
004C5C77 . 58 pop eax
这里搜索所有命令“or eax,FFFFFFF8”,结果:
004C23D6 or eax,FFFFFFF8///双击这行。
004C2933 or eax,FFFFFFF8
004C5C6E test eax,eax
双击后来到:
004C238A > \83BD D0F5FFFF 00 cmp dword ptr ss:[ebp-A30],0/////下断,Shift+F9中断下来 把[ebp-A30]=[0012EB70]=00000005清0
004C2391 . 0F8C A9020000 jl 004C2640 ; 004C2640
004C2397 . 8B8D D0F5FFFF mov ecx,dword ptr ss:[ebp-A30]
004C239D . 3B0D E4254F00 cmp ecx,dword ptr ds:[4F25E4]///注意[4F25E4]
004C23A3 . 0F8D 97020000 jge 004C2640//解码结束后跳转004C2640,到004C2640处下断
004C23A9 . 8B95 44F6FFFF mov edx,dword ptr ss:[ebp-9BC]
004C23AF . 81E2 FF000000 and edx,0FF
004C23B5 . 85D2 test edx,edx
004C23B7 . 0F84 AD000000 je 004C246A ; 004C246A
004C23BD . 6A 00 push 0
004C23BF . 8BB5 D0F5FFFF mov esi,dword ptr ss:[ebp-A30]
004C23C5 . C1E6 04 shl esi,4
004C23C8 . 8B85 D0F5FFFF mov eax,dword ptr ss:[ebp-A30]
004C23CE . 25 07000080 and eax,80000007
004C23D3 . 79 05 jns short 004C23DA ; 004C23DA
004C23D5 . 48 dec eax
004C23D6 . 83C8 F8 or eax,FFFFFFF8///来到这里。
004C23D9 . 40 inc eax
004C23DA > 33C9 xor ecx,ecx
004C23DC . 8A88 800A4F00 mov cl,byte ptr ds:[eax+4F0A80]
004C23E2 . 8B95 D0F5FFFF mov edx,dword ptr ss:[ebp-A30]
004C23E8 . 81E2 07000080 and edx,80000007
004C23EE . 79 05 jns short 004C23F5 ; 004C23F5
004C23F0 . 4A dec edx
004C23F1 . 83CA F8 or edx,FFFFFFF8
004C23F4 . 42 inc edx
004C23F5 > 33C0 xor eax,eax
004C23F7 . 8A82 810A4F00 mov al,byte ptr ds:[edx+4F0A81]
004C23FD . 8B3C8D 60C24E00 mov edi,dword ptr ds:[ecx*4+4EC260]
004C2404 . 333C85 60C24E00 xor edi,dword ptr ds:[eax*4+4EC260]
004C240B . 8B8D D0F5FFFF mov ecx,dword ptr ss:[ebp-A30]
004C2411 . 81E1 07000080 and ecx,80000007
004C2417 . 79 05 jns short 004C241E ; 004C241E
004C2419 . 49 dec ecx
004C241A . 83C9 F8 or ecx,FFFFFFF8
004C241D . 41 inc ecx
004C241E > 33D2 xor edx,edx
004C2420 . 8A91 820A4F00 mov dl,byte ptr ds:[ecx+4F0A82]
004C2426 . 333C95 60C24E00 xor edi,dword ptr ds:[edx*4+4EC260]
004C242D . 8B85 D0F5FFFF mov eax,dword ptr ss:[ebp-A30]
004C2433 . 99 cdq
004C2434 . B9 1C000000 mov ecx,1C
004C2439 . F7F9 idiv ecx
004C243B . 8BCA mov ecx,edx
004C243D . D3EF shr edi,cl
004C243F . 83E7 0F and edi,0F
004C2442 . 03F7 add esi,edi
004C2444 . 8B15 D4254F00 mov edx,dword ptr ds:[4F25D4]
004C244A . 8D04B2 lea eax,dword ptr ds:[edx+esi*4]
004C244D . 50 push eax
004C244E . 8B8D D0F5FFFF mov ecx,dword ptr ss:[ebp-A30]
004C2454 . 51 push ecx
004C2455 . E8 FF1F0000 call 004C4459 ; 004C4459
004C245A . 83C4 0C add esp,0C
004C245D . 25 FF000000 and eax,0FF///这里开始Patch
004C2462 . 85C0 test eax,eax
004C2464 . 0F84 D6010000 je 004C2640 ; 004C2640
004C246A > 837D D8 00 cmp dword ptr ss:[ebp-28],0
004C246E . 75 28 jnz short 004C2498 ; 004C2498
004C2470 . 8B15 B8C24E00 mov edx,dword ptr ds:[4EC2B8]
004C2476 . 3315 CCC24E00 xor edx,dword ptr ds:[4EC2CC]
004C247C . 3315 D0C24E00 xor edx,dword ptr ds:[4EC2D0]
004C2482 . 81E2 00002000 and edx,200000
004C2488 . 85D2 test edx,edx
Patch代码:
004C245D FF85 D0F5FFFF inc dword ptr ss:[ebp-A30]
004C2463 C705 E8254F00 0100>mov dword ptr ds:[4F25E8],1
004C246D ^ E9 18FFFFFF jmp 004C238A ; 004C238A
004C2472 90 nop
004C2473 90 nop
用以上代码欺骗主进程解码。
SHIFT+F9,程序断在:
004C2640 > \E9 E00F0000 jmp 004C3625///断在这里。
004C2645 > 8B0D A0C24E00 mov ecx,dword ptr ds:[4EC2A0]
004C264B . 81F1 050000C0 xor ecx,C0000005
004C2651 . 398D D8F5FFFF cmp dword ptr ss:[ebp-A28],ecx
此时子进程代码全部解开,运行LordPE,完全Dump出子进程。
3.寻找IAT
将DUMP出来的程序OEP改为97738,然后用OD载入,跟踪几步就可以找到IAT。
004063B8 - FF25 0CD24900 jmp dword ptr ds:[49D20C]
004063BE 8BC0 mov eax,eax
004063C0 - FF25 08D24900 jmp dword ptr ds:[49D208] ; kernel32.LocalAlloc
004063C6 8BC0 mov eax,eax
004063C8 - FF25 04D24900 jmp dword ptr ds:[49D204] ; kernel32.TlsGetValue
004063CE 8BC0 mov eax,eax
004063D0 - FF25 00D24900 jmp dword ptr ds:[49D200] ; kernel32.TlsSetValue
004063D6 8BC0 mov eax,eax
0049D13C 00 00 00 00 12 9D F6 77 ....?w
0049D144 80 B3 F5 77 A0 B2 F5 77 ?貅_蝉w
0049D14C 45 A7 E5 77 CB 15 E6 77 Eуw?骥
0049D154 72 AC E5 77 A0 60 E5 77 r?w_`鬻
。。。。。。
0049D884 CB 3D 40 77 8B 88 D1 00 ?@w??
0049D88C 58 0F DB 77 C3 88 D1 00 X埙??
0049D894 6B 65 72 6E 65 6C 33 32 kernel32
0049D89C 2E 64 6C 6C 00 00 00 00 .dll....
IAT地址49D13C 大小49D894-49D13C=758
重新载入主程序,BP DebugActiveProcess 中断后看堆栈:
0012DAC4 004C1BDB /CALL 到 DebugActiveProcess 来自 Ball4.004C1BD5
0012DAC8 00000F2C \ProcessId = F2C
新开一个OllyDbg,附加进程ID E2C的子进程(每次子进程ID会不同)
F9,再F12,会暂停在EP处:
004D1999 B>/$- EB FE jmp short 004D1999 ///在此死循环。
004D199B |? EC in al,dx
004D199C |. 6A FF push -1
004D199E |. 68 501C4F00 push 4F1C50
004D19A3 |. 68 80134D00 push 4D1380 ; SE handler installation
004D19A8 |. 64:A1 00000000 mov eax,dword ptr fs:[0]
004D19AE |. 50 push eax
004D19AF |. 64:8925 00000000 mov dword ptr fs:[0],esp
将4D1999处代码改回558B :
004D1999 B> 55 push ebp///改回后的代码。
004D199A 8BEC mov ebp,esp
004D199C 6A FF push -1
004D199E 68 501C4F00 push 4F1C50
004D19A3 68 80134D00 push 4D1380 ; SE handler installation
004D19A8 64:A1 00000000 mov eax,dword ptr fs:[0]
004D19AE 50 push eax
现在再用上述脚本转换为单进程。然后下断HE GetModuleHandleA SHIFT+F9 断下后堆栈如下:
0012ECC8 77C059FC /CALL 到 GetModuleHandleA 来自 msvcrt.77C059F6
0012ECCC 77BE31AC \pModule = "kernel32.dll"
。。。。。。
0012BF20 00BFC807 /CALL 到 GetModuleHandleA 来自 00BFC801
0012BF24 00C0D6C8 \pModule = "kernel32.dll"
0012BF28 00C0E67C ASCII "VirtualAlloc"
0012BF20 00BFC824 /CALL 到 GetModuleHandleA 来自 00BFC81E
0012BF24 00C0D6C8 \pModule = "kernel32.dll"
0012BF28 00C0E670 ASCII "VirtualFree"
0012BC98 00BE799B /CALL 到 GetModuleHandleA 来自 00BE7995
0012BC9C 0012BDD4 \pModule = "kernel32.dll"
堆栈如上变化时,取消GetModuleHandleA处断点,Alt+F9返回:
00BE799B 8B0D E011C100 mov ecx,dword ptr ds:[C111E0]
00BE79A1 89040E mov dword ptr ds:[esi+ecx],eax
00BE79A4 A1 E011C100 mov eax,dword ptr ds:[C111E0]
00BE79A9 393C06 cmp dword ptr ds:[esi+eax],edi
00BE79AC 75 16 jnz short 00BE79C4
00BE79AE 8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C]
00BE79B4 50 push eax
00BE79B5 FF15 CC80C000 call dword ptr ds:[C080CC] ; kernel32.LoadLibraryA
00BE79BB 8B0D E011C100 mov ecx,dword ptr ds:[C111E0]
00BE79C1 89040E mov dword ptr ds:[esi+ecx],eax
00BE79C4 A1 E011C100 mov eax,dword ptr ds:[C111E0]
00BE79C9 393C06 cmp dword ptr ds:[esi+eax],edi
00BE79CC 0F84 AD000000 je 00BE7A7F///改为JMP
00BE79D2 33C9 xor ecx,ecx
00BE79D4 8B03 mov eax,dword ptr ds:[ebx]
00BE79D6 3938 cmp dword ptr ds:[eax],edi
00BE79D8 74 06 je short 00BE79E0
00BE79DA 41 inc ecx
00BE79DB 83C0 0C add eax,0C
00BE79DE ^ EB F6 jmp short 00BE79D6
00BE79E0 8BC1 mov eax,ecx
00BE79E2 C1E0 02 shl eax,2
。。。。。。
00BE7A7F 83C3 0C add ebx,0C
00BE7A82 83C6 04 add esi,4
00BE7A85 397B FC cmp dword ptr ds:[ebx-4],edi
00BE7A88 ^ 0F85 CCFEFFFF jnz 00BE795A
00BE7A8E EB 03 jmp short 00BE7A93
SHIFT+F9来到OEP处,由于代码没有解密,所以程序无法运行。
00497738 66:C7 ??? ///停在这里。
0049773A 6C ins byte ptr es:[edi],dx
0049773B DFF7 fcomip st,st(7)
0049773D BC 38B44705 mov esp,547B438
00497742 80B407 A176A392 C4 xor byte ptr ds:[edi+eax+92A376A1],0C4
0049774A 2915 33C780B4 sub dword ptr ds:[B480C733],edx
用ImportREC手动填入OEP=97738,RVA=9D13C,SIZE=758,去掉不可用的指针即可获得完整的IAT。
FIX,完工。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!