Hello Habralyudi. In this topic, I will tell you how I researched a simple crackme. This kryakmis is intended, first of all, for beginners who want to practice reversing. I plan to continue the cycle of articles on this subject, moving gradually from simple to complex.
Start
So let's get started.
Required tools:
- 1. crackme itself (with crackmes.de)
- 2. Debugger (I personally use Olly)
To get started, we start quacking. We see a simple form with two fields for entering a name and a registration code. Enter the fake data and see the abusive message that the serial number is incorrect.
The situation becomes clearer when we see a message caused by the MessageBoxA function, and the text from the fields is entered into the buffer by the function GetDlgItemTextA.
Action plan
So a further action algorithm:
1. Load the crack in the debugger.
2. We put breakpoints on all calls to the MessageBoxA and GetDlgItemTextA functions (in Olly this is done by pressing the Alt + F1 key combination and entering the bpx% function_name% command into the form that appears).
3. We execute the program before the breakpoint and: a) we are looking for a place to go to a branch with an abusive message and change the conditional transition so that we switch to a branch with the “correct” message;
b) look for a place to modify the name in the serial, find out the encryption algorithm and write keygen.
We will go according to plan b, since my main goal is to explore.
Anti-debug code
Having placed the bryaks and running the program, we see that the bang on MessageBoxA worked. But what else is MesadBox, after running the program for the first time without a debugger, we did not see any message? Having traced the program one step further (in Olli by pressing F8), we see the following:

It turns out in our mall there is an anti-debug code. We'll have to get around it. Scroll the code up a bit and find out where the jump to our “anti-debug messaging box” came from. Here is a piece of code from this point:
')
004027DA . 64:A1 18000000 MOV EAX,DWORD PTR FS:[18]
004027E0 . 8B40 30 MOV EAX,DWORD PTR DS:[EAX+30]
004027E3 . 8B40 18 MOV EAX,DWORD PTR DS:[EAX+18]
004027E6 . 8378 10 00 CMP DWORD PTR DS:[EAX+10],0
004027EA 75 01 JNZ SHORT crackme_.004027ED //We'll have to patch. Change the JNZ command (opcode 75) to JE (opcode 74). We apply the patch, restart the program under the debugger and do not see the abusive messaging of boxing.
Algorithm
Enter the fake data in the fields (I entered someuser: somepassword), and click on Check. And right there it is triggered on the call to the function GetDlgItemTextA. Here is this piece of code:
00401D3E . E8 CD0D0000 CALL <JMP.&user32.GetDlgItemTextA> // GetDlgItemTextA
00401D43 . BE 64404000 MOV ESI,crackme_.00404064 // ESI
00401D48 > 8006 01 ADD BYTE PTR DS:[ESI],1 // 1 ESI
00401D4B . 83C6 02 ADD ESI,2 // ESI 2, ESI ,
00401D4E . 803E 00 CMP BYTE PTR DS:[ESI],0 // ESI
00401D51 .^75 F5 JNZ SHORT crackme_.00401D48 // "" 00401D48
00401D53 . E9 BB010000 JMP crackme_.00401F13 // "" 00401F13Thus, we see the Username encryption algorithm.
Tracing further, we get to the next section:
00401F1D . 81F9 00500000 CMP ECX,5000
00401F23 -7F FE JG SHORT crackme_.00401F23In my opinion, this is another anti-debugging trick, so replace JG with JE and calmly trace further. And again we stumble on the GetDlgItemTextA function bryak. This time she reads reg. code:
00401FE6 > E8 250B0000 CALL <JMP.&user32.GetDlgItemTextA> // GetDlgItemTextA
00401FEB . BE 64404000 MOV ESI,crackme_.00404064 // ESI ( . )
00401FF0 . BF 64484000 MOV EDI,crackme_.00404864 // EDI . ,
00401FF5 . 8B07 MOV EAX,DWORD PTR DS:[EDI] // EAX . ,
00401FF7 . 8B1E MOV EBX,DWORD PTR DS:[ESI] // EBX .
00401FF9 . 3BC3 CMP EAX,EBX //
00401FFB 0F85 C4020000 JNZ crackme_.004022C5 // , 004022C5
00402001 . 83C6 04 ADD ESI,4
00402004 . 83C7 04 ADD EDI,4
00402007 . 8B1E MOV EBX,DWORD PTR DS:[ESI] // EBX .
00402009 . 8B07 MOV EAX,DWORD PTR DS:[EDI] // EAX . ,
0040200B . 3BC3 CMP EAX,EBX //
0040200D 0F85 B2020000 JNZ crackme_.004022C5 // 004022C5
00402013 . E9 5C000000 JMP crackme_.00402074 // ""Conclusion
Thus, it turns out that the entire encryption algorithm is the replacement of every second character of the name with the character following in the ASCII table.
Plus, the program checks only the first 8 characters of the serial number, which, accordingly, is a disadvantage.
Keygen
And here is keygen:
var
s:string;
i:integer;
c:char;
begin
readln(s);
while i<= length(s) do begin
Inc(s[i]);
i:=i+2;
end;
writeln(s);
end.Thanks for attention.
PS Sorry for Pascal, I did not find another compiler.
PPS And sorry for the simplicity.