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.