It always uses TP/Delphi. I also like to play with compilation. It's okay to break through the software, but the level can only deal with clear code comparison ...... Faint
Recently, I saw a Keygen very interesting, but people had to do it themselves instead of giving it a template. After a few days, I had some experiences. So write it down, and you should not throw bricks.
========================================================== ======================================
I found that I had a special hobby and liked to collect KeyGen templates. What should I do? I feel that those things are both
Small and exquisite, especially the KeyGen of some cracking organizations, and some special effects. But obviously, he
We will not release the template. In this way, you only need to start with the disassembly result of KeyGen and try to restore it.
Source code. Fortunately, in order to reduce the size of the final file, KeyGen is generally written In SDK and used
The language is similar to ASM, Delphi, and VC. It is not too difficult to reverse.
OK. Select a victim first. Run the command first. In the Protocol box, click agree to go to the main interface. Shelling and repair
Resources. You can see that it is Delphi by peid. Use IDA to reverse the attack.
0000: 00405370 start:
0000: 00405370 push ebp
0000: 00405371 mov ebp, esp
0000: 00405373 add esp, 0FFFFFFF4h
0000: 00405376 mov eax, offset dword_405338
0000: 0040537B call @ Sysinit @ InitExe $ qqrv; Sysinit ::__ linkproc _ InitExe (void)
0000: 00405380 push 0
0000: 00405382 call GetModuleHandleA_0
0000: 00405387 mov ds: hInstance, eax
// Note that this is a global variable
0000: 0040538C push 1F1F1Fh
0000: 00405391 call CreateSolidBrush
0000: 00405396 mov ds: hbr, eax
0000: 0040539B push 70 h
0000: 0040539D mov eax, ds: hInstance
0000: 004053A2 push eax
0000: 004053A3 call LoadCursorA
0000: 004053A8 mov ds: hCursor, eax
0000: 004053AD push 64 h
0000: 004053AF mov eax, ds: hInstance
0000: 004053B4 push eax
0000: 004053B5 call LoadIconA
0000: 004053BA mov ds: dword_4076E8, eax
// Store the obtained Handle here. IDA sometimes has some problems.
0000: 004053BF push offset sub_404DD4
// Obviously, this is a Callback. Do you need a sub address in other places?
// Of course, this refers to the absence of ret!
0000: 004053C4 xor ecx, ecx
0000: 004053C6 mov edx, 3E8h
0000: 004053CB mov eax, ds: hInstance
0000: 004053D0 call sub_403CCC
// Follow in!
0000: 004053D5 cmp ds: dword_4060B0, 0
0000: 004053DC jz short loc_4053F4
0000: 004053DE push offset sub_404A44
0000: 004053E3 xor ecx, ecx
0000: 004053E5 mov edx, 7D0h
0000: 004053EA mov eax, ds: hInstance
0000: 004053EF call sub_403CCC
0000: 004053F4
0000: 004053F4 loc_4053F4:
0000: 004053F4 mov eax, ds: hbr
0000: 004053F9 push eax
0000: 004053FA call DeleteObject
0000: 004053FF push 0
Call ExitProcess_0
Call @ System @ Halt0 $ qqrv; System ::__ linkproc _ Halt0 (void)
We can see that the two calls at the beginning and end are very interesting. They are actually something in System. Here we can
As you can see, the main program is very short and ExitProcess is used when exiting instead of ending naturally. There are five global variables (
In the ds segment ). Sub_403CCC and sub_404A44 go in and check whether it is a call.
The subprogram of DialogBoxParamA. OK, sub_403CCC seems to be the Protocol box, And sub_404A44 should be
Is the main dialog box. Sub_403CCC is listed here:
0000: 00403CCC sub_403CCC proc near
0000: 00403CCC
0000: 00403CCC
0000: 00403CCC lpDialogFunc = dword ptr 8
0000: 00403CCC
0000: 00403CCC push ebp
0000: 00403CCD mov ebp, esp
0000: 00403CCF push ebx
0000: 00403CD0 push 0; dwInitParam
0000: 00403CD2 mov ebx, [ebp + lpDialogFunc]
// Callback
0000: 00403CD5 push ebx; lpDialogFunc
0000: 00403CD6 push ecx; hWndParent
0000: 00403CD7 push edx; lpTemplateName
0000: 00403CD8 push eax; hInstance
0000: 00403CD9 call DialogBoxParamA
0000: 00403CDE pop ebx
0000: 00403CDF pop ebp
0000: 00403CE0 retn 4
0000: 00403CE0 sub_403CCC endp
Combined with the code that calls this program above, you can get the src of the main program:
Var
H_Icon: HICON;
H_Inst: HMODULE;
H_Cur: hCursor;
H_Brush: HBRUSH;
Flag: Boolean;
Begin
H_Inst: = GetModuleHandle (nil );
H_Brush: = CreateSolidBrush ($ 1F1F1F );
H_Cur: = LoadCursor (h_Inst, MAKEINTRESOURCE (LINKCURSOR ));
H_Icon: = LoadIcon (h_Inst, MAKEINTRESOURCE (MAINICON ));
// Display the Protocol dialog box
DialogBox (h_Inst, LPCTSTR (IDD_LICENSEDLG), 0, @ LicenseProc );
If Flag Then DialogBox (h_Inst, LPCTSTR (IDD_MAINDLG), 0, @ MainProc );
DeleteObject (h_Brush );
// Exit the program
ExitProcess (0 );
End.
What's interesting: Is Flag not assigned a value? The answer is: In LicenseProc!
Source: [Hundred trees] Delphi reverse engineering learning notes [1]
Http://www.bmpj.net/forum-viewthread-tid-263-fromuid-2.html