-
-
[原创]第一题分析-Crack_Me-凉飕飕
-
发表于: 2016-11-3 01:57 5290
-
OD载入,点运行后程序退出,回溯调用栈,找到检测调试器的地方:
//1。检测父进程是否为explorer,不是则退出
00401000 /E9 3B030000 jmp 00401340
00401340 /> push ebp
00401341 |. mov ebp, esp
00401343 |. mov eax, 4B24
00401348 |. call 00417150
0040134D |. mov eax, [41F014]
00401352 |. xor eax, ebp
00401354 |. mov [ebp-4], eax
00401357 |. push ebx
00401358 |. push esi
00401359 |. push edi ; /Procname
0040135A |. call 004048DE ; |[Crack_Me.004048DE
0040135F |. mov ecx, offset 0041D988 ; |ASCII "A{^zj}vFai`}bn{f`a_}`lj||"
00401364 |. call 00401180 ; |[Crack_Me.00401180
00401369 |. mov esi, eax ; |
0040136B |. call 00401080 ; |[Crack_Me.00401080
00401370 |. mov edi, eax ; |
00401372 |. push esi ; |
00401373 |. push edi ; |/FileName
00401374 |. call [<&KERNEL32.LoadLibraryW>] ; |\KERNEL32.LoadLibraryW
0040137A |. push eax ; |hModule
0040137B |. call [<&KERNEL32.GetProcAddress>] ; \KERNEL32.GetProcAddress
00401381 |. mov [ebp-250], eax
00401387 |. call [<&KERNEL32.GetCurrentProcessId> ; [KERNEL32.GetCurrentProcessId
0040138D |. push eax ; /ProcessID
0040138E |. push 0 ; |InheritHandle = FALSE
00401390 |. push 1FFFFF ; |Access =
00401395 |. call [<&KERNEL32.OpenProcess>] ; \KERNEL32.OpenProcess
0040139B |. push esi ; /Arg1
0040139C |. mov ebx, eax ; |
0040139E |. call 00402CDF ; \Crack_Me.0040C93D
004013A3 |. push edi ; /Arg1
004013A4 |. call 00402CDF ; \Crack_Me.0040C93D
004013A9 |. add esp, 8
004013AC |. test ebx, ebx
004013AE |.- jnz short 004013C4
004013B0 |. pop edi
004013B1 |. pop esi
004013B2 |. or eax, FFFFFFFF
004013B5 |. pop ebx
004013B6 |. mov ecx, [ebp-4]
004013B9 |. xor ecx, ebp
004013BB |. call 00402CC5
004013C0 |. mov esp, ebp
004013C2 |. pop ebp
004013C3 |. retn
004013C4 |> lea eax, [ebp-8]
004013C7 |. push eax
004013C8 |. push 18
004013CA |. lea eax, [ebp-24C]
004013D0 |. push eax
004013D1 |. push 0
004013D3 |. push ebx
004013D4 |. call [ebp-250]
004013DA |. mov eax, [ebp-238]
004013E0 |. push ebx ; /hObject
004013E1 |. mov [ebp-254], eax ; |
004013E7 |. call [<&KERNEL32.CloseHandle>] ; \KERNEL32.CloseHandle
004013ED |. call 004048DE ; [Crack_Me.004048DE
004013F2 |. push 0 ; /ProcessID = 0 (0.)
004013F4 |. push 2 ; |Flags = TH32CS_SNAPPROCESS
004013F6 |. call [<&KERNEL32.CreateToolhelp32Snap ; \KERNEL32.CreateToolhelp32Snapshot
004013FC |. mov edi, eax
004013FE |. mov dword ptr [ebp-234], 22C
00401408 |. push 228 ; /Arg3 = 228
0040140D |. lea eax, [ebp-230] ; |
00401413 |. mov [ebp-250], edi ; |
00401419 |. push 0 ; |Arg2 = 0
0040141B |. push eax ; |Arg1
0040141C |. call 004039D0 ; \Crack_Me.004039D0
00401421 |. add esp, 0C
00401424 |. lea eax, [ebp-234]
0040142A |. push eax ; /Arg2
0040142B |. push edi ; |Arg1
0040142C |. call [<&KERNEL32.Process32FirstW>] ; \KERNEL32.Process32FirstW
00401432 |. mov esi, eax
00401434 |. call 00401240 ; [Crack_Me.00401240
00401439 |. mov ebx, eax ; //串"explorer.exe"
0040143B |. test esi, esi
0040143D |.- jz short 004014AC
0040143F |. lea edi, [ebp+FFFFB4DC]
00401445 |> /test ebx, ebx
00401447 |.- |jz short 0040148F
00401449 |. |mov ax, [ebp-210]
00401450 |. |cmp ax, [ebx]
00401453 |.- |ja short 0040148F
00401455 |. |lea eax, [ebp-210]
0040145B |. |mov esi, ebx
0040145D |. |mov ecx, eax
0040145F |. |sub esi, ecx
00401461 |> |/movzx edx, word ptr [eax+esi]
00401465 |. ||movzx ecx, word ptr [eax]
00401468 |. ||cmp cx, dx
0040146B |.- ||jne short 00401477
0040146D |. ||test cx, cx
00401470 |.- ||jz short 00401484
00401472 |. ||add eax, 2
00401475 |.- ||jmp short 00401479
00401477 |>- ||jb short 0040148F
00401479 |> ||mov cx, [eax]
0040147C |. ||cmp cx, [eax+esi]
00401480 |.- |\jbe short 00401461
00401482 |.- |jmp short 0040148F
00401484 |> |mov eax, [ebp-22C] ; //取进程ID
0040148A |. |mov [edi], eax ; //存入explorer进程ID数组
0040148C |. |add edi, 4
0040148F |> |lea eax, [ebp-234]
00401495 |. |push eax ; /Arg2
00401496 |. |push dword ptr [ebp-250] ; |Arg1
0040149C |. |call [<&KERNEL32.Process32NextW>] ; \KERNEL32.Process32NextW
004014A2 |. |test eax, eax
004014A4 |.- \jnz short 00401445
004014A6 |. mov edi, [ebp-250]
004014AC |> mov ebx, [ebp-254] ; //取父进程ID
004014B2 |. mov edx, 1
004014B7 |. cmp ebx, [ebp+FFFFB4DC] ; //父进程ID与explorer进程ID数组中的ID依次比较
004014BD |. mov ecx, edx
004014BF |. sete al
004014C2 |. cmp ebx, [ebp+FFFFB4E0]
004014C8 |. movzx eax, al
004014CB |. cmove eax, edx
004014CE |. cmp ebx, [ebp+FFFFB4E4]
004014D4 |. movzx eax, al
004014D7 |. cmovne ecx, eax
004014DA |. cmp ebx, [ebp+FFFFB4E8]
004014E0 |. movzx eax, cl
004014E3 |. mov ecx, edx
004014E5 |. cmove eax, edx
004014E8 |. cmp ebx, [ebp+FFFFB4EC]
004014EE |. movzx eax, al
004014F1 |. cmovne ecx, eax
004014F4 |. cmp ebx, [ebp+FFFFB4F0]
004014FA |. movzx eax, cl
004014FD |. mov ecx, edx
004014FF |. cmove eax, edx
00401502 |. cmp ebx, [ebp+FFFFB4F4]
00401508 |. movzx eax, al
0040150B |. cmovne ecx, eax
0040150E |. cmp ebx, [ebp+FFFFB4F8]
00401514 |. movzx eax, cl
00401517 |. cmove eax, edx
0040151A |. cmp ebx, [ebp+FFFFB4FC]
00401520 |. movzx eax, al
00401523 |. cmovne edx, eax
00401526 |. cmp ebx, [ebp+FFFFB500]
0040152C |.- je short 00401532
0040152E |. test dl, dl
00401530 |.- jz short 0040154C ; //父进程ID不在explorer进程ID数组中,即父进程名不是explorer则转
00401532 |> push edi ; /hObject
00401533 |. call [<&KERNEL32.CloseHandle>] ; \KERNEL32.CloseHandle
00401539 |. mov ecx, [ebp-4]
0040153C |. xor eax, eax
0040153E |. pop edi
0040153F |. pop esi
00401540 |. xor ecx, ebp
00401542 |. pop ebx
00401543 |. call 00402CC5
00401548 |. mov esp, ebp
0040154A |. pop ebp
0040154B |. retn
0040154C |> push 0 ; //退出
0040154E \. call 00404BB1
解决办法PATCH 00401000 为 RETN
//2。取时钟,多个地方调用,用于检测调试器
004048DE /$ mov edi, edi ; Crack_Me.004048DE(推测 void)
004048E0 |. push ebp
004048E1 |. mov ebp, esp
004048E3 |. push ecx
004048E4 |. push ecx
004048E5 |. mov ecx, [41FC18]
004048EB |. and ecx, [41FC1C]
004048F1 |. push esi
004048F2 |. or esi, FFFFFFFF
004048F5 |. cmp ecx, esi
004048F7 |. je short 00404939
004048F9 |. lea eax, [local.2]
004048FC |. push eax
004048FD |. call [<&KERNEL32.QueryPerformanceCounter>]
00404903 |. test eax, eax
00404905 |. jz short 00404939
00404907 |. mov eax, [local.2]
0040490A |. sub eax, [41FC18]
00404910 |. mov ecx, [local.1]
00404913 |. sbb ecx, [41FC1C]
00404919 |. test ecx, ecx
0040491B |. jg short 00404923
0040491D |. jl short 00404939
0040491F |. test eax, eax
00404921 |. jb short 00404939
00404923 |> push ecx ; /Arg2
00404924 |. push eax ; |Arg1
00404925 |. call 00404817 ; \Crack_Me.00404817
0040492A |. pop ecx
0040492B |. pop ecx
0040492C |. test edx, edx
0040492E |. jl short 0040493B
00404930 |. jg short 00404939
00404932 |. cmp eax, 7FFFFFFF
00404937 |. jbe short 0040493B
00404939 |> mov eax, esi
0040493B |> pop esi
0040493C |. mov esp, ebp
0040493E |. pop ebp
0040493F \. retn
解决办法PATCH 004048DE为:
xor eax,eax
mov edx,eax
retn
解决了反调试,就可以慢慢分析,算法还是比较简单,只是不在一个地方,比较分散,关键代码如下,分析见注释:
004022C4 |. mov eax, ds:[420318] ; 事例 3EB of switch Crack_Me.402296
004022C9 |. inc eax ; //点击次数计数加一
004022CA |. push eax ; /Arg4
004022CB |. push offset 0041DAA0 ; |Arg3 = UNICODE "%d"
004022D0 |. mov ds:[420318], eax ; |
004022D5 |. lea eax, [local.21] ; |
004022D8 |. push 0A ; |Arg2 = 0A
004022DA |. push eax ; |Arg1 => offset LOCAL.21
004022DB |. call 00402790 ; \Crack_Me.00402790
004022E0 |. mov edi, ds:[<&USER32.GetDlgItem>]
004022E6 |. lea eax, [local.21]
004022E9 |. add esp, 10
004022EC |. push eax ; /Text => offset LOCAL.21
004022ED |. push 3E8 ; |/ItemID = 1000.
004022F2 |. push ebx ; ||hDialog
004022F3 |. call edi ; |\USER32.GetDlgItem
004022F5 |. push eax ; |hWnd
004022F6 |. call ds:[<&USER32.SetWindowTextW>] ; \USER32.SetWindowTextW
004022FC |. push 14 ; /Arg1 = 14
004022FE |. call 00402CF2 ; \Crack_Me.00402CF2
00402303 |. add esp, 4
00402306 |. mov dword ptr ss:[local.2], 0
0040230D |. mov esi, eax
0040230F |. xorps xmm0, xmm0
00402312 |. lea eax, [local.6]
00402315 |. movups ss:[local.6], xmm0
00402319 |. push 0A
0040231B |. push eax
0040231C |. push 3E8
00402321 |. push ebx
00402322 |. call edi
00402324 |. push eax ; |hWnd
00402325 |. call ds:[<&USER32.GetWindowTextW>] ; \USER32.GetWindowTextW
0040232B |. lea eax, [local.72] ; //读点击次数计数
00402331 |. push eax ; /Arg3 => offset LOCAL.72
00402332 |. lea eax, [local.6] ; |
00402335 |. push offset 0041DAA0 ; |Arg2 = UNICODE "%d"
0040233A |. push eax ; |Arg1 => offset LOCAL.6
0040233B |. call 004027C0 ; \Crack_Me.004027C0
00402340 |. mov eax, ss:[local.72]
00402346 |. add esp, 0C
00402349 |. mov ds:[esi], eax ; //点击次数,窗口句柄等依次写入参数结构,并建立计算线程
0040234B |. mov ds:[esi+4], ebx
0040234E |. push 3EA
00402353 |. push ebx
00402354 |. call edi
00402356 |. push 3E8
0040235B |. push ebx
0040235C |. mov ds:[esi+0C], eax
0040235F |. call edi
00402361 |. push 0
00402363 |. push 0
00402365 |. push esi
00402366 |. mov ds:[esi+8], eax
00402369 |. mov ds:[esi+10], esi
0040236C |. push 004020E0 ; //计算线程地址
00402371 |. jmp 0040276B
0040276B |> \push 0 ; |StackSize = 0
0040276D |. push 0 ; |pSecurity = NULL
0040276F |. call ds:[<&KERNEL32.CreateThread>] ; \KERNEL32.CreateThread
00402775 |> mov ecx, ss:[local.1] ; 事例 68 of switch Crack_Me.402296
00402778 |. xor eax, eax
0040277A |. pop edi
0040277B |. pop esi
0040277C |. xor ecx, ebp
0040277E |. pop ebx
0040277F |. call 00402CC5
00402784 |. mov esp, ebp
00402786 |. pop ebp
00402787 \. retn 10
//计算线程
004020E0 /. push ebp
004020E1 |. mov ebp, esp
004020E3 |. mov ecx, ss:[arg.1]
004020E6 |. xor edx, edx
004020E8 |. call 00401CB0 //调用计算子程序
004020ED |. push 14
004020EF |. push dword ptr ss:[arg.1]
004020F2 |. call 00402CE4
004020F7 |. add esp, 8
004020FA |. xor eax, eax
004020FC |. pop ebp
004020FD \. retn 4
//计算子程序
00401CB0 /$ push ebp
00401CB1 |. mov ebp, esp
00401CB3 |. sub esp, 0D0
00401CB9 |. mov eax, ds:[41F014]
00401CBE |. xor eax, ebp
00401CC0 |. mov ss:[local.1], eax
00401CC3 |. push edi
00401CC4 |. mov edi, ecx
00401CC6 |. test edi, edi
00401CC8 |. jz 00401E2F
00401CCE |. test edx, edx
00401CD0 |. jnz 00401D57
00401CD6 |. call 00401C00 ; //查找输入是否有字符'b',没有则转
00401CDB |. test eax, eax
00401CDD |. jz short 00401D33
00401CDF |. push 0C8 ; /Arg3 = 0C8
00401CE4 |. lea eax, [local.51] ; |
00401CEA |. push 0 ; |Arg2 = 0
00401CEC |. push eax ; |Arg1 => offset LOCAL.51
00401CED |. call 004039D0 ; \Crack_Me.004039D0
00401CF2 |. add esp, 0C
00401CF5 |. lea eax, [local.51]
00401CFB |. push 64 ; /MaxCount = 100.
00401CFD |. push eax ; |String => offset LOCAL.51
00401CFE |. push dword ptr ds:[edi+0C] ; |hWnd
00401D01 |. call ds:[<&USER32.GetWindowTextW>] ; \USER32.GetWindowTextW
00401D07 |. push 70 ; /Arg1 = 70, //字符'p'
00401D09 |. lea edx, [local.51] ; |
00401D0F |. call 00402A50 ; \Crack_Me.00402A50
00401D14 |. test eax, eax
00401D16 |. jz short 00401D33 ; //输入没有字符'p'则转
00401D18 |. mov edx, 1
00401D1D |. mov ecx, edi
00401D1F |. call 00401CB0 ; //输入有字符'p'和'b'则下一步
00401D24 |. pop edi
00401D25 |. mov ecx, ss:[local.1]
00401D28 |. xor ecx, ebp
00401D2A |. call 00402CC5
00401D2F |. mov esp, ebp
00401D31 |. pop ebp
00401D32 |. retn
00401D33 |> push 0 ; /lParam = NULL
00401D35 |. push 40F ; |wParam = NotifyCode = MENU/BN_CLICKED..., ID = 1039.
00401D3A |. push 111 ; |Msg = WM_COMMAND
00401D3F |. push dword ptr ds:[edi+4] ; |hWnd
00401D42 |. call ds:[<&USER32.SendMessageW>] ; \USER32.SendMessageW
00401D48 |. pop edi
00401D49 |. mov ecx, ss:[local.1]
00401D4C |. xor ecx, ebp
00401D4E |. call 00402CC5
00401D53 |. mov esp, ebp
00401D55 |. pop ebp
00401D56 |. retn
00401D57 |> push esi
00401D58 |. call 004048DE ; [Crack_Me.004048DE
00401D5D |. push 0C8 ; /Arg3 = 0C8
00401D62 |. mov ss:[local.52], eax ; |
00401D68 |. lea eax, [local.51] ; |
00401D6E |. push 0 ; |Arg2 = 0
00401D70 |. push eax ; |Arg1 => offset LOCAL.51
00401D71 |. call 004039D0 ; \Crack_Me.004039D0
00401D76 |. add esp, 0C
00401D79 |. lea eax, [local.51]
00401D7F |. push 0C8 ; /MaxCount = 200.
00401D84 |. push eax ; |String => offset LOCAL.51
00401D85 |. push dword ptr ds:[edi+0C] ; |hWnd
00401D88 |. call ds:[<&USER32.GetWindowTextW>] ; \USER32.GetWindowTextW
00401D8E |. xor esi, esi
00401D90 |. lea eax, [local.51]
00401D96 |. cmp ss:[local.51], si
00401D9D |. je short 00401DAA
00401D9F |. nop
00401DA0 |> /lea eax, [eax+2]
00401DA3 |. |inc esi
00401DA4 |. |cmp word ptr ds:[eax], 0
00401DA8 |.^ \jne short 00401DA0
00401DAA |> xor ecx, ecx
00401DAC |. lea eax, [esi+1]
00401DAF |. mov edx, 2
00401DB4 |. mul edx
00401DB6 |. push ebx
00401DB7 |. seto cl
00401DBA |. neg ecx
00401DBC |. or ecx, eax
00401DBE |. push ecx ; /Arg1
00401DBF |. call 00402CD6 ; \Crack_Me.00402CD6
00401DC4 |. add esp, 4
00401DC7 |. mov ebx, eax
00401DC9 |. call 004048DE ; [Crack_Me.004048DE
00401DCE |. sub eax, ss:[local.52]
00401DD4 |. cmp eax, 2 ; //时间大于2则认为被调试,退出程序
00401DD7 |. jg short 00401E3E
00401DD9 |. lea eax, [local.51]
00401DDF |. push eax ; /Arg2 => offset LOCAL.51
00401DE0 |. push ebx ; |Arg1
00401DE1 |. call 00402870 ; \Crack_Me.00402870
00401DE6 |. cmp esi, 7 ; //输入长度不为7则错误
00401DE9 |. jae short 00401DF6
00401DEB |. push 0
00401DED |. push 0
00401DEF |. push 40E
00401DF4 |. jmp short 00401E01
00401DF6 |> jbe short 00401E24
00401DF8 |. push 0
00401DFA |. push 0
00401DFC |. push 40D
00401E01 |> push dword ptr ds:[edi+4] ; |hWnd
00401E04 |. call ds:[<&USER32.SendMessageW>] ; \USER32.SendMessageW
00401E0A |. push ebx ; /Arg1
00401E0B |. call 00402CDF ; \Crack_Me.0040C93D
00401E10 |. add esp, 4
00401E13 |. pop ebx
00401E14 |. pop esi
00401E15 |. pop edi
00401E16 |. mov ecx, ss:[local.1]
00401E19 |. xor ecx, ebp
00401E1B |. call 00402CC5
00401E20 |. mov esp, ebp
00401E22 |. pop ebp
00401E23 |. retn
00401E24 |> mov edx, ebx ; //输入有'b','p',且长度为7则下一步
00401E26 |. mov ecx, edi
00401E28 |. call 00401A60
00401E2D |. pop ebx
00401E2E |. pop esi
00401E2F |> mov ecx, ss:[local.1]
00401E32 |. xor ecx, ebp
00401E34 |. pop edi
00401E35 |. call 00402CC5
00401E3A |. mov esp, ebp
00401E3C |. pop ebp
00401E3D |. retn
00401E3E |> push 0 ; //退出程序
00401E40 \. call 00404BB1
//查找输入是否有字符'b'
00401C00 $ push ebp
00401C01 . mov ebp, esp
00401C03 . sub esp, 0CC
00401C09 . mov eax, ds:[41F014]
00401C0E . xor eax, ebp
00401C10 . mov ss:[ebp-4], eax
00401C13 . push esi
00401C14 . push 0C8 ; /Arg3 = 0C8
00401C19 . lea eax, [ebp-0CC] ; |
00401C1F . mov esi, ecx ; |
00401C21 . push 0 ; |Arg2 = 0
00401C23 . push eax ; |Arg1
00401C24 . call 004039D0 ; \Crack_Me.004039D0
00401C29 . add esp, 0C
00401C2C . lea eax, [ebp-0CC]
00401C32 . push 64 ; /MaxCount = 100.
00401C34 . push eax ; |String
00401C35 . push dword ptr ds:[esi+0C] ; |hWnd
00401C38 . call ds:[<&USER32.GetWindowTextW>] ; \USER32.GetWindowTextW
00401C3E . mov cx, ss:[ebp-0CC]
00401C45 . lea eax, [ebp-0CC]
00401C4B . pop esi
00401C4C . test cx, cx
00401C4F . je short 00401C5B
00401C51 > cmp word ptr ds:[eax+2], 0
00401C56 . lea eax, [eax+2]
00401C59 .^ jne short 00401C51
00401C5B > xor eax, eax
00401C5D . test cx, cx
00401C60 . je short 00401C83
00401C62 . movzx ecx, cx
00401C65 . mov edx, 62 ; //字符‘b’
00401C6A db 66 ; char 'f'
00401C6B db 0F
00401C6C db 1F
00401C6D db 44 ; char 'D'
00401C6E db 00
00401C6F db 00
00401C70 /> /cmp dx, cx ; //查找字符‘b’
00401C73 |. |je short 00401C93
00401C75 |. |movzx ecx, word ptr ss:[eax*2+ebp-0CA]
00401C7D |. |inc eax
00401C7E |. |test cx, cx
00401C81 |.^ \jnz short 00401C70
00401C83 |> xor eax, eax ; //未找到字符‘b’,返回0
00401C85 |. mov ecx, ss:[ebp-4]
00401C88 |. xor ecx, ebp
00401C8A |. call 00402CC5
00401C8F |. mov esp, ebp
00401C91 |. pop ebp
00401C92 |. retn
00401C93 |> mov ecx, ss:[ebp-4] ; //找到字符‘b’,返回1
00401C96 |. mov eax, 1
00401C9B |. xor ecx, ebp
00401C9D |. call 00402CC5
00401CA2 |. mov esp, ebp
00401CA4 |. pop ebp
00401CA5 \. retn
00401A60 /$ push ebp
00401A61 |. mov ebp, esp
00401A63 |. sub esp, 19C
00401A69 |. mov eax, ds:[41F014]
00401A6E |. xor eax, ebp
00401A70 |. mov ss:[local.1], eax
00401A73 |. push ebx
00401A74 |. push esi
00401A75 |. push edi
00401A76 |. push 0C8 ; /Arg3 = 0C8
00401A7B |. lea eax, [local.51] ; |
00401A81 |. mov edi, ecx ; |
00401A83 |. push 0 ; |Arg2 = 0
00401A85 |. push eax ; |Arg1 => offset LOCAL.51
00401A86 |. mov ebx, edx ; |
00401A88 |. mov ss:[local.102], edi ; |
00401A8E |. call 004039D0 ; \Crack_Me.004039D0
00401A93 |. push 0C8 ; /Arg3 = 0C8
00401A98 |. lea eax, [local.101] ; |
00401A9E |. push 0 ; |Arg2 = 0
00401AA0 |. push eax ; |Arg1 => offset LOCAL.101
00401AA1 |. call 004039D0 ; \Crack_Me.004039D0
00401AA6 |. mov esi, ds:[<&USER32.SendMessageW>]
00401AAC |. lea eax, [local.51]
00401AB2 |. add esp, 18
00401AB5 |. push eax ; /lParam => offset LOCAL.51
00401AB6 |. push 0D ; |wParam = 13.
00401AB8 |. push 0D ; |Msg = WM_GETTEXT
00401ABA |. push dword ptr ds:[edi+0C] ; |hWnd
00401ABD |. call esi ; \USER32.SendMessageW
00401ABF |. lea eax, [local.101]
00401AC5 |. push eax
00401AC6 |. push 40C
00401ACB |. push 111
00401AD0 |. push dword ptr ds:[edi+4]
00401AD3 |. call esi
00401AD5 |. xor ecx, ecx
00401AD7 |. lea eax, [local.51]
00401ADD |. cmp ss:[local.51], cx
00401AE4 |. je short 00401AF0
00401AE6 |> /lea eax, [eax+2]
00401AE9 |. |inc ecx
00401AEA |. |cmp word ptr ds:[eax], 0
00401AEE |.^ \jne short 00401AE6
00401AF0 |> test ecx, ecx
00401AF2 |. jz short 00401B05
00401AF4 |. xor eax, eax
00401AF6 |. lea edi, [local.51]
00401AFC |. shr ecx, 1
00401AFE |. rep stos dword ptr es:[edi]
00401B00 |. adc ecx, ecx
00401B02 |. rep stos word ptr es:[edi]
00401B05 |> xor ecx, ecx
00401B07 |. lea eax, [local.101]
00401B0D |. cmp ss:[local.101], cx
00401B14 |. je short 00401B20
00401B16 |> /lea eax, [eax+2]
00401B19 |. |inc ecx
00401B1A |. |cmp word ptr ds:[eax], 0
00401B1E |.^ \jne short 00401B16
00401B20 |> test ecx, ecx
00401B22 |. jz short 00401B35
00401B24 |. xor eax, eax
00401B26 |. lea edi, [local.101]
00401B2C |. shr ecx, 1
00401B2E |. rep stos dword ptr es:[edi]
00401B30 |. adc ecx, ecx
00401B32 |. rep stos word ptr es:[edi]
00401B35 |> xor ecx, ecx
00401B37 |. mov eax, ebx
00401B39 |. test ebx, ebx
00401B3B |. jz short 00401B4C
00401B3D |. cmp ds:[ebx], cx
00401B40 |. je short 00401B4C
00401B42 |> /lea eax, [eax+2]
00401B45 |. |inc ecx
00401B46 |. |cmp word ptr ds:[eax], 0
00401B4A |.^ \jne short 00401B42
00401B4C |> lea eax, [ecx+1]
00401B4F |. mov edx, 2
00401B54 |. xor ecx, ecx
00401B56 |. mul edx
00401B58 |. seto cl
00401B5B |. neg ecx
00401B5D |. or ecx, eax
00401B5F |. push ecx ; /Arg1
00401B60 |. call 00402CD6 ; \Crack_Me.00402CD6
00401B65 |. mov esi, eax
00401B67 |. add esp, 4
00401B6A |. xor eax, eax
00401B6C |. cmp ds:[ebx], ax
00401B6F |. je short 00401B87
00401B71 |. movzx ecx, word ptr ds:[ebx]
00401B74 |. xor edx, edx
00401B76 |> /inc eax
00401B77 |. |mov ds:[esi+edx], cx
00401B7B |. |lea edx, [eax+eax]
00401B7E |. |movzx ecx, word ptr ds:[ebx+edx]
00401B82 |. |test cx, cx
00401B85 |.^ \jnz short 00401B76
00401B87 |> xor ecx, ecx
00401B89 |. mov ds:[eax*2+esi], cx
00401B8D |. mov eax, esi
00401B8F |. test esi, esi
00401B91 |. jz short 00401BCA
00401B93 |. cmp ds:[esi], cx
00401B96 |. je short 00401BA2
00401B98 |> /lea eax, [eax+2]
00401B9B |. |inc ecx
00401B9C |. |cmp word ptr ds:[eax], 0
00401BA0 |.^ \jne short 00401B98
00401BA2 |> xor eax, eax
00401BA4 |. test ecx, ecx
00401BA6 |. jz short 00401BCA
00401BA8 |> /cmp eax, 2 ; //对输入串加密
00401BAB |. |jae short 00401BB4
00401BAD |. |xor word ptr ds:[eax*2+esi], 000F
00401BB2 |. |jmp short 00401BC5
00401BB4 |> |cmp eax, 4
00401BB7 |. |jae short 00401BC0
00401BB9 |. |xor word ptr ds:[eax*2+esi], 0050
00401BBE |. |jmp short 00401BC5
00401BC0 |> |xor word ptr ds:[eax*2+esi], 0042
00401BC5 |> |inc eax
00401BC6 |. |cmp eax, ecx
00401BC8 |.^ \jb short 00401BA8
00401BCA |> push ebx ; /Arg1
00401BCB |. call 00402CDF ; \Crack_Me.0040C93D
00401BD0 |. mov ecx, ss:[local.102]
00401BD6 |. add esp, 4
00401BD9 |. mov edx, esi
00401BDB |. call 00401870 //下一步
00401BE0 |. mov ecx, ss:[local.1]
00401BE3 |. pop edi
00401BE4 |. pop esi
00401BE5 |. xor ecx, ebp
00401BE7 |. pop ebx
00401BE8 |. call 00402CC5
00401BED |. mov esp, ebp
00401BEF |. pop ebp
00401BF0 \. retn
00401870 $ push ebp
00401871 . mov ebp, esp
00401873 . sub esp, 54
00401876 . mov eax, ds:[41F014]
0040187B . xor eax, ebp
0040187D . mov ss:[ebp-4], eax
00401880 . push ebx
00401881 . push esi
00401882 . push edi
00401883 . push 36 ; /Arg3 = 36
00401885 . lea eax, [ebp-50] ; |
00401888 . mov ebx, ecx ; |
0040188A . push 0 ; |Arg2 = 0
0040188C . push eax ; |Arg1
0040188D . mov edi, edx ; |
0040188F . mov ss:[ebp-54], ebx ; |
00401892 . call 004039D0 ; \Crack_Me.004039D0
00401897 . add esp, 0C
0040189A . lea ecx, [ebp-18]
0040189D . mov eax, 30
004018A2 > mov ds:[ecx], ax
004018A5 . lea ecx, [ecx+2]
004018A8 . inc eax
004018A9 . cmp eax, 39
004018AC .^ jle short 004018A2
004018AE . mov eax, 61 //生成a-z串
004018B3 . lea ecx, [ebp-50]
004018B6 > mov ds:[ecx], ax
004018B9 . lea ecx, [ecx+2]
004018BC . inc eax
004018BD . cmp eax, 7A
004018C0 .^ jle short 004018B6
004018C2 . xor edx, edx
004018C4 . lea eax, [ebp-50]
004018C7 . cmp ss:[ebp-50], dx
004018CB . je short 004018DA
004018CD . nop ds:[eax]
004018D0 > lea eax, [eax+2]
004018D3 . inc edx
004018D4 . cmp word ptr ds:[eax], 0
004018D8 .^ jne short 004018D0
004018DA > xor ecx, ecx
004018DC . test edx, edx
004018DE . je short 004018FC
004018E0 > movzx eax, word ptr ss:[ecx*2+ebp-50]
004018E5 . cmp eax, 61 ; Switch (事例 61..7A, 2 退出)
004018E8 . jb short 004018F7
004018EA . cmp eax, 7A
004018ED . ja short 004018F7
004018EF . add eax, -20 ; //转为A-Z串
004018F2 . mov ss:[ecx*2+ebp-50], ax
004018F7 > inc ecx ; 默认情况下 of switch Crack_Me.4018E5
004018F8 . cmp ecx, edx
004018FA .^ jb short 004018E0
004018FC > xor ecx, ecx
004018FE . mov eax, edi
00401900 . test edi, edi
00401902 . je short 0040197A
00401904 . cmp ds:[edi], cx
00401907 . je short 0040191A
00401909 . nop ds:[eax]
00401910 > lea eax, [eax+2]
00401913 . inc ecx
00401914 . cmp word ptr ds:[eax], 0
00401918 .^ jne short 00401910
0040191A > xor eax, eax
0040191C . test ecx, ecx
0040191E . je short 00401942
00401920 > cmp eax, 2 ; //还原加密了的输入串
00401923 . jae short 0040192C
00401925 . xor word ptr ds:[eax*2+edi], 000F
0040192A . jmp short 0040193D
0040192C > cmp eax, 4
0040192F . jae short 00401938
00401931 . xor word ptr ds:[eax*2+edi], 0050
00401936 . jmp short 0040193D
00401938 > xor word ptr ds:[eax*2+edi], 0042
0040193D > inc eax
0040193E . cmp eax, ecx
00401940 .^ jb short 00401920
00401942 > xor edx, edx
00401944 . mov eax, edi
00401946 . cmp ds:[edi], dx
00401949 . je short 0040195A
0040194B db 0F
0040194C db 1F
0040194D db 44 ; char 'D'
0040194E db 00
0040194F db 00
00401950 > lea eax, [eax+2]
00401953 . inc edx
00401954 . cmp word ptr ds:[eax], 0
00401958 .^ jne short 00401950
0040195A > xor ecx, ecx
0040195C . test edx, edx
0040195E . je short 0040197A
00401960 > movzx eax, word ptr ds:[ecx*2+edi]
00401964 . cmp eax, 61 ; Switch (事例 61..7A, 2 退出)
00401967 . jb short 00401975
00401969 . cmp eax, 7A
0040196C . ja short 00401975
0040196E . add eax, -20 ; //输入串转大写
00401971 . mov ds:[ecx*2+edi], ax
00401975 > inc ecx ; 默认情况下 of switch Crack_Me.401964
00401976 . cmp ecx, edx
00401978 .^ jb short 00401960
0040197A > xor esi, esi
0040197C . xorps xmm0, xmm0
0040197F . movq ss:[ebp-10], xmm0
00401984 . mov ss:[ebp-8], si
00401988 . cmp ds:[edi], si
0040198B . je short 004019D5
0040198D . mov cx, ss:[ebp-50]
00401991 . lea ebx, [ebp-10] //这儿有BUG,存放输入串中的字母BUFFER,BUFFER大小为(0x10-4)/sizeof(WCHAR)=6,不过要是输入串为7个字母,就会溢出
00401994 . mov eax, edi
00401996 > test cx, cx
00401999 . je short 004019C7
0040199B . movzx edx, word ptr ds:[eax] ; //依次取已转大写的输入字符
0040199E . lea ecx, [ebp-50]
004019A1 . xor eax, eax
004019A3 > cmp dx, ds:[ecx] ; //判断是否在A-Z之间
004019A6 . je short 004019B8
004019A8 . inc eax
004019A9 . lea ecx, [ebp-50]
004019AC . cmp word ptr ds:[eax*2+ecx], 0
004019B1 . lea ecx, [eax*2+ecx]
004019B4 .^ jne short 004019A3
004019B6 . jmp short 004019C3
004019B8 > mov ax, ss:[eax*2+ebp-50]
004019BD . mov ds:[ebx], ax ; //是大写字母,存入数组
004019C0 . add ebx, 2
004019C3 > mov cx, ss:[ebp-50]
004019C7 > inc esi
004019C8 . cmp word ptr ds:[esi*2+edi], 0
004019CD . lea eax, [esi*2+edi]
004019D0 .^ jne short 00401996
004019D2 . mov ebx, ss:[ebp-54]
004019D5 > xor ecx, ecx
004019D7 . lea eax, [ebp-10]
004019DA . cmp ss:[ebp-10], cx
004019DE . je short 00401A39
004019E0 > lea eax, [eax+2]
004019E3 . inc ecx
004019E4 . cmp word ptr ds:[eax], 0
004019E8 .^ jne short 004019E0
004019EA . cmp ecx, 2
004019ED . jne short 00401A39 ; //输入串中字母个数不为2则转出错
004019EF . xor eax, eax
004019F1 . mov dword ptr ss:[ebp-10], 350031 ; //串'15PB'
004019F8 . mov dword ptr ss:[ebp-0C], offset 00420050
004019FF . lea esi, [edi+4] ; //从大写输入串第三个字符开始,与串'15PB'比较
00401A02 . mov ss:[ebp-8], ax
00401A06 . xor ecx, ecx
00401A08 db 0F
00401A09 db 1F
00401A0A db 84
00401A0B db 00
00401A0C db 00
00401A0D db 00
00401A0E db 00
00401A0F db 00
00401A10 /> /mov ax, ss:[ecx*2+ebp-10]
00401A15 |. |cmp ax, ds:[esi]
00401A18 |. |jne short 00401A39 ; //不等则出错
00401A1A |. |inc ecx
00401A1B |. |add esi, 2
00401A1E |. |cmp ecx, 4
00401A21 |.^ \jb short 00401A10
00401A23 |. mov edx, edi ; //等则下一步
00401A25 |. mov ecx, ebx
00401A27 |. call 00401740
00401A2C |. push 0
00401A2E |. test eax, eax
00401A30 |. jz short 00401A3B
00401A32 |. push 40B
00401A37 |. jmp short 00401A40
00401A39 |> push 0
00401A3B |> push 40A
00401A40 |> push 111 ; |Msg = WM_COMMAND
00401A45 |. push dword ptr ds:[ebx+4] ; |hWnd
00401A48 |. call ds:[<&USER32.PostMessageW>] ; \USER32.PostMessageW
00401A4E |. mov ecx, ss:[ebp-4]
00401A51 |. pop edi
00401A52 |. pop esi
00401A53 |. xor ecx, ebp
00401A55 |. pop ebx
00401A56 |. call 00402CC5
00401A5B |. mov esp, ebp
00401A5D |. pop ebp
00401A5E \. retn
00401740 $ push ebp
00401741 . mov ebp, esp
00401743 . sub esp, 50
00401746 . mov eax, ds:[41F014]
0040174B . xor eax, ebp
0040174D . mov ss:[ebp-4], eax
00401750 . push ebx
00401751 . mov ebx, edx
00401753 . mov dword ptr ss:[ebp-0C], 0
0040175A . mov edx, ecx
0040175C . mov word ptr ss:[ebp-8], 0
00401762 . xorps xmm0, xmm0
00401765 . mov ss:[ebp-4C], edx
00401768 . push esi
00401769 . push edi
0040176A . movups ss:[ebp-24], xmm0
0040176E . lea ecx, [ebp-24]
00401771 . mov eax, 31 ; //生成串1-9
00401776 . movq ss:[ebp-14], xmm0
0040177B db 0F
0040177C db 1F
0040177D db 44 ; char 'D'
0040177E db 00
0040177F db 00
00401780 /> /mov ds:[ecx], ax
00401783 |. |lea ecx, [ecx+2]
00401786 |. |inc eax
00401787 |. |cmp eax, 39
0040178A |.^ \jle short 00401780
0040178C |. mov eax, ds:[edx] ; //取点击次数
0040178E |. xor esi, esi
00401790 |. lea ecx, [eax*2+ebx] ; //从点击次数位置取输入大写子串
00401793 |. mov eax, ebx
00401795 |. test ebx, ebx
00401797 |. jz short 004017AA
00401799 |. cmp ds:[ebx], si
0040179C |. je short 004017AA
0040179E |. nop
004017A0 |> /lea eax, [eax+2]
004017A3 |. |inc esi
004017A4 |. |cmp word ptr ds:[eax], 0
004017A8 |.^ \jne short 004017A0
004017AA |> push ecx ; /Arg2
004017AB |. lea eax, [ebp-24] ; |//连接子串到1-9之后
004017AE |. push eax ; |Arg1
004017AF |. call 004028D0 ; \Crack_Me.004028D0
004017B4 |. lea esi, [esi-1]
004017B7 |. mov edi, eax
004017B9 |. lea eax, [esi*2+ebx]
004017BC |. mov ss:[ebp-48], edi
004017BF |. xor esi, esi
004017C1 |. mov ss:[ebp-50], eax ; //取输入串最后一个字符的位置
004017C4 |. cmp ss:[ebp-24], si
004017C8 |. je short 004017FB
004017CA |. movzx edi, word ptr ds:[eax] ; //取最后一个输入字符
004017CD |. lea ecx, [ebp-24]
004017D0 |. and edi, 00000001
004017D3 |> /mov ax, ds:[ecx]
004017D6 |. |shr ax, 2
004017DA |. |add ax, di
004017DD |. |cmp ax, 32
004017E1 |. |je short 0040185B
004017E3 |. |cmp ax, 64
004017E7 |. |je short 004017F8
004017E9 |. |inc esi
004017EA |. |lea ecx, [ebp-24]
004017ED |. |lea edx, [esi+esi]
004017F0 |. |add ecx, edx
004017F2 |. |cmp word ptr ds:[ecx], 0
004017F6 |.^ \jne short 004017D3
004017F8 |> mov edi, ss:[ebp-48]
004017FB |> lea ecx, [ebp-24]
004017FE |. mov esi, ebx
00401800 |. mov eax, ecx
00401802 |. mov edx, 31
00401807 |. sub esi, eax
00401809 |. nop ds:[eax]
00401810 |> /mov ax, ds:[ecx] ; //比较输入串与串1-9(只循环2次所以只比较前二个字符)
00401813 |. |cmp ax, ds:[ecx+esi]
00401817 |. |jne short 0040185B
00401819 |. |add edx, 6
0040181C |. |add ecx, 2
0040181F |. |cmp edx, 39
00401822 |.^ \jle short 00401810
00401824 |. movzx ecx, word ptr ds:[edi+12] ; //取前面连接子串第一个字符,及输入的第点击次数个字符
00401828 |. movzx eax, word ptr ds:[ebx] ; //取输入第一个字符'1'即0x31
0040182B |. add ecx, eax
0040182D |. cmp ecx, 63
00401830 |. jne short 0040185B ; //和不为63转出错
00401832 |. mov eax, ss:[ebp-4C]
00401835 |. movzx ecx, word ptr ds:[edi+0C] ; //取字符'7'
00401839 |. add ecx, ds:[eax] ; //加上点击次数
0040183B |. mov eax, ss:[ebp-50]
0040183E |. movzx eax, word ptr ds:[eax] ; //取输入串最后一个字符
00401841 |. cmp eax, ecx
00401843 |. jne short 0040185B ; //输入串最后一个字符必须等于'7'+点击次数
00401845 |. pop edi //满足以上所有条件,返回1代表成功
00401846 |. pop esi
00401847 |. mov eax, 1
0040184C |. pop ebx
0040184D |. mov ecx, ss:[ebp-4]
00401850 |. xor ecx, ebp
00401852 |. call 00402CC5
00401857 |. mov esp, ebp
00401859 |. pop ebp
0040185A |. retn
0040185B |> mov ecx, ss:[ebp-4] //返回0,代表失败
0040185E |. xor eax, eax
00401860 |. pop edi
00401861 |. pop esi
00401862 |. xor ecx, ebp
00401864 |. pop ebx
00401865 |. call 00402CC5
0040186A |. mov esp, ebp
0040186C |. pop ebp
0040186D \. retn
设输入为SN,点击次数为K,由以上分析不难看出有如下规则:
1.SN中一定有'b','p'字符
2.SN长度为7
3.SN中字母个数为2
4.SN第2-5个字符为'15pb'
5.SN第0-1个字符为'12'
6.SN[K] + 0x31 = 0x63,及SN[K] = 0x32 = '2'
7.SN[6] = '7' + K
由4,5可知SN[0-5] = '1215pb'
由6可知K = 1
由7和K=1可知SN[6]='8'
所以SN = '1215pb8'
分析中发现程序有BUG(前面有注释),在取出输入串中的字母时,BUFFER小了,在特定情况下会溢出(当输入SN全字母,且长度为7,且有'b'和'p'时),程序会崩溃。还有点击次数K好像也没有限制,不知道点N次过后,会不会来个0xC0000005异常?
//1。检测父进程是否为explorer,不是则退出
00401000 /E9 3B030000 jmp 00401340
00401340 /> push ebp
00401341 |. mov ebp, esp
00401343 |. mov eax, 4B24
00401348 |. call 00417150
0040134D |. mov eax, [41F014]
00401352 |. xor eax, ebp
00401354 |. mov [ebp-4], eax
00401357 |. push ebx
00401358 |. push esi
00401359 |. push edi ; /Procname
0040135A |. call 004048DE ; |[Crack_Me.004048DE
0040135F |. mov ecx, offset 0041D988 ; |ASCII "A{^zj}vFai`}bn{f`a_}`lj||"
00401364 |. call 00401180 ; |[Crack_Me.00401180
00401369 |. mov esi, eax ; |
0040136B |. call 00401080 ; |[Crack_Me.00401080
00401370 |. mov edi, eax ; |
00401372 |. push esi ; |
00401373 |. push edi ; |/FileName
00401374 |. call [<&KERNEL32.LoadLibraryW>] ; |\KERNEL32.LoadLibraryW
0040137A |. push eax ; |hModule
0040137B |. call [<&KERNEL32.GetProcAddress>] ; \KERNEL32.GetProcAddress
00401381 |. mov [ebp-250], eax
00401387 |. call [<&KERNEL32.GetCurrentProcessId> ; [KERNEL32.GetCurrentProcessId
0040138D |. push eax ; /ProcessID
0040138E |. push 0 ; |InheritHandle = FALSE
00401390 |. push 1FFFFF ; |Access =
00401395 |. call [<&KERNEL32.OpenProcess>] ; \KERNEL32.OpenProcess
0040139B |. push esi ; /Arg1
0040139C |. mov ebx, eax ; |
0040139E |. call 00402CDF ; \Crack_Me.0040C93D
004013A3 |. push edi ; /Arg1
004013A4 |. call 00402CDF ; \Crack_Me.0040C93D
004013A9 |. add esp, 8
004013AC |. test ebx, ebx
004013AE |.- jnz short 004013C4
004013B0 |. pop edi
004013B1 |. pop esi
004013B2 |. or eax, FFFFFFFF
004013B5 |. pop ebx
004013B6 |. mov ecx, [ebp-4]
004013B9 |. xor ecx, ebp
004013BB |. call 00402CC5
004013C0 |. mov esp, ebp
004013C2 |. pop ebp
004013C3 |. retn
004013C4 |> lea eax, [ebp-8]
004013C7 |. push eax
004013C8 |. push 18
004013CA |. lea eax, [ebp-24C]
004013D0 |. push eax
004013D1 |. push 0
004013D3 |. push ebx
004013D4 |. call [ebp-250]
004013DA |. mov eax, [ebp-238]
004013E0 |. push ebx ; /hObject
004013E1 |. mov [ebp-254], eax ; |
004013E7 |. call [<&KERNEL32.CloseHandle>] ; \KERNEL32.CloseHandle
004013ED |. call 004048DE ; [Crack_Me.004048DE
004013F2 |. push 0 ; /ProcessID = 0 (0.)
004013F4 |. push 2 ; |Flags = TH32CS_SNAPPROCESS
004013F6 |. call [<&KERNEL32.CreateToolhelp32Snap ; \KERNEL32.CreateToolhelp32Snapshot
004013FC |. mov edi, eax
004013FE |. mov dword ptr [ebp-234], 22C
00401408 |. push 228 ; /Arg3 = 228
0040140D |. lea eax, [ebp-230] ; |
00401413 |. mov [ebp-250], edi ; |
00401419 |. push 0 ; |Arg2 = 0
0040141B |. push eax ; |Arg1
0040141C |. call 004039D0 ; \Crack_Me.004039D0
00401421 |. add esp, 0C
00401424 |. lea eax, [ebp-234]
0040142A |. push eax ; /Arg2
0040142B |. push edi ; |Arg1
0040142C |. call [<&KERNEL32.Process32FirstW>] ; \KERNEL32.Process32FirstW
00401432 |. mov esi, eax
00401434 |. call 00401240 ; [Crack_Me.00401240
00401439 |. mov ebx, eax ; //串"explorer.exe"
0040143B |. test esi, esi
0040143D |.- jz short 004014AC
0040143F |. lea edi, [ebp+FFFFB4DC]
00401445 |> /test ebx, ebx
00401447 |.- |jz short 0040148F
00401449 |. |mov ax, [ebp-210]
00401450 |. |cmp ax, [ebx]
00401453 |.- |ja short 0040148F
00401455 |. |lea eax, [ebp-210]
0040145B |. |mov esi, ebx
0040145D |. |mov ecx, eax
0040145F |. |sub esi, ecx
00401461 |> |/movzx edx, word ptr [eax+esi]
00401465 |. ||movzx ecx, word ptr [eax]
00401468 |. ||cmp cx, dx
0040146B |.- ||jne short 00401477
0040146D |. ||test cx, cx
00401470 |.- ||jz short 00401484
00401472 |. ||add eax, 2
00401475 |.- ||jmp short 00401479
00401477 |>- ||jb short 0040148F
00401479 |> ||mov cx, [eax]
0040147C |. ||cmp cx, [eax+esi]
00401480 |.- |\jbe short 00401461
00401482 |.- |jmp short 0040148F
00401484 |> |mov eax, [ebp-22C] ; //取进程ID
0040148A |. |mov [edi], eax ; //存入explorer进程ID数组
0040148C |. |add edi, 4
0040148F |> |lea eax, [ebp-234]
00401495 |. |push eax ; /Arg2
00401496 |. |push dword ptr [ebp-250] ; |Arg1
0040149C |. |call [<&KERNEL32.Process32NextW>] ; \KERNEL32.Process32NextW
004014A2 |. |test eax, eax
004014A4 |.- \jnz short 00401445
004014A6 |. mov edi, [ebp-250]
004014AC |> mov ebx, [ebp-254] ; //取父进程ID
004014B2 |. mov edx, 1
004014B7 |. cmp ebx, [ebp+FFFFB4DC] ; //父进程ID与explorer进程ID数组中的ID依次比较
004014BD |. mov ecx, edx
004014BF |. sete al
004014C2 |. cmp ebx, [ebp+FFFFB4E0]
004014C8 |. movzx eax, al
004014CB |. cmove eax, edx
004014CE |. cmp ebx, [ebp+FFFFB4E4]
004014D4 |. movzx eax, al
004014D7 |. cmovne ecx, eax
004014DA |. cmp ebx, [ebp+FFFFB4E8]
004014E0 |. movzx eax, cl
004014E3 |. mov ecx, edx
004014E5 |. cmove eax, edx
004014E8 |. cmp ebx, [ebp+FFFFB4EC]
004014EE |. movzx eax, al
004014F1 |. cmovne ecx, eax
004014F4 |. cmp ebx, [ebp+FFFFB4F0]
004014FA |. movzx eax, cl
004014FD |. mov ecx, edx
004014FF |. cmove eax, edx
00401502 |. cmp ebx, [ebp+FFFFB4F4]
00401508 |. movzx eax, al
0040150B |. cmovne ecx, eax
0040150E |. cmp ebx, [ebp+FFFFB4F8]
00401514 |. movzx eax, cl
00401517 |. cmove eax, edx
0040151A |. cmp ebx, [ebp+FFFFB4FC]
00401520 |. movzx eax, al
00401523 |. cmovne edx, eax
00401526 |. cmp ebx, [ebp+FFFFB500]
0040152C |.- je short 00401532
0040152E |. test dl, dl
00401530 |.- jz short 0040154C ; //父进程ID不在explorer进程ID数组中,即父进程名不是explorer则转
00401532 |> push edi ; /hObject
00401533 |. call [<&KERNEL32.CloseHandle>] ; \KERNEL32.CloseHandle
00401539 |. mov ecx, [ebp-4]
0040153C |. xor eax, eax
0040153E |. pop edi
0040153F |. pop esi
00401540 |. xor ecx, ebp
00401542 |. pop ebx
00401543 |. call 00402CC5
00401548 |. mov esp, ebp
0040154A |. pop ebp
0040154B |. retn
0040154C |> push 0 ; //退出
0040154E \. call 00404BB1
解决办法PATCH 00401000 为 RETN
//2。取时钟,多个地方调用,用于检测调试器
004048DE /$ mov edi, edi ; Crack_Me.004048DE(推测 void)
004048E0 |. push ebp
004048E1 |. mov ebp, esp
004048E3 |. push ecx
004048E4 |. push ecx
004048E5 |. mov ecx, [41FC18]
004048EB |. and ecx, [41FC1C]
004048F1 |. push esi
004048F2 |. or esi, FFFFFFFF
004048F5 |. cmp ecx, esi
004048F7 |. je short 00404939
004048F9 |. lea eax, [local.2]
004048FC |. push eax
004048FD |. call [<&KERNEL32.QueryPerformanceCounter>]
00404903 |. test eax, eax
00404905 |. jz short 00404939
00404907 |. mov eax, [local.2]
0040490A |. sub eax, [41FC18]
00404910 |. mov ecx, [local.1]
00404913 |. sbb ecx, [41FC1C]
00404919 |. test ecx, ecx
0040491B |. jg short 00404923
0040491D |. jl short 00404939
0040491F |. test eax, eax
00404921 |. jb short 00404939
00404923 |> push ecx ; /Arg2
00404924 |. push eax ; |Arg1
00404925 |. call 00404817 ; \Crack_Me.00404817
0040492A |. pop ecx
0040492B |. pop ecx
0040492C |. test edx, edx
0040492E |. jl short 0040493B
00404930 |. jg short 00404939
00404932 |. cmp eax, 7FFFFFFF
00404937 |. jbe short 0040493B
00404939 |> mov eax, esi
0040493B |> pop esi
0040493C |. mov esp, ebp
0040493E |. pop ebp
0040493F \. retn
解决办法PATCH 004048DE为:
xor eax,eax
mov edx,eax
retn
解决了反调试,就可以慢慢分析,算法还是比较简单,只是不在一个地方,比较分散,关键代码如下,分析见注释:
004022C4 |. mov eax, ds:[420318] ; 事例 3EB of switch Crack_Me.402296
004022C9 |. inc eax ; //点击次数计数加一
004022CA |. push eax ; /Arg4
004022CB |. push offset 0041DAA0 ; |Arg3 = UNICODE "%d"
004022D0 |. mov ds:[420318], eax ; |
004022D5 |. lea eax, [local.21] ; |
004022D8 |. push 0A ; |Arg2 = 0A
004022DA |. push eax ; |Arg1 => offset LOCAL.21
004022DB |. call 00402790 ; \Crack_Me.00402790
004022E0 |. mov edi, ds:[<&USER32.GetDlgItem>]
004022E6 |. lea eax, [local.21]
004022E9 |. add esp, 10
004022EC |. push eax ; /Text => offset LOCAL.21
004022ED |. push 3E8 ; |/ItemID = 1000.
004022F2 |. push ebx ; ||hDialog
004022F3 |. call edi ; |\USER32.GetDlgItem
004022F5 |. push eax ; |hWnd
004022F6 |. call ds:[<&USER32.SetWindowTextW>] ; \USER32.SetWindowTextW
004022FC |. push 14 ; /Arg1 = 14
004022FE |. call 00402CF2 ; \Crack_Me.00402CF2
00402303 |. add esp, 4
00402306 |. mov dword ptr ss:[local.2], 0
0040230D |. mov esi, eax
0040230F |. xorps xmm0, xmm0
00402312 |. lea eax, [local.6]
00402315 |. movups ss:[local.6], xmm0
00402319 |. push 0A
0040231B |. push eax
0040231C |. push 3E8
00402321 |. push ebx
00402322 |. call edi
00402324 |. push eax ; |hWnd
00402325 |. call ds:[<&USER32.GetWindowTextW>] ; \USER32.GetWindowTextW
0040232B |. lea eax, [local.72] ; //读点击次数计数
00402331 |. push eax ; /Arg3 => offset LOCAL.72
00402332 |. lea eax, [local.6] ; |
00402335 |. push offset 0041DAA0 ; |Arg2 = UNICODE "%d"
0040233A |. push eax ; |Arg1 => offset LOCAL.6
0040233B |. call 004027C0 ; \Crack_Me.004027C0
00402340 |. mov eax, ss:[local.72]
00402346 |. add esp, 0C
00402349 |. mov ds:[esi], eax ; //点击次数,窗口句柄等依次写入参数结构,并建立计算线程
0040234B |. mov ds:[esi+4], ebx
0040234E |. push 3EA
00402353 |. push ebx
00402354 |. call edi
00402356 |. push 3E8
0040235B |. push ebx
0040235C |. mov ds:[esi+0C], eax
0040235F |. call edi
00402361 |. push 0
00402363 |. push 0
00402365 |. push esi
00402366 |. mov ds:[esi+8], eax
00402369 |. mov ds:[esi+10], esi
0040236C |. push 004020E0 ; //计算线程地址
00402371 |. jmp 0040276B
0040276B |> \push 0 ; |StackSize = 0
0040276D |. push 0 ; |pSecurity = NULL
0040276F |. call ds:[<&KERNEL32.CreateThread>] ; \KERNEL32.CreateThread
00402775 |> mov ecx, ss:[local.1] ; 事例 68 of switch Crack_Me.402296
00402778 |. xor eax, eax
0040277A |. pop edi
0040277B |. pop esi
0040277C |. xor ecx, ebp
0040277E |. pop ebx
0040277F |. call 00402CC5
00402784 |. mov esp, ebp
00402786 |. pop ebp
00402787 \. retn 10
//计算线程
004020E0 /. push ebp
004020E1 |. mov ebp, esp
004020E3 |. mov ecx, ss:[arg.1]
004020E6 |. xor edx, edx
004020E8 |. call 00401CB0 //调用计算子程序
004020ED |. push 14
004020EF |. push dword ptr ss:[arg.1]
004020F2 |. call 00402CE4
004020F7 |. add esp, 8
004020FA |. xor eax, eax
004020FC |. pop ebp
004020FD \. retn 4
//计算子程序
00401CB0 /$ push ebp
00401CB1 |. mov ebp, esp
00401CB3 |. sub esp, 0D0
00401CB9 |. mov eax, ds:[41F014]
00401CBE |. xor eax, ebp
00401CC0 |. mov ss:[local.1], eax
00401CC3 |. push edi
00401CC4 |. mov edi, ecx
00401CC6 |. test edi, edi
00401CC8 |. jz 00401E2F
00401CCE |. test edx, edx
00401CD0 |. jnz 00401D57
00401CD6 |. call 00401C00 ; //查找输入是否有字符'b',没有则转
00401CDB |. test eax, eax
00401CDD |. jz short 00401D33
00401CDF |. push 0C8 ; /Arg3 = 0C8
00401CE4 |. lea eax, [local.51] ; |
00401CEA |. push 0 ; |Arg2 = 0
00401CEC |. push eax ; |Arg1 => offset LOCAL.51
00401CED |. call 004039D0 ; \Crack_Me.004039D0
00401CF2 |. add esp, 0C
00401CF5 |. lea eax, [local.51]
00401CFB |. push 64 ; /MaxCount = 100.
00401CFD |. push eax ; |String => offset LOCAL.51
00401CFE |. push dword ptr ds:[edi+0C] ; |hWnd
00401D01 |. call ds:[<&USER32.GetWindowTextW>] ; \USER32.GetWindowTextW
00401D07 |. push 70 ; /Arg1 = 70, //字符'p'
00401D09 |. lea edx, [local.51] ; |
00401D0F |. call 00402A50 ; \Crack_Me.00402A50
00401D14 |. test eax, eax
00401D16 |. jz short 00401D33 ; //输入没有字符'p'则转
00401D18 |. mov edx, 1
00401D1D |. mov ecx, edi
00401D1F |. call 00401CB0 ; //输入有字符'p'和'b'则下一步
00401D24 |. pop edi
00401D25 |. mov ecx, ss:[local.1]
00401D28 |. xor ecx, ebp
00401D2A |. call 00402CC5
00401D2F |. mov esp, ebp
00401D31 |. pop ebp
00401D32 |. retn
00401D33 |> push 0 ; /lParam = NULL
00401D35 |. push 40F ; |wParam = NotifyCode = MENU/BN_CLICKED..., ID = 1039.
00401D3A |. push 111 ; |Msg = WM_COMMAND
00401D3F |. push dword ptr ds:[edi+4] ; |hWnd
00401D42 |. call ds:[<&USER32.SendMessageW>] ; \USER32.SendMessageW
00401D48 |. pop edi
00401D49 |. mov ecx, ss:[local.1]
00401D4C |. xor ecx, ebp
00401D4E |. call 00402CC5
00401D53 |. mov esp, ebp
00401D55 |. pop ebp
00401D56 |. retn
00401D57 |> push esi
00401D58 |. call 004048DE ; [Crack_Me.004048DE
00401D5D |. push 0C8 ; /Arg3 = 0C8
00401D62 |. mov ss:[local.52], eax ; |
00401D68 |. lea eax, [local.51] ; |
00401D6E |. push 0 ; |Arg2 = 0
00401D70 |. push eax ; |Arg1 => offset LOCAL.51
00401D71 |. call 004039D0 ; \Crack_Me.004039D0
00401D76 |. add esp, 0C
00401D79 |. lea eax, [local.51]
00401D7F |. push 0C8 ; /MaxCount = 200.
00401D84 |. push eax ; |String => offset LOCAL.51
00401D85 |. push dword ptr ds:[edi+0C] ; |hWnd
00401D88 |. call ds:[<&USER32.GetWindowTextW>] ; \USER32.GetWindowTextW
00401D8E |. xor esi, esi
00401D90 |. lea eax, [local.51]
00401D96 |. cmp ss:[local.51], si
00401D9D |. je short 00401DAA
00401D9F |. nop
00401DA0 |> /lea eax, [eax+2]
00401DA3 |. |inc esi
00401DA4 |. |cmp word ptr ds:[eax], 0
00401DA8 |.^ \jne short 00401DA0
00401DAA |> xor ecx, ecx
00401DAC |. lea eax, [esi+1]
00401DAF |. mov edx, 2
00401DB4 |. mul edx
00401DB6 |. push ebx
00401DB7 |. seto cl
00401DBA |. neg ecx
00401DBC |. or ecx, eax
00401DBE |. push ecx ; /Arg1
00401DBF |. call 00402CD6 ; \Crack_Me.00402CD6
00401DC4 |. add esp, 4
00401DC7 |. mov ebx, eax
00401DC9 |. call 004048DE ; [Crack_Me.004048DE
00401DCE |. sub eax, ss:[local.52]
00401DD4 |. cmp eax, 2 ; //时间大于2则认为被调试,退出程序
00401DD7 |. jg short 00401E3E
00401DD9 |. lea eax, [local.51]
00401DDF |. push eax ; /Arg2 => offset LOCAL.51
00401DE0 |. push ebx ; |Arg1
00401DE1 |. call 00402870 ; \Crack_Me.00402870
00401DE6 |. cmp esi, 7 ; //输入长度不为7则错误
00401DE9 |. jae short 00401DF6
00401DEB |. push 0
00401DED |. push 0
00401DEF |. push 40E
00401DF4 |. jmp short 00401E01
00401DF6 |> jbe short 00401E24
00401DF8 |. push 0
00401DFA |. push 0
00401DFC |. push 40D
00401E01 |> push dword ptr ds:[edi+4] ; |hWnd
00401E04 |. call ds:[<&USER32.SendMessageW>] ; \USER32.SendMessageW
00401E0A |. push ebx ; /Arg1
00401E0B |. call 00402CDF ; \Crack_Me.0040C93D
00401E10 |. add esp, 4
00401E13 |. pop ebx
00401E14 |. pop esi
00401E15 |. pop edi
00401E16 |. mov ecx, ss:[local.1]
00401E19 |. xor ecx, ebp
00401E1B |. call 00402CC5
00401E20 |. mov esp, ebp
00401E22 |. pop ebp
00401E23 |. retn
00401E24 |> mov edx, ebx ; //输入有'b','p',且长度为7则下一步
00401E26 |. mov ecx, edi
00401E28 |. call 00401A60
00401E2D |. pop ebx
00401E2E |. pop esi
00401E2F |> mov ecx, ss:[local.1]
00401E32 |. xor ecx, ebp
00401E34 |. pop edi
00401E35 |. call 00402CC5
00401E3A |. mov esp, ebp
00401E3C |. pop ebp
00401E3D |. retn
00401E3E |> push 0 ; //退出程序
00401E40 \. call 00404BB1
//查找输入是否有字符'b'
00401C00 $ push ebp
00401C01 . mov ebp, esp
00401C03 . sub esp, 0CC
00401C09 . mov eax, ds:[41F014]
00401C0E . xor eax, ebp
00401C10 . mov ss:[ebp-4], eax
00401C13 . push esi
00401C14 . push 0C8 ; /Arg3 = 0C8
00401C19 . lea eax, [ebp-0CC] ; |
00401C1F . mov esi, ecx ; |
00401C21 . push 0 ; |Arg2 = 0
00401C23 . push eax ; |Arg1
00401C24 . call 004039D0 ; \Crack_Me.004039D0
00401C29 . add esp, 0C
00401C2C . lea eax, [ebp-0CC]
00401C32 . push 64 ; /MaxCount = 100.
00401C34 . push eax ; |String
00401C35 . push dword ptr ds:[esi+0C] ; |hWnd
00401C38 . call ds:[<&USER32.GetWindowTextW>] ; \USER32.GetWindowTextW
00401C3E . mov cx, ss:[ebp-0CC]
00401C45 . lea eax, [ebp-0CC]
00401C4B . pop esi
00401C4C . test cx, cx
00401C4F . je short 00401C5B
00401C51 > cmp word ptr ds:[eax+2], 0
00401C56 . lea eax, [eax+2]
00401C59 .^ jne short 00401C51
00401C5B > xor eax, eax
00401C5D . test cx, cx
00401C60 . je short 00401C83
00401C62 . movzx ecx, cx
00401C65 . mov edx, 62 ; //字符‘b’
00401C6A db 66 ; char 'f'
00401C6B db 0F
00401C6C db 1F
00401C6D db 44 ; char 'D'
00401C6E db 00
00401C6F db 00
00401C70 /> /cmp dx, cx ; //查找字符‘b’
00401C73 |. |je short 00401C93
00401C75 |. |movzx ecx, word ptr ss:[eax*2+ebp-0CA]
00401C7D |. |inc eax
00401C7E |. |test cx, cx
00401C81 |.^ \jnz short 00401C70
00401C83 |> xor eax, eax ; //未找到字符‘b’,返回0
00401C85 |. mov ecx, ss:[ebp-4]
00401C88 |. xor ecx, ebp
00401C8A |. call 00402CC5
00401C8F |. mov esp, ebp
00401C91 |. pop ebp
00401C92 |. retn
00401C93 |> mov ecx, ss:[ebp-4] ; //找到字符‘b’,返回1
00401C96 |. mov eax, 1
00401C9B |. xor ecx, ebp
00401C9D |. call 00402CC5
00401CA2 |. mov esp, ebp
00401CA4 |. pop ebp
00401CA5 \. retn
00401A60 /$ push ebp
00401A61 |. mov ebp, esp
00401A63 |. sub esp, 19C
00401A69 |. mov eax, ds:[41F014]
00401A6E |. xor eax, ebp
00401A70 |. mov ss:[local.1], eax
00401A73 |. push ebx
00401A74 |. push esi
00401A75 |. push edi
00401A76 |. push 0C8 ; /Arg3 = 0C8
00401A7B |. lea eax, [local.51] ; |
00401A81 |. mov edi, ecx ; |
00401A83 |. push 0 ; |Arg2 = 0
00401A85 |. push eax ; |Arg1 => offset LOCAL.51
00401A86 |. mov ebx, edx ; |
00401A88 |. mov ss:[local.102], edi ; |
00401A8E |. call 004039D0 ; \Crack_Me.004039D0
00401A93 |. push 0C8 ; /Arg3 = 0C8
00401A98 |. lea eax, [local.101] ; |
00401A9E |. push 0 ; |Arg2 = 0
00401AA0 |. push eax ; |Arg1 => offset LOCAL.101
00401AA1 |. call 004039D0 ; \Crack_Me.004039D0
00401AA6 |. mov esi, ds:[<&USER32.SendMessageW>]
00401AAC |. lea eax, [local.51]
00401AB2 |. add esp, 18
00401AB5 |. push eax ; /lParam => offset LOCAL.51
00401AB6 |. push 0D ; |wParam = 13.
00401AB8 |. push 0D ; |Msg = WM_GETTEXT
00401ABA |. push dword ptr ds:[edi+0C] ; |hWnd
00401ABD |. call esi ; \USER32.SendMessageW
00401ABF |. lea eax, [local.101]
00401AC5 |. push eax
00401AC6 |. push 40C
00401ACB |. push 111
00401AD0 |. push dword ptr ds:[edi+4]
00401AD3 |. call esi
00401AD5 |. xor ecx, ecx
00401AD7 |. lea eax, [local.51]
00401ADD |. cmp ss:[local.51], cx
00401AE4 |. je short 00401AF0
00401AE6 |> /lea eax, [eax+2]
00401AE9 |. |inc ecx
00401AEA |. |cmp word ptr ds:[eax], 0
00401AEE |.^ \jne short 00401AE6
00401AF0 |> test ecx, ecx
00401AF2 |. jz short 00401B05
00401AF4 |. xor eax, eax
00401AF6 |. lea edi, [local.51]
00401AFC |. shr ecx, 1
00401AFE |. rep stos dword ptr es:[edi]
00401B00 |. adc ecx, ecx
00401B02 |. rep stos word ptr es:[edi]
00401B05 |> xor ecx, ecx
00401B07 |. lea eax, [local.101]
00401B0D |. cmp ss:[local.101], cx
00401B14 |. je short 00401B20
00401B16 |> /lea eax, [eax+2]
00401B19 |. |inc ecx
00401B1A |. |cmp word ptr ds:[eax], 0
00401B1E |.^ \jne short 00401B16
00401B20 |> test ecx, ecx
00401B22 |. jz short 00401B35
00401B24 |. xor eax, eax
00401B26 |. lea edi, [local.101]
00401B2C |. shr ecx, 1
00401B2E |. rep stos dword ptr es:[edi]
00401B30 |. adc ecx, ecx
00401B32 |. rep stos word ptr es:[edi]
00401B35 |> xor ecx, ecx
00401B37 |. mov eax, ebx
00401B39 |. test ebx, ebx
00401B3B |. jz short 00401B4C
00401B3D |. cmp ds:[ebx], cx
00401B40 |. je short 00401B4C
00401B42 |> /lea eax, [eax+2]
00401B45 |. |inc ecx
00401B46 |. |cmp word ptr ds:[eax], 0
00401B4A |.^ \jne short 00401B42
00401B4C |> lea eax, [ecx+1]
00401B4F |. mov edx, 2
00401B54 |. xor ecx, ecx
00401B56 |. mul edx
00401B58 |. seto cl
00401B5B |. neg ecx
00401B5D |. or ecx, eax
00401B5F |. push ecx ; /Arg1
00401B60 |. call 00402CD6 ; \Crack_Me.00402CD6
00401B65 |. mov esi, eax
00401B67 |. add esp, 4
00401B6A |. xor eax, eax
00401B6C |. cmp ds:[ebx], ax
00401B6F |. je short 00401B87
00401B71 |. movzx ecx, word ptr ds:[ebx]
00401B74 |. xor edx, edx
00401B76 |> /inc eax
00401B77 |. |mov ds:[esi+edx], cx
00401B7B |. |lea edx, [eax+eax]
00401B7E |. |movzx ecx, word ptr ds:[ebx+edx]
00401B82 |. |test cx, cx
00401B85 |.^ \jnz short 00401B76
00401B87 |> xor ecx, ecx
00401B89 |. mov ds:[eax*2+esi], cx
00401B8D |. mov eax, esi
00401B8F |. test esi, esi
00401B91 |. jz short 00401BCA
00401B93 |. cmp ds:[esi], cx
00401B96 |. je short 00401BA2
00401B98 |> /lea eax, [eax+2]
00401B9B |. |inc ecx
00401B9C |. |cmp word ptr ds:[eax], 0
00401BA0 |.^ \jne short 00401B98
00401BA2 |> xor eax, eax
00401BA4 |. test ecx, ecx
00401BA6 |. jz short 00401BCA
00401BA8 |> /cmp eax, 2 ; //对输入串加密
00401BAB |. |jae short 00401BB4
00401BAD |. |xor word ptr ds:[eax*2+esi], 000F
00401BB2 |. |jmp short 00401BC5
00401BB4 |> |cmp eax, 4
00401BB7 |. |jae short 00401BC0
00401BB9 |. |xor word ptr ds:[eax*2+esi], 0050
00401BBE |. |jmp short 00401BC5
00401BC0 |> |xor word ptr ds:[eax*2+esi], 0042
00401BC5 |> |inc eax
00401BC6 |. |cmp eax, ecx
00401BC8 |.^ \jb short 00401BA8
00401BCA |> push ebx ; /Arg1
00401BCB |. call 00402CDF ; \Crack_Me.0040C93D
00401BD0 |. mov ecx, ss:[local.102]
00401BD6 |. add esp, 4
00401BD9 |. mov edx, esi
00401BDB |. call 00401870 //下一步
00401BE0 |. mov ecx, ss:[local.1]
00401BE3 |. pop edi
00401BE4 |. pop esi
00401BE5 |. xor ecx, ebp
00401BE7 |. pop ebx
00401BE8 |. call 00402CC5
00401BED |. mov esp, ebp
00401BEF |. pop ebp
00401BF0 \. retn
00401870 $ push ebp
00401871 . mov ebp, esp
00401873 . sub esp, 54
00401876 . mov eax, ds:[41F014]
0040187B . xor eax, ebp
0040187D . mov ss:[ebp-4], eax
00401880 . push ebx
00401881 . push esi
00401882 . push edi
00401883 . push 36 ; /Arg3 = 36
00401885 . lea eax, [ebp-50] ; |
00401888 . mov ebx, ecx ; |
0040188A . push 0 ; |Arg2 = 0
0040188C . push eax ; |Arg1
0040188D . mov edi, edx ; |
0040188F . mov ss:[ebp-54], ebx ; |
00401892 . call 004039D0 ; \Crack_Me.004039D0
00401897 . add esp, 0C
0040189A . lea ecx, [ebp-18]
0040189D . mov eax, 30
004018A2 > mov ds:[ecx], ax
004018A5 . lea ecx, [ecx+2]
004018A8 . inc eax
004018A9 . cmp eax, 39
004018AC .^ jle short 004018A2
004018AE . mov eax, 61 //生成a-z串
004018B3 . lea ecx, [ebp-50]
004018B6 > mov ds:[ecx], ax
004018B9 . lea ecx, [ecx+2]
004018BC . inc eax
004018BD . cmp eax, 7A
004018C0 .^ jle short 004018B6
004018C2 . xor edx, edx
004018C4 . lea eax, [ebp-50]
004018C7 . cmp ss:[ebp-50], dx
004018CB . je short 004018DA
004018CD . nop ds:[eax]
004018D0 > lea eax, [eax+2]
004018D3 . inc edx
004018D4 . cmp word ptr ds:[eax], 0
004018D8 .^ jne short 004018D0
004018DA > xor ecx, ecx
004018DC . test edx, edx
004018DE . je short 004018FC
004018E0 > movzx eax, word ptr ss:[ecx*2+ebp-50]
004018E5 . cmp eax, 61 ; Switch (事例 61..7A, 2 退出)
004018E8 . jb short 004018F7
004018EA . cmp eax, 7A
004018ED . ja short 004018F7
004018EF . add eax, -20 ; //转为A-Z串
004018F2 . mov ss:[ecx*2+ebp-50], ax
004018F7 > inc ecx ; 默认情况下 of switch Crack_Me.4018E5
004018F8 . cmp ecx, edx
004018FA .^ jb short 004018E0
004018FC > xor ecx, ecx
004018FE . mov eax, edi
00401900 . test edi, edi
00401902 . je short 0040197A
00401904 . cmp ds:[edi], cx
00401907 . je short 0040191A
00401909 . nop ds:[eax]
00401910 > lea eax, [eax+2]
00401913 . inc ecx
00401914 . cmp word ptr ds:[eax], 0
00401918 .^ jne short 00401910
0040191A > xor eax, eax
0040191C . test ecx, ecx
0040191E . je short 00401942
00401920 > cmp eax, 2 ; //还原加密了的输入串
00401923 . jae short 0040192C
00401925 . xor word ptr ds:[eax*2+edi], 000F
0040192A . jmp short 0040193D
0040192C > cmp eax, 4
0040192F . jae short 00401938
00401931 . xor word ptr ds:[eax*2+edi], 0050
00401936 . jmp short 0040193D
00401938 > xor word ptr ds:[eax*2+edi], 0042
0040193D > inc eax
0040193E . cmp eax, ecx
00401940 .^ jb short 00401920
00401942 > xor edx, edx
00401944 . mov eax, edi
00401946 . cmp ds:[edi], dx
00401949 . je short 0040195A
0040194B db 0F
0040194C db 1F
0040194D db 44 ; char 'D'
0040194E db 00
0040194F db 00
00401950 > lea eax, [eax+2]
00401953 . inc edx
00401954 . cmp word ptr ds:[eax], 0
00401958 .^ jne short 00401950
0040195A > xor ecx, ecx
0040195C . test edx, edx
0040195E . je short 0040197A
00401960 > movzx eax, word ptr ds:[ecx*2+edi]
00401964 . cmp eax, 61 ; Switch (事例 61..7A, 2 退出)
00401967 . jb short 00401975
00401969 . cmp eax, 7A
0040196C . ja short 00401975
0040196E . add eax, -20 ; //输入串转大写
00401971 . mov ds:[ecx*2+edi], ax
00401975 > inc ecx ; 默认情况下 of switch Crack_Me.401964
00401976 . cmp ecx, edx
00401978 .^ jb short 00401960
0040197A > xor esi, esi
0040197C . xorps xmm0, xmm0
0040197F . movq ss:[ebp-10], xmm0
00401984 . mov ss:[ebp-8], si
00401988 . cmp ds:[edi], si
0040198B . je short 004019D5
0040198D . mov cx, ss:[ebp-50]
00401991 . lea ebx, [ebp-10] //这儿有BUG,存放输入串中的字母BUFFER,BUFFER大小为(0x10-4)/sizeof(WCHAR)=6,不过要是输入串为7个字母,就会溢出
00401994 . mov eax, edi
00401996 > test cx, cx
00401999 . je short 004019C7
0040199B . movzx edx, word ptr ds:[eax] ; //依次取已转大写的输入字符
0040199E . lea ecx, [ebp-50]
004019A1 . xor eax, eax
004019A3 > cmp dx, ds:[ecx] ; //判断是否在A-Z之间
004019A6 . je short 004019B8
004019A8 . inc eax
004019A9 . lea ecx, [ebp-50]
004019AC . cmp word ptr ds:[eax*2+ecx], 0
004019B1 . lea ecx, [eax*2+ecx]
004019B4 .^ jne short 004019A3
004019B6 . jmp short 004019C3
004019B8 > mov ax, ss:[eax*2+ebp-50]
004019BD . mov ds:[ebx], ax ; //是大写字母,存入数组
004019C0 . add ebx, 2
004019C3 > mov cx, ss:[ebp-50]
004019C7 > inc esi
004019C8 . cmp word ptr ds:[esi*2+edi], 0
004019CD . lea eax, [esi*2+edi]
004019D0 .^ jne short 00401996
004019D2 . mov ebx, ss:[ebp-54]
004019D5 > xor ecx, ecx
004019D7 . lea eax, [ebp-10]
004019DA . cmp ss:[ebp-10], cx
004019DE . je short 00401A39
004019E0 > lea eax, [eax+2]
004019E3 . inc ecx
004019E4 . cmp word ptr ds:[eax], 0
004019E8 .^ jne short 004019E0
004019EA . cmp ecx, 2
004019ED . jne short 00401A39 ; //输入串中字母个数不为2则转出错
004019EF . xor eax, eax
004019F1 . mov dword ptr ss:[ebp-10], 350031 ; //串'15PB'
004019F8 . mov dword ptr ss:[ebp-0C], offset 00420050
004019FF . lea esi, [edi+4] ; //从大写输入串第三个字符开始,与串'15PB'比较
00401A02 . mov ss:[ebp-8], ax
00401A06 . xor ecx, ecx
00401A08 db 0F
00401A09 db 1F
00401A0A db 84
00401A0B db 00
00401A0C db 00
00401A0D db 00
00401A0E db 00
00401A0F db 00
00401A10 /> /mov ax, ss:[ecx*2+ebp-10]
00401A15 |. |cmp ax, ds:[esi]
00401A18 |. |jne short 00401A39 ; //不等则出错
00401A1A |. |inc ecx
00401A1B |. |add esi, 2
00401A1E |. |cmp ecx, 4
00401A21 |.^ \jb short 00401A10
00401A23 |. mov edx, edi ; //等则下一步
00401A25 |. mov ecx, ebx
00401A27 |. call 00401740
00401A2C |. push 0
00401A2E |. test eax, eax
00401A30 |. jz short 00401A3B
00401A32 |. push 40B
00401A37 |. jmp short 00401A40
00401A39 |> push 0
00401A3B |> push 40A
00401A40 |> push 111 ; |Msg = WM_COMMAND
00401A45 |. push dword ptr ds:[ebx+4] ; |hWnd
00401A48 |. call ds:[<&USER32.PostMessageW>] ; \USER32.PostMessageW
00401A4E |. mov ecx, ss:[ebp-4]
00401A51 |. pop edi
00401A52 |. pop esi
00401A53 |. xor ecx, ebp
00401A55 |. pop ebx
00401A56 |. call 00402CC5
00401A5B |. mov esp, ebp
00401A5D |. pop ebp
00401A5E \. retn
00401740 $ push ebp
00401741 . mov ebp, esp
00401743 . sub esp, 50
00401746 . mov eax, ds:[41F014]
0040174B . xor eax, ebp
0040174D . mov ss:[ebp-4], eax
00401750 . push ebx
00401751 . mov ebx, edx
00401753 . mov dword ptr ss:[ebp-0C], 0
0040175A . mov edx, ecx
0040175C . mov word ptr ss:[ebp-8], 0
00401762 . xorps xmm0, xmm0
00401765 . mov ss:[ebp-4C], edx
00401768 . push esi
00401769 . push edi
0040176A . movups ss:[ebp-24], xmm0
0040176E . lea ecx, [ebp-24]
00401771 . mov eax, 31 ; //生成串1-9
00401776 . movq ss:[ebp-14], xmm0
0040177B db 0F
0040177C db 1F
0040177D db 44 ; char 'D'
0040177E db 00
0040177F db 00
00401780 /> /mov ds:[ecx], ax
00401783 |. |lea ecx, [ecx+2]
00401786 |. |inc eax
00401787 |. |cmp eax, 39
0040178A |.^ \jle short 00401780
0040178C |. mov eax, ds:[edx] ; //取点击次数
0040178E |. xor esi, esi
00401790 |. lea ecx, [eax*2+ebx] ; //从点击次数位置取输入大写子串
00401793 |. mov eax, ebx
00401795 |. test ebx, ebx
00401797 |. jz short 004017AA
00401799 |. cmp ds:[ebx], si
0040179C |. je short 004017AA
0040179E |. nop
004017A0 |> /lea eax, [eax+2]
004017A3 |. |inc esi
004017A4 |. |cmp word ptr ds:[eax], 0
004017A8 |.^ \jne short 004017A0
004017AA |> push ecx ; /Arg2
004017AB |. lea eax, [ebp-24] ; |//连接子串到1-9之后
004017AE |. push eax ; |Arg1
004017AF |. call 004028D0 ; \Crack_Me.004028D0
004017B4 |. lea esi, [esi-1]
004017B7 |. mov edi, eax
004017B9 |. lea eax, [esi*2+ebx]
004017BC |. mov ss:[ebp-48], edi
004017BF |. xor esi, esi
004017C1 |. mov ss:[ebp-50], eax ; //取输入串最后一个字符的位置
004017C4 |. cmp ss:[ebp-24], si
004017C8 |. je short 004017FB
004017CA |. movzx edi, word ptr ds:[eax] ; //取最后一个输入字符
004017CD |. lea ecx, [ebp-24]
004017D0 |. and edi, 00000001
004017D3 |> /mov ax, ds:[ecx]
004017D6 |. |shr ax, 2
004017DA |. |add ax, di
004017DD |. |cmp ax, 32
004017E1 |. |je short 0040185B
004017E3 |. |cmp ax, 64
004017E7 |. |je short 004017F8
004017E9 |. |inc esi
004017EA |. |lea ecx, [ebp-24]
004017ED |. |lea edx, [esi+esi]
004017F0 |. |add ecx, edx
004017F2 |. |cmp word ptr ds:[ecx], 0
004017F6 |.^ \jne short 004017D3
004017F8 |> mov edi, ss:[ebp-48]
004017FB |> lea ecx, [ebp-24]
004017FE |. mov esi, ebx
00401800 |. mov eax, ecx
00401802 |. mov edx, 31
00401807 |. sub esi, eax
00401809 |. nop ds:[eax]
00401810 |> /mov ax, ds:[ecx] ; //比较输入串与串1-9(只循环2次所以只比较前二个字符)
00401813 |. |cmp ax, ds:[ecx+esi]
00401817 |. |jne short 0040185B
00401819 |. |add edx, 6
0040181C |. |add ecx, 2
0040181F |. |cmp edx, 39
00401822 |.^ \jle short 00401810
00401824 |. movzx ecx, word ptr ds:[edi+12] ; //取前面连接子串第一个字符,及输入的第点击次数个字符
00401828 |. movzx eax, word ptr ds:[ebx] ; //取输入第一个字符'1'即0x31
0040182B |. add ecx, eax
0040182D |. cmp ecx, 63
00401830 |. jne short 0040185B ; //和不为63转出错
00401832 |. mov eax, ss:[ebp-4C]
00401835 |. movzx ecx, word ptr ds:[edi+0C] ; //取字符'7'
00401839 |. add ecx, ds:[eax] ; //加上点击次数
0040183B |. mov eax, ss:[ebp-50]
0040183E |. movzx eax, word ptr ds:[eax] ; //取输入串最后一个字符
00401841 |. cmp eax, ecx
00401843 |. jne short 0040185B ; //输入串最后一个字符必须等于'7'+点击次数
00401845 |. pop edi //满足以上所有条件,返回1代表成功
00401846 |. pop esi
00401847 |. mov eax, 1
0040184C |. pop ebx
0040184D |. mov ecx, ss:[ebp-4]
00401850 |. xor ecx, ebp
00401852 |. call 00402CC5
00401857 |. mov esp, ebp
00401859 |. pop ebp
0040185A |. retn
0040185B |> mov ecx, ss:[ebp-4] //返回0,代表失败
0040185E |. xor eax, eax
00401860 |. pop edi
00401861 |. pop esi
00401862 |. xor ecx, ebp
00401864 |. pop ebx
00401865 |. call 00402CC5
0040186A |. mov esp, ebp
0040186C |. pop ebp
0040186D \. retn
设输入为SN,点击次数为K,由以上分析不难看出有如下规则:
1.SN中一定有'b','p'字符
2.SN长度为7
3.SN中字母个数为2
4.SN第2-5个字符为'15pb'
5.SN第0-1个字符为'12'
6.SN[K] + 0x31 = 0x63,及SN[K] = 0x32 = '2'
7.SN[6] = '7' + K
由4,5可知SN[0-5] = '1215pb'
由6可知K = 1
由7和K=1可知SN[6]='8'
所以SN = '1215pb8'
分析中发现程序有BUG(前面有注释),在取出输入串中的字母时,BUFFER小了,在特定情况下会溢出(当输入SN全字母,且长度为7,且有'b'和'p'时),程序会崩溃。还有点击次数K好像也没有限制,不知道点N次过后,会不会来个0xC0000005异常?
赞赏
他的文章
赞赏
雪币:
留言: