benbentaiyang 的CRACKME4反跟踪分析 日期:2005年4月3日 分析人:csjwaman[DFCG]
――――――――――――――――――――――――――――――――――――――――――― 【软件名称】:benbentaiyang 的CRACKME4
【下载地址】:http://bbs.pediy.com/showthread.php?s=&threadid=11588
【分析声明】:初学Crack,只是感兴趣,没有其它目的。失误之处敬请诸位大侠赐教!
【操作系统】:win2k
【脱壳工具】:OD等传统工具
―――――――――――――――――――――――――――――――――――――――――――
【分析过程】:
一、解除SetUnhandledExceptionFilter反跟踪
调用SetUnhandledExceptionFilter来反跟踪曾经难倒了我们这些菜鸟。还好俄国人做了个插件,可以抵抗其反跟踪。后来simonzh2000等大大进行了深入研究,终于找到了对付它的办法。因此可以它已经从迷踪拳变成了大众拳了,再用它来反跟踪似乎无太大的意义。 004014FD > $ 58 pop eax////OD载入后来到这里。
004014FE . A3 FC384000 mov dword ptr ds:[4038FC],eax
00401503 . 9B wait
00401504 . DBE3 finit
00401506 . 90 nop
00401507 . 90 nop
00401508 . 90 nop
00401509 . 90 nop
0040150A . 90 nop
往下看看: 0040152A . 90 nop
0040152B . 90 nop
0040152C . 90 nop
0040152D 68 00104000 push 401000////回调地址。
00401532 E8 B3000000 call 004015EA//// 这里调用SetUnhandledExceptionFilter!!!
00401537 A3 48304000 mov dword ptr ds:[403048],eax
0040153C . 6A 00 push 0 ; /pModule = NULL
0040153E . E8 95000000 call 004015D8 ; \GetModuleHandleA
00401543 . A3 54304000 mov dword ptr ds:[403054],eax
00401548 33C0 xor eax,eax
0040154A C700 01000000 mov dword ptr ds:[eax],1////人为造成异常!
00401550 . D9D0 fnop
00401552 . D9F8 fprem
00401554 . E8 07000000 call 00401560 ; 00401560
00401559 C7 db C7
0040155A 83 db 83
0040155B . 83C0 13 add eax,13 在0040154A处用F7过,会来到:
77F75DB0 8B1C24 mov ebx,dword ptr ss:[esp]////来到这里。
77F75DB3 51 push ecx
77F75DB4 53 push ebx
77F75DB5 E8 BC1A0200 call 77F97876 ////用F7跟进。
77F75DBA 0AC0 or al,al
77F75DBC 74 0C je short 77F75DCA ; 77F75DCA
77F75DBE 5B pop ebx
77F75DBF 59 pop ecx
77F75DC0 6A 00 push 0
77F75DC2 51 push ecx 77F97876 55 push ebp
77F97877 8BEC mov ebp,esp
77F97879 83EC 60 sub esp,60
77F9787C 56 push esi
77F9787D FF75 0C push dword ptr ss:[ebp+C]
77F97880 8B75 08 mov esi,dword ptr ss:[ebp+8]
77F97883 56 push esi
77F97884 E8 5554FDFF call 77F6CCDE ; 77F6CCDE
77F97889 84C0 test al,al
77F9788B 74 07 je short 77F97894 ; 77F97894
77F9788D B0 01 mov al,1
77F9788F E9 FE000000 jmp 77F97992 ; 77F97992
77F97894 53 push ebx
77F97895 57 push edi
77F97896 8D45 F8 lea eax,dword ptr ss:[ebp-8]
77F97899 50 push eax
77F9789A 8D45 FC lea eax,dword ptr ss:[ebp-4]
77F9789D 50 push eax
77F9789E E8 B99F0100 call 77FB185C ; 77FB185C
77F978A3 E8 D09F0100 call 77FB1878 ; 77FB1878
77F978A8 8365 08 00 and dword ptr ss:[ebp+8],0
77F978AC 8BD8 mov ebx,eax
77F978AE E9 C8000000 jmp 77F9797B ; 77F9797B
77F978B3 3B5D FC cmp ebx,dword ptr ss:[ebp-4]
77F978B6 0F82 CE000000 jb 77F9798A ; 77F9798A
77F978BC 8D43 08 lea eax,dword ptr ds:[ebx+8]
77F978BF 3B45 F8 cmp eax,dword ptr ss:[ebp-8]
77F978C2 0F87 C2000000 ja 77F9798A ; 77F9798A
77F978C8 F6C3 03 test bl,3
77F978CB 0F85 B9000000 jnz 77F9798A ; 77F9798A
77F978D1 8B43 04 mov eax,dword ptr ds:[ebx+4]
77F978D4 3B45 FC cmp eax,dword ptr ss:[ebp-4]
77F978D7 72 09 jb short 77F978E2 ; 77F978E2
77F978D9 3B45 F8 cmp eax,dword ptr ss:[ebp-8]
77F978DC 0F82 A8000000 jb 77F9798A ; 77F9798A
77F978E2 F605 3E47FC77 8>test byte ptr ds:[77FC473E],80
77F978E9 74 11 je short 77F978FC ; 77F978FC
77F978EB 6A 10 push 10
77F978ED 53 push ebx
77F978EE 6A 00 push 0
77F978F0 FF75 0C push dword ptr ss:[ebp+C]
77F978F3 56 push esi
77F978F4 E8 B1F7FFFF call 77F970AA ; 77F970AA
77F978F9 8945 F4 mov dword ptr ss:[ebp-C],eax
77F978FC FF73 04 push dword ptr ds:[ebx+4]
77F978FF 8D45 F0 lea eax,dword ptr ss:[ebp-10]
77F97902 50 push eax
77F97903 FF75 0C push dword ptr ss:[ebp+C]
77F97906 53 push ebx
77F97907 56 push esi
77F97908 E8 BF9D0100 call 77FB16CC////直接F4到这里,然后F7跟进。
77F9790D F605 3E47FC77 8>test byte ptr ds:[77FC473E],80
77F97914 8BF8 mov edi,eax
77F97916 74 09 je short 77F97921 ; 77F97921
77F97918 57 push edi
77F97919 FF75 F4 push dword ptr ss:[ebp-C]
77F9791C E8 8FF7FFFF call 77F970B0 ; 77F970B0
77F97921 395D 08 cmp dword ptr ss:[ebp+8],ebx
77F97924 75 08 jnz short 77F9792E ; 77F9792E
77F97926 8366 04 EF and dword ptr ds:[esi+4],FFFFFFEF
77F9792A 8365 08 00 and dword ptr ss:[ebp+8],0
77F9792E 8BC7 mov eax,edi
77F97930 33C9 xor ecx,ecx
77F97932 2BC1 sub eax,ecx
77F97934 74 20 je short 77F97956 ; 77F97956
77F97936 48 dec eax 77FB16CC BA 4217FB77 mov edx,77FB1742////跟到这里。
77FB16D1 EB 09 jmp short 77FB16DC ; 77FB16DC
77FB16D3 90 nop
77FB16D4 BA 6917FB77 mov edx,77FB1769
77FB16D9 8D49 00 lea ecx,dword ptr ds:[ecx]
77FB16DC 53 push ebx
77FB16DD 56 push esi
77FB16DE 57 push edi
77FB16DF 33C0 xor eax,eax
77FB16E1 33DB xor ebx,ebx
77FB16E3 33F6 xor esi,esi
77FB16E5 33FF xor edi,edi
77FB16E7 FF7424 20 push dword ptr ss:[esp+20]
77FB16EB FF7424 20 push dword ptr ss:[esp+20]
77FB16EF FF7424 20 push dword ptr ss:[esp+20]
77FB16F3 FF7424 20 push dword ptr ss:[esp+20]
77FB16F7 FF7424 20 push dword ptr ss:[esp+20]
77FB16FB E8 08000000 call 77FB1708 ; 77FB1708
77FB1700 5F pop edi
77FB1701 5E pop esi
77FB1702 5B pop ebx
77FB1703 C2 1400 retn 14
77FB1706 8BFF mov edi,edi
77FB1708 55 push ebp
77FB1709 8BEC mov ebp,esp
77FB170B FF75 0C push dword ptr ss:[ebp+C]
77FB170E 52 push edx
77FB170F 64:FF35 0000000>push dword ptr fs:[0]
77FB1716 64:8925 0000000>mov dword ptr fs:[0],esp
77FB171D FF75 14 push dword ptr ss:[ebp+14]
77FB1720 FF75 10 push dword ptr ss:[ebp+10]
77FB1723 FF75 0C push dword ptr ss:[ebp+C]
77FB1726 FF75 08 push dword ptr ss:[ebp+8]
77FB1729 8B4D 18 mov ecx,dword ptr ss:[ebp+18]
77FB172C FFD1 call ecx////直接F4到这里。
77FB172E 64:8B25 0000000>mov esp,dword ptr fs:[0]
77FB1735 64:8F05 0000000>pop dword ptr fs:[0]
77FB173C 8BE5 mov esp,ebp
77FB173E 5D pop ebp
77FB173F C2 1400 retn 14 77E74809 55 push ebp
77E7480A 8BEC mov ebp,esp
77E7480C 83EC 08 sub esp,8
77E7480F 53 push ebx
77E74810 56 push esi
77E74811 57 push edi
77E74812 55 push ebp
77E74813 FC cld
77E74814 8B5D 0C mov ebx,dword ptr ss:[ebp+C]
77E74817 8B45 08 mov eax,dword ptr ss:[ebp+8]
77E7481A F740 04 0600000>test dword ptr ds:[eax+4],6
77E74821 0F85 F3300000 jnz 77E7791A ; 77E7791A
77E74827 8945 F8 mov dword ptr ss:[ebp-8],eax
77E7482A 8B45 10 mov eax,dword ptr ss:[ebp+10]
77E7482D 8945 FC mov dword ptr ss:[ebp-4],eax
77E74830 8D45 F8 lea eax,dword ptr ss:[ebp-8]
77E74833 8943 FC mov dword ptr ds:[ebx-4],eax
77E74836 8B73 0C mov esi,dword ptr ds:[ebx+C]
77E74839 8B7B 08 mov edi,dword ptr ds:[ebx+8]
77E7483C 83FE FF cmp esi,-1
77E7483F ^ 0F84 D9EFFFFF je 77E7381E ; 77E7381E
77E74845 8D0C76 lea ecx,dword ptr ds:[esi+esi*2]
77E74848 837C8F 04 00 cmp dword ptr ds:[edi+ecx*4+4],0
77E7484D 74 3E je short 77E7488D ; 77E7488D
77E7484F 56 push esi
77E74850 55 push ebp
77E74851 8D6B 10 lea ebp,dword ptr ds:[ebx+10]
77E74854 FF548F 04 call dword ptr ds:[edi+ecx*4+4]////F7跟进。
77E74858 5D pop ebp
77E74859 5E pop esi
77E7485A 8B5D 0C mov ebx,dword ptr ss:[ebp+C]
77E7485D 0BC0 or eax,eax
77E7485F 74 2C je short 77E7488D ; 77E7488D 77E737C8 8B45 EC mov eax,dword ptr ss:[ebp-14]
77E737CB 8B08 mov ecx,dword ptr ds:[eax]
77E737CD 8B09 mov ecx,dword ptr ds:[ecx]
77E737CF 894D E4 mov dword ptr ss:[ebp-1C],ecx
77E737D2 50 push eax
77E737D3 E8 E8F8FFFF call 77E730C0 ////调用 UnhandledExceptionFilter了!F7跟进。
77E737D8 C3 retn
77E737D9 64:A1 18000000 mov eax,dword ptr fs:[18] 77E730C0 > 68 00050000 push 500
77E730C5 68 F852E777 push 77E752F8
77E730CA E8 0972FEFF call 77E5A2D8 ; 77E5A2D8
77E730CF C745 E4 0400000>mov dword ptr ss:[ebp-1C],4
77E730D6 8B7D 08 mov edi,dword ptr ss:[ebp+8]
77E730D9 8B07 mov eax,dword ptr ds:[edi]
77E730DB BB 050000C0 mov ebx,C0000005
77E730E0 33F6 xor esi,esi
77E730E2 3918 cmp dword ptr ds:[eax],ebx
77E730E4 75 09 jnz short 77E730EF ; 77E730EF
77E730E6 3970 14 cmp dword ptr ds:[eax+14],esi
77E730E9 0F85 77DC0000 jnz 77E80D66 ; 77E80D66
77E730EF 8975 E0 mov dword ptr ss:[ebp-20],esi
77E730F2 56 push esi
77E730F3 6A 04 push 4
77E730F5 8D45 E0 lea eax,dword ptr ss:[ebp-20]
77E730F8 50 push eax
77E730F9 6A 07 push 7
77E730FB E8 B9B5FEFF call 77E5E6B9 ; GetCurrentProcess
77E73100 50 push eax
77E73101 FF15 AC10E477 call dword ptr ds:[77E410AC] ; ntdll.ZwQueryInformationProcess
77E73107 85C0 test eax,eax
77E73109 7C 09 jl short 77E73114 ; 77E73114
77E7310B 3975 E0 cmp dword ptr ss:[ebp-20],esi////关键处!此时[ebp-20]=FFFFFFFF,表示发现调试器。
77E7310E 0F85 C5060000 jnz 77E737D9////不能跳。干脆NOP掉。
77E73114 A1 B473EB77 mov eax,dword ptr ds:[77EB73B4]
77E73119 3BC6 cmp eax,esi
77E7311B 74 15 je short 77E73132 ; 77E73132
77E7311D 57 push edi
77E7311E FFD0 call eax////F8走到这里时EAX=401000。想起0040152D处的push 401000了吗?
77E73120 83F8 01 cmp eax,1
77E73123 0F84 E9030000 je 77E73512 ; 77E73512
00401000 /. 55 push ebp
00401001 |. 8BEC mov ebp,esp
00401003 |. 60 pushad
00401004 |. 8B75 08 mov esi,dword ptr ss:[ebp+8]
00401007 |. 8B7E 04 mov edi,dword ptr ds:[esi+4]
0040100A |. C787 B8000000>mov dword ptr ds:[edi+B8],401404////注意这里。
00401014 |. 61 popad
00401015 |. 33C0 xor eax,eax
00401017 |. C705 3B304000>mov dword ptr ds:[40303B],1
00401021 |. B8 FFFFFFFF mov eax,-1
00401026 |. C9 leave
00401027 \. C2 0400 retn 4////返回到系统DLL中。
到401404处F2下断,然后F9,断在:
00401404 . D9F9 fyl2xp1////断在这里。
00401406 . DAE9 fucompp
00401408 . 90 nop
00401409 . 90 nop
0040140A . E8 24000000 call 00401433 ; 00401433
0040140F . 8B4424 04 mov eax,dword ptr ss:[esp+4]
00401413 . 8B00 mov eax,dword ptr ds:[eax]
00401415 . 3D 04000080 cmp eax,80000004
至此SetUnhandledExceptionFilter反跟踪解除。弄清原理后,可以直接 bp UnhandledExceptionFilter 来到关键处。这样可以节省不少时间。 二、解除时间差校验
解除SetUnhandledExceptionFilter反跟踪后,F9可以出现程序界面。但等输入用户名和注册码后一点确定程序就自动退出!
看来还有暗桩在里面。下面看看暗桩在哪里。 bp ExitProcess F9断在: 77E598FD > 55 push ebp////断在这里。
77E598FE 8BEC mov ebp,esp
77E59900 6A FF push -1
77E59902 68 B0F3E877 push 77E8F3B0
77E59907 FF75 08 push dword ptr ss:[ebp+8]
77E5990A E8 86FFFFFF call 77E59895 ; 77E59895
77E5990F ^ E9 A47DFEFF jmp 77E416B8 ; TerminateProcess 断下后看看堆栈数据:
0012FA7> 004015A1 /CALL 到 ExitProcess 来自 CrackeMe.0040159C
0012FA8> 00000000 \ExitCode = 0 到0040159C处看看:
0040158F 90 nop
00401590 90 nop
00401591 > 90 nop
00401592 . 51 push ecx
00401593 . 53 push ebx
00401594 . 50 push eax
00401595 . E8 90FAFFFF call 0040102A ; 0040102A
0040159A . 6A 00 push 0 ; /ExitCode = 0
0040159C . E8 31000000 call 004015D2 ; \ExitProcess
再向上找找看是从哪里跳来的:
00401042 $ A1 1C304000 mov eax,dword ptr ds:[40301C]////看来[40301C]中的数据是关键。
00401047 . 83F8 00 cmp eax,0
0040104A . 74 05 je short 00401051////原来是从这里来的!!!
0040104C . E9 40050000 jmp 00401591
00401051 > C3 retn
那么[40301C]中的数据从何而来?我们在40301C处的四个字节上下硬件访问断点。然后重新加载程序,解除SetUnhandledExceptionFilter反跟踪后,F9运行程序。程序断在: 004011BE |. E8 2D040000 call 004015F0 ; \VirtualProtect
004011C3 |. FF15 EC384000 call dword ptr ds:[4038EC] ; kernel32.GetTickCount
004011C9 |. 2B05 30304000 sub eax,dword ptr ds:[403030]////GetTickCount返回值减去[403030]中保存的值。
004011CF |. 2D C8000000 sub eax,0C8////再减去C8。
004011D4 |. 72 08 jb short 004011DE////跳则表示没有被调试。这里一定要跳。
004011D6 |. 33C0 xor eax,eax
004011D8 |. 40 inc eax
004011D9 |. A3 1C304000 mov dword ptr ds:[40301C],eax////给[40301C]赋值了。
004011DE |> 68 00100000 push 1000 ////断在这里。
004011E3 |. FF35 54304000 push dword ptr ds:[403054]
004011E9 |. E8 CC030000 call 004015BA
004011EE |. 50 push eax 稍微看一下上面的代码,我们就可知道这是用时间差在反跟踪。调用的就是 GetTickCount。那么来看看程序是如何使用时间差反跟踪的。重新加载程序,解除SetUnhandledExceptionFilter反跟踪后,bp GetTickCount F9运行程序断在:
77E5A29B > BA 0000FE7F mov edx,7FFE0000////断在这里。取消断点。
77E5A2A0 8B02 mov eax,dword ptr ds:[edx]
77E5A2A2 F762 04 mul dword ptr ds:[edx+4]
77E5A2A5 0FACD0 18 shrd eax,edx,18
77E5A2A9 C3 retn ALT+F9返回:
004014D0 . 90 nop
004014D1 . FF15 EC384000 call dword ptr ds:[4038EC] ; kernel32.GetTickCount
004014D7 . 50 push eax////返回到这里。EAX中保存的就是GetTickCount返回值。
004014D8 . 8F05 30304000 pop dword ptr ds:[403030]////利用堆栈传递数据,把返回值保存在[403030]中。
004014DE . 90 nop
004014DF . 90 nop
004014E0 . 6A 00 push 0 ; /lParam = NULL
004014E2 . 68 74114000 push 401174 ; |DlgProc = CrackeMe.00401174
004014E7 . 6A 00 push 0 ; |hOwner = NULL
004014E9 . 6A 01 push 1 ; |pTemplate = 1
004014EB . FF35 54304000 push dword ptr ds:[403054] ; |hInst = 00400000 其实程序就是在004014D7处调用GetTickCount获取时间值,保存到[403030]。运行到004011C3时再次调用GetTickCount获取时间值,然后与先前保存的值比较,如果差值大于C8则说明被调试。
解除了上述两处反跟踪程序就听话了。但我是用FLY兄弟修改的OD跟踪的,因为这个OD有免疫力,所以可能还有别的反跟踪手段让OD自行反掉了。
至于算法我就不跟踪了。这里应该是关键处:
00401098 > \A1 28304000 mov eax,dword ptr ds:[403028]
0040109D . 83F8 06 cmp eax,6
004010A0 . 0F8C B0000000 jl 00401156 ; 00401156
004010A6 . 8D3D 58304000 lea edi,dword ptr ds:[403058]
004010AC . B9 00000000 mov ecx,0
004010B1 . 33C0 xor eax,eax
004010B3 . 33DB xor ebx,ebx
004010B5 . 8A07 mov al,byte ptr ds:[edi]
004010B7 . 83F9 07 cmp ecx,7
004010BA . 73 21 jnb short 004010DD ; 004010DD
004010BC . 6BC0 50 imul eax,eax,50
004010BF . 83F9 04 cmp ecx,4
004010C2 . 73 0B jnb short 004010CF ; 004010CF
004010C4 . 6BC0 43 imul eax,eax,43
004010C7 . 83F9 01 cmp ecx,1
004010CA . 73 03 jnb short 004010CF ; 004010CF
004010CC . 6BC0 47 imul eax,eax,47
004010CF > 031D 20304000 add ebx,dword ptr ds:[403020]
004010D5 . 03D8 add ebx,eax
004010D7 . 891D 20304000 mov dword ptr ds:[403020],ebx
004010DD > 83C1 03 add ecx,3
004010E0 . 83C7 02 add edi,2
004010E3 . 83F9 07 cmp ecx,7
004010E6 . 73 06 jnb short 004010EE ; 004010EE
004010E8 . 68 B1104000 push 4010B1
004010ED . C3 retn
004010EE > \8B0D 2C304000 mov ecx,dword ptr ds:[40302C]
004010F4 . 83F9 06 cmp ecx,6
004010F7 . 7C 5C jl short 00401155 ; 00401155
004010F9 . 8D3D D8304000 lea edi,dword ptr ds:[4030D8]
004010FF . B9 00000000 mov ecx,0
00401104 . 33C0 xor eax,eax
00401106 . 33DB xor ebx,ebx
00401108 . 8A07 mov al,byte ptr ds:[edi]
0040110A . 83F9 07 cmp ecx,7
0040110D . 73 21 jnb short 00401130 ; 00401130
0040110F . 6BC0 70 imul eax,eax,70
00401112 . 83F9 04 cmp ecx,4
00401115 . 73 0B jnb short 00401122 ; 00401122
00401117 . 6BC0 63 imul eax,eax,63
0040111A . 83F9 01 cmp ecx,1
0040111D . 73 03 jnb short 00401122 ; 00401122
0040111F . 6BC0 67 imul eax,eax,67
00401122 > 031D 24304000 add ebx,dword ptr ds:[403024]
00401128 . 03D8 add ebx,eax
0040112A . 891D 24304000 mov dword ptr ds:[403024],ebx
00401130 > 83C1 03 add ecx,3
00401133 . 83C7 02 add edi,2
00401136 . 83F9 07 cmp ecx,7
00401139 . 73 06 jnb short 00401141 ; 00401141
0040113B . 68 04114000 push 401104
00401140 . C3 retn
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课