http://www.mesa-sys.com/~eternal/mexcrk1.zip - (116k).
Welcome once again to a new section. Just a word to the confused amongst you, essentially a CrackMe is a program written for the express purpose of reversing. CrackMe's vary in difficulty a great deal but if you have the time you should study them and adapt your reversing techniques to beat them. I'll start by just examining this example from MEXELiTE, its a very simple scheme best accomplished using SoftICE (using the disassembler will teach you very little). So launch the program, here's the screen you should be looking at:
So lets enter a fake number in the top dialog, you'll find a >bpx Hmemcpy works well in SoftICE, now just start tracing to this code, (use either F10 or F12), once again watch the pattern, user into kernel32 then into our program with some stack heavy code until we reach this:
:0042D534 MOV EAX,[EBP-04] <-- EAX holds code entered.
:0042D537 MOV EDX,0042D590 <-- EDX holds string Benadryl.
:0042D53C CALL 004038D0 <-- Compare.
:0042D541 JZ 0042D555 <-- Jump_good_code.
In code terms there's little to learn here, and under the inspection of W32Dasm you would have found this code very easily. However, this simple CrackMe uses code which you will see a lot of in many shareware programs.
http://www.mesa-sys.com/~eternal/mexcrk4.zip - (118k).
Welcome once again to another CrackMe by nIabI and hence another tutorial, No. 4 in terms of code complexity is considerably more challenging than No. 1, although I would suggest to true reversers that there are 2 possible solutions:
i) Locate the value of the good code (easy).
ii) Reverse engineer the maths behind the scheme (harder).
I'll start with the first approach, you'll find that you have to set a >bpx Hmemcpy if you want the program to break. After allowing the necessary returns you should start pressing F12. If you take a look at the disassembly listing you'll easily find the deciding code shown below:
:0042DCBC CMP EAX,[0042F760] <-- Compare EAX (good
code) with code entered.
:0042DCC2 JNZ 0042DCDB <-- Jump_away_bad_code.
So without examining any of the many function calls along the way, you can live step with F10 inside SoftICE to the above code and find out what the good code should have been (this of course assumes you pass the name length check for at least 6). At the CMP instruction you can use the registers window to view the code entered, in my case I see DS:0042F760=00BC614E, so just ? 00BC614E to see your code. Obviously a ? EAX will reveal the good code because the zero flag has to be set.
The key generator is obviously going to be more challenging, below you'll find some snippets of the main protection code routine (of course fully commented), but as you would expect its very long and maybe not worth investigating completely.
:0042DB6E MOV EAX,[EBP-04] <-- Name entered.
:0042DB71 CALL 004037C0 <-- Check name for 0 and return name length in EAX.
:0042DB76 CMP EAX,06 <-- Name_length_check.
:0042DB79 JGE 0042DB95 <-- Good_guy_jump_(name_was_6_or_more).
:0042DB9E CALL 0041A228 <-- Gets length of code entered.
:0042DBA3 CMP DWORD PTR [EBP-04],00 <-- Check for code presence.
:0042DBA7 JNZ 0042DBC3 <-- Jump_code_entered.
:0042DBDE MOV EAX,[EBP-04] <-- Name.
:0042DBE1 MOV EDX,[ESI] <-- 2nd letter of name.
:0042DBE3 MOVZX EAX, BYTE PTR [EAX+EDX-01] <-- EAX holds 2nd letter value.
:0042DBE8 LEA EDX,[EBP-08]
:0042DBEB CALL 00406578 <-- Get_value_of_name_letter.
:0042DBF0 MOV EDX,[EBP-08] <-- Store_value_here.
:0042DBF3 MOV EAX,EDI
:0042DBF5 CALL 004037C8
:0042DBFA INC DWORD PTR [ESI] <-- Increment loop count.
:0042DBFC CMP DWORD PTR [ESI], 00000007 <-- Compare loop count variable.
:0042DBFF JNZ 0042DBD0 <-- Loop (name-1 times).
:0042DC01 LEA EAX,[EBP-08]
:0042DC04 PUSH EAX
:0042DC05 MOV ECX,00000003
:0042DC0A MOV EDX,00000001 <-- Simpler instructions.
:0042DC0F MOV EAX,[EDI] <-- Value generated from loop.
Well, I'm going to stop here, note that I used the name CrackZ, at 0042DC0F you'll find what looks like some sort of code, for me its 114979910790, but an examination of the functions called during the loop would alert you to how this value was created.
114 = r
97 = a <-- a = 61 hex = 97 dec.
99 = c
107 = k
90 = Z <-- Z = 5A hex = 90 dec.
So lets continue and find out whether the program uses this value at all and if so what manipulations are performed.
:0042DC11 CALL 004039C4 <-- Check length of value
:0042DC16 MOV EAX,[EBP-08]
:0042DC2C CALL 0042D8E4 <-- This function call is very interesting.
:0042DC31 MOV EAX,[0042F750] <-- EAX holds real value generated by previous function call.
Well I've stopped again, 0042D8E4 is a fairly complex function, its easy to understand on a line by line basis so trace it, interestingly it uses only the 2nd letter in your name to generate yet another number. I warn you that this function is not for the faint hearted, theres some simple addition and multiplication at the start but later on expect some shirling and xoring.
:0042DC3D CALL 0042D934 <-- More maths.
The code continues in the same vein calling more functions most of which perform operations on values obtained from the 2nd letter, there will also be a check that the serial # digits are between 30-39h (0-9). The next call (0042D934) is another maths extravaganza, just make sure you understand each of these operations like SAR (shift arithmetic right), there's also more xoring (10 & 25) as well as some integer division with IDIV. I'm not going to continue explaining here, the rest of the function calls should all be fairly routine, its only maths, I'll be perfectly honest with my readers and say that I couldn't see a great deal to learn from working out these functions once you understand these key operations.
Well, nIabI's CrackMe is certainly strong in maths, perhaps a little bit too tedious in that respect, it does perform some fairly nice tricks, plenty of shirling, xoring, (no junking but I'd guess thats difficult in Delphi). However, yet again the actual 'guts' of the protection is still very weak CMP, JNZ.....and its easily beaten. A key generator, well maybe one day when I'm not busy I'll invest the time writing one.
This CrackMe is useful for newer reversers who don't understand many of the arithmetic/shifting operations e.g. SHL, SAR, XOR, ADD, IDIV. Practically, well I've never seen a commercial protection with so much maths, in fact I'd suggest maybe nIabI wen't purely for the wide desert approach, i.e. use so much maths that no-one bothers writing a key generator.
I guess it sounds as if I'm criticising the CrackMe for being so long, but in reality this is a pleasing CrackMe with something for reversers new and old alike.