About this tutorial:
Tutorial:Cracking Crudd Me 1.0 Target:Crudd Me 1.0(http://www.crackmes.cjb.net) Tools:SoftICE 3.24, W32Dasm 8.9x, HIEW 6.1x, Resource Hacker 2.2.0.1(these are good softwares, worth buying) Date:20th February 2000(Last updated on 27th March 2000) Descriptions&Comments:Well, well, well, here is another crackme which I love very much. The author is Crudd. This crackme is easy to crack but its protections are very similar to many commercial protections out there. Crudd ask for a tutorial covering 4 protections but I am doing 5 here since that is not too hard for me. Contains 5 different protections. Protections:Hardcoded, Self checking, Name/Serial, Patching, Disabled Disclaimer:This file is used for educational purposes only. Any misuse of the information presented here is not my responsibility. Copyright information:This tutorial is copyright © ManKind Starting words:
|
The process:
Introduction:
Well, what to say? This is another crackme which I enjoy cracking very
much, not too hard and not too easy.... Thanks Crudd! Now, let's attempt
on its protections one by one...
Part 1:HardCoded
Choose HardCoded from the menu and enter the following in the text
field:
23199981
Go into SoftICE, set a breakpoint on hmemcpy like below:
bpx hmemcpy
Leave SoftICE and press the Check It button and SoftICE will pop up. Press F11 once and F12 11 times and you will reach the following code:
:00441A8F MOV EAX,[EBP-08] <-- you land here
:00441A92 MOV EDX,[EBP-04]
When the white line of indicator land on address 00441A92, you can view the correct HardCoded serial in the data window by using the following command:
d eax
What do you see in the data window? I see the following:
1235666
Looks similar. That's the correct serial. I think the author choose this serial so that we will not suspect this as the real serial(when we see it in either SoftICE or W32Dasm) since it is similar to the default serial at the text field. By the way, this crack can be done using W32Dasm too.
Part two:Self Checking
As usual, choose the Self Checking protection from the menu and enter
any serial or use the default one(do not use 23199981 because 231 is the
correct serial and anything after that is not checked, you'll understand
by continue reading). This time I have to use W32Dasm to assist me to present
the listing to you because the codes are too much if I am to copy the code
directly from SoftICE. Select the Self Checking part from the menu, enter
241 as Serial, go into SoftICE and set a breakpoint on hmemcpy like below:
bpx hmemcpy
Leave SoftICE, press the Check It button, you will be in SoftICE, press F11 once to return to the caller, press F12 11 times and you will reach the following code which is where the protection lies:
:00441B79 8B45FC
mov eax, dword ptr [ebp-04] <-- move name to eax
:00441B7C 0FB600
movzx eax, byte ptr [eax] <-- get the first byte(character) of serial
to eax
:00441B7F 83E830
sub eax, 00000030 <-- subtract 30h(48 decimal) from eax
:00441B82 83F802
cmp eax, 00000002 <-- compare eax with 2
:00441B85 7C05
jl 00441B8C <-- jump to bad_cracker_message if eax is lower than 2
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:00441B21(C)
|
:00441B87 83F809
cmp eax, 00000009 <-- compare eax with 9
:00441B8A 7E1B
jle 00441BA7 <-- if eax is lower than or equal to 9, we will continue
with the check, else we get bad_cracker_message(in our condition, we will
jump)
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:00441B85(C)
|
:00441B8C 6A00
push 00000000
* Possible StringData Ref from Code Obj ->"Crudd
Me 1. 0"
|
:00441B8E 68341C4400
push 00441C34
* Possible StringData Ref from Code Obj ->"Sorry,
you suck"
|
:00441B93 68441C4400
push 00441C44
:00441B98 8BC3
mov eax, ebx
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:00441B2C(C)
|
:00441B9A E86567FEFF
call 00428304
:00441B9F 50
push eax
* Reference To: user32.MessageBoxA, Ord:0000h
|
:00441BA0 E82F4AFCFF
Call 004065D4
:00441BA5 EB69
jmp 00441C10
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:00441B8A(C)
|
:00441BA7 8B55FC
mov edx, dword ptr [ebp-04] <-- we will reach here
:00441BAA 0FB64402FF
movzx eax, byte ptr [edx+eax-01] get the byte at the specified location([edx+eax-01]),
which happens to be 4(second byte of serial) in our condition
:00441BAF 83E830
sub eax, 00000030 <-- subtract 30h(48 decimal) from eax
:00441BB2 85C0
test eax, eax
:00441BB4 7F05
jg 00441BBB <-- will jump if the Sign Flag is not set, we will jump
:00441BB6 83F809
cmp eax, 00000009
:00441BB9 7D0B
jge 00441BC6
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:00441BB4(C)
|
:00441BBB 8B55FC
mov edx, dword ptr [ebp-04] <-- move serial into edx
:00441BBE 0FB67402FF
movzx esi, byte ptr [edx+eax-01] <-- get the byte at the specified location([edx+eax-01])
to esi, edx+eax-01 happens to be the 4th location of our serial
:00441BC3 83EE30
sub esi, 00000030 <-- subtract 30h(48 decimal) from esi
* Referenced by a (U)nconditional or (C)onditional
Jump at Addresses:
|:00441B4F(C), :00441BB9(C)
|
:00441BC6 8B55FC
mov edx, dword ptr [ebp-04] <-- move serial into edx
:00441BC9 0FB65432FF
movzx edx, byte ptr [edx+esi-01] <-- get the FFFFFFD0th byte of serial
into edx
:00441BCE 8B4DFC
mov ecx, dword ptr [ebp-04] <-- move serial to ecx
:00441BD1 0FB64401FF
movzx eax, byte ptr [ecx+eax-01] <-- refer to 00441BBE
:00441BD6 03F0
add esi, eax <-- add eax to esi
:00441BD8 3BD6
cmp edx, esi <-- compare edx with esi
:00441BDA 751B
jne 00441BF7 <-- jump to bad_cracker_message if edx is not equal to
esi
:00441BDC 6A00
push 00000000
* Possible StringData Ref from Code Obj ->"Crudd
Me 1.0"
|
:00441BDE 68541C4400
push 00441C54
* Possible StringData Ref from Code Obj ->"Congrats...
Self-checking serial "
->"complete."
|
:00441BE3 68641C4400
push 00441C64
:00441BE8 8BC3
mov eax, ebx
:00441BEA E81567FEFF
call 00428304
:00441BEF 50
push eax
* Reference To: user32.MessageBoxA, Ord:0000h
|
:00441BF0 E8DF49FCFF
Call 004065D4
:00441BF5 EB19
jmp 00441C10
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:00441BDA(C)
|
:00441BF7 6A00
push 00000000
* Possible StringData Ref from Code Obj ->"Crudd
Me 1. 0"
|
:00441BF9 68341C4400
push 00441C34
* Possible StringData Ref from Code Obj ->"Sorry,
you kinda suck"
|
:00441BFE 68901C4400
push 00441C90
:00441C03 8BC3
mov eax, ebx
:00441C05 E8FA66FEFF
call 00428304
:00441C0A 50
push eax
* Reference To: user32.MessageBoxA, Ord:0000h
|
:00441C0B E8C449FCFF
Call 004065D4
Wow, lots of codes. Concentrate only on code that are in between 00441BBE
and 00441BDA. I'll explain what it does there:
1. get the 4th byte of serial into esi and subtract(minus) it by 30h=48
decimal
2. move name to edx
3. get the 4th byte of serial into edx
4. move serial to ecx
5. get the 4th byte of serial to eax
6. add eax to esi
7. compare edx with esi
8. jump to bad_cracker_message if not equal, else display good_cracker_message
How to conclude here? We have to find out a missing number(4th byte
of serial) that can make our serial(241) a valid one. After some calculation,
I found out that the *magic* number is 1, so our serial will be 2411 and
actually the third byte of our serial(1) can be any number because it is
not checked. Here's how I get the fourth byte:
1. 1 in hexadecimal value is 31h
2. when it is subtracted by 30h(48 decimal), its value is 1
3. by then, instructions at address 00441BC9 will get the 1st byte
of serial into edx(edx(1)+esi(1)-01=1st byte of serial) which is 2(32 in
hexadecimal)
4. eax which will hold 31h will then be added to esi which is holding
1h and that would equal to 32h
5. when edx(32h) is compared to esi(32h), they will generate the EQUAL
flag!
By the way, I really got shocked when I enter my 'usual fake serial' which is 23199981 and it appear to be a valid serial(231 is a valid serial, anything after that is not checked). What a coincidence...
And do contact me for further explanation if you can't understand this piece....
Part three:Name/Serial
As I have stated in my previous essays, I really can't explain to you
how I know which address location should I dump to view the real serial,
its just my feeling and trial-and-error. Now, choose Name/Serial from the
menu, and enter the following at the text fields:
Name:ManKind
Serial:23199981
Go into SoftICE, set a breakpoint on hmemcpy like above, leave SoftICE and press the Check It button. You are back in SoftICE. To go to the main calculation routine(or algo) press F5 once, F11 once, F12 11 times and you will see the following code:
:00441CDD MOV EAX,[EBP-08] <-- move name into
eax
:00441CE0 CALL 00403B48 <-- get length of
name and put it in eax
:00441CE5 MOV EDX,[EBP-08] <-- move name into
edx
:00441CE8 MOVZX ESI,BYTE PTR[EDX] <-- move
the ascii value of the first character of name into esi
:00441CEB MOV EDX,[EBP-08]
:00441CEE MOVZX EDX,BYTE PTR[EAX+EDX-01] <--
move the ascii value of the last character of name into edx
:00441CF3 IMUL ESI,EDX <-- move the value
of esi * edx into esi
:00441CF6 IMUL ESI,EAX <-- move value of esi
* eax to esi
:00441CF9 MOV EAX,[EBP-04] <-- move serial
to eax
:00441CFC CALL 00407A38
:00441D01 CMP ESI,EAX <-- compare the real
serial with the fake one
:00441D03 JNZ 0044D20 <-- jump to bad_cracker_message
if esi not equal to eax
If you want to view the correct serial, do the following command at address 00441D01:
? esi
At this moment, you can either move on to the other part or continue with this part if you are interested in keygenning. Interested ones, let me explain what the above codes do. First, it gets the name length into eax, first character to esi, last character to edx, multiple esi by edx, result which is stored in esi multiple by eax and store the result which is now the real serial into esi. Here is a keygen I coded in QBasic for Crudd Me 1.0 Name/Serial Keygen in about 5 minutes time.
CLS
DIM serial AS LONG PRINT ">>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<"
|
Part four:Patch me
Disassemble Crudd Me 1.0 with W32Dasm. Once disassembled, look for
"Nope. Try again." which is the message we get if we haven't crack the
patch me part and you should land at the following code:
* Possible StringData Ref from Code Obj ->"Sorry.
You suck"
|
:0044171D 6854174400
push 00441754
* Possible StringData Ref from Code Obj ->"Nope. Try again."
Scroll up a little to see if there is any jump that CAN jump to the good_cracker_message or else we will have to nop out the bad_cracker_ message. Here's a conditional jump which I located, just right above the above code:
:00441719 751B jne 00441736
If this jump is taken, we will be presented with a good_cracker_message else the bad_cracker_message will pop up. How can we make sure the jump will always be taken? Patch it! Yeah, correct answer. Get the offset of the conditional jump from the status bar of W32Dasm, load up HIEW and change its opcode like below:
Original:
751B
Change to:
EB1B <-- this make sure that the jump is always taken
Part five:Enable me
Surprise! We have reached the final part. This is easy. Fire up Resource
Hacker(a good and new resource editor) and open CruddMe.exe. Expand the
RCDATA folder, expand TFORM1 subfolder, highlight the 0 and you will see
the following text:
object EnableMe1: TMenuItem
Caption = '&Enable Me'
Enabled = False <-- pay attention to this
line
OnClick = EnableMe1Click
Here's the properties for the main window of the crackme. Pay attention to the line I mark. Compare the property of that menu item with the others. You will notice that the other menu item doesn't have that line which I mark. If you have programmed in Visual Basic before, you should understand what that line does, else you should too since its damn easy. You can now either change the False to True or remove that line altogether. When you have modified it, press Compile Script and save it back to the original exe file(File -> Save As). Run the crackme, the menu is enabled! Good job! By the way, just as an extra note and to introduce a new tool to you, eXeScope 5.11, another nice and new resource editor can be used to enable the crackme too but I choose Resource Hacker as the main tool because it is smaller in size and is freeware compared to eXeScope which is shareware.
I hope you like this essay. That's all for now. Hope to see you soon on my next tutorial. As usual, contact me if I make any mistake, give me your feedback, comments, suggestions and opinions about this tutorial and my way of presenting it.
Extra notes:
Gotta say I love this crackme very much.....Crudd and other programmers,
keep up your good work!
Ending:
Thanks and greetz to:
+ORC, +HCU, Sandman, HarvestR, tKC, ytc_, Punisher, Kwai_Lo, TORN@DO,
CrackZ, cLUSTER, LaZaRuS, mISTER fANATIC, yes123, WhizKiD, Volatility,
ACiD BuRN, Eternal Bliss, R!SC, Kwazy Webbit, +Mammon, MisterE, Shadow,
^tCM^, WaJ, Borna Janes, Kathras, AB4DS(Death), douby, Steinowitz, Lord Soth, Latigo, Lucifer48, NeuRaL_NoiSE, Fravia+, Latigo, Duelist, Alpine, flag eRRatum, Nitrus, +Frog's Print, Muad`Dib, Iczelion, Razzia, Warezpup, Bomber Monkey, llama and other crackers, individuals and organisations who have helped me, either directly or indirectly.
Service for Mankind
ManKind
mankind001@bigfoot.com