
The study of simple crackme (part 2)
Hello, Habralyudi!
This topic is a continuation of a series of articles on the study of quackies ( part 1 ). In this article, we will look at kryakmis in a more complicated way than in the previous article. The main difficulty will be in the encryption algorithm. However, all the same, for many it will seem too simple.
So let's get started.
Of the tools, I will only use the debugger. That’s the crack.
So, traditionally we’ll run it without a debugger, enter fake data, and look at the result:

This time there was no message box. So we will put the breakdown on all calls to the GetDlgItemTextA function, since it is she who is responsible for the "extraction" of data from text fields in this case.
Put the breaks, run the program, enter the name and serial, and click Verify. We see that the breakdown worked. We take a step forward, thereby allowing the function to execute. The function was executed and pushed the data (name) onto the stack at the address 022F9C4. We trace the program until the second function call. The function was executed and pushed the data (our serial) onto the stack at the address 022F8B4 (I learned this data from the arguments that go to the GetDlgItemTextA function).
Further, here in this piece of code:

There is already a procedure for modifying a name that is already familiar to us, in which each of its (name) characters is replaced by a subsequent one in the ASCII table.
Дальше самое интересное:
Тут происходит создание восьми последовательностей, состоящих из цифр. Далее, шесть из них, посредством функции sprintf с аргументом C%dr%do%dm%da%dx%dX, образуют такую строку (п — последовательность) —
Cп1rп2oп3mп4aп5xп6X.
Потом идёт процедура, которая заменяет каждый символ этой огромной строки на симвот следующий за следующим В таблице ASCII(извините но не знаю как это по — другому объяснить). Например был символ A стал С, был 1 стал 3, и так далее. И в итоге получается готовый, валидный серийник.
The difficulty is that these lines are formed almost randomly. That is, here we see not a traditional name modification, but rather a modification of the addresses contained in the registers and the stack. Addresses vary depending on the length of the name, so names with the same length would have the same serial if it weren’t for some random value, the principle of formation of which I can not understand (it is commented on). The code above is not commented on by me, since it contains mainly mathematical operations that are not difficult to understand.
Example name - Myname
example seriynika - E99696;: 2t5284; 342q87; : 6458o696924: c3995: 68326z432575;: 22Z
example imeni2 - name
Example seriynika2 - E73872238t9: 5274: q; 5257262o; 2752558c3: 72987622z3 : 575886 :: Z
Examples can you not work, just because of random value.
Here is such an example of an unsettled keygenmy.
PS The next article will be more interesting. I'll tell you about manual unpacking, and about more complex encryption algorithms.
This topic is a continuation of a series of articles on the study of quackies ( part 1 ). In this article, we will look at kryakmis in a more complicated way than in the previous article. The main difficulty will be in the encryption algorithm. However, all the same, for many it will seem too simple.
Material needed
So let's get started.
Of the tools, I will only use the debugger. That’s the crack.
Trial run
So, traditionally we’ll run it without a debugger, enter fake data, and look at the result:

This time there was no message box. So we will put the breakdown on all calls to the GetDlgItemTextA function, since it is she who is responsible for the "extraction" of data from text fields in this case.
Trace
Put the breaks, run the program, enter the name and serial, and click Verify. We see that the breakdown worked. We take a step forward, thereby allowing the function to execute. The function was executed and pushed the data (name) onto the stack at the address 022F9C4. We trace the program until the second function call. The function was executed and pushed the data (our serial) onto the stack at the address 022F8B4 (I learned this data from the arguments that go to the GetDlgItemTextA function).
Further, here in this piece of code:

There is already a procedure for modifying a name that is already familiar to us, in which each of its (name) characters is replaced by a subsequent one in the ASCII table.
Main difficulty
Дальше самое интересное:
004015FF |> 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8]
00401602 |. 0385 14FFFFFF ADD EAX,DWORD PTR SS:[EBP-EC]
00401608 |. 83E8 70 SUB EAX,70
0040160B |. 0FBE10 MOVSX EDX,BYTE PTR DS:[EAX]
0040160E |. 8B85 10FFFFFF MOV EAX,DWORD PTR SS:[EBP-F0]
00401614 |. 31D0 XOR EAX,EDX
00401616 |. 0FBE4D EC MOVSX ECX,BYTE PTR SS:[EBP-14] //рандомное значение.
0040161A |. D3E0 SHL EAX,CL
0040161C |. 8B8D 14FFFFFF MOV ECX,DWORD PTR SS:[EBP-EC]
00401622 |. D3F8 SAR EAX,CL
00401624 |. 8985 0CFFFFFF MOV DWORD PTR SS:[EBP-F4],EAX
0040162A |. 8D85 10FFFFFF LEA EAX,DWORD PTR SS:[EBP-F0]
00401630 |. FF00 INC DWORD PTR DS:[EAX]
00401632 |. 8B85 0CFFFFFF MOV EAX,DWORD PTR SS:[EBP-F4]
00401638 |. 3385 10FFFFFF XOR EAX,DWORD PTR SS:[EBP-F0]
0040163E |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX
00401642 |. 8B85 0CFFFFFF MOV EAX,DWORD PTR SS:[EBP-F4]
00401648 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
0040164C |. 8B85 10FFFFFF MOV EAX,DWORD PTR SS:[EBP-F0]
00401652 |. 890424 MOV DWORD PTR SS:[ESP],EAX
00401655 |. E8 36FCFFFF CALL craomaxx.00401290
0040165A |. 8985 08FFFFFF MOV DWORD PTR SS:[EBP-F8],EAX
00401660 |. 8B85 0CFFFFFF MOV EAX,DWORD PTR SS:[EBP-F4]
00401666 |. 3385 10FFFFFF XOR EAX,DWORD PTR SS:[EBP-F0]
0040166C |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX
00401670 |. 8B85 0CFFFFFF MOV EAX,DWORD PTR SS:[EBP-F4]
00401676 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
0040167A |. 8B85 10FFFFFF MOV EAX,DWORD PTR SS:[EBP-F0]
00401680 |. 890424 MOV DWORD PTR SS:[ESP],EAX
00401683 |. E8 2EFCFFFF CALL craomaxx.004012B6
00401688 |. 8985 04FFFFFF MOV DWORD PTR SS:[EBP-FC],EAX
0040168E |. 8B85 04FFFFFF MOV EAX,DWORD PTR SS:[EBP-FC]
00401694 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
00401698 |. 8B85 08FFFFFF MOV EAX,DWORD PTR SS:[EBP-F8]
0040169E |. 890424 MOV DWORD PTR SS:[ESP],EAX
004016A1 |. E8 34FCFFFF CALL craomaxx.004012DA
004016A6 |. 8985 00FFFFFF MOV DWORD PTR SS:[EBP-100],EAX
004016AC |. 8B85 00FFFFFF MOV EAX,DWORD PTR SS:[EBP-100]
004016B2 |. 2385 08FFFFFF AND EAX,DWORD PTR SS:[EBP-F8]
004016B8 |. 3385 04FFFFFF XOR EAX,DWORD PTR SS:[EBP-FC]
004016BE |. 8985 FCFEFFFF MOV DWORD PTR SS:[EBP-104],EAX
004016C4 |. 8B85 00FFFFFF MOV EAX,DWORD PTR SS:[EBP-100]
004016CA |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX
004016CE |. 8B85 04FFFFFF MOV EAX,DWORD PTR SS:[EBP-FC]
004016D4 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
004016D8 |. 8B85 08FFFFFF MOV EAX,DWORD PTR SS:[EBP-F8]
004016DE |. 890424 MOV DWORD PTR SS:[ESP],EAX
004016E1 |. E8 D0FBFFFF CALL craomaxx.004012B6
004016E6 |. 8985 F8FEFFFF MOV DWORD PTR SS:[EBP-108],EAX
004016EC |. 8B85 F8FEFFFF MOV EAX,DWORD PTR SS:[EBP-108]
004016F2 |. 894424 0C MOV DWORD PTR SS:[ESP+C],EAX
004016F6 |. 8B85 FCFEFFFF MOV EAX,DWORD PTR SS:[EBP-104]
004016FC |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX
00401700 |. 8B85 04FFFFFF MOV EAX,DWORD PTR SS:[EBP-FC]
00401706 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
0040170A |. 8B85 08FFFFFF MOV EAX,DWORD PTR SS:[EBP-F8]
00401710 |. 890424 MOV DWORD PTR SS:[ESP],EAX
00401713 |. E8 DCFBFFFF CALL craomaxx.004012F4
00401718 |. 8985 F4FEFFFF MOV DWORD PTR SS:[EBP-10C],EAX
0040171E |. 8B85 10FFFFFF MOV EAX,DWORD PTR SS:[EBP-F0]
00401724 |. 890424 MOV DWORD PTR SS:[ESP],EAX
00401727 |. E8 F8FBFFFF CALL craomaxx.00401324
0040172C |. 8985 10FFFFFF MOV DWORD PTR SS:[EBP-F0],EAX
00401732 |. 8B85 0CFFFFFF MOV EAX,DWORD PTR SS:[EBP-F4]
00401738 |. 890424 MOV DWORD PTR SS:[ESP],EAX
0040173B |. E8 E4FBFFFF CALL craomaxx.00401324
00401740 |. 8985 0CFFFFFF MOV DWORD PTR SS:[EBP-F4],EAX
00401746 |. 8B85 08FFFFFF MOV EAX,DWORD PTR SS:[EBP-F8]
0040174C |. 890424 MOV DWORD PTR SS:[ESP],EAX
0040174F |. E8 D0FBFFFF CALL craomaxx.00401324
00401754 |. 8985 08FFFFFF MOV DWORD PTR SS:[EBP-F8],EAX
0040175A |. 8B85 04FFFFFF MOV EAX,DWORD PTR SS:[EBP-FC]
00401760 |. 890424 MOV DWORD PTR SS:[ESP],EAX
00401763 |. E8 BCFBFFFF CALL craomaxx.00401324
00401768 |. 8985 04FFFFFF MOV DWORD PTR SS:[EBP-FC],EAX
0040176E |. 8B85 00FFFFFF MOV EAX,DWORD PTR SS:[EBP-100]
00401774 |. 890424 MOV DWORD PTR SS:[ESP],EAX
00401777 |. E8 A8FBFFFF CALL craomaxx.00401324
0040177C |. 8985 00FFFFFF MOV DWORD PTR SS:[EBP-100],EAX
00401782 |. 8B85 F4FEFFFF MOV EAX,DWORD PTR SS:[EBP-10C]
00401788 |. 890424 MOV DWORD PTR SS:[ESP],EAX
0040178B |. E8 94FBFFFF CALL craomaxx.00401324
00401790 |. 8985 F4FEFFFF MOV DWORD PTR SS:[EBP-10C],EAX ; |
00401796 |. 8B85 F4FEFFFF MOV EAX,DWORD PTR SS:[EBP-10C] ; |
0040179C |. 894424 1C MOV DWORD PTR SS:[ESP+1C],EAX ; |
004017A0 |. 8B85 00FFFFFF MOV EAX,DWORD PTR SS:[EBP-100] ; |
004017A6 |. 894424 18 MOV DWORD PTR SS:[ESP+18],EAX ; |
004017AA |. 8B85 04FFFFFF MOV EAX,DWORD PTR SS:[EBP-FC] ; |
004017B0 |. 894424 14 MOV DWORD PTR SS:[ESP+14],EAX ; |
004017B4 |. 8B85 08FFFFFF MOV EAX,DWORD PTR SS:[EBP-F8] ; |
004017BA |. 894424 10 MOV DWORD PTR SS:[ESP+10],EAX ; |
004017BE |. 8B85 0CFFFFFF MOV EAX,DWORD PTR SS:[EBP-F4] ; |
004017C4 |. 894424 0C MOV DWORD PTR SS:[ESP+C],EAX ; |
004017C8 |. 8B85 10FFFFFF MOV EAX,DWORD PTR SS:[EBP-F0] ; |
004017CE |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX ; |
004017D2 |. C74424 04 7840>MOV DWORD PTR SS:[ESP+4],craomaxx.004040>; |ASCII "C%dr%do%dm%da%dx%dX"
004017DA |. 8D85 18FFFFFF LEA EAX,DWORD PTR SS:[EBP-E8] ; |
004017E0 |. 890424 MOV DWORD PTR SS:[ESP],EAX ; |
004017E3 |. E8 C8070000 CALL ; \sprintf
004017E8 |. C785 14FFFFFF >MOV DWORD PTR SS:[EBP-EC],0
004017F2 |> 8D85 18FFFFFF /LEA EAX,DWORD PTR SS:[EBP-E8] ; |
004017F8 |. 890424 |MOV DWORD PTR SS:[ESP],EAX ; |
004017FB |. E8 D0070000 |CALL ; \strlen
00401800 |. 3985 14FFFFFF |CMP DWORD PTR SS:[EBP-EC],EAX
00401806 |. 73 2A |JNB SHORT craomaxx.00401832
00401808 |. 8D45 F8 |LEA EAX,DWORD PTR SS:[EBP-8]
0040180B |. 0385 14FFFFFF |ADD EAX,DWORD PTR SS:[EBP-EC]
00401811 |. 2D E0000000 |SUB EAX,0E0
00401816 |. FE00 |INC BYTE PTR DS:[EAX]
00401818 |. 8D45 F8 |LEA EAX,DWORD PTR SS:[EBP-8]
0040181B |. 0385 14FFFFFF |ADD EAX,DWORD PTR SS:[EBP-EC]
00401821 |. 2D E0000000 |SUB EAX,0E0
00401826 |. FE00 |INC BYTE PTR DS:[EAX]
00401828 |. 8D85 14FFFFFF |LEA EAX,DWORD PTR SS:[EBP-EC]
0040182E |. FF00 |INC DWORD PTR DS:[EAX]
00401830 |.^EB C0 \JMP SHORT craomaxx.004017F2
00401832 |> 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
00401835 |. 894424 08 MOV DWORD PTR SS:[ESP+8],EAX
Тут происходит создание восьми последовательностей, состоящих из цифр. Далее, шесть из них, посредством функции sprintf с аргументом C%dr%do%dm%da%dx%dX, образуют такую строку (п — последовательность) —
Cп1rп2oп3mп4aп5xп6X.
Потом идёт процедура, которая заменяет каждый символ этой огромной строки на симвот следующий за следующим В таблице ASCII(извините но не знаю как это по — другому объяснить). Например был символ A стал С, был 1 стал 3, и так далее. И в итоге получается готовый, валидный серийник.
The difficulty is that these lines are formed almost randomly. That is, here we see not a traditional name modification, but rather a modification of the addresses contained in the registers and the stack. Addresses vary depending on the length of the name, so names with the same length would have the same serial if it weren’t for some random value, the principle of formation of which I can not understand (it is commented on). The code above is not commented on by me, since it contains mainly mathematical operations that are not difficult to understand.
Examples
Example name - Myname
example seriynika - E99696;: 2t5284; 342q87; : 6458o696924: c3995: 68326z432575;: 22Z
example imeni2 - name
Example seriynika2 - E73872238t9: 5274: q; 5257262o; 2752558c3: 72987622z3 : 575886 :: Z
Examples can you not work, just because of random value.
Here is such an example of an unsettled keygenmy.
PS The next article will be more interesting. I'll tell you about manual unpacking, and about more complex encryption algorithms.