Author: Monster [E.S. T]
I accidentally pulled a scanner named ipscan from the 12-phase black client X-File CD and opened it. I needed to register the scanner. I was so depressed that I had no money to register the scanner. I just entered a registration code, the prompt "Registration is not valid, please try again", ah, I'm not lucky. Since I didn't guess it, I 'd better stay the same style (Long Live piracy ), put it in PEID and check it. It shows that ASPack has been used with shell, and ASPack has a good shell. We can simply solve this problem by using the ESP law,
Here is OEP. Check the Code:
004c3c6 55 push ebp
004C3C19 8BEC mov ebp, esp
004C3C1B 83C4 F0 add esp,-10
004C3C1E 53 push ebx
004C3C1F B8 38384C00 mov eax, 004C3838
Right-click "Dump debugger process" in the OD and select "Dump debugger process" to Dump it out. Because it is an ASPack shell, you can skip the fix and put it in PEID, hey, I guess it's not wrong. Now load OD after shelling, right-click in OD and choose "Ultra String Reference"> "Find ASCII" to enable the OD String search function, check whether there are any sensitive strings, but the result is nothing. Now many friends may think of a function breakpoint for functions such as GetWindowText or GetDlgItemText, or a message breakpoint for the "OK" button, if you think so, you will ignore the problem, that is, the feature of Delphi. Delphi does not call the Windows API function when obtaining the text in the text box, instead, send a WM_GETTEXT message to the text box to obtain the content of the text box (WndProc is called directly instead of the message function ), I used Dede to find the event called when the "OK" button is clicked in the registration window. We can see that its RVA is 004C0070, open the OD loading program and press Ctrl + G. In the pop-up window, enter 004C0070 to jump to the code. Here we press F2 next breakpoint, now we press F9 to run the program in OD. At this time, we enter a registration code and press the "OK" button, and the program is disconnected from the place where we just clicked the breakpoint, let's follow up on F8 and then we will come here. The Code is as follows:
004C0099 mov eax, dword ptr [ebp-4]; get registration code
004C009C call 004C371C; check the registration code
004C00A1 test al, al; comparison statement
004C00A3 jnz short 004C00E3; key jump
Some of our friends who have some experience in cracking will find that we only need to change the jnz of the Code 004C00A3 jnz short 004C00E3 to jmp, which is the key jump, that is, the storm we often say, in this way, no matter what password we enter, We will prompt that the registration is successful, save the cracked file, run it, enter a registration code casually, and then go to the main interface.
It can be said that the attack has been successful, but in this case, I am very upset. If we want to do it, we have to solve it. Let's analyze its algorithm. We press Ctrl + F2 to reload and continue tracking. When we encounter the statement 004C009C call 004C371C, we press F7 to follow up. Here is the place to check the registration code. The Code is as follows:
004C3747 cmp eax, 0A; check whether the registration code length is 10
004C374A jnz short 004C37A2; Skip if not equal (skip not allowed)
004C374C mov eax, dword ptr [ebp-4]; get registration code
004C374F xor ecx, ecx; ecx cleared
004C3751 mov cl, byte ptr [eax]; first place of registration code
004C3753 mov eax, ecx
004C3755 mov edx, dword ptr [ebp-4]; get registration code
004C3758 movzx esi, byte ptr [edx + 4]; fifth digit of the registration code
004C375C add eax, esi; add the first and fifth digits
004C375E sub eax, 60
004C3761 cmp eax, 8; Comparison between values and 8
004C3764 jle short 004C37A2; Skip if the value is not greater than (skip not allowed)
004C3766 mov eax, ecx
004C3768 mov edx, dword ptr [ebp-4]; get registration code
004C376B movzx edx, byte ptr [edx + 2]; Third digit of the registration code
004C376F add eax, edx; and add first
004C3771 add eax, esi; then add to the fifth digit
004C3773 sub eax, 90
004C3778 mov ecx, 0A; ecx = 10
004C377D cdq
004C377E idiv ecx; divided by 10 (eax = Operator, edx is the remainder)
004C3780 mov eax, dword ptr [ebp-4]; get registration code
004C3783 movzx eax, byte ptr [eax + 3]; fourth digit of the registration code
004C3787 sub eax, 30
004C378A cmp edx, eax; comparison between the fourth digit and the remainder
004c0000c jnz short 004C37A2; Skip if not equal (skip not allowed)
004c0000e mov eax, dword ptr [ebp-4]; get registration code
004c00001 cmp byte ptr [eax + 1], 35; Comparison between second and 5
004C3795 jbe short 004C37A2; Skip if it is not higher than (cannot skip)
004c00007 mov eax, dword ptr [ebp-4]; get registration code
004c0000a cmp byte ptr [eax + 5], 32; comparison between the Sixth and second
004c0000e ja short 004C37A2; Skip if it is higher than (cannot skip)
Here we can analyze the following points:
1. The length of the registration code is 10.
2. The sum of the First and Fifth places is greater than 8.
3. First, the sum of the third and fifth digits is equal to the fourth digit.
4. The second digit is greater than 5
5. The sixth digit is less than 2
Now that we know this, we can write a registration machine. Let's look at the code I wrote:
// TestDlg. cpp: implementation file
//
# Include "stdafx. h"
# Include "test. h"
# Include "testDlg. h"
# Ifdef _ DEBUG
# Define new DEBUG_NEW
# Undef THIS_FILE
Static char THIS_FILE [] = _ FILE __;
# Endif
Char chkey [10];
Int I;
Void makekey ()
{
Int key [10], I;
Key [2] = rand () % 10;
Key [6] = rand () % 10;
Key [7] = rand () % 10;
Key [8] = rand () % 10;
Key [9] = rand () % 10;
Do
Key [0] = rand () % 10;
While (key = 0 );
Do
Key [4] = rand () % 10;
While (key [0] + key [4] <= 8 );
Key [3] = (key [0] + key [2] + key [4]) % 10;
Do
Key [5] = rand () % 10;
While (key [5]> 2 );
Do
Key [