XCyber
2004-09-07
软件名称:PRTG v3.26
加壳方式:Armadillo 1.xx - 2.xx
破解工具:Ollydbg,Hiew,ImportREC
软件介绍:PRTG v3.26是windows平台下的MRTG,它利用SNMP协议对网络流量,CPU负载,内存利用率等数据的进行监控,并且生成各种统计图形,Web页面和报表。MRTG使用起来复杂,操作都是命令行格式,需要perl支持,而PRTG提供图形化的向导,方便简单。
软件下载:http://www.paessler.com/products/prtg
PRTG v3.26是一个标准壳,没有双进程,没有到解密一定页以后就加密原来页。
[1]找oep和Dump方法:
1.Olldby加载prtg3.exe,设bp VirtualProtect,一直按F9或shift + F9,直到堆栈第一次出现如下
0012BAEC 010562F9 /CALL 到 VirtualProtect 来自 010562F7
0012BAF0 00400000 |Address = prtg3.00400000
0012BAF4 00000040 |Size = 40 (64.)
0012BAF8 00000004 |NewProtect = PAGE_READWRITE
0012BAFC 0012BB18 \pOldProtect = 0012BB18
继续按Shift + F9,直到第二次出现与上面一模一样的情况,停下来。一直按Ctrl + F9回到主线程,并不是prtg3.exe领空
0105634F 50 push eax ;<<<<<<返回到这
01056350 F7D0 not eax
01056352 0FC8 bswap eax
01056354 58 pop eax
01056355 73 00 jnb short 01056357
01056357 9C pushfd
01056358 60 pushad
继续按F8,慢,直到到达下面
0105638B 0FC8 bswap eax
0105638D F7D1 not ecx
0105638F 0FC8 bswap eax
01056391 F7D1 not ecx
01056393 8B45 F4 mov eax,dword ptr ss:[ebp-C]
01056396 2BDF sub ebx,edi
01056398 0158 3C add dword ptr ds:[eax+3C],ebx ;这句是修改PE的0x3c,把ebx设为0,防止修改PE头
继续F8,到达下面
0105640F E8 ECABFDFF call 01031000
01056414 83E0 03 and eax,3
01056417 8D4D F8 lea ecx,dword ptr ss:[ebp-8]
0105641A 40 inc eax
0105641B 66:0147 06 add word ptr ds:[edi+6],ax ;这里修改块数,改ax为0
0105641F E8 DCABFDFF call 01031000
这样就去掉Armadillo对PE头的修改,继续按Ctrl + F9回到prtg3.exe领空,继续F8,直到返回到这
006670E4 . 8945 E4 mov dword ptr ss:[ebp-1C],eax ;<<<<<返回到这!
006670E7 . 60 pushad
006670E8 . 33C0 xor eax,eax
006670EA . 75 02 jnz short prtg3.006670EE
006670EC . EB 15 jmp short prtg3.00667103
006670EE > EB 33 jmp short prtg3.00667123
006670F0 C0 db C0
006670F1 . 75 18 jnz short prtg3.0066710B
006670F3 . 7A 0C jpe short prtg3.00667101
006670F5 > 70 0E jo short prtg3.00667105
006670F7 . EB 0D jmp short prtg3.00667106
006670F9 E8 db E8
006670FA 72 db 72 ; CHAR 'r'
006670FB 0E db 0E
006670FC 79 db 79 ; CHAR 'y'
006670FD F1 db F1
006670FE FF db FF
006670FF 15 db 15
00667100 00 db 00
继续按F8,这里要小心,好多乱码,不用管他,直到出现第一个call dword ptr ds:[xxxxxxxx],F7进入
006671C9 . 8BC0 mov eax,eax
006671CB . 6A 00 push 0 ; /Arg1 = 00000000
006671CD . E8 6E000000 call prtg3.00667240 ; \prtg3.00667240
006671D2 . 83C4 04 add esp,4
006671D5 . 6A 00 push 0
006671D7 . E8 DF2C0100 call prtg3.00679EBB
006671DC . 83C4 04 add esp,4
006671DF . 837D E4 01 cmp dword ptr ss:[ebp-1C],1
006671E3 . 75 11 jnz short prtg3.006671F6
006671E5 . 68 C8726900 push prtg3.006972C8
006671EA . FF15 EC726900 call dword ptr ds:[6972EC] ;F7进入
一直F8,直到出现call edi
01057661 E8 1305FFFF call 01047B79
01057666 50 push eax
01057667 A1 88900601 mov eax,dword ptr ds:[1069088]
0105766C 8B48 44 mov ecx,dword ptr ds:[eax+44]
0105766F 3348 20 xor ecx,dword ptr ds:[eax+20]
01057672 3348 10 xor ecx,dword ptr ds:[eax+10]
01057675 2BF9 sub edi,ecx
01057677 FFD7 call edi ; prtg3.0061A7EC <<<<<<这就是eop!!!
F7进入,在这就可Dump了!
[2]寻找magin jump,还原iat:
1.找到oep后,或者确定iat已经处理完后,启动ImportREC,填入正确的oep,点IAT AutoSearch,看看IAT的第一个地址,这里是22c230
2.重新启动,设bp VirtualProtect,在数据窗口看22c230 + 400000 = 62c230,开始时全是0,然后不断按Ctrl+F9,第一次看到62c230开始变化,这些并不是输入函数地址(应该是索引这类的),这时一直往下拖,看看iat的尾部在哪,当你看到又全是0时(准确是在Kernel32.dll字符串前,假设kernel32.dll的地址是0xaaaaaaaa),那个iat的长度是0xaaaaaaaa - 62c230
3.接着可以在62c230和后面的几个DWORD作硬件写入断点,Ctrl+F9,直到硬件中断到如下
010547D3 /73 1D jnb short 010547F2
010547D5 |8B85 1CE8FFFF mov eax,dword ptr ss:[ebp-17E4]
010547DB |8B8D 80E2FFFF mov ecx,dword ptr ss:[ebp-1D80]
010547E1 |8908 mov dword ptr ds:[eax],ecx
010547E3 |8B85 1CE8FFFF mov eax,dword ptr ss:[ebp-17E4] ; prtg3.0062C230 在这里硬件写入中断
010547E9 |83C0 04 add eax,4
010547EC |8985 1CE8FFFF mov dword ptr ss:[ebp-17E4],eax
010547F2 ^\E9 36FDFFFF jmp 0105452D
然后就细心找Magin jump,一直按F8(记住一定要F8),当看到
010546A6 E8 F434FEFF call 01037B9F
010546AB 83C4 0C add esp,0C
010546AE 8D85 74E1FFFF lea eax,dword ptr ss:[ebp-1E8C]
010546B4 50 push eax
010546B5 FFB5 7CE2FFFF push dword ptr ss:[ebp-1D84]
010546BB FF15 30B30501 call dword ptr ds:[105B330] ; MSVCRT._stricmp
010546C1 59 pop ecx
010546C2 59 pop ecx
010546C3 85C0 test eax,eax
010546C5 75 11 jnz short 010546D8 ;改jnz为jmp,这样特殊函数就不会加密
010546C7 8B85 74E2FFFF mov eax,dword ptr ss:[ebp-1D8C]
010546CD 8B40 08 mov eax,dword ptr ds:[eax+8]
010546D0 8985 80E2FFFF mov dword ptr ss:[ebp-1D80],eax
010546D6 EB 02 jmp short 010546DA
010546D8 ^ EB 9D jmp short 01054677
010546DA 83BD 80E2FFFF 00 cmp dword ptr ss:[ebp-1D80],0
010546E1 75 3F jnz short 01054722
010546E3 0FB785 84E2FFFF movzx eax,word ptr ss:[ebp-1D7C]
010546EA 85C0 test eax,eax
010546EC 74 0F je short 010546FD
由于当找到magin jump时已有部分iat解码了,所以重来,重复到第3步,发现iat第一次由0变成有数据时,设bp 1039bf6断点,然后把jnz改为jmp,一直到最后一个iat地址被解码(为了准确,可以在最后一个iat地址0xaaaaaaaa - 4设置硬件写入断点),这是就可以启动ImportREC设好oep和iat等,然后Get Imports,接着点Show Invalid,把所有invalid cut掉,就大功告成。
[3]脱完壳,然后破解prtg v3.26
0.prtg是用Delphi写的,破解Delphi方法可以看<<加密与解密>>
1.把ArmAccess.dll考到同一目录,ArmAccess.dll是欺骗注册码校验的
2.OllyDbg加在脱壳的prtg3.exe,设bp LoadLibraryA,一直按F9,注意堆栈,当堆栈到这里停下来
=============================================================================
0012FD34 00612C51 /CALL 到 LoadLibraryA 来自 prtg3.00612C4C
0012FD38 00612CB4 \FileName = "ArmAccess.DLL" ;注意!
0012FD3C 0012FD68 指针到下一个 SEH 记录
0012FD40 00612CA3 SE 句柄
0012FD44 0012FD60
0012FD48 00607ADC prtg3.00607ADC
0012FD4C 016D17B8
0012FD50 016DD238
0012FD54 016DD238
0012FD58 016DD9BC ASCII "TEAM iNFECTED"
0012FD5C 016DEEA0 ASCII "TEAM iNFECTED"
=============================================================================
3.返回prtg3.exe领空:
00612C47 68 B42C6100 push prtg3.00612CB4 ; ASCII "ArmAccess.DLL"
00612C4C E8 D74DDFFF call <jmp.&kernel32.LoadLibraryA>
00612C51 8BF0 mov esi,eax
00612C53 85F6 test esi,esi
00612C55 74 31 je short prtg3.00612C88
00612C57 68 C42C6100 push prtg3.00612CC4 ; ASCII "CheckCode"
00612C5C 56 push esi
00612C5D E8 EE4CDFFF call <jmp.&kernel32.GetProcAddress>
00612C62 8BF8 mov edi,eax
00612C64 897D F4 mov dword ptr ss:[ebp-C],edi
00612C67 85FF test edi,edi
00612C69 74 17 je short prtg3.00612C82
00612C6B 8B45 F8 mov eax,dword ptr ss:[ebp-8]
00612C6E E8 B528DFFF call prtg3.00405528
00612C73 50 push eax
00612C74 8B45 FC mov eax,dword ptr ss:[ebp-4]
00612C77 E8 AC28DFFF call prtg3.00405528
00612C7C 50 push eax
00612C7D FF55 F4 call dword ptr ss:[ebp-C]
00612C80 8BD8 mov ebx,eax
00612C82 56 push esi
00612C83 E8 104CDFFF call <jmp.&kernel32.FreeLibrary>
00612C88 33C0 xor eax,eax
00612C8A 5A pop edx
00612C8B 59 pop ecx
00612C8C 59 pop ecx
00612C8D 64:8910 mov dword ptr fs:[eax],edx
00612C90 68 AA2C6100 push prtg3.00612CAA
00612C95 8D45 F8 lea eax,dword ptr ss:[ebp-8]
00612C98 BA 02000000 mov edx,2
00612C9D E8 EA23DFFF call prtg3.0040508C
00612CA2 C3 retn
4.一直按F8,直到返回到如下代码:注意!看到"PRTG V3.26 - Pro Edition"没,所以很快就找到关键地方了!!!
006097AB E8 502EFFFF call prtg3.005FC600
006097B0 8BC3 mov eax,ebx
006097B2 E8 79FBFFFF call prtg3.00609330
006097B7 E8 3CF4FFFF call prtg3.00608BF8 ;<<<<<返回到这,我们看到eax==0时就破解了
006097BC 48 dec eax
006097BD 75 0E jnz short prtg3.006097CD
006097BF BA 30996000 mov edx,prtg3.00609930 ; ASCII "PRTG V3.26 - Pro Edition"
006097C4 8BC3 mov eax,ebx
006097C6 E8 A10CE6FF call prtg3.0046A46C
006097CB EB 0C jmp short prtg3.006097D9
006097CD BA 54996000 mov edx,prtg3.00609954 ; ASCII "PRTG V3.26 - Free Edition"
006097D2 8BC3 mov eax,ebx
006097D4 E8 930CE6FF call prtg3.0046A46C
006097D9 E8 1AF4FFFF call prtg3.00608BF8
006097DE 48 dec eax
006097DF 75 1D jnz short prtg3.006097FE
006097E1 8B83 4C030000 mov eax,dword ptr ds:[ebx+34C]
006097E7 33D2 xor edx,edx
006097E9 E8 162FE7FF call prtg3.0047C704
5.重新来一次,到第3步设bp 006097B7断点,触发后F7进入:
00608BFD 51 push ecx
00608BFE 51 push ecx
00608BFF 51 push ecx
00608C00 51 push ecx
00608C01 53 push ebx
00608C02 33C0 xor eax,eax
00608C04 55 push ebp
00608C05 68 A78C6000 push prtg3.00608CA7
00608C0A 64:FF30 push dword ptr fs:[eax]
00608C0D 64:8920 mov dword ptr fs:[eax],esp
00608C10 B8 C08C6000 mov eax,prtg3.00608CC0 ; ASCII "edition"
00608C15 E8 E639FFFF call prtg3.005FC600
00608C1A 33DB xor ebx,ebx
00608C1C 8D55 FC lea edx,dword ptr ss:[ebp-4]
00608C1F B8 C88C6000 mov eax,prtg3.00608CC8 ; ASCII "TYPE"
00608C24 E8 E3FCFFFF call prtg3.0060890C
00608C29 8D45 F8 lea eax,dword ptr ss:[ebp-8]
00608C2C 8B4D FC mov ecx,dword ptr ss:[ebp-4]
00608C2F BA D88C6000 mov edx,prtg3.00608CD8 ; ASCII "type="
00608C34 E8 3BC7DFFF call prtg3.00405374
00608C39 8B45 F8 mov eax,dword ptr ss:[ebp-8]
00608C3C E8 BF39FFFF call prtg3.005FC600
00608C41 8B45 FC mov eax,dword ptr ss:[ebp-4]
00608C44 BA E88C6000 mov edx,prtg3.00608CE8
00608C49 E8 26C8DFFF call prtg3.00405474
00608C4E 75 05 jnz short prtg3.00608C55 ;nop it ,crack successfully!
00608C50 BB 01000000 mov ebx,1
00608C55 8D55 FC lea edx,dword ptr ss:[ebp-4]
00608C58 B8 EC8C6000 mov eax,prtg3.00608CEC ; ASCII "EXPIRED"
00608C5D E8 AAFCFFFF call prtg3.0060890C
00608C62 837D FC 00 cmp dword ptr ss:[ebp-4],0
00608C66 74 02 je short prtg3.00608C6A
00608C68 33DB xor ebx,ebx
00608C6A 8D55 F0 lea edx,dword ptr ss:[ebp-10]
00608C6D 8BC3 mov eax,ebx
00608C6F E8 6814E0FF call prtg3.0040A0DC
00608C74 8B4D F0 mov ecx,dword ptr ss:[ebp-10]
00608C77 8D45 F4 lea eax,dword ptr ss:[ebp-C]
00608C7A BA FC8C6000 mov edx,prtg3.00608CFC ; ASCII "edition "
00608C7F E8 F0C6DFFF call prtg3.00405374
00608C84 8B45 F4 mov eax,dword ptr ss:[ebp-C]
00608C87 E8 7439FFFF call prtg3.005FC600
00608C8C 33C0 xor eax,eax
00608C8E 5A pop edx
00608C8F 59 pop ecx
00608C90 59 pop ecx
00608C91 64:8910 mov dword ptr fs:[eax],edx
00608C94 68 AE8C6000 push prtg3.00608CAE
00608C99 8D45 F0 lea eax,dword ptr ss:[ebp-10]
00608C9C BA 04000000 mov edx,4
00608CA1 E8 E6C3DFFF call prtg3.0040508C
00608CA6 C3 retn
00608CA7 ^ E9 F8BCDFFF jmp prtg3.004049A4
00608CAC ^ EB EB jmp short prtg3.00608C99
00608CAE 8BC3 mov eax,ebx
00608CB0 5B pop ebx
00608CB1 8BE5 mov esp,ebp
00608CB3 5D pop ebp
00608CB4 C3 retn
记住00608C4E,先用Peditor查查00608C4E的文件偏移是00208C4E,用Hiew去把它改为nop nop,搞定!!!
6.到了第5步,prtg3.exe基本破了,但是点注册页面时,还是会说没注册。进入prtg,打开注册页面,设bp LoadLibraryA在注册页面点Check Key后,触发断点,回到prtg领空。如下:
00612C47 68 B42C6100 push prtg3.00612CB4 ; ASCII "ArmAccess.DLL"
00612C4C E8 D74DDFFF call <jmp.&kernel32.LoadLibraryA>
00612C51 8BF0 mov esi,eax ;<<<<<<返回到这!
00612C53 85F6 test esi,esi
00612C55 74 31 je short prtg3.00612C88
00612C57 68 C42C6100 push prtg3.00612CC4 ; ASCII "CheckCode"
00612C5C 56 push esi
00612C5D E8 EE4CDFFF call <jmp.&kernel32.GetProcAddress>
00612C62 8BF8 mov edi,eax
00612C64 897D F4 mov dword ptr ss:[ebp-C],edi
00612C67 85FF test edi,edi
00612C69 74 17 je short prtg3.00612C82
00612C6B 8B45 F8 mov eax,dword ptr ss:[ebp-8]
00612C6E E8 B528DFFF call prtg3.00405528
00612C73 50 push eax
00612C74 8B45 FC mov eax,dword ptr ss:[ebp-4]
00612C77 E8 AC28DFFF call prtg3.00405528
00612C7C 50 push eax
00612C7D FF55 F4 call dword ptr ss:[ebp-C]
00612C80 8BD8 mov ebx,eax
00612C82 56 push esi
00612C83 E8 104CDFFF call <jmp.&kernel32.FreeLibrary>
00612C88 33C0 xor eax,eax
00612C8A 5A pop edx
00612C8B 59 pop ecx
00612C8C 59 pop ecx
00612C8D 64:8910 mov dword ptr fs:[eax],edx
00612C90 68 AA2C6100 push prtg3.00612CAA
00612C95 8D45 F8 lea eax,dword ptr ss:[ebp-8]
00612C98 BA 02000000 mov edx,2
00612C9D E8 EA23DFFF call prtg3.0040508C
00612CA2 C3 retn
00612CA3 ^ E9 FC1CDFFF jmp prtg3.004049A4
00612CA8 ^ EB EB jmp short prtg3.00612C95
00612CAA 8BC3 mov eax,ebx ;可以看到返回值eax是由ebx传递的!
00612CAC 5F pop edi
00612CAD 5E pop esi
00612CAE 5B pop ebx
00612CAF 8BE5 mov esp,ebp
00612CB1 5D pop ebp
00612CB2 C3 retn
一直按F8返回到上一级:
00612DE7 E8 2CFEFFFF call prtg3.00612C18
00612DEC 84C0 test al,al ;<<<<<<返回到这!这是关键,判断返回值,如果al为0,就是没注册
00612DEE 74 6B je short prtg3.00612E5B ; nop it,crack successfully!!!
00612DF0 B2 01 mov dl,1
00612DF2 A1 E8184400 mov eax,dword ptr ds:[4418E8]
00612DF7 E8 10EDE2FF call prtg3.00441B0C
记住00612DEE,文件offest是00212DEE,Hiew修改成nop这样就可以不要ArmAccess.dll了!
[4]prtg3.exe是用Armadillo 1.xx - 2.xx壳,脱完壳后仍然需要调用ArmAccess.dll来判断注册码。
有两种方法绕过ArmAccess.dll的限制:
1.利用伪装的ArmAccess.dll返回正确值
2.修改prtg3.exe绕过ArmAccess.dll的限制,这样破解就不需要多带一个ArmAccess.dll
第[3]提到的方法就是绕过ArmAccess.dll的限制
prtg3.exe的破解信息:
oep RVA:21a7ec
iat RVA:22c230
iat len:958
magin jump:1039bf6
PRTG v3.26 破解补丁下载
ftp://211.96.225.114/XCyber/prtg326_crack.rar[url=ftp://][/url]