[ 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              
:004012C783F801cmpeax,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:4021501F 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 :  phrozen_q@cyberdude.com
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
