Target program download address: http://opencrackmes.crackmes.de/ope...rackmes/k4n.zip to some of the hacker sites to transfer, found that the most popular, the number of clicks is some "Teachers Birds Trojan "Intrusion Primary Tutorial" article, and "Outlook Express HTML Mail Ultra-length byte HREF Boffering Flow Defect" "PHP FOPEN () function is prone to crlf inJection attack" This article is lacking, even though this Perhaps it is the real master. Now I have gradually increased in the snow forum, of course, because everyone's level is improved, but also brought trouble to the rookie that I have just introduced, I can't understand it, it is not a problem in the master. Question often troublesome newcomers for a long time: Why is it a key jump? Is it important CALL? Why is there any Call to follow up, some calls just have you only? I will succeed in accordance with the step by the master, can you do this? I want more people who don't easily break a clearly comparison software, I want to post it, I am afraid to do it for the master. So I found a very simple CRACKME (if you are a master, you should get the static commissioning should be done), from the head to the tail carefully written the analysis process, add some places I think that I should pay attention to, I hope to help some friends who have just started. I am not a master, and I am more skilled in a single thing. Maybe it's more difficult to understand the newcomers. Here I use W32DASM as a static disassembly tool, you may use C32ASM or other, basic functions should be similar. Enter your username and registration code first, click "Check the Serial" to see what is wrong (if "registration code is correct", don't look at it here, hurry to buy lottery tickets) Out, "this Serial is * NOT * VALID !! TRY AGAIN ...: Unregistered ". It is good to run W32DASM to make it back, in string referen, pay attention to it, sometimes it can not be fully displayed when the string is longer, then just find a long time, such as this time, find "this Serial is * not * valid !! try ", it is it, double click to reference the string. (PS: Sometimes the error message will appear more than once in the code, then you can find other places as long as you double-click multiple times.) Let me quote the code (this is in the form of W32DASM, if you use OD or Si Dynamics There is slightly different in the form of tracing). Don't be dawn by so many code, it is recommended to skip the code first to see my back instructions, then control it from the code.
Code:
* Possible Reference to Dialog: Dialogid_0001, Control_ID: 0066, ""
|
: 00401085 6A66 PUSH 00000066; Enter the text box ID of the username
: 00401087 53 PUSH EBX; dialog box handle
* Reference to: user32.getdlgitem, ORD: 0000H
|
: 00401088 E8159C0000 Call 0040ACA2; Get text box handle
: 0040108D 6A64 Push 00000064; Get the maximum length of the string
: 0040108F 8D9548FFFFFFLE EDX, DWORD PTR [EBP FFFFFFF48]: 00401095 52 PUSH EDX; EDX is the address of the access string
: 00401096 50 Push Eax; EAX is the text frame handle obtained above
* Reference to: user32.getwindowTexta, ORD: 0000H
|
: 00401097 E8129C0000 Call 0040acae; get username, in [EBP ffffff48]
* Possible Reference to Dialog: DialogID_0001, Control_ID: 0068, ""
|
: 0040109C 6A68 PUSH 00000068; The same operation, enter the text box ID of the registration code
0040109E 53 PUSH EBX
* Reference to: user32.getdlgitem, ORD: 0000H
|
: 0040109F E8FE9B0000 CALL 0040ACA2
004010A4 6A64 Push 00000064
004010A6 8D8DE4FEFFFFLE ECX, DWORD PTR [EBP FFFFEE4]
: 004010AC 51 PUSH ECX
: 004010AD 50 Push EAX
* Reference to: user32.getwindowTexta, ORD: 0000H
|
: 004010AE E8FB9B0000 Call 0040acae; get registration code, in [EBP FFFFFEE4]
* Possible Reference to Dialog: Dialogid_0001, Control_ID: 0067, ""
|
: 004010B3 6A67 PUSH 00000067; This is the ID of the text of the text of the lower prompt
: 004010B5 53 Push EBX
Seduce
* Reference to: user32.getdlgitem, ORD: 0000H
|
: 004010B6 E8E79B0000 Call 0040ACA2; Get handle
: 004010BB 8BF0 MOV ESI, Eax; Placed in ESI standby
: 004010BD 8D8548FFFFFF LEA EAX, DWORD PTR [EBP ffffff48]
: 004010C3 50 Push Eax; pointing to the username
: 004010C4 E867050000 CALL 00401630; Get user name length
: 004010C9 59 POP ECX
: 004010CA 8945D8 MOV DWORD PTR [EBP-28], EAX; Length in [EBP-28]
: 004010CD 8D95E4Feffff Lea EDX, DWORD PTR [EBP FFFFFEE4]
: 004010D3 52 Push EDX; point to registration code: 004010D4 E857050000 Call 00401630; Get registration code length
: 004010D9 59 POP ECX
004010DA 68EAB04000 PUSH 0040B0EA
: 004010DF E84C050000 Call 00401630
: 004010E4 59 POP ECX
: 004010E5 680EB14000 PUSH 0040B10E
: 004010EA E841050000 Call 00401630
: 004010EF 59 POP ECX
: 004010F0 837DD803 CMP DWORD PTR [EBP-28], 00000003
: 004010F4 7E7B JLE 00401171; User name length cannot be less than equal to 3
004010F6 90 NOP
004010F7 90 NOP
004010F8 90 NOP
004010F9 90 NOP
: 004010FA 33C9 XOR ECX, ECX
: 004010FC 33D2 XOR EDX, EDX
: 004010FE 33DB XOR EBX, EBX
: 00401100 33C0 XOR EAX, EAX
: 00401102 837DD832 CMP DWORD PTR [EBP-28], 00000032
: 00401106 7D69 JGE 00401171; User name length cannot be greater than or equal to 32h
: 00401108 90 NOP
00401109 90 NOP
0040110A 90 NOP
: 0040110B 90 NOP
* Reference by A (u) Nconditional OR (C) ONDITIONAL JUMP AT ATDRESS:
|: 0040111C (c)
|
: 0040110C 0FBE840D48FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ECX-000000B8]; the characters according to the user name
: 00401114 41 INC ECX; ECX is a cyclic variable
00401115 33C1 XOR EAX, ECX; Taked Character and Cyclic Variables
: 00401117 03D8 Add EBX, EAX; accumulate results to EBX
: 00401119 3B4DD8 CMP ECX, DWORD PTR [EBP-28]; circulating variables compared to the length of the username
: 0040111C 75ee JNE 0040110C; Jump back if not taken
: 004011E 6BC006 Imul Eax, 00000006; The last round of calculation results in Eax, take 6: 00401121 C1E307 SHL EBX, 07; front accumulation results left shift 7
: 00401124 03C3 Add Eax, EBX; add
00401126 8945C8 MOV DWORD PTR [EBP-38], EAX
: 00401129 FF75C8 PUSH [EBP-38]; Push the above results
* Possible StringData Ref from data obj -> "% lx"
|
: 0040112C 6838B44000 PUSH 0040B438; One Conversion Identification
: 00401131 8D8D80Feffff Lea ECX, DWORD PTR [EBP FFFFFE80]
: 00401137 51 PUSH ECX; address of the storage result
: 00401138 E8873D0000 CALL 00404EC4; Digital to hex three strings
: 0040113D 83C40C Add ESP, 0000000C
: 00401140 8D8580Feffff Lea Eax, DWORD PTR [EBP FFFFFE80]
: 00401146 50 Push Eax; String of the above conversion
: 00401147 8D95E4Feffff LEA EDX, DWORD PTR [EBP FFFFEE4]
: 0040114D 52 Push EDX; fake registration code
* Reference to: kernel32.lstrcmpa, ORD: 0000H
|
: 0040114E E8339C0000 Call 0040AD86; Comparison
: 00401153 85c0 Test Eax, EAX
: 00401155 750D JNE 00401164; Here is a key jump
* Possible StringData Ref from Data Obj -> "Congratuations! If this Number"
-> "comes * from Your * Keygen, Write"
-> "a tutorial dude."
|
: 00401157 683CB44000 PUSH 0040B43C; Point to the Successful string
: 0040115C 56 PUSH ESI; ESI still remember? The handle of the prompt text box
* Reference to: user32.setwindowTexta, ORD: 0000H
|
: 0040115D E8289B0000 Call 0040ac8a; display
: 00401162 EB18 JMP 0040117C
* Reference by A (u) Nconditional OR (C) ONDITIONAL JUMP AT ATDRESS:
|: 00401155 (C)
|
* Possible StringData Ref from data obj -> "this serial is * not * valid !! Try" -> "again ...: unregistered"
|
: 00401164 6890B44000 PUSH 0040B490; Start stopping in this sentence, looking up
: 00401169 56 Push ESI; ESI prompts the handle of the text box
* Reference to: user32.setwindowTexta, ORD: 0000H
|
: 0040116A E81B9B0000 Call 0040AC8A
: 0040116F EB0B JMP 0040117C
* Reference by A (u) Nconditional OR (C) OONDitional Jump At Addresses:
| 004010F4 (C),: 00401106 (C)
|
* Possible StringData Ref from Data Obj -> "Name Must Contain More Than 4"
-> "Chars and Less Than 50 Chars !!"
|
00401171 68C9B44000 PUSH 0040B4C9; Username does not meet the requirements to jump here
00401176 56 Push ESI; ESI prompts the handle of the text box
* Reference to: user32.setwindowTexta, ORD: 0000H
|
: 00401177 E80E9B0000 Call 0040AC8A
* Reference by A (u) Nconditional OR (C) OONDitional Jump At Addresses:
|: 00401162 (U),: 0040116F (U)
|
: 0040117C 5F POP EDI
0040117D 5E POP ESI
0040117E 5B POP EBX
: 0040117F 8BE5 MOV ESP, EBP
: 00401181 5D POP EBP; I have finished returning
: 00401182 C3 RET
Double-click the cursor to stop in 401164. Obviously, if we come to this sentence, we will die, and if our registration code is correct, it will not come to this sentence (too nonsense), then this sentence will definitely have a conditional jump Directive. (This is the basic idea of finding blasting points) to find it up, found :: 00401155 750D JNE 00401164 Just jump to 401164 error message. Oh, if you want to blast, just change the 750D to 740D (JE, turn the condition, the registration code is displayed correctly) or changed to EB0D (JMP, unconditional jump, no matter how three seven twenty one is correct) . OK, we can't satisfy this, let's take a look at its algorithm, and like the mysterious master like a registration machine. I will give you a little lesson, which is the call to the function. In addition to some Delphi programs, the transfer of the function parameters is done with a stack, simply, putting the various parameters of the function first push, then call this function. In the function inside, general [EBP 8] is the first parameter, [EBP C] is the second parameter, each time more, and this type is pushed. The local variable inside the function is commonly used [EBP-4] [EBP-8] ... etc. (The reason is a bit complicated, remember to remember) The return value of the function is in Eax. In general, the judgment of the software is a function. The most classic two sentences starting in the function is Push Ebpmov EBP, ESP and stack processing, our rookie should not be too understandable, know that this is usually a function of a function. . Looking up, there is no, find it, where is the top (I am not listed above). If you want to completely judge its algorithm, you will usually start here. In this program, there are some initialized stuff, so I omitted the front part. (This is also the principle of cracking, don't do nothing to do, in advanced language, the code has a large part of the machine is automatically generated, the computer, the line of writing does not know how tired, how is the human brain and one line of reading code Get? Your head is a few GHZ CPU? Common Some of the compilation masters that do not crack experience, completely understand the meaning of each line of code, is not a key place, it turns out that he is in the API in the API. Useless work.) Ok, now you can dynamically debug. Let's start here, step by step, there is a Call getdlgitem, let's take a look at the function description (the hand is required) hwnd getdlgitem (hwnd hdlg, // handle of dialog box int Niddlgitem // identifier of control; huh, simple saying that this function is to let the program determine the control on a dialog, the first parameter is the handle of the dialog, the second parameter is the ID, function of a control on the dialog. Will return the handle of the control, so you can use this handle to operate. See the program: Code:
* Possible Reference to Dialog: Dialogid_0001, Control_ID: 0066, ""
|
: 00401085 6A66 PUSH 00000066; Control ID
: 00401087 53 Push EBX; dialog box * Reference to: user32.getdlgitem, Ord: 0000H
|
: 00401088 E8159C0000 Call 0040ACA2
See the first line, there is no, dialogid_0001, control_id: 0066, pressing a 66 as the second parameter: Control ID (Note that the API call is from right to left, that is, the last side of a parameter first push), use the resource View tool What is the ID of 66, huh, it is the text box that enters the username. Ok, now we have the handle of the text box, there is an eax. Then look down, another API is getWindowText. Look at the description: int GETWINDOWTEXT (HWND HWND, // Handle of Window OR Control with text lptstr lpstring, // address // maximum number of character of character of character) to copy; from the name can also guess, this function That is to get a window of a window control. The first parameter is the handle of the control, the second is the address of the buffer that stores the resulting text, the third parameter sets the maximum length of the text. See the program:
Code:
: 0040108D 6A64 PUSH 00000064; Maximum length
: 0040108F 8D9548FFFFFF LEA EDX, DWORD PTR [EBP ffffff48]; put [EBP FFFFFFF48] first in EDX
: 00401095 52 PUSH EDX; Buffer address [EBP fffffff48]
: 00401096 50 Push Eax; EAX? Is the return value of the API above, the control handle
* Reference to: user32.getwindowTexta, ORD: 0000H
|
00401097 E8129C0000 Call 0040ACAE
Ok, now d eBP ffffff48, isn't it the username entered? (Instead, in the form of [EBP-B8] in Olly or Sice, it is actually the same as a similar operation, but the control ID has become 68. It is conceivable that it is a registration code, the registration code is placed [ EBP FFFFFEE4]. Oh, continue, I have a few words:
Code:
: 004010BD 8D8548FFFFFF LEA EAX, DWORD PTR [EBP ffffff48]
: 004010C3 50 Push EAX
004010C4 E867050000 Call 00401630
What is this teeth? Do you want to enter 4010C4 this CALL 401630? And slow! I have said in front, don't be in a regular place, (! A egg throwing up: Who knows that it is important?) Don't worry, generally, first roughly follow it, try to guess Call Role. If you find that the return value is very suspicious, you will not follow it again. (This requires a certain "intuition", English is called "sens", Taiwan is called "touch" or "first death", don't worry, there will be this feeling, this feeling is hard to say. Sometimes, I know that the kind of situation will know that it is far away, and we come back to see the code. A Call, there is a Push Eax in front, it is obvious to the parameters of Call. (See me the previous description) See Eax: Lea Eax, DWORD PTR [EBP ffffff48]. [EBP FFFFFF48] Is there any impression? Yes, it is the address of the username in front API call. After the D eax after this, I am not our username. I entered "Roba". After taking this call, I take a look at EAX, um ~~~~ is 4. What did you think of? No? It doesn't matter how we continue to look at: Code:
: 004010C9 59 POP ECX
: 004010CA 8945D8 MOV DWORD PTR [EBP-28], EAX; Remember, the return result above [EBP-28]
: 004010CD 8D95E4Feffff Lea EDX, DWORD PTR [EBP FFFFFEE4]
004010D3 52 Push EDX
: 004010D4 E857050000 Call 00401630
It is also a Call 401630, the same as above. Take a look at its parameters EDX, [EBP fffee4] Oh is a fake registration code, I lose '87654321', return value eax = 8, find anything wrong? Yes, this Call is the length of the string, if you follow and give a lot of time. down:
Code:
: 004010F0 837DD803 CMP DWORD PTR [EBP-28], 00000003
004010F4 7E7B JLE 00401171
: 00401102 837DD832 CMP DWORD PTR [EBP-28], 00000032
004017 7D69 JGE 00401171
Remember what [EBP-28] is? Yes, it is the length of the username. These words are obvious. The length of the username must be greater than 3 less than 32h, otherwise it will jump to 401171, you can follow the past, huh is not Tips that meet the requirements. Ok, we come to the key place:
Code:
* Reference by A (u) Nconditional OR (C) ONDITIONAL JUMP AT ATDRESS:
|: 0040111C (c)
|
: 0040110C 0FBE840D48FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFET [EBP ECX-000000B8]: 004015]: 00401114 41 INC ECX
: 00401115 33C1 XOR EAX, ECX
: 00401117 03D8 Add EBX, EAX
: 00401119 3B4DD8 CMP ECX, DWORD PTR [EBP-28]
: 0040111C 75ee JNE 0040110C
Oh, is it dizzy? [EBP ECX-B8] Is this awkward? Don't worry, there must be a road before the car. First D EBP ECX-B8, 哟, isn't our username? what happened? Think about it, ECX is now 0, [EBP-B8] and [EBP FFFFFF48] (remember not? Add the address of the username) Not a matter! (I don't understand how the negative representation method, I don't know why W32DASM sometimes writes -b8 to ffffff48), look carefully, Movsx Eax, Byte PTR [EBP ECX-000000B8], pay attention to Byte PTR, That is, read in bytes (that is, a character is read each time), and an ECX is added. If you break more, you should immediately understand: the key place is there. This is a very typical loop structure, see it? ECX is a loop variable, and each execution will take a character from the username, then ECX plus 1, so [EBP ECX-B8] is pointing to the next character of the username. The charted characters are operated with the cyclic variable, and the results are accumulated to EBX. Then the loop variables and [EBP-28] are also the length of the user name, if not, if it is not yet, it will return to the next character of the username. This is not until it is taken.
Code:
: 0040111E 6BC006 Imul Eax, 00000006; EAX is actually the result of the last round of calculation, take 6
: 00401121 C1E307 SHL EBX, 07; EBX is a few rounds of calculation, and the left shift 7 position
: 00401124 03C3 Add Eax, EBX; add up
00401126 8945C8 MOV DWORD PTR [EBP-38], EAX
: 00401129 FF75C8 PUSH [EBP-38]; the result of the above, as a parameter
* Possible StringData Ref from data obj -> "% lx"
|
: 0040112C 6838B44000 push 0040b438; "% lx" a bit of a bit
: 00401131 8D8D80Feffff Lea ECX, DWORD PTR [EBP FFFFFE80]
: 00401137 51 Push ECX; what is this?
: 00401138 E8873D0000 CALL 00404EC4
: 0040113D 83C40C ADD ESP, 0000000C The previous sentence is to continue the calculation above, send the value of the EAX * 6 and EBX left 7 bits, then copy to [EBP-38] this part of the part of the CALL as a parameter below Then [EBP FFFFFE80] is a second parameter, then another call, or so, don't worry, look at there is anything, the first parameter [EBP-38], there is nothing to say, The result of the above calculation. The second parameter points to "% lx". This string has written the C language. It is the identifier used in the PRINTF in the top of the uppercase, and it is more than one number 255. Convert the string "FF". "What is the third parameter in WSPrintf in WinAPI? See more in front of this form, guess! We verify that the previous guess is correct, I use "Roba" to calculate the result is 46430, which is the 16-binary B55E, we have followed this Call to see the results? What, what is the result? Clever, have you not thought about it, the third parameter above [EBP fffe80] is the address of the result. How do you not find it. (In fact, from 40113d, the add ESP, C can also be seen, because only this parameter number of parameters in the function outside the function is a function. Reject, I don't know how it doesn't matter), then look:
Code:
: 00401140 8D8580Feffff Lea Eax, DWORD PTR [EBP FFFFFE80]; eye, just the result of conversion
: 00401146 50 Push Eax; EAX point to the string of the above conversion
: 00401147 8D95E4Feffff Lea EDX, DWORD PTR [EBP FFFFFEE4]; this is very early, looking for it in front, 啥
: 0040114D 52 Push EDX; EDX points to the fake registration code we entered
* Reference to: kernel32.lstrcmpa, ORD: 0000H
|
: 0040114E E8339C0000 CALL 0040AD86
: 00401153 85c0 Test Eax, EAX
: 00401155 750D JNE 00401164; Key jump 哟
Haha, lstrcmp, what does it mean, I don't have to say it, of course, the stringcompare string is compared. Comparing the calculated results with the false code entered in front, it is OK. Ok, now the complete code above, how, is it not difficult to write a registration machine?
Code:
#include
#include
#include
void main ()
{
INT EAX = 0, EBX = 0, LEN;
CHAR Name [50] = {0};
Char Password [50] = {0};
Printf ("please input your name:");
Scanf ("% s", name);
Len = Strlen (name);
For (int i = 0; i EAX = Name [i] ^ (i 1); EBX = EAX; } EAX * = 6; EBX << = 7; EAX = EBX; Printf ("Your Password IS:% LX / N", EAX); Printf ("Keygen By Roba Enjoy CRACKING, NewBies! / N"); } Simple C procedure, you can also write one with your familiar language. Postscript: This is a simple CRACKME. I have been solved by the three words. I have said such a big pile by me, I hope to truly understand the problem. I hope you discover the software through this article. And even the registration machine is not a difficult thing. As long as you stick to it, everyone has the day of the master, and I hope that the masters can pick more articles that are suitable for lower levels or at least a lot of newcomers to this article. . Enjoy cracking, newbies!