L ZZZZZZ RRRRR SSSSS L Z R R S L aaa Z aaa R R u u S L a Z a RRRRR u u SSSSS XX L aaaa Z aaaa R R u u S XXXX L a a Z a a R R u u S XXXXXX LLLLLLL aaaaa ZZZZZZZ aaaaa R R uuuuu SSSSSS XXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXX XXXXXX XXXX proudly presents his 28.Cracking Tutorial (25.08.1999) XX Cracking the #cracking4newbies CrackMe #3 I. Introduction I.1 The tools II. The essay II.1 First look at the target II.2 The serial II.3 The keygen III. BTW I. Introduction This is the first essay I write for TORN@DO who had this brilliant idea with the weekly Newbies' target. So, here comes my contribution to support it. I.1 The tools W32Dasm (I have v8.9) MASM (if you want to compile the MASM source for the keygen) Quite few tools, so choose a good piece of music. It's a matter of fact that I drive 10 seconds per lap faster in F1 Grandprix when I hear "Born to be wild" in the background. In my case it is the band "Eisregen" and the song "Krebskolonie" - I assume nobody who reads this has ever heard of them: Fucking good German Underground Metal. II. The essay II.1 First look at the target The CrackMe is plain and simple. Start it, and you'll see what to do. Enter a name and a serial, that registers it: The concept is not hard ;) If you enter no name a message will appear saying "Don't you have a name?!", if you enter a name and no serial "No serial number entered!". If you enter a name and a serial, the message "Wrong number!!" appears. If anything else appears contact me. II.2 The serial After having a small look at the target, we jump right into cracking it. Load it in W32Dasm and search for things we know. What do we know? We know the strings that appear when you enter a wrong name/serial combination. It was "Wrong number!!". So let's search for it. Click in W32Dasm at the second button of the right "StrnRef". This will open the string reference. Search for "Wrong number!!" and double-click on it. Now close the String refs and you should see this: * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00401117(C) ;; INTERESTING AND IMPORTANT | * Possible StringData Ref from Data Obj ->"Bad!" ;; THE CAPTION OF THE MESSAGEBOX | :00401134 6840504000 push 00405040 ;; PUSH IT * Possible StringData Ref from Data Obj ->"Wrong number!!" ;; THE TEXT OF THE MESSAGEBOX | :00401139 6830504000 push 00405030 ;; PUSH IT :0040113E 53 push ebx * Reference To: USER32.MessageBoxA, Ord:01BEh ;; DISPLAY MESSAGEBOX This code displays the messagebox. The important thing is, from where from this code is jumped to. We can see that it is :00401117 - So go to this line and you should see this. :00401102 8D55F4 lea edx, dword ptr [ebp-0C] :00401105 52 push edx :00401106 E840010000 call 0040124B :0040110B 8B4D08 mov ecx, dword ptr [ebp+08] :0040110E 83C404 add esp, 00000004 :00401111 03CE add ecx, esi :00401113 3BC8 cmp ecx, eax ;; COMPARE SOMETHING :00401115 6A00 push 00000000 :00401117 751B jne 00401134 ;; CONDITIONAL JUMP * Possible StringData Ref from Data Obj ->"Good!" ;; THE FOLLOWING LINES | ;; DISPLAY THE :00401119 685C504000 push 0040505C ;; "WELL DONE" MESSAGEBOX * Possible StringData Ref from Data Obj ->"Congratulations!!" | :0040111E 6848504000 push 00405048 :00401123 53 push ebx * Reference To: USER32.MessageBoxA, Ord:01BEh | :00401124 FF1598404000 Call dword ptr [00404098] ;; HERE THE MSGBOX APPEARS Look closer to line 401117. There is a "jne" which means "Jump if Not Equal". But what should be equal? The solution is two lines above. The "cmp ecx, eax" compares two values. If they are not the same, the jne is taken and the "Wrong" messagebox is displayed, if they are the same, the "Good" messagebox is displayed. So we have to look what is compared there. At this part of the essay, I assume that everyone else switches to SoftICE. Not me! I definetely needn't drive to school with a Ferrari - My bike is enough, if you know what I mean. (btw: Carpathia - the W32Dasm-Debugger is useful :P). So fire up the W32Dasm debugger by choosing "Debug"/"Load Process". It can be that the debugger wants a command line from you. Just hit enter in that case. After the debugger windows are loaded, choose "Goto"/ "Goto Code Location" and choose 401113. Then hit [F2] and a breakpoint is set on that line. You see a yellow square if everything's OK. Then hit [F9] to start the CrackMe and enter a name and a serial and hit press [ENTER]. Now the debugger windows should appear and you are at line :00401113 (the "CMP ECX, EAX"). Now look what ecx and eax contains. Never saw these values? You better choose a "standard-serial" you enter always as a test and you should know what this one is in hex. In my case it is 666999d and A2D77h. If you choose 666999 as serial next time, eax will contain A2D77. If you choose "LaZaRuS" as name, ecx will contain this value: 14382h - It is compared with the serial we entered, so it should be the correct serial. So enter 14382 as serial and... the "Wrong" box appears again. Why? Heh, you have to convert this value back to decimal, as it is compared with our serial in hex. Converted it is: 82818. This is the valid serial for "LaZaRuS". II.3 The keygen Now, we have the serial. Let's keygen it! To find the starting point you could follow the code back from the "good message". Between the "No Name" and "No serial" message there's some interesting code: * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004010C6(C) |;; THE FOLLOWING LOOP IS EXECUTED FOR EVERY CHAR OF THE NAME :004010AF 0FBE4415C0 movsx eax, byte ptr [ebp+edx-40] ;; LOADS i. CHAR :004010B4 03F0 add esi, eax ;; SUMS UP ALL CHARS IN ESI :004010B6 8D7DC0 lea edi, dword ptr [ebp-40] ;; THE FOLLWING LINES :004010B9 83C9FF or ecx, FFFFFFFF ;; GET THE LENGTH OF :004010BC 33C0 xor eax, eax ;; THE NAME AND LOOK :004010BE 42 inc edx ;; IF THERE ARE STILL :004010BF F2 repnz ;; CHARS TO GO :004010C0 AE scasb :004010C1 F7D1 not ecx :004010C3 49 dec ecx :004010C4 3BD1 cmp edx, ecx ;; CHARS TO GO? :004010C6 76E7 jbe 004010AF ;; IF SO, THEN JUMP :004010C8 897508 mov dword ptr [ebp+08], esi ;; SAVE ESI IN EBP+08 :004010CB C1650807 shl dword ptr [ebp+08], 07 ;; SHL EBP+08 WITH 7 :004010CF 8D4DF4 lea ecx, dword ptr [ebp-0C] :004010D2 6A0A push 0000000A :004010D4 51 push ecx :004010D5 68E9030000 push 000003E9 :004010DA 53 push ebx * Reference To: USER32.GetDlgItemTextA, Ord:0104h | :004010DB FF15A0404000 Call dword ptr [004040A0] ;; GETS SERIAL :004010E1 85C0 test eax, eax ;; IS SERIAL NOT 0? :004010E3 5F pop edi :004010E4 751C jne 00401102 ;; IF SO, THEN JUMP :004010E6 50 push eax * Possible StringData Ref from Data Obj ->"No serial!" ;; THE FOLLOWING LINES | ;; DISPLAY THE "NO SERIAL" :004010E7 6880504000 push 00405080 ;; MESSAGEBOX * Possible StringData Ref from Data Obj ->"No serial number entered!" | :004010EC 6864504000 push 00405064 :004010F1 53 push ebx * Reference To: USER32.MessageBoxA, Ord:01BEh | :004010F2 FF1598404000 Call dword ptr [00404098] :004010F8 5E pop esi :004010F9 33C0 xor eax, eax :004010FB 5B pop ebx :004010FC 8BE5 mov esp, ebp :004010FE 5D pop ebp :004010FF C21000 ret 0010 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004010E4(C) | :00401102 8D55F4 lea edx, dword ptr [ebp-0C] :00401105 52 push edx :00401106 E840010000 call 0040124B :0040110B 8B4D08 mov ecx, dword ptr [ebp+08] ;; ECX = (SUM OF CHARS) SHL 7 :0040110E 83C404 add esp, 00000004 :00401111 03CE add ecx, esi ;; ADD SUM OF CHARS :00401113 3BC8 cmp ecx, eax ;; YOU KNOW WHAT HAPPENS HERE :00401115 6A00 push 00000000 :00401117 751B jne 00401134 The loop from :004010AF to :004010C6 sums up all ASCII values of the characters of the name and stores it in ESI. Then it is saved in EBP+08 (:004010C8). This value is "shifted logically left" by 7 bits. An example: 010010101001 will be (after is is shifted to the left by 7) 010010000000 (just move every bit to the left seven times and fill the left side with 0) To make it short: "shl eax, 7" means multiply eax with 2^7. In :0040110B ecx, gets this value and in :00401111 the sum of the chars, which was stored in esi all the way down, gets added to the "shl, 7-value" again. You find the source for a keygen (in MASM) inside the zipfile. III. BTW Greets to: Errm, scary task, this time. So many ppl I want to greet here. Well, I greet everyone in #cracking4newbies and especially [INSERTYOURNAMEHERE]. (I hope everyone is satisfied, as I don't forget anyone in this way ;).