160 crackme training for novice crackers
1. Demolition
2. Find Algorithm
One: Blasting procedure
This program is a VB program, and I have not been exposed to programs other than C++ before. When the program is loading, neither BP MessageBoxA nor MessageBoxW can break the pop-up window.
Temporarily look at the VB program of “Encryption and Decryption III” and learn that the dialog box function of VB is: rtcMsgBox. There are VB function breakpoints in the OD plug-in, click to clear the rtcMsgBox breakpoint. Then enter the account tqdn password 1234 and click the control OK to let the program run.
After the program ran, it was broken in the dynamic link library of MSVBVM50. This should be the scope of the rtcMsgBox function. Just press F8 to get out of this function, a message box will pop up and display “You Get Wrong Try Again” as you go down, it should be an error message.
After stepping out of the function, return to the following.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
004025E1 . 51 push ecx 004025E2 . 52 push edx 004025E3 . EB 56 jmp XAfkayas_.0040263B ; Skipped wrong display 004025E5 > 68 C81B4000 push Afkayas_.00401BC8 ; UNICODE "You Get Wrong" 004025EA . 68 9C1B4000 push Afkayas_.00401B9C ; ASCII "\r" 004025EF . FFD7 call edi 004025F1 . 8BD0 mov edx , eax 004025F3 . 8D4D E8 lea ecx , dword ptr ss :[ ebp -0x18] 004025F6 . FFD3 call ebx 004025F8 . 50 push eax 004025F9 . 68 E81B4000 push Afkayas_.00401BE8 ; UNICODE "Try Again" 004025FE . FFD7 call edi 00402600 . 8945 CC mov dword ptr ss :[ ebp -0x34], eax 00402603 . 8D45 94 lea eax , dword ptr ss :[ ebp -0x6C] 00402606 . 8D4D A4 lea ecx , dword ptr ss :[ ebp -0x5C] 00402609 . 50 push eax 0040260A . 8D55 B4 lea edx , dword ptr ss :[ ebp -0x4C] 0040260D . 51 push ecx 0040260E . 52 push edx 0040260F . 8D45 C4 lea eax , dword ptr ss :[ ebp -0x3C] 00402612 . 6A 00 push 0x0 00402614 . 50 push eax 00402615 . C745 C4 08000> mov dword ptr ss :[ ebp -0x3C],0x8 0040261C . FF15 10414000 call dword ptr ds :[<&MSVBVM50.#595>] ; Function to display error message box 00402622 . 8D4D E8 lea ecx , dword ptr ss :[ ebp -0x18] ; Current EIP location |
Looking up at the current EIP, the nearest one is a JMP instruction. Clicking on this instruction on the OD directly skips the function that displays the error message. Then look up again. Are there any jump instructions.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
00402569 . 83C4 0C add esp ,0xC 0040256C . B9 04000280 mov ecx ,0x80020004 00402571 . B8 0A000000 mov eax ,0xA 00402576 . 894D 9C mov dword ptr ss :[ ebp -0x64], ecx 00402579 . 66:85F6 test si , si ; 比较SI是否为0 0040257C . 8945 94 mov dword ptr ss :[ ebp -0x6C], eax 0040257F . 894D AC mov dword ptr ss :[ ebp -0x54], ecx 00402582 . 8945 A4 mov dword ptr ss :[ ebp -0x5C], eax 00402585 . 894D BC mov dword ptr ss :[ ebp -0x44], ecx 00402588 . 8945 B4 mov dword ptr ss :[ ebp -0x4C], eax 0040258B . 74 58 je XAfkayas_.004025E5 ; If SI is equal to 0 then jump to the wrong display 0040258D . 68 801B4000 push Afkayas_.00401B80 ; UNICODE "You Get It" 00402592 . 68 9C1B4000 push Afkayas_.00401B9C ; ASCII "\r" 00402597 . FFD7 call edi 00402599 . 8BD0 mov edx , eax 0040259B . 8D4D E8 lea ecx , dword ptr ss :[ ebp -0x18] 0040259E . FFD3 call ebx 004025A0 . 50 push eax 004025A1 . 68 A81B4000 push Afkayas_.00401BA8 ; UNICODE "KeyGen It Now" 004025A6 . FFD7 call edi 004025A8 . 8D4D 94 lea ecx , dword ptr ss :[ ebp -0x6C] 004025AB . 8945 CC mov dword ptr ss :[ ebp -0x34], eax 004025AE . 8D55 A4 lea edx , dword ptr ss :[ ebp -0x5C] 004025B1 . 51 push ecx 004025B2 . 8D45 B4 lea eax , dword ptr ss :[ ebp -0x4C] 004025B5 . 52 push edx 004025B6 . 50 push eax 004025B7 . 8D4D C4 lea ecx , dword ptr ss :[ ebp -0x3C] 004025BA . 6A 00 push 0x0 004025BC . 51 push ecx 004025BD . C745 C4 08000> mov dword ptr ss :[ ebp -0x3C],0x8 004025C4 . FF15 10414000 call dword ptr ds :[<&MSVBVM50.#595>>; msvbvm50.rtcMsgBox 004025CA . 8D4D E8 lea ecx , dword ptr ss :[ ebp -0x18] 004025CD . FF15 80414000 call dword ptr ds :[<&MSVBVM50.__vba>; msvbvm50.__vbaFreeStr 004025D3 . 8D55 94 lea edx , dword ptr ss :[ ebp -0x6C] 004025D6 . 8D45 A4 lea eax , dword ptr ss :[ ebp -0x5C] 004025D9 . 52 push edx 004025DA . 8D4D B4 lea ecx , dword ptr ss :[ ebp -0x4C] 004025DD . 50 push eax 004025DE . 8D55 C4 lea edx , dword ptr ss :[ ebp -0x3C] 004025E1 . 51 push ecx 004025E2 . 52 push edx 004025E3 . EB 56 jmp XAfkayas_.0040263B ; Skipped wrong display 004025E5 > 68 C81B4000 push Afkayas_.00401BC8 ; UNICODE "You Get Wrong" 004025EA . 68 9C1B4000 push Afkayas_.00401B9C ; ASCII "\r" 004025EF . FFD7 call edi 004025F1 . 8BD0 mov edx , eax 004025F3 . 8D4D E8 lea ecx , dword ptr ss :[ ebp -0x18] |
. Looking up and found a reliable jumping point:
. 0040258B je XAfkayas_.004025E5; If SI is equal to 0 then jump to the wrong display
. Try to modify the JE here to nop. Then run the program~~ Successful blasting!
2: Find out the algorithm
. First of all, if you want to find an algorithm, you should clear the breakpoint at the blasting point first, and run here.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
00402561 . 6A 02 push 0x2 00402563 . FF15 F4404000 call dword ptr ds :[<&MSVBVM50.__vba>; msvbvm50.__vbaFreeObjList 00402569 . 83C4 0C add esp ,0xC 0040256C . B9 04000280 mov ecx ,0x80020004 00402571 . B8 0A000000 mov eax ,0xA 00402576 . 894D 9C mov dword ptr ss :[ ebp -0x64], ecx 00402579 . 66:85F6 test si , si ; 比较SI是否为0 0040257C . 8945 94 mov dword ptr ss :[ ebp -0x6C], eax 0040257F . 894D AC mov dword ptr ss :[ ebp -0x54], ecx 00402582 . 8945 A4 mov dword ptr ss :[ ebp -0x5C], eax 00402585 . 894D BC mov dword ptr ss :[ ebp -0x44], ecx 00402588 . 8945 B4 mov dword ptr ss :[ ebp -0x4C], eax 0040258B . 74 58 je XAfkayas_.004025E5 ; If SI is equal to 0 then jump to the wrong display 0040258D . 68 801B4000 push Afkayas_.00401B80 ; UNICODE "You Get It" 00402592 . 68 9C1B4000 push Afkayas_.00401B9C ; ASCII "\r" 00402597 . FFD7 call edi |
The jump of JE is controlled by TEST SI, SI, so we should find the instruction to assign SI there.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
0040252D . 8D4D E0 lea ecx , dword ptr ss :[ ebp -0x20] 00402530 . FFD3 call ebx ; <&MSVBVM50.__vbaStrMove> 00402532 . 50 push eax 00402533 . FF15 28414000 call dword ptr ds :[<&MSVBVM50.__vba>; msvbvm50.__vbaStrCmp 00402539 . 8BF0 mov esi , eax ; The return value of the vbaStrCmp string comparison function is given to ESI 0040253B . 8D55 E0 lea edx , dword ptr ss :[ ebp -0x20] 0040253E . F7DE neg esi 00402540 . 8D45 E8 lea eax , dword ptr ss :[ ebp -0x18] 00402543 . 52 push edx 00402544 . 1BF6 sbb esi , esi 00402546 . 8D4D E4 lea ecx , dword ptr ss :[ ebp -0x1C] 00402549 . 50 push eax 0040254A . 46 inc esi 0040254B . 51 push ecx 0040254C . 6A 03 push 0x3 0040254E . F7DE neg esi 00402550 . FF15 5C414000 call dword ptr ds :[<&MSVBVM50.__vba>; msvbvm50.__vbaFreeStrList 00402556 . 83C4 10 add esp ,0x10 00402559 . 8D55 D8 lea edx , dword ptr ss :[ ebp -0x28] 0040255C . 8D45 DC lea eax , dword ptr ss :[ ebp -0x24] 0040255F . 52 push edx 00402560 . 50 push eax 00402561 . 6A 02 push 0x2 00402563 . FF15 F4404000 call dword ptr ds :[<&MSVBVM50.__vba>; msvbvm50.__vbaFreeObjList 00402569 . 83C4 0C add esp ,0xC 0040256C . B9 04000280 mov ecx ,0x80020004 00402571 . B8 0A000000 mov eax ,0xA 00402576 . 894D 9C mov dword ptr ss :[ ebp -0x64], ecx 00402579 . 66:85F6 test si , si ; Compare whether SI is 0 0040257C . 8945 94 mov dword ptr ss :[ ebp -0x6C], eax 0040257F . 894D AC mov dword ptr ss :[ ebp -0x54], ecx |
Looking up from TEST SI, SI, the return value of the vbaStrCmp string comparison function is given to ESI in a very close place. We clear the breakpoint at vbaStrCmp, and run OD to see what the comparison is. You can see in the observation stack that the function directly compares the password 1234 I entered with the KEY value calculated by the program in plain text.
Let’s look up the disassembly code
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
004024E5 . 8D45 D8 lea eax , dword ptr ss :[ ebp -0x28] 004024E8 . 50 push eax 004024E9 . FFD3 call ebx 004024EB . 8BF0 mov esi , eax 004024ED . 8D55 E4 lea edx , dword ptr ss :[ ebp -0x1C] 004024F0 . 52 push edx 004024F1 . 56 push esi 004024F2 . 8B0E mov ecx , dword ptr ds :[ esi ] 004024F4 . FF91 A0000000 call dword ptr ds :[ ecx +0xA0] 004024FA . 85C0 test eax , eax 004024FC . 7D 12 jge XAfkayas_.00402510 004024FE . 68 A0000000 push 0xA0 00402503 . 68 5C1B4000 push Afkayas_.00401B5C 00402508 . 56 push esi 00402509 . 50 push eax 0040250A . FF15 04414000 call dword ptr ds :[<&MSVBVM50.__vbaHresu>; msvbvm50.__vbaHresultCheckObj 00402510 > 8B45 E8 mov eax , dword ptr ss :[ ebp -0x18] 00402513 . 8B4D E4 mov ecx , dword ptr ss :[ ebp -0x1C] 00402516 . 8B3D 00414000 mov edi , dword ptr ds :[<&MSVBVM50.__vbaSt>; msvbvm50.__vbaStrCat 0040251C . 50 push eax 0040251D . 68 701B4000 push Afkayas_.00401B70 ; UNICODE "AKA-" 00402522 . 51 push ecx ; /String 00402523 . FFD7 call edi ; \__vbaStrCat 00402525 . 8B1D 70414000 mov ebx , dword ptr ds :[<&MSVBVM50.__vbaSt>; msvbvm50.__vbaStrMove 0040252B . 8BD0 mov edx , eax 0040252D . 8D4D E0 lea ecx , dword ptr ss :[ ebp -0x20] 00402530 . FFD3 call ebx ; <&MSVBVM50.__vbaStrMove> 00402532 . 50 push eax 00402533 . FF15 28414000 call dword ptr ds :[<&MSVBVM50.__vbaStrCm>; msvbvm50.__vbaStrCmp 00402539 . 8BF0 mov esi , eax ; vbaStrCmp The return value of the string comparison function is given to ESI |
The first parameter of vbaStrCmp is given by the return value of vbaStrMove. Observe the disassembly
1
2
3
4
5
6
7
|
00402525 . 8B1D 70414000 mov ebx , dword ptr ds :[<&MSVBVM50.__vbaSt>; msvbvm50.__vbaStrMove 0040252B . 8BD0 mov edx , eax 0040252D . 8D4D E0 lea ecx , dword ptr ss :[ ebp -0x20] 00402530 . FFD3 call ebx ; <&MSVBVM50.__vbaStrMove> 00402532 . 50 push eax 00402533 . FF15 28414000 call dword ptr ds :[<&MSVBVM50.__vbaStrCm>; msvbvm50.__vbaStrCmp 00402539 . 8BF0 mov esi , eax ; vbaStrCmp The return value of the string comparison function is given to ESI |
Did not see the instruction of PUSH parameter in vbaStrMove. Let’s clear the breakpoint here and go in to see what the implementation of vbaStrMove looks like.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
Implementation of vbaStrMovevbaStrMove的实现 7403F8DA > 56 push esi 7403F8DB 57 push edi 7403F8DC 8B01 mov eax , dword ptr ds :[ ecx ] ; ECX去一个DWORD给EAX 7403F8DE 8BFA mov edi , edx ;EDX content to EDI 7403F8E0 8BF1 mov esi , ecx ; ECX content to ESI 7403F8E2 85C0 test eax , eax ; Determine whether the content of ECX is NULL 7403F8E4 75 07 jnz Xmsvbvm50.7403F8ED 7403F8E6 8BC7 mov eax , edi 7403F8E8 893E mov dword ptr ds :[ esi ], edi ; ECX fetch content is not equal to NULL, store EDI in ECX 7403F8EA 5F pop edi 7403F8EB 5E pop esi 7403F8EC C3 retn 7403F8ED 50 push eax 7403F8EE FF15 88190274 call dword ptr ds :[<&OLEAUT32.#6>] ; oleaut32.SysFreeString 7403F8F4 ^ EB F0 jmp Xmsvbvm50.7403F8E6 ; Otherwise it will return directly |
By explaining the disassembly, we can know that vbaStrMove does not use the stack to pass parameters but uses two registers EDX and ECX. Combined with disassembly, EDX is given by the return value of vbaStrCat. ECX comes from ebp-0x20.
The two parameters of vbaStrCat are directly pushing a string “AKA-” and pushing an ECX, which points to a string “390240”. The KEY bit “AKA-390240” obtained by clearing the breakpoint at the blasting point at the beginning is very close to the algorithm. Our next step is to find out where ECX comes from. but failed. I am not familiar with VB, and the results given by the function here make me inexplicable.
So I decided to clear the breakpoint in the function header of the blasting point again, and then follow the process step by step. And pay attention to the return value and outgoing parameters of the function (lea EXX, ebp-XX, in this case, consider the outgoing parameter, check the current address directly in the hexadecimal window, and what is modified after the function is completed data!)
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
004023ED . FF90 A0000000 call dword ptr ds :[ eax +0xA0] ; Get the account here 004023F3 . 3BC7 cmp eax , edi 004023F5 . 7D 12 jge XAfkayas_.00402409 004023F7 . 68 A0000000 push 0xA0 ; If the return value is less than 0, go here 004023FC . 68 5C1B4000 push Afkayas_.00401B5C 00402401 . 53 push ebx 00402402 . 50 push eax 00402403 . FF15 04414000 call dword ptr ds :[<&MSVBVM50.__vbaHresultChec>; msvbvm50.__vbaHresultCheckObj 00402409 > 8B95 50FFFFFF mov edx , dword ptr ss :[ ebp -0xB0] 0040240F . 8B45 E4 mov eax , dword ptr ss :[ ebp -0x1C] ; vbaLenBstr gets the length of the account, eax returns the length 00402412 . 50 push eax ; /String 00402413 . 8B1A mov ebx , dword ptr ds :[ edx ] ; | 00402415 . FF15 E4404000 call dword ptr ds :[<&MSVBVM50.__vbaLenBstr>] ; \__vbaLenBstr 0040241B . 8BF8 mov edi , eax ; Account length is stored in EDI 0040241D . 8B4D E8 mov ecx , dword ptr ss :[ ebp -0x18] 00402420 . 69FF FB7C0100 imul edi , edi ,0x17CFB ; account length * 0x17CFB 00402426 . 51 push ecx ; /String 00402427 . 0F80 91020000 jo Afkayas_.004026BE ; |The calculated result >=0x80000000 is abnormal 0040242D . FF15 F8404000 call dword ptr ds :[<&MSVBVM50.#516>] ; \rtcAnsiValueBstr 00402433 . 0FBFD0 movsx edx , ax ; Returns the first character code of the account 00402436 . 03FA add edi , edx ; The returned character code is added to the account length * 0x17CFB 00402438 . 0F80 80020000 jo Afkayas_.004026BE ; If the result is greater than 0x80000000, it is abnormal 0040243E . 57 push edi ; This function converts I4 to STR 0040243F . FF15 E0404000 call dword ptr ds :[<&MSVBVM50.__vbaStrI4>] ; msvbvm50.__vbaStrI4 00402445 . 8BD0 mov edx , eax ; The return value is 390240 string |
The string is 390240, which passed the first failed trace. Then you can know that this place is where the integer string is calculated. For KEY, you only need to splice an “AKA-” before the string.
This algorithm is very simple, just like 001, only the first byte of the account is taken. However, this account is calculated by taking the account length. Therefore, the KEY calculated by an account can only get the correct result when the first letter and the account length are equal!
1
2
3
4
5
6
7
|
void Fun( char *ZhangHu) { char szBuff[256]; unsigned long data = strlen (ZhangHu) * 0x17CFB + (unsigned long )ZhangHu[0]; sprintf (szBuff, "AKA-%d" , data); printf ( "%s \r\n" , szBuff); } |
Reviews
There are no reviews yet.