[ Written By THE_q/PC ] [March 98]
WinIce Cracking tutorial - Cracking Cruehead's CrackMe v2.0
└───────────────────────────────────────────────────────────────┘
Introduction:
══════════════╝
When NuMega disigned Soft-Ice , they ment this debugger to help programers
fixing their software , debugging it and quickly find the error , when the
High-lenguage debugger didn't help . However , as it turned up , the debugger
has become an importent tool for the CrAcKeR .
This tutorial , mainly for new bees, will help you to work with the BEST
debugger in the world - WinICE.
Like the ladder for the painter , winice will help you disable,enable,study
or in other words - crack ANY protection out there .
What you Need:
═══════════════╝
-The program to crack : CrackME v2.0 - written by Cruehead/MiB
(it is propably attached to this text file,since it's a small windowz prog.)
-And geuss what ? WINICE !! :) Newest ver 3.22 .
Try http://cracking.home.ml.org -LordCaligo cracking site .
Or search in ftp search for file : siw95-32.zip
and si322p95.exe (on NuMega ftp site)
Geting WinICE started:
═══════════════════════╝
First , you need to edit winice.dat so winice will load all symbols and
common win95 dlls .
Open winice.dat , and go to End Of file , in the last section : Exported -
Symbols and delete all the semi-colloms .
It should look like this :
; ***** Examples of export symbols that can be included for Windows 95 *****
; Change the path to the appropriate drive and directory
EXP=c:\windows\system\kernel32.dll
EXP=c:\windows\system\user32.dll
EXP=c:\windows\system\gdi32.dll
EXP=c:\windows\system\comdlg32.dll
EXP=c:\windows\system\shell32.dll
EXP=c:\windows\system\advapi32.dll
EXP=c:\windows\system\shell232.dll
EXP=c:\windows\system\comctl32.dll
EXP=c:\windows\system\crtdll.dll
EXP=c:\windows\system\version.dll
EXP=c:\windows\system\netlib32.dll
EXP=c:\windows\system\msshrui.dll
EXP=c:\windows\system\msnet32.dll
EXP=c:\windows\system\mspwl32.dll
EXP=c:\windows\system\mpr.dll
In order for us to look at the same winice screen , go to the line INIT in
winice.dat (should be near the top) and change it to :
INIT="WR;WL;WD;CODE ON;X;"
Ok , Run windows with winice loaded , and press Ctrl-d to enter Winice.
A typical Winice Screen : ~~~~~~~~
┌───────────────────────────────────────────────────────────────────────────┐
│ -= Registers & Flags =- │
│ EAX=00000009 EBX=0063FA46 ECX=800A0698 EDX=8009F8E8 ESI=00008A6A │
│ EDI=0063F9FC EBP=0063F9F4 ESP=0063F9E8 EIP=004012C7 o d I S z a P c │
│ CS=0137 DS=013F SS=013F ES=013F FS=2257 GS=0000 │
│───═CRACKME2!DATA+0175════════════════════════════════════════════════──── │
│ -= Data Window =- │
│13F:40217E 41 42 43 44 56 31 32 33-34 00 00 00 00 00 00 00 abcDV1234.......│
│13F:40217E 00 00 00 00 54 72 79 20-74 6F 20 63 72 61 63 6B ....Try to crack│
├───═══════════════════════════════════════════════════════════════════──── │
│ -= Code Window =- │
│:004012BF FF7508 push [ebp+08] │
│:004012C2 E8D5010000 Call USER32!GetDlgItemTextA │
│:004012C7░83F801░░░░░░░░░░░░░░░░░░cmp░eax,░00000001░░░░░░░░░░░░░░░░░░░░░░░ │
│:004012CA C74510EB030000 mov [ebp+10], 000003EB │
│:004012D1 72CC jb 0040129F │
│:004012D3 B801000000 mov eax, 00000001 │
│:004012D8 EB07 jmp 004012E1 │
│:004012DA B800000000 mov eax, 00000000 │
│:004012DF EBA1 jmp 00401282 █ │
│:004012E1 50 push eax │
│:004012E2 FF7508 push [ebp+08] │
│:004012E5 E894010000 Call 0040147E │
│:004012EA B801000000 mov eax, 00000001 │
│:004012EF EB91 jmp 00401282 │
│ │
│───════════════════════════════CRACKME2!CODE+02C2═════════════════════──── │
│ -= User Window =- │
│:? 48692020 │
│48692020 1214849056 "Hi " │
│:ver │
│SoftICE 3.22 (Windows 95 / Windows 98 Beta 1-2) │
│Copyright (c) 1991-1998 NuMega Technologies ,Inc. All rights reserved. │
│:▄ │
└──────────────────────────────────────────────────────────────────crackme2─┘
Prologe
═════════╝
To crack a program u must first get to the protection code , study it a bit
and , well ,kill it .The Best and quickes way to locate the protection
procedure is using s-ice .
Sometimes u'll work throu the function that gets the Serial Entered ,
Sometimes throu the beep or 'Bad_Serial' error message, sometimes throu
the registery operations the program will do and sometimes using the dead
listing (w32dasm) to find the address of the protection .
There are many ways to locate the protection , and once located , 50% of the
job is done,as for the rest s-ice will help u crack the protection in notime.
One last thing , bare in mind that the coputer works in a LOgic way , so
use ur Comom sense.For example,there is no point in checking the date (to see
if it's expiered) if the user is already registered , so if u'll get to the
date check procedure , the register/unregister check should be near it.
Let's Rock
════════════╝
Run the program , goto Help/Enter_Password and enter "abcDV1234" as password,
hit the OK button , and see what happans if u enter a wrong pass.
As u see there's an error message+beep to help u figure out u just entered
the wrong password.We could get to the protection throu those notes the
program gives out when u enter a wrong password , but I chose to get there
throu the part that is responsable to get the password entered .
(It's like geting off the Bus 1 stop before ur destination , instead of 1 stop
after it .. Damm i wish i had a car ;)
By now u have seen me sayin' "get throu this.." 8 times ; what i meen ,and
this is where s-ice enters the picture, is BREAKPOINT on the function that
does the specific task of Geting the text from an edit box , or one of
Puting an error message , or get the current date ..
U see, the operating system and the program have a spacial relesionship,where
the OS will put the text on the screen , but the program will have to call
a certane function to get that text to it's own memory , where it can check
if the text is correct.
ok , nough said , lets crack ;)
Goto Help/Enter_Password , and enter 'abcDV1234' as password .Don't hit the
OK button just yet .
Enter S-ice (ctrl+D - btw, u can change it) and enter the following :
('>' is only an indicator )
>Bpx GetWindowTextA [Enter]
>Bpx GetDlgItemTextA [Enter]
(BPX = BreakPoint on eXecution)
┌──────────────────── Side Reference
│ SETTING BREAK POINTS
│ BPM, BPMB, BPMW, BPMD
│ - Breakpoint on memory access
│ BPR - Breakpoint on memory range
│ BPIO - Breakpoint on I/O port access
│ BPINT - Breakpoint on interrupt
│ BPX - Breakpoint on execution
│ BMSG - Breakpoint on Windows message
│ BSTAT - Breakpoint Statistics
│ CSIP - Set CS:EIP range qualifier
│ MANIPULATING BREAK POINTS
│ BPE - Edit breakpoint
│ BPT - Use breakpoint as a template
│ BL - List current breakpoints
│ BC - Clear breakpoint
│ BD - Disable breakpoint
│ BE - Enable breakpoint
│ BH - Breakpoint history
│ DISPLAY/CHANGE MEMORY
│ R - Display/change register contents
│ U - Un-assembles instructions
│ D, DB, DW, DD, DS, DL, DT
│ - Display memory
│ E, EB, EW, ED, ES, EL, ET
│ - Edit memory
│
└─────────────────────────────────────────────────────────
What u've just did is BreakPoint on the most common functions used to get
a text from an edit box . This will couse S-ice to "pop" whenever those
functions are called . When poped the computer will frease (in a good way:)
and u'll be able to see and change EVERYTHING . (now do u begin to see the
power of s-ice ? ;)
To view all the current BreakPoint enter :
>BL
(BL = Breakpoint List)
U should see this :
00) BPX USER32!GetWindowTextA
01) BPX USER32!GetDlgItemTextA
The numbers on the left are the BreakPoint number in the list .
Ok, leave s-ice and let the program continue (unawar of the danger;) . Do
this by either pressing F5 , or >G or >X ..
Ok, now press the OK button in the program ....and ... BOOm , s-ice poped !
At this point u r INSIDE the GetDlgItemTextA function .
HOw do u know it's GetDlgItemTextA and not GetWindowTextA?
well,s-ice says : 'Break due to BPX USER32!GetDlgItemTextA'.
And how do u know u r INDISE that function ?
For that look at the Line Between the Code Window , and the User Window ;It
says 'USER32!,text+0654' that meens that what is currently in the code window
is code from the file USER32.dll ( and not Crackme2.exe ).
U need to get out of this call , to get to the program code ,for that press
F12 (p ret) , that will tell s-ice to let the computer proceed (p) until
the RET command.
┌─────────────────────────────────────────── Side Reference ──
│The program is build procedures by procedures , where each procedure has it's
│own task to do in the general,big,continues run of the program.
│So when the GetDlgItemTextA procedure is called from the program , the
│location (the status of the big run) is saved , and the procedure is executed
│until a Ret command , which tell the procesor to RETurn to the calling part.
│It's prety much like in Music (take Bach's Fuges for example;) , u have to
│finish a certain melody before u enter a new one .. (DaVinci will back me up
│on this...i think :)
└───────────────────────────────────────────────────────────────────────
Ok,after presing F12 once ,the GetDlgItemTextA funcion is executed,
and s-ice pops in the calling part. u'll see in that line 'CRACKME2!CODE+02C2' which
tell us that we r now looking in the program code .(The figure of winice screen
--look above-- shows where u r now.)
Remember what the function does ? It takes the Text in the edit box, and copy
it to the Program memory , where the program is free to play,change and eat
the password entered .
So where is that location ?
This location (the Buffer for the text) is entered as paramter for the
GetDlgItemTextA funcion .
Normaly parameters are entered throu the stack like this :
.
.
push 00000011 ;Parameter #4
push 0040217E ;Parameter #3
push 000003E8 ;Parameter #2
push [ebp+08] ;Parameter #1
Call GetDlgItemTextA
In this Function the parameters are :
Parameter #1 // handle of dialog box
Parameter #2 // identifier of control
Parameter #3 // address of buffer for text <-The 1 we'r interested
Parameter #4 // maximum size of string
But u don't have to remember all this , just Check them all ! :)
it's only 4 parameter .
How to check ?
Since we r looking for an addres , the parameter for it is a pointer
for that Buffer ,So we'll have to View the memory at those locations ; in
S-ice enter :
>D DS:00000011
(D = Dump memory)
Check the Data window , do u see the password entered ? No, try the next
parameter :
>D DS:0040217E
See the Password entered ? Yes , well ofcource , the 3rd parameter is the
the address of the buffer . :)
Now what should we do ?
Now the program is free to do what it wants with the password,wether it's
a simple compare to the correct code (Don't u just love those?) , or
changing it and then a compare , or to check if the serial has the correct
properties of a valid serial (like Length, or if the sum of the password
bytes is equale to a constant) , or whatever the programer had in mind.
And we are here to study this , so Let's breakpoint on that memory address
, in this way when the program tougchs the password ,s-ice will pop.
Enter : >BPM DS:0040217E RW
(BPM = BreakPoint on Memory Access ; RW = Read/Write)
Before we continue , we should turn off the other BreakPoint We Made .
Do the following :
>BL
U'll Get : 00) BPX USER32!GetWindowTextA
01) BPX USER32!GetDlgItemTextA
02) BPMB #013F:0040217E RW DR3
>BC 0
(BC = Breakpoint Clear .. since we know GetDlgItemTextA is the function called
and not GetWindowTextA we'll clear it)
>BD 1
(BD = Breakpoint Disable .. GetDlgItemTextA will stay in the list , but it
will not be active)
>BL
U'll Get : 01) * BPX USER32!GetDlgItemTextA
02) BPMB #013F:0040217E RW DR3
And let it roll ..(F5 to continue)
NOw the program will continue , and s-ice pops at the place where the program
is operating on the password .
U should be at location CS:00401373
:00401371 8A06 ╓──>> mov al, byte ptr [esi]
:00401373 84C0 ║ test al, al
:00401375 7419 ║ je 00401390 ────────────┐
:00401377 FE0518214000 ║ inc byte ptr [00402118] │
:0040137D 3C41 ║ cmp al, 41 │
:0040137F 7204 ║ jb 00401385 ═╗ │
:00401381 3C5A ║ cmp al, 5A ║ │
:00401383 7303 ║ jnb 00401388 ║ ─════╕ │
:00401385 46 ║ inc esi <<═╝ │ │
:00401386 EBE9 ╟─── jmp 00401371 │ │
║ │ │
:00401388 E825000000 ║ call 004013B2 <<════════╛ │
:0040138D 46 ║ inc esi │
:0040138E EBE1 ╙─── jmp 00401371 │
│
│
:00401390 5E pop esi ─────────────────┘
:00401391 E803000000 call 00401399
S-ice pops one instrucion after the program access to the password,
so look at the instrucion at 00401371 : Mov al,Byte ptr [esi] .
Do >D ds:esi
see the password ? Ok , so the password is read byte by byte , and somthing
is done to it . Look in a lazy eye on the folowing instructions , like :
Cmp Al,41 .. Cmp AL,5A
What is going on ?? Why the values 41 and 5A ?
It's simple , Do
>? 41
00000041 00000065 "A"
>? 5A
0000005A 00000090 "Z"
Ahah,it checks for small letters , if AL (which is , as said, with a Char
from the password) is with a small letter , then a Call 004013B2 is executed.
In large protections , the best way to figure out calls is to look at it
like a Black Box , meening giving it Input , and check the Output , and try
to figure out what was doen (wether a Decimal Value -> hex , OR a value in
a register -> a printable value .. It will save time ; However if a complex
thing is doen , then it's time to trace into the call .)
In this case do the folloing :
>Bpx cs:401390
Why there ?
coz that is where the computer (processor) will be after the first operation
on the password.
How do we know that ?
See the
Test al,al
je 00401390
It will Jump when the value in al is zero (the end of the password,the null
byte)
Press F5 to continue, and s-ice will pop at Location 401390 ,after the first
operation . now check the Password :
>D DS:0040217E
See that it changed from 'abcDV1234' to 'ABCDV1234' ? The first operation
changes all small letters to capital .
Are We done ??
NoNO .. We'll be done when we know where the program 'understands' that u
have entered the wrong password, and this is not it ! (besides , u saw i
said FIRST operation,didn't u ? :)
Hopefully ur still with me , i'll continue .. ;)
Press F5 to continue and wait for s-ice to pop on the next operation to
our password .
[BoooM] , now we r in location 004013A5 :
:0040139B 33FF xor edi, edi
:0040139D 8A8FA3214000 ╒══>> mov cl, byte ptr [edi+004021A3]
:004013A3 8A1E │ mov bl, byte ptr [esi] ; ESI -> Password
:004013A5 84DB │ test bl, bl
:004013A7 7408 │ je 004013B1 ───────────┐
:004013A9 32D9 │ xor bl, cl │
:004013AB 881E │ mov byte ptr [esi], bl │
:004013AD 46 │ inc esi │
:004013AE 47 │ inc edi │
:004013AF EBEC ╘════ jmp 0040139D │
:004013B1 C3 ret ─────────────────┘
[ This operation is the main operation on the password , so we'll study it to
understand the protection ..]
Ok , we should take it slow , trace throu the code , and watch what's going
on . To trace press F8 , this will let the current instruction to be executed
and pause again in the next instuction.
┌────────────────────────────── Side reference
│ How to navigate in WinIce ?
│ To scroll thou the CODE window , keep CTRL pressed and move with
│ up/down arrows .
│
│ To scroll thou the DATA window , keep ALT pressed and move with
│ up/down arrows .
│
│ To scroll thou the USER window , keep SHIfT pressed and move with
│ up/down arrows .
│
└─────────────────────────────────────────────────────
Let's see where we are now (at location 4013A5) :
>d ds:esi will give us the password , so esi points to password.
Look at bl , it has the first char of the password.
EDI=1 and gets INCed in each loop , so edi = Loop index ,and also the
Password Index.
CL has a value from location [edi+004021A3] , that meens in each loop
CL gets a value from a constant table . To look at this Table do :
>D ds:004021A3
u'll get :
013F:004021A3 4D 65 73 73 69 6E 67 5F-69 6E 5F 62 79 74 65 73 Messing_in_bytes
013F:004021B3 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
Bl gets XORed with CL , and the Result is put back to the password location.
(xor bl, cl ; mov byte ptr [esi], bl )
Confused ? Welcome to the club ;)
to Sumerize, the english translation of this code_block will be :
A byte from password goes to bl , a value from a constant table (004021A3)
goes to cl , and they get XORed , the result is put back to the password
address [ds:esi] .
If translated to Pascal it will be something like this :
edi:=1;
while Pass[edi]<>#0 do
Begin
cl := Tab[edi];
bl := Pass[edi];
bl := bl Xor Cl;
Pass[edi] := bl;
Inc(edi);
End;
Password: 41 42 43 44 56 31 32 33 34 ABCDV1234
Xor
Table: 4D 65 73 73 69 6E 67 5F 69 Messing_i
------------------------------ -------------
Result: 0C 27 30 37 3F 5F 55 6C 5D .'07?_uL]
Ok , that was the second operation on the password , as u see the program
played 'scramble' with it ;)
Press F5 to continue.
Our next Stop is at location 4013C9.
Let's have a look :
:004013B8 33FF xor edi, edi
:004013BA 33C9 xor ecx, ecx
:004013BC B110 mov cl, 10
:004013BE 8B742404 mov esi, dword ptr [esp+04]
:004013C2 BF50214000 mov edi, 00402150
:004013C7 F3 repz cmpsb
:004013C9 C3 ret
What do we have here ? A 'rep cmpsb' !!
This instrucion is used to COMPARE the string at address DS:ESI with a string
at address ES:EDI .
This is where the program desides wether it's the correct password.
Do >D ds:esi to see ur password (after the 2nd operation)
and >D es:edi to see the string that should be after the second operation .
Now that we have done all this work , we'll do just a bit more to find out
the Correct password , the one to put in the registration window.
What we are looking is a password , that after the 2nd operation will give us
the following string :
>D es:edi
┌────────────────────────────────────────────────┐
013F:402150│1F 2C 37 36 3B 3D 28 19 3D 26 1A 31 2D 3B 37 3E │.,76;=(.=&.1-;7>
└────────────────────────────────────────────────┘
So we need to 'reverse' the 2nd operation .
As we've seen,in the 2nd op. basicly, the password is XORed with a constant
one .
the XOR instrucion is good for encryptions , why ? Becouse it is REVERSABLE .
REVERSABLE ??
┌──────────────────── Side Reference
│XOR Val1 , Val2
│
│Val2 = Val1 XOR Val2
│
│Xor is a logic operation between the 2 operands (val1 and val2) ,
│The logical operation is for the situation of :
│"If Smith goes to the Party , Than John Won't"
│So there are only 2 posible way : Eighter Only Smith will go , Or
│Only John will go , BUT they can't be there together , and they can't
│NOT be there together .
│Here's the true table for XOR :
│
│ Val1 │ Val2 │ Val1 XOR Val2
│ ──────┼──────┼─────────────────
│ 0 │ 0 │ 0
│ 0 │ 1 │ 1
│ 1 │ 0 │ 1
│ 1 │ 1 │ 0
│
│When we have 31 XOR 6E , there's a Bit_2_Bit Xor meening :
│
│ 31 00110001
│ XOR
│ 6E 01101110
│ ------ ----------
│ 5F 01011111
└───────────────────────────────────────────────────────
Yes, meening : if a XOR b = c
then a XOR c = b
AND
b XOR c = a
if u have the result (c) and one of the Opreands (a or b) then u get find
the second operand . (XOR is also good for more than 2 operands)
Example : 31 XOR 6E = 5F
5F XOR 31 = 6E
Like ADD is the reverse of SUB (and vis versa) ,OR Like Blur is The reverse
operation of sharpen (in PS filters;) , so is XOR the reverse of itself.
|
Meening : 14 - 0F = 5 | 24 XOR 73 = 57
|
5 + 0F = 14 | 57 XOR 73 = 24
|
To test it u can use s-ice too !
use the '?' command (which is a very powerful command .)
where '^' = XOR
'&' = AND
'|' = OR
'!' = NOT
>? 31 ^ 6E
0000005F
>? 5F ^ 31
0000006E
┌────────
│ >? esi ;to see the value in esi ..
│ >? al & 13 ;result of : Value_In_Al AND 13
└────────────────────────────────────
And guess what ? We have the result (the string at 00402150) , and we have
one of the operands (the constant string at 004021A3) , so all there left
to do is XOR them to find the 2nd operand , the correct string !
Result : 1F 2C 37 36 3B 3D 28 19 3D 26 1A 31 2D 3B 37 3E .,76;=(.=&.1-;7>
XOR
Table : 4D 65 73 73 69 6E 67 5F 69 6E 5F 62 79 74 65 73 Messing_in_bytes
------------------------------------------------ ----------------
Password: 52 49 44 45 52 53 4F 46 54 48 45 53 54 4F 52 4D RIDERSOFTHESTORM
That's it !! the password is : "RidersOfTheStorm" !!
Let's check it , disable all breakpoints (so s-ice won't pop) :
>BD *
Press F5 to continu .. goto Help/Enter Password and enter :
RidersOfTheStorm
(you can put it in small letters since it will be converted to capitals
in the 1st operant ;)
And BooM , we get a 'Great Work , Mate!' message :))
Apendix : Tips For WinIce
═════════════════════════════╝
Here are some functions that u should break point in s-ice when cracking
varius protections .
┌─────────────────────
│ Note : Case u get a 'symble not defined' message from s-ice , use the EXP
│ command (EXP = Display Export Symbols) , for example :
│
│ >EXP Message
│ USER
│ 1817:006E MESSAGEBOXINDIRECT 1817:0013 MESSAGEBOXEX
│ 1817:0000 MESSAGEBOX 1817:1E6A MESSAGEBEEP
│ USER32
│ 0137:BFC023C1 MessageBeep
│ 0137:BFC038D9 MessageBoxA
│ 0137:BFC02BEC MessageBoxExA
│ 0137:BFC038F3 MessageBoxExW
│ 0137:BFC03D71 MessageBoxIndirectA
│ 0137:BFC01014 MessageBoxIndirectW
│ 0137:BFC039A4 MessageBoxW
│
│ Hey look at that , there's a MessageBoxIndirectA symble ;)
└────────────────────────────────────────────────────────
Reading/Writing files :
-----------------------
ReadFile
WriteFile
CreateFileA
SetFilePointer
Reading date from INI file :
----------------------------
(The 'A' at the end is for 32 bit program ... don't worry about it , most
of the programs are 32 bit, and if they're not , use the same function name
without the 'A' .. Or use EXP command ;)
GetPrivateProfileStringA
GetPrivateProfileIntA
WritePrivateProfileStringA
WritePrivateProfileIntA
Registery Access :
------------------
RegCreateKeyA
RegDeleteKeyA
RegQueryValueA
RegCloseKeyA
RegOpenKeyA
DialogBoxes :
-------------
GetWindowTextA
GetDlgItemTextA
GetDlgItemInt
MessageBoxes :
---------------
MessageBox
MessageBoxA
MessageBoxExA
MessageBeep
Time And Date :
---------------
GetLocalTime
GetSystemTime
GetFileTime
Creating a window (like a Nag) :
--------------------------------
CreateWindowExA
ShowWindow
CD-Rom :
--------
GetDriveTypeA
GetLogicalDrivesA
GetLogicalDriveStringsA
HelpFul in hunting serials in VB program : HMEMCPY
* For more info check the win32 programmer reference help file .
Last Words
════════════╝
Cracking is a skill only time and practice will make better , and most
importent NEVER say NEVER . :)
I really hope u enjoyed this tut , as i did writing it .
Feel Free to ask me anything u want .
E-mail : [email protected]
IcQ : 8175894
GreetZ
════════╝
DaVinci , This tut is For ya mate! :)
EveryOne in PC .. UR the BEST ! :)
And all my freinds in Israel who keep asking me "How do u do it??" and i keep
answering "This is kinda magic ;)"
L8r !
-THE_q