Site hosted by Angelfire.com: Build your free website today!
Back to index
                                             The Newbie Tracing Guide

This guide is intended to help peole who might have tried some cracking, and might even have fished a serial or two
but in reality have no idea what they are doing, it is also intended for thoose who are taking their first wobbly steps
into the world of cracking.

For this tutorial you need the tracing.zip which is downloadable right here.


                                                         The TraceMe1.exe

Now, load the symbol (traceme1.nms) with the softice symbol loader. before you run the traceme1.exe there is an 
important step you must take, go into softice and type i3here on and hit enter. You have to do this for this program
because it has an instruction on its entrypoint (more on entrypoints later) that makes softice break automatically
when you run it. But if you havent set i3here on in softice the program wont run at all, just crash.
 
When you load debug symbols into loader32 you have to load them twice, forst once from the file menu, and then again
from the module menu.
When you now run the program you will have comments inside softice, i know that anyone who is used to tracng code
and cracking would probably feel a bit sick seeing it look like that, but since youre new to this it wont matter much how 
it looks. 

Now run the program and trace with the F10 key.

Ok what do we see, well first there is a PUSH 0, this is what is called a parameter, almost always when a function inside
windows is beeing called you have to supply it with one or a few parameters. This first PUSH 0 tells the windows function
MessageBoxA to create a box with 1 OK button.
The second parameter is  PUSH 402014, this is a needed for the messagebox to know what text it should print in the
caption of the MessageBoxA, 402014 is an address in memory or an offset if you will (address=offset and vice versa)
The third PUSH 402000 is for the text inside the box, the text is of course at address 402000.
Last PUSH 0 tells us which other process owns the messagebox, this is very unimportant to us at the moment, but 
we can see that this parameter is 0 and that means that it has no owner and is a standalone messagbox. 

Next up is the CALL MessageBoxA, this is where the program hands over control to windows itself, it leaves us to go
do its thing so to speak. the MessageBoxA procedure will now take theese parameters and use them to create a
messagebox just like we asked it to do.

As soon as you step over the CALL MessageBoxA you will exit from softice and see the box on your screen and when 
you hit OK you will return into softice.

When we return we face another API call (API stands for Application Programming Interface, more on that later)
called ExitProcess, this also takes a parameter, but only one :)
In this case it is PUSH 1 which tells exitprocess to indeed exit the process.

What about API then... well the windows API is a set (quite large set) of readymade functions that are made available
to windows programmers by through a few .dll files. most notable in cracking are probably User32.dll and Kernel32.dll.
Simply put we can say that User32 makes the windows, dialogboxes and messageboxes, and kernel32 moves memory
back and forth and handles other .dll files or as we will call them from now on "Librarys" because that is what they are.
The abbreviation .dll stands for "dynamik link library" and this is how it works.
Each .dll has a set of functions that it exports (makes available) for .exe executable files. The functions arent available
all the time, only when they have been imported by the .exe that wants to use them.
So to sum it up we can say that a .dll exports functions, and an .exe imports them.

                                           


                                              The TraceMe2.exe

Now we move on, open your symbol loader again, and this time select "symbol tables" from the edit menu, now
remove teh old symbol table for traceme1.exe.
After this is done we load the symbols for traceme2.exe, im only explaining this because some people have trouble
using the loader.

After the are loaded be sure to have your i3here on so that the program dont crash. This time is going to more crack
related, we are going to pretend that we are in a serial scheme, and we are gonna trace it and reverse it, in fact
we are gonna crack it in several ways.
When you trace it you may find it confusing to use the debug symbols, if you do you can jsut unload them, but if you
are new you might benifit from having them loaded on the first run. I will not them when i paste code snippets in here
because i will comment them anyway.
To make this useful you must pretend that we have just entered the hexadecimal value 55 in an edit box and pressed
a register button, the program must now store our serial and that is how the program starts:


00401017  B855000000          MOV       EAX,00000055    <--mov 55h into the general purpose register EAX    
0040101C  A340204000          MOV       [00402040],EAX   <-we move the content of EAX into a memory location              
00401021  33C0                    XOR       EAX,EAX              <- xoring eax with itself results in eax being cleared   
00401023  E84A000000          CALL      00401072 <-we call a subroutine, read below to find out what it does

Now the program have stored our serial and can retrieve it whenever it wants from the memory location 402040.
It has to do this to free up EAX so that it can be used for other things. when we enter this call EAX = 00000000
Now lets see waht happens in here.

00401072  B840204000           MOV       EAX,00402040      <-the address at which our serial is stored is moved into EAX
                                                                                  <-not the serial but only the address at which it is
                                                                                  <-we can say that EAX now points to the serial
00401077  C10003                  ROL       DWORD PTR [EAX],03    <-the serial is encrypted with a ROL instruction   
0040107A  8B18                     MOV       EBX,[EAX]                 <- we mov our now encrypted serial into EBX 
                                                                                        <- EBX also  general purpose regiser like EAX        
0040107C  891D44204000        MOV       [00402044],EBX        <-the encrypted serial is moved into a memory location             
00401082  C3                         RET                                <- we return to the main code


Ok what happened, well im hoping it was pretty clear, i guess the ony thing that might be confusing is the pointer 
thing, it works something like this:

If you mov something like this MOV [402040],EAX you move the content of EAX INTO the address 402040, the length
of the address you MOV into is determined by the size of the register you are moving from, EAX is a 32 bit register
so it can hold 32 bits or in other words 4 bytes. so therefor only 4 bytes will be written to 402040.
The address 402040 can contain anything but when you mov t it it becoems the numbers that were in EAX at the
time of the MOV.

If you on te other hand do MOV EAX,402044 you simply move the number 402044 into EAX, this can be used if you 
wanna make a EAX point to an address, look here, this is the same code as above but exaplined further:

00401072  B840204000           MOV       EAX,00402040      

We mov 402040 into EAX, EAX is now 402040


00401077  C10003                  ROL       DWORD PTR [EAX],03

See how we ROL the DWORD PTR [EAX] with the number 3 this means that the address that EAX is pointing to is going 
to be ROLed with 3, in this case EAX points to 402040, if we had done XOR EAX,EAX before the ROL instruction we 
would have ROLed the address 00000000 with 3 since eax would have been 00000000. 

In short when you have a [blahblah] it means what is inside the blahblah and if you just have blahbah it simply means
blahblah.

Ok lets get back to our main goal which is cracking this serial scheme. We have just returned from encrypting our serial
and are now about to compare it with the hardcoded already encrypted serial. 

00401083  8B1D48204000                 MOV       EBX,[00402048]  <-the hardcoded already encrypted serial is moved
                                                                                           <-into EBX                   
00401089  391D44204000                 CMP       [00402044],EBX   <-EBX is compared to our encrypted fake serial                  
0040108F  750A                               JNZ       0040109B             <-if theese dont match it jumps to the return              
00401091  C7054C20400001000000    MOV       DWORD PTR [0040204C],00000001  <-if they match 00000001 is
                                                                                                                    <- moved into the location 40204c
                                                                                                                    <-this is our "flag" and if flag is 1
                                                                                                                    <-it means that the serial is valid
0040109B  C3                                  RET                                 < we return to main code     


Ok this is pretty straightforward i think, i'll jsut explain the flag part, we use the "flag" so that we can at any time 
use the content of the flag to check if our program is actually registered or not, this way we wont have to check the
actual serial more than once, and instead just see if the registration flag is set to 1. This is also very vulnerable as 
probably understand.
Important note!! The registration flag i speak of is not at all the same as the Zero Flag!! 

Now we come to the last part, it should be very simple to understand:

00401031  33C0                       XOR       EAX,EAX     <-clear EAX                      
00401033  33DB                       XOR       EBX,EBX     <-clear EBX                      
00401035  833D4C20400001      CMP       DWORD PTR [0040204C],01  <-compare our flag to 00000001 please note
                                                                                                  <-how it compares the [40204c] which is the
                                                                                                  <-content of that address and NOT the address
                                                                                                  <-itself. this is very important.              
0040103C  741A                       JZ        00401058          <-jump is 0, this means that if the flag mathces the 01
                                                                               <-it will jump to the good messagebox                 
  

now it continues like this:

0040103E  6A00                   PUSH      00     <-if the flag was wrong we continue and get the NOT CRACKED message                     
00401040  6815204000         PUSH      00402015                           
00401045  6800204000         PUSH      00402000                           
0040104A  6A00                   PUSH      00                                 
0040104C  E869000000         CALL      USER32!MessageBoxA                 
00401051  6A01                   PUSH      01                                 <-we exit
00401053  E850000000         CALL      KERNEL32!ExitProcess               


00401058  6A00                   PUSH      00      <-if the flag was correct we jump here and get the CRACKED message                           
0040105A  6819204000         PUSH      00402019                           
0040105F  6821204000         PUSH      00402021                           
00401064  6A00                   PUSH      00                                 
00401066  E84F000000         CALL      USER32!MessageBoxA                 
0040106B  6A01                   PUSH      01                               <-we exit
0040106D  E836000000         CALL      KERNEL32!ExitProcess  

Ok, thats all for now, i hope you learned a little and if you dont understand some of this you really should go to my
links section and visit _mammons page and read his tutorial on assembly. It is almost garanteed to clear thigns up
you find them in his textbase section.
And if all this just felt stupid to you you should go visit my friend r!sc and read some of his tutorial, very nice and
one of the few people who really explains how things work.