Monday, October 22, 2007

how to make a crack with pictures tootal 9 tution


All the tools you will need can be found online:
Let us first get set up and ready to crack. I like to open the folder with my target in it. In this case c:\program files\worldtv\ and make a quick backup that we can work on without fear of screwing up the file. I named mine worldtv2.exe and I will refer to it as such through the tutorial.

It has become habit to first examine a target with PEiD to determine the packer or protector. Open up PEiD and drag worldtv2.exe into it. The result: "Microsoft Visual C++ 5.0". Surprisingly, the target is not packed or protected. That will make it all the easier to crack.

find your newly patched WorldTV2.exe and run it.

It asks for a serial; give it any one you want, I will use 1234567. Press Validate Registration and... Success! Registration Code Accepted. Are we done? No.

Close WorldTV2.exe and open it back up again. It is still asking for a serial. Now, we could just put in a serial every time we use it but that is annoying. Instead, we are going to find a real serial.

Finding a Serial:
To begin, review what we know about the program so far:
1. It checks for a serial when starting up
2. After registering with a bogus serial it is unregistered the next time you start it up
This means that before the program even completely loads it is checking for the existence of a good serial. We need to find out where that serial is being stored. There are usually two places a serial is stored; the registry and in a file. We are going to start with checking the registry. Start up WorldTV2.exe and put in 1234567 as the serial. Validate the serial and then close WorldTV.

Go to your Start menu and find the Run command. A box will open asking you to "Type the name of a program, folder, etc...". Type in "regedit", without the quotes, and press enter. You will now be in the regedit window and see a two pane window with a list of folders in the left pane. Click on the plus sign in front of HKEY_CURRENT_USER. It will open, you now have another list of folders. Click the plus sign in front of Software. Scroll down until you find WorldTV and click on the folder. Aha! In the right pane we have a key called RegCode with our bogus key: 1234567 stored in it. We now know that WorldTV checks the registry for a serial before loading.

We are going to start by opening Ollydbg. I am using version 1.09d because I found 1.10 will sometimes crash when setting a breakpoint. Using Ollydbg, open the original WorldTV.exe.

You should see something similar to the image above. Before pressing the Run key we want to set some breakpoints first. Right-click in the Code window of Olly and choose Search For, select All Intermodular Calls. This will bring up the Calls window. Sort the calls by Destination. Scroll down until you find RegQueryValueExA. Select it and Right-Click; set a breakpoint on every call to RegQueryValueExA

Now press the Run button . You will first break at FF15 0C304400 CALL DWORD PTR DS:[<&ADVAPI32.RegQueryValueExA>]. If you look at the Register's window on the right side of Olly, you will see EDI is holding the ASCII value "Recordings". This is not the registry key we are looking for so press Run again. We break again on the Recordings registry key so press Run again. We will have to press Run 24 more times before we break here:

Notice the Value of EAX is ASCII "RegCode". Press Run once more and we are now here:

And ECX now holds the ASCII value "RegCode". We know we are getting close because WorldTV just looked for the registration code. We are now going to step through the code and pay attention to the Registers. After a few steps we find that ESI is holding our bogus serial 1234567 and EDI is holding 00000000-00000000-00000000-00000000. This is interesting, however I doubt that a bunch of zeros is the registration code. Stepping through some more, we see that EDI is shortened to -00000000-00000000-00000000. This still does not give us the serial. Continue to step through past where EDI is replaced by "C:\Program Files\WorldTV\Scheduler.txt.tmp". You will find soon after that point that you come to here:

Notice that EAX, EBX, and EDX were all zeroed out. Also we see an ASCII value moved into EDI. It is here we are going to start seeing our serial come together. After a little more stepping through we find that we are in a loop. We can see that a serial is being made and can be seen at this address: MOV EDI,WorldTV.004C8950. Rather than stepping through the code line by line we are going to set a breakpoint on MOV EDI,WorldTV.004C8950 and watch our serial come together. Select the line and press F2 to set a breakpoint. Now press the Run button a few times and we can watch our serial build itself.

Paying attention to EDI earlier we know that our serial is either 4 sets of 8 characters or 3 sets of eight characters. As you get near 3 full sets slow down or you will miss the serial. When you only have 2 characters left to go stop pressing the Run button and just step through the code. When you step past the following line REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] you will see the last two characters of your serial added on.

Go ahead and write this number down. Press Run again to see if there is another set of characters to be added. Nope. Pressing Run again will start you through another loop where a separate serial is calculated (for what? I am not sure because it would not register the program).

Go ahead and close Ollydbg. Open up the original WorldTV.exe and try registering with the serial we wrote down. Registration Code Accpeted, we have succesfully registered WorldTV with a real serial. No patching invloved!

tution 2

All the tools you will need can be found online:

Let us first get set up and ready to crack. I like to open the folder with my target in it. In this case c:\program files\@stake\ and make a quick backup that we can work on without fear of screwing up the file. I named mine lc52.exe and I will refer to it as such through the tutorial.

We will begin again by opening LC52.exe in PEID to see if it is packed or protected. The result: Microsoft Visual C++ 7.0. Good, we will not have to worry about unpacking this file before reversing it.

Note: I used three seperate computers to create this tutorial. This is why my serial changes halway through. It is also why my Addresses in Olly change. If your Addresses in Olly do not match mine, it is not a problem. The code will be the same.


Knowing that we will not need to unpack the executable lets us do a little examination of the protection scheme. Open up LC52.exe. It goes directly into the nag screen. From the previous tutorial we know that it is checking for a registration key. Press Register and we are presented with a new window holding a unique serial number and a box asking for our unlock code. Enter anything in as the unlock code and press Okay. We get a message box saying "You have entered an invalid code. Please try again.". Remeber to write this message down as we will be searching for it later. Press Okay and the program returns to the window asking for our unlock code.

Searching For A Serial:
Rather than try and patch the registration of this target, we are going to try and find a valid serial number. Close LC52.exe and open Ollydbg. In Olly, go to File, and open LC52.exe. It will take a second as Olly analyzes the code. We are going to start by looking for the string from the error message we recieved. To do this, right click on the code window and go to Search For, select All Referenced Text Strings.

A new window will open up with all the referenced strings in the executable. Scroll to the top of the page and select the first string. Right click and choose Search For Text. In the dialog box enter "you have entered" without the quotes. Make sure Case Sensitive in unchecked. You should end up here.

Double click the selected line and you will be taken to this code in the program:

Scroll up a little and we can see that there are three different versions of the program you can register as. Basic, Professional, and Administrator. We see that there is a TEST EAX, EAX before each registration confirmation. The program first tests if you entered the Basic unlock code, then if you entered the Professional unlock code and, finally if you entered the Administrator code. We are going to try and register the Administrator version. Scroll back down until your Screen matches what is shown above. If we look closely we can see where the test is made to call the messagebox. 0041082A . 85C0 TEST EAX,EAX followed by a push and then a Jump if Not Zero, JNZ 4108B2. 004108B2 is where our invalid message is created. Let's find out what is going on when the test is made. Select 0041082A . 85C0 TEST EAX,EAX and press F2. This will set a breakpoint on the test.

Press the Run button. The LC5 nag screen pops up, press the Register button. In the window asking for our unlock code enter any serial. Let's try 1234567890. Press Okay. Olly breaks on our TEST EAX, EAX. First thing you notice is the registers on the right hand side. There are a string of numbers and letters in ECX and EDX that look suspiciously like an unlock code.

Was it that easy? Well, try them and find out. Open the original LC5.exe and use the numbers to try and register. This is new, a license agreement opens up. After pressing Okay on the License Agreement, we are presented with the message that we have successfully registered the Administrator version of LC5.

It was that easy!
So, are we done?

Before we continue, return the program to the state of unregistered. Go the the START MENU in Windows and select the RUN command. Type in REGEDIT and press Okay. In REGEDIT's left window, click on the [+] in front of HKEY_CURRENT_USER. Then click on the [+] in front of SOFTWARE. Click on the [+] in front of @STAKE and then the [+] in front of LC5. Select the Registration folder. In the right hand window you will see Unlock Code. Double click it, and erase the Value Data in the new window. Press Okay and close REGEDIT.

Creating An Internal Keygen:
Because the unlock code for this program is computed based on the unique serial of our computer, anyone who wants to register would have to find the unlock code for themselves. We are going to solve that problem by using the program as a personal keygen. This is not often considered good reversing because you do not understand how the key is generated. However, as a beginner it can be an valuable learning experience.

Before we begin let's evaluate what we need to do to create an internal keygen.
1. We need to find where the unlock code is created and stored in memory
2. We need to find someway to display the unlock code to the user
3. We need to let the user know that they are seeing the unlock code

We already know where to find the unlock code so we need to solve how to display the code. A good idea would be, rather than displaying an error message, we display the unlock code. Let's reexamine the code where we see the test and where we see the "You have entered an invalid..." string pushed for the message box.

What we want to do is edit the code. Instead of pushing the error message onto the stack we can push our unlock code. There are a few things to consider when editing code. We need to make sure that what we change is not vital to the program's function. We are also restrained by how many bytes we can use to write new code. We can only overwrite current code. We cannot add our own. (There are ways to add your own code but it is more advanced than this tutorial, search for "code caves" if interested ) The other thing we need to consider is the stack. The stack is a designated part of memory where you can save values and instructions to. The stack is true to it's name, values are stacked onto it as you would stack boxes. The first one on is at the bottom and the last one is on the top. Instructions are then removed from the stack in the order of top to bottom. Last one on is the first one off.

You can view the stack in Ollydbg at the bottom right of the window. When modifying code we must make sure that nothing extra gets added or removed from the stack. Otherwise our program will cease to function.

Now that we know what we need to consider, let's move onto how to implement the unlock code into the messagebox. We know where the error message is pushed onto the stack so let's start by changing the code to push our code instead. We can see our code in both the ECX and EDX registers. However before we get to the PUSH, EAX is zeroed out and our code is overwritten in memory. So let's address that issue first. We only need our code in one register so we can keep XOR EAX, EAX. To stop our code from being overwritten we need to change MOV DWORD PTR SS:[ESP+14],ECX, MOV DWORD PTR SS:[ESP+1C],ECX and, MOV BYTE PTR SS:[ESP+24],CL. Select the first one with your mouse and right click. Choose Assemble from the menu. This will bring up a box where you can edit the code.
We want to remove this code alltogether, so in the box type NOP and make sure that the Fill With NOP's is selected. NOP stands for No Operation and is written in hex as 90. When the program runs it will just pass over these bytes. Press the Assemble button and your code is edited with NOP's. Do the same for the other two lines that overwrite our unlock code. It should end up looking like this:

Okay, we have now succesfully stopped our code from being overwritten. Press RUN and make sure that the program still works. Excellent, we still see our error message box pop up. Press Okay on the error box, and Okay on the Registration box so we will return to our breakpoint in Olly. At our breakpoint, begin pressing the Step Over button . Keep a watch on the registers where our serial is stored. As we get to the PUSH EBX, we see that our serial is still in register EDX. Keep stepping until you get to the NOP just above the PUSH lc5.004D62D4.

We are now going to make our messsage box display the unlock code. Select PUSH lc5.004D62D4 and select Assemble. When the box comes up, enter PUSH EDX and press Assemble. Now press the Run button and...

It works! We are now halfway finished. Before we continue we want to make sure we save our changes to a file. Return to the breakpoint in Olly and right click anywhere in the code section. Select Copy to Executable, and then All Modifications. A box pops up asking us if we want to copy the selction, choose Copy All. A new window will open with the program in it and our changes included. Right click and select Save File. Save it as LC5Modified.exe. You can now close Olly, though we will use it again in a few seconds.

Modifying the Internal Keygen:
Because we made the keygen, we know that the messagebox is now displaying an unlock code. A normal person would not know what these letters and numbers represent. What we are going to do next is change the title of the window to inform the user that they are seeing the unlock code for the Administrator version.

A Quick Overview of the Messagebox Function:

The MessageBox function is an internal function in Windows. This means that a programmer can write a program and, instead of having to code his/her own message box, they can use the one included with Windows.
The MessageBox function is called like any other function. When it is used you must pass it variables called Arguments.
The Arguments for MessageBox are HWND hWnd: handle of owner window, LPCTSTR lpText: address of text in message box, LPCTSTR lpCaption: address of title of message box, and UINT uType: style of message box.
Knowing how a MessageBox is created gives us the knowledge of how to manipulate it. (For more information on internal functions of Windows research Win32 API). What we want to do is find where the program calls MessageBox and where the Arguments are passed.

Open your new LC5modified.exe up in Ollydbg. Right click in the code area and choose Search For, select All Intermodular Calls. A new window opens up with all the functions called by the program. We will sort these by Destination by clicking the Destination bar at the top. As you can see they are now in alphabetical order. Scroll down until you find MessageBoxA. Select one of the MessageBoxA lines and right click. Now select Set Breakpoint On Every Call To MessageBoxA:

Press the Run button to start the program. At the nag screen go through the registration process again. Remember to enter an invalid code. When you press Okay, to try and register with your code, you should break here:

If you take a look at the Stack you can see the Arguments that were PUSHed for this MessageBox. The first one pushed on is at the bottom of the stack. So the first Argument is Window Style, the second is Title, the third is the Text, and the last is the Owner Window.

Our objective is to let the user know that the code they are seeing is the Unlock Code. A good place to do so would be in the Title of the message box. Let's examine how we are going to change the Title.

We need to find a place in code to create our new text string. Because we cannot write new code we are going to have to overwrite old code. We then need to change the code for the MessageBox call to PUSH our string as the Title Argument. Let's begin by creating a new string.

Because we have already modified this program, we know of a string that is not being used: "You have entered an invalid code. Please try again". If we refer back to the original code of the serial test we can see this string being pushed onto the stack: PUSH lc5.004D63D4. We now know that the string is located at 004D63D4. We will change it later, let's first try and get the program to actually push this value in.

Looking at the code we see that this part of the code jumps to MessageBoxA.
74 05 | JE SHORT lc5modif.004BD576 : Jumps to GetModuleFileNameA
8B79 4C | MOV EDI,DWORD PTR DS:[ECX+4C] : Moves ECX+43 into EDI. EDI is where the Title is stored.
EB 1A | JMP SHORT lc5modif.004BD590 : Jumps to the MessageBoxA call

In the Arguments for MessageBoxA we see EDI is pushed as the Title. And the value for Title is moved into EDI just before the call to the MessageBox. We need to change the program to move our string into EDI rather than ECX+43. I am going to show you the very ugly, unaccepted, however it works, way to change the program.

Begin by selecting MOV EDI,DWORD PTR DS:[ECX+4C], select Assemble (or press spacebar), and in the box type MOV EDI, 4D63D4. Press Assemble. Do you see why this method is ugly and unaccepted? Because our code to move the string into EDI is longer than the original code, we have just overwritten our jump to MessageBox. "Well, just write it underneath". That would seem the logical option, but we will be destroying the function call to GetModuleFileNameA. Let's find out how many times GetModuleFileName is called before we do any overwriting. Select the first line of the function: 68 04010000 PUSH 104. At the bottom of the code window we see: Jump from 004BD56F. There is only one jump to this function and it is directly above our jump to MessageBoxA. Set a breakpoint on JE SHORT lc5modif.005BD576 and press Run. Go through the registration process and when we reach our breakpoint (do not step past it or the program will quit) we see in the bottom code window that the Jump is not even taken. If we insert our new jump overtop of PUSH 104 the program will call a MessageBox instead of GetModuleFileName but we do not even see the program calling GetModuleFileName anyway so let's try it out.

Select PUSH 104 and choose Assemble. Enter JMP SHORT 4BD590 (Your number may need to be different, check the Address of PUSH EBX, that is the Address you want to jump to). Your code should look like this:

Go ahead and press Run to get to the MessageBoxA breakpoint. Press Run again and let's see if it worked.

It worked! Go through the registration process a few times to make sure that the program does not crash. For future information: The correct way to modify this program would be to jump to a code cave, move our serial into EDI and jump back to the MessageBox function. You can try it out on your own if you are interested, I may cover code caves in another tutorial.

Now we want to save our modifications before we do anything else. Just as before, select Copy to Executable, and then All Modifications. A box pops up asking us if we want to copy the selction, choose Copy All. A new window will open with the program in it and our changes included. Right click and select Save File. Save it as LC5Final.exe. You can close Olly, we are almost done. The last thing we need to do is change the text string "You have entered..."

Changing The Text String:
We want to change the text into something informative. To do this Open LC5Final.exe in Hex Workshop. You can do so by right clicking the actual file and choosing Hex Edit with Hex Workshop. With LC5final open, right click in Hex Workshop and choose Find. Select Text String from the drop down box and enter "You have entered" without the quotes. Make sure Match Case is unchecked and press Okay.

You will end up at 000D63D4. Sound familiar, that is the same value you pushed into EDI just a few minutes ago. We have found the correct string.

We can only overwrite the current string, we cannot use any more or any less space. By placing your cursor just before the Y in the right hand window you can type just as you would in any text editor. Experiment around until you find something that will completely overwrite the string. Keep in mind the string includes a period at the end. Here is my modified string:

Backup LC5final.exe and then save the newly modified program. Close Hex Workshop and try out LC5Final. Go through the registration process and... Success! We now have a Title in our MessageBox that will let the user know what they are seeing.

Creating a Patch:
The final thing we are going to cover is how to create a patch. What happens when we reverse a program and want to share that new reversed program with other people? We can zip up the executable and send it to them, however some programs are very big. We can write a tutorial on it, however that takes time and assumes reversing knowledge of the other party. Or we can quickly create a small program that will automatically apply the changes we made to the file. That is what we are going to do here.

There are two ways to make a patch. Code it completely yourself, or use a program that will help you create it. There are many different patching programs to choose from. I am going to use Diablos2002 Universal Patcher, or DUP. It is newer, easy to use, and allows you to customize how and what you want to patch.

Begin by opening up DUP. You start in the Patcher Settings. Click the browse button next to the Target Filename box and browse to lc5.exe. The other boxes are optional, under Release Info you may want to give a little description on how to use the patch. You can customize the About Box and the Icon and add your own skin as well as other options, by pressing the Options button.

Once you have filled in the boxes, choose the Offset Patch tab at the top. Select, for the Original File, LC5.exe and, for the Patched File, LC5Final.exe. Press the Compare button and it will create a list of the different bytes between the two. Last thing you need to do is press the Create Patch button and choose a name for your patch.

You are done! Backup LC5.exe and run the patch. Then try registering with an invalid serial... It works! You have successfully modified a program to create an display a valid serial. You also learned how to create a patch so you can apply the modifications on other computers. You can now apply the techniques you learned to other reversing projects.


All the tools you will need can be found online:
Olly Plugins:

As usual first get your program set up and ready to crack. Make a quick backup so we don't screw anything up when working on the file.

Begin by opening LanHelper.exe in PEID to see if it is packed or protected. The result: AsPack 2.12. Okay our first packed file. What does it mean when an executable is packed? Just as we pack files using Winzip or Winrar we can pack executables to protect them and conserve space. You can't open a zip file without a program to unpack it. The same is true for packed executables; except the program that unpacks it is part of the executable. The unpacker program is called a STUB. When you run a packed EXE the STUB first decrypts/unpacks the original EXE into memory. Then it executes the original program. The beginning of the original program is called the Original Entry Point "OEP". What we want to do is wait until the program is decrypted into memory, find the OEP and then dump the decrypted file to our hard drive. However, the OEP does not mean the beginning of a "working" EXE. We may have the programs code but an executable can have many different sections outside of the code. One very important section is called the Import Address Table "IAT". The Import Address Table allows a program to use functions stored outside of the program. A Messagebox from the Windows API (covered in tutorial #2) is an example of an outside function. When a program wants to use an outside function Windows loads the DLL with that function into memory address space and then gives the IAT the code location for the desired functions. A table is created with called functions, and addresses of those functions within the DLL's; hence the Import Address Table.

Note: I used three seperate computers to create this tutorial. This is why my serial changes halway through. It is also why my Addresses in Olly change. If your Addresses in Olly do not match mine, it is not a problem. The code will be the same.

Before we unpack the file we will examine its protection scheme. Open LanHelper.exe. After it is loaded we are presented with a box telling us that we "are on day 1 of our 30 day trial". We then have an option to enter a registration code. Let's try it out. A box comes up asking for our name and registration code. Enter anything and press OK. A box pops up telling us that "The registration code you have entered is not correct". Notice that the box that the box that pops up looks very much like a messagebox that we covered in the previous tutorial. That is something to keep in mind when we are trying to crack the program.

Unpacking is becoming a bigger part of reverse engineering. Many companies are choosing to pack or protect their programs to discourage people from reversing them. Because the packer used for this program is so popular, the method we are going to use to unpack it is not exclusive to this tutorial. In fact look for a tutorial by Ferrari on System Mechanic for more information on this method.

As a precursor to unpacking any program I usually use the hidedebugger plugin. Many packers and protectors are detecting whether or not you are debugging their program, and will quit if it detects that you are. Download the HideDebugger DLL using the selected link and place it in the same folder as Olly. Do the same for the Ollydump plugin as we will use it later.

We are going to begin by opening up LanHelper.exe in Ollydbg. You will be presented with a box about the program having an entry point outside of code. Click Okay. Another box will pop up asking if you want to analyze the code. Click Yes. You should find yourself here:

Press the Step Into button once . Now look at your registers. Understanding the registers is an integral part to learning how to reverse programs. Think of registers as 32 bit memory reserves. Information can be stored, modified, and accessed in registers. The registers are part of the processor so you can perform calculations without having to use extra memory. This is why 64 bit processors are becoming more popular. They use 64 bit registers allocatting more memory at the processor level.

With 32 bit registers you have General Registers: EAX EBX ECX EDX. These are the most used by program calculations. You also have Index and Pointer Registers: ESI EDI EBP EIP ESP. These have a variety of functions most involve pointing to addresses that the program will use. The register we will use to unpack this program is ESP. ESP contains the top address of the stack (You will remember we covered the stack in tutorial #2). For more information on registers and their uses: - basic information on registers - Information on how registers are used and what for.

Now take a look at the registers and then take a look at the stack window.
You'll notice that the values of the registers have been pushed onto the Stack. This is the result of the PUSHAD function at the beginning of the program. PUSHAD pushes the values of the registers onto the stack in their respective order. You'll notice EAX went on first, then ECX, etc... This unique function is used when the program wants to modify these registers but leave no trace of their modification behind. Their initial values are saved and then restored later. This is a perfect function for a packer. It can run the STUB, unpack the program and then restore the registers as if the STUB never existed. What we want to do is find out where the registers are restored because then we will know where the OEP of our program is.

The function that POP's the register values from the stack is appropriately called POPAD. This will pop the values off of the stack and back into the registers. We know the order that the registers were PUSHed, which means we know what order they will be POPed. EDI was last and will be the first register removed from the stack.We also know EDI's location on the stack because our register ESP points to the top of the stack. (Your register values may be different than mine but the information still applies).

Right click on the ESP register and choose Follow In Dump. You will see in the dump window, at the bottom of Olly, that you are at location 0012FFA4 (AKA the top of the stack). Highlight the first four Bytes and Right-Click. Select Breakpoint, then "Hardware, On Access", and Dword. What we are doing is setting a breakpoint so that Olly will stop when the first four bytes (EDI) are accessed. The reason we choose Dword is becausewe highlighted 4 bytes: 2 Bytes are a Word and 2 Words are a Dword (DoubleWord)
Okay we are all set to stop when EDI is POPed. Press the RUN button. Assuming you did everything correctly you should stop on the instruction JNZ SHORT LanHelpe.005533BA. Scroll up a bit and you will see directly above the JNZ is our POPAD function.

Now we are not at the OEP just yet. Our packer just needs to leave the decryption routine. Press the Step Into button 2 times and we will see how ASPack jumps to the OEP without actually jumping. You will see that the program PUSHed a location onto the stack and then immediately follows it up with a RETN. The location pushed is our OEP and the program then executes the RETN thinking that the location on the stack is the location of the function that originally called it.

Press Step Into one more time to execute the RETN and we are at the OEP. It looks wierd because the analysis of the program was done before the file was unpacked. Right click in the code window and select Analysis and then Analyse Code (or just press CTRL+A).

Our program is now unpacked into memory and we are sitting at the entry point. We are now able to dump the unpacked file from memory. Select the Plugins drop down list at the top of the Ollydbg window. Choose Ollydump and then Dump Debugged Process. You will be presented with the following box:

Look at the button "Get EIP as OEP" We do not need to press this in this tutorial. However for future reference; The EIP register (or instruction pointer) can also be called "program counter." It contains the offset of the next instruction to be executed. Pressing this button sets the OEP of the dump equal to the address stored in EIP. In this case they are both the same. We need to remember to write our OEP down. We will use the OEP address to rebuild our imports.

Now before continuing make sure that Rebuild Imports is UNchecked. Press Dump and then choose a name for your dumped executable. I chose LanDump.exe. Press the Save button and you can close Ollydbg. We now have a unpacked version of our executable. The only problem is: It won't run.

In the Introduction I gave you a brief overview of the Import Address Table (IAT). When a program is dumped from memory the IAT is not dumped along with it. We have to rebuild it ourselves and then attach it to our already dumped file. Sometimes this can be a very time consuming process because some protectors like to mess up the IAT in efforts to stop unpacking. However, this time we will find our IAT intact.

Rebuilding the IAT:
What we are going to do is use ImportReconstructor (ImpREC) and take the IAT from the original exe and attach it to our dumped file. Begin by running the original LanHelper.exe. Once LanHelper has started, open up ImportREC.exe and from the drop down menu choose the LanHelper process.

ImportREC needs to know where to look for the IAT. Without knowing where the OEP is, ImpREC looks at the entry point of the STUB and cannot find an IAT. Remember writing down the OEP when you dumped the program? This is where we will use it.

Enter the OEP in the bottom box labeled OEP. Then press "IAT AutoSearch". ImpREC will pop up saying it found what it thinks to be an IAT. Press Okay. Now Press the "Get Imports" button and wait for the Imported functions list to populate.

If the packer had messed up some of our functions, at the end of the lines you would see valid:NO. Press "Show Invalid" just to be safe. Okay nothing happened. We know that all our functions are valid. (I will cover fixing invalid functions at another time. If you are interested: Look for tutorials on AsProtect and/or rebuilding IAT's)

Press the "Fix Dump" Button and choose our LanDump.exe file. (ImpREC will save the newly modified file as FileName_.exe) Press Open and wait until the Log window of ImpREC says that LanDump_.exe was saved successfully. You can now close ImpREC and LanHelper. Okay let's open up LanDump_.exe and test it out. It Runs! You have successfully fixed the IAT and now have a working unpacked version! The only problem is: It's still not registered.

Patching the Registration Function:
Now that we have an unpacked executable we can figure out how to register it. To do this we are going to use the Attach feature of Olly. The reason we are going to attach to the process is One: because you will learn how to debug processes that are already running and Two: The dumped exe throws an exception in Olly and the program enters an endless loop that cannot be terminated outside of restarting the computer. (If anyone has more knowledge as to why this happens please email me *address at bottom*) So begin by running LanDump_.exe. Then run Ollydbg and open the File Menu, choose Attach. Find the LanDump_.exe process in the list of processes running and press Attach.

Once you attach you will find yourself in module ntdll. You know this because the titlebar of Ollydbg displays what module you are currently in. We need to get ourselves back in the main process and then continure running the program. Select the View drop down list. And then select Executable Modules. A list of all the executable modules for this program is displayed. At the top you will see LanDump_. Select that line and then Right-Click. From the menu choose Follow Entry. This will put you back into the main thread.

Press RUN to continue running the program. (If you get an error about suspended threads: Close Ollydbg. Then restart LanDump_.exe and Ollydbg. You only get one chance to attach with Ollydbg before having to close it and open it back up)

Now we are attached to the process and can go about reversing it's protection scheme. Remember the error message that came up when we entered an incorrect serial? It looked very much like a messagebox. So we are going to start by setting a breakpoint on every call to a message box.

Right-Click and choose Search For, and then choose All Intermodular Calls.You now have a list of all the calls made by the program to other modules. Press the Destination bar at the top to sort alphabetically by destination. Scroll down until you find a bunch of calls to User32.MessageBoxA. Select one of the calls and Right-Click. Choose Set Breakpoint on Every Call to MessageBoxA.

Now go to LanDump_.exe and enter your name with any serial and press Okay. Olly will pop up and you should have broken on CALL . Scroll the code window up a little bit and then press CTRL+A. This will analyze the code again giving us more information of what the program is doing.
In the image you can see I circled an >. The > represents an entry point for this function. If we locate the code that jumped to this entry point we may find where the program compares our serial. Olly makes finding the jump to this function very easy. Highlight the LEA ECX,DWORD PTR SS:[EBP-10] line that has the > in front of it and then Right-Click. From the menu select Go-To and at the bottom of the menu select go to JE from 004DB6CE. This is the location of the JE that took us to this messagebox code.

By selecting Go-To JE from 004DB6CE we find ourselves directly below a TEST AL,AL. This checks to see if AL = 1. If AL does not equal 1 then it will jump to the messagebox telling us we entered an incorrect registration code. We could patch the jump but that will not help us if the registration is checked on startup. (Which in this case it is. You can try patching it and then restarting the program to verify for yourself.) What we want to do is patch the routine that checks the serial. What happens is our name and serial are passed to a function. I will call it CheckSerial(). The function checks our serial code and then sets AL equal to 1 or 0 depending on whether the serial is correct or not. Many times a developer will use the same function in different areas of the program. He call the CheckSerial() function on startup, and to verify the registration code when it is entered, even see if you are trying to access a disabled feature. If we patch the function to always set AL=1 then we do not have to search through the program trying to change every JE to JNE.

Looking directly above the TEST AL, AL we can see the CheckSerial() function. Highlight the line and set a breakpoint on it by pressing F2. We are going to break on this function and then trace into it to find out where the value for AL is set. Press RUN and go back to LanDump_.exe.

Go ahead and try entering your name and any serial in LanDump_.exe again. Press Okay and we will find ourselves at our breakpoint in Olly at CALL LanDump.004C4BFC. Press the Step Into button and we will be inside the registration scheme of LanHelper. Rather then step through all this code looking for where the value for AL is determined. We are going to jump right to the end because we know that setting AL equal to 1 or 0 is one of the last things the function will do before returning. Press the Execute Till Return button . This will run the code until it reaches a RETN. You should end up at the following place in code.
But looking at the stack we see that the RETN we are on will only move us down to 004C511A. That happens to be exactly where we want to go. At that location we can see that AL is being set equal to [EBP-9]. We can find out what EBP-9 is by Right-Clicking on EBP in the registers window and then choosing Follow in Dump. Count back 9 bytes from where you start in the dump and you will end up at 0012EE73 which contains 00.

To fix this program we are going to change the line so that AL always equals 1. Now select MOV AL,BYTE PTR SS:[EBP-9] and press Spacebar to edit it. In the window that pops up change MOV AL,BYTE PTR SS:[EBP-9] to MOV AL,1. Make sure Fill With NOP's is checked and press Assemble. Close the editing box and press RUN. If you have not removed your MessageBoxA breakpoints you will break on a call to a messagebox. By looking at the stack we can see that it is thanking us for registering LanHelper. Success! But will it work when we restart the program?

To make sure our program works when we restart it we need to save our changes to a new executable. Right-Click in the code window and choose Copy to Executable then All Modifications. A box will pop up asking if you want to copy the selected modification to the executable file; choose Copy All. A new window will open up with our modified program in it. Right-Click in the window and choose Save File. Pick a name for your file (I choose LanFixed.exe) and press Save. You can now close Olly.

Time to test it. Open up your newly saved file and... It works! No nag screen. Choose Help and then About from the menu and you will see that the program is now registered to your name.

Creating a Patch:
The final thing we are going to cover is how to create a patch for a packed file. This is useful because it is much easier to send a patch out rather than a large modified executable. Once again I am going to use Diablos2oo2 Universal Patcher, or DUP. We used this patcher before to create an offset patch but this time we are going to use it to create a patch based on virtual offsets. A nice thing about this patcher is the fact that it supports packed files.

Begin by opening up DUP. You start in the Patcher Settings. Enter LanHelper in the Application Name. Click the browse button next to the Target Filename box and browse to LanHelper.exe. The other boxes are optional, under Release Info you may want to give a little description on how to use the patch. You can customize the About Box and the Icon and add your own skin and other options, by pressing the Options button.

Once you have filled in the boxes, choose the Offset Patch tab at the top. First check the box that says Virtual Address Mode this allows us to patch the executable based on the offsets of the program when it is loaded into memory. For the original file choose our unpacked LanDump_.exe and for the Patched File choose LanFixed.exe. Press the Compare button and it will fill our list with the modified bytes. Now we need to give the patcher the information of our original packed executable. Press the Get It... button under Target File: Filesize + CRC32. Choose LanHelper.exe and then Open. Once dUP has the target file information press Create Patch and choose a name for your patch.

You are done! Backup LanHelper.exe and run the patch. Now run the patched LanHelper and it will show you as registered! To test registering it again, delete the values from the sn and user keys under HKEY_LOCAL_MACHINE\SOFTWARE\LanHelper. You have successfully unpacked a packed executable and have patched a registration scheme at the deepest level. You can now take whet you used here and apply it to other targets.


1. Follow the same steps under Dumping except you will break on a JMP after the POPAD.
2. Follow that JMP to get to the OEP.
3. Fix the IAT in the same way as above, using your newly discovered OEP.

1. Load newly dumped executable in Olly
2. You are going to encounter a few exceptions. So in Olly's Debugging Options check Ignore memory access violations in Kernel32, and INT 3 breaks. Also, check the Ignore Custom Exceptions box. In the custom exceptions add the range (00000005 to ) and the range (C0000005 (Access Violation) to ).
3. If play around with the executable for awhile you will notice that setting a Breakpoint on MessageBox in the intermodular calls does not work.
4. Use the command bar plugin and type "BP MessageBoxA" without the quotes.
5. Try and register the program: type in any name and serial and press Okay. You will break on MessageboxA in the user32 module.
6. Look at the top line of the stack to see where the Call to messageboxA came from. In my case it was 4D5C1C.
7. Right click in Olly and choose Go-To->Expression. Type in 4D5C1C, or whatever address your call occured at, and press Okay. You will be at the call to messageboxa
8. Scrolling up in Olly's you will see code that is very similar to the code that calls the messagebox in version 1.40. However it is missing that nice little > that tells us what called this code.
-No Problem-
9. Remember w32dasm? Hope so! Leave Olly open, but also open up your dumped executable in w32dasm. Wait for it to analyze the file.
10. When you have the executable loaded into w32dasm. Choose GoTo at the top and choose Code Location on the drop down menu. Type in 4D5C1C, or whatever your call location was, and press Okay
11. You will see that you are at the call to messageboxA, scroll up a little until you see
Referenced by a (U)nconditional or (C)onditional Jump at Address:
4D571E(C) <-**This number may be different**
12. That address is where the Jump to the messagebox is made. Write it down and close out w32dasm.
13. Back in olly right-click and choose Go-to->Expression. Type in the address you just found and press Okay. You will find yourself just below a CALL and TEST. Just as in version 1.40.
14. Fixing the call and patching the program is just the same as in 1.40.


This tutorial is a followup of the series of three wrote by Gabri3l, available on our tutorial's site. I will suppose you read them before, because some the things he already said are given as known. Expecially what I'm referring to is the last tutorial, the third one, arguing about a program protected with AsPack 2.11.

In this tutorial I will (ab)use another little program protected with AsPack, but which cannot be unpacked with the same method Gabri3l told in his already mentioned third tutorial. The target is Super Video Joiner, a nice program useful to join different videos into an unique final one, also DivXs.

As we will see later on, this target has a different Import Address Table -IAT- format which will require a little more advanced use of Import Reconstructor. I will also show you how to tell Olly to automatically unpack self-extracting applications (such those protected with aspack, upx or similar but not with asprotect, armadillo etc). The patching of the unpacked application is indeed, once dumped, very easy and will be covered in a few steps.

Lastly I will concentrate on the creation of a smart patch which will, hopefully, be valid for future versions: Gabri3l shown you how to use Dup (Diablo2oo2 Universal Patcher) using the Offset Patch, I instead will show you how to use the Search and Replace tab...

So, fasten your seatbelts ;-)


This tutorial is a followup of the series of three wrote by Gabri3l, available on our tutorial's site. I will suppose you read them before, because some the things he already said are given as known. Expecially what I'm referring to is the last tutorial, the third one, arguing about a program protected with AsPack 2.11.

In this tutorial I will (ab)use another little program protected with AsPack, but which cannot be unpacked with the same method Gabri3l told in his already mentioned third tutorial. The target is Super Video Joiner, a nice program useful to join different videos into an unique final one, also DivXs.

As we will see later on, this target has a different Import Address Table -IAT- format which will require a little more advanced use of Import Reconstructor. I will also show you how to tell Olly to automatically unpack self-extracting applications (such those protected with aspack, upx or similar but not with asprotect, armadillo etc). The patching of the unpacked application is indeed, once dumped, very easy and will be covered in a few steps.

Lastly I will concentrate on the creation of a smart patch which will, hopefully, be valid for future versions: Gabri3l shown you how to use Dup (Diablo2oo2 Universal Patcher) using the Offset Patch, I instead will show you how to use the Search and Replace tab...

So, fasten your seatbelts ;-)

2. Unpacking the program

Understanding the program compression used
As usual the very first step of any cracking session is to understand what we are facing to! The first thing to do is to open PEiD and to see what it reports.

By the way, PEiD is not always 100% correct and sometimes report wrong results. Its authors for this reason included the possibility to use an external signature database, an external file inside its installation folder, called userrdb.txt.

This file contains all the additional signatures not already included into PEiD. These signatures are usually posted in the forums around, even our one, and you might take time to collect some of them to improve your PEiD accuracy. PEiD installer install a sample userdfb.txt file with no meaningful things inside, so often you need to find a real one around.

Anyway our case is very simple and AsPack is recognised by PEiD easily. You should already know that AsPack is a program's packer, not a program's protector, so it's main target is to reduce the whole exe image file's size, rather than to protect it. So its main characteristic is to be "re-entrant", which means that when the unpacking code finishes to unpack the program into the memory, it doesn't leave any trace and the program appears in memory as nothing happened (see also Gabri3l tutorials). This lead to the method suggested by Gabri3l in his tutorial, which consists in placing an hardware breakpoint on Dword on the stack, just after the first PUSHAD.

On the other hand protectors like AsProtect (of the same author of AsPack), instead do several things to the original executable's code and are "not re-entrant"; also when the program is uncompressed in memory, ready to execute, it's code has been widely modified (its IAT modified so as to not rebuild it easily, its instructions modified to not follow the program's flow easily and so on).

Let Ollydbg unpack the program for us
Ok we can now open OllyDbg and unpack the program. Follow on your own, as an exercise, the method exposed in the third Gabri3l's tutorial, just to see if you have understood it clearly. Done?? Ok, so go on reading this..

In this document I will follow instead an alternative way, which is already implemented into OllyDbg and which is not so much known/used.

Goto into the OllyDbg settings and set them as in the picture below:

OllyDbg has an automatic Self Extractors (SFX) feature, which does the a trick similar (more complex actually) to what Gabri3l explained you. This trick is valid as I told for all the "re-entrant" program's packers or generally for all the self extractor executable. Ollydbg is able to do all the work for you and to stop at the right place!

Once you set your settings as above you are ready to load your target into Ollydbg (in this case the program is videojoiner.exe). There's not need to close and reopen Olly, it's enough to relauch the program, e.g. using CTRL-F2 if it was already opened.

Usually Ollydbg would have stopped at the first instruction of the AsPack unpacker (see below), which was a PUSHAD

004F8001 > 60 PUSHAD
004F8002 E8 03000000 CALL videojoi.004F800A
004F8007 - E9 EB045D45 JMP 45AC84F7

This time instead Ollydbg behaves differently and starts to analize deeply the program and expecially starts to trace it (see the left bottom part of the interface, there is a message "Tracing SFX.."). Let Ollydbg works till the process stops and you land at what Ollydbg believe could be the final destination of the self extracting procedure.

As you can see Olly also reports in the status bar a staticstic of the work done:

If you haven't still done it press a CTRL-A to reanalize the program, and to see clearly that we are in the real OEP of the program.

A note about Ollydbg: Ollydbg stores away (into the UDD file) the original OEP just found, so the next time we will launch the same program the OEP will be immediately found and Ollydbg will report that the SFX entrypoint (aka the OEP) has been "learned":

As you can see the point where we stopped this time is the same we would have obtained doing the process manually! Well, a little bit of work skipped!

Dumping the Process and Fixing the IAT
Now we are ready to dump the program as usually. Try, before reading on, to do as Gabri3l told you in the third tutorial, and you will see that ImpRec is not be able to get any valid import from the runnig process; there's no way to obtain a fixed dump operating as Gabri3l told you. Why? Well, we will see it in a moment.

First of all dump the program using OllyDump, uncheck Rebuind Import and take note of the OEP. In this case is: AF0A0.

I called the dump file, with a name of fantasy, dump.exe.

Now open Import Reconstructor 1.6 and open the process you are debugging from the processes list. I'll do it brief hoping you are already accustomed to this program, so the picture reports everything needed, and the number are the steps to follow.

Once you press the "IAT Autosearch" button ImpRec pops up to you this dialog message:

As you should already know this is the address where ImpRec beleives the IAT is (the IAT has a fixed structure so it's easily recognized by ImpRec).
Go forward to step 3 and 4 and you should get the point: the IAT cannot be reconstructed in this way!

We need to instruct ImpRec to find on it's own the APIs in the memory space of the process in a different way!

See how..

Right click on the white space of the interface, and you should get this contextual menu:

Select the "Get API Calls" and this is the final dialog which appears to you:

Before pressing Ok, do you understand what the program is going to do? It is going to scan all the CALL [X] instructions in the memory that goes from 0000000 to FFFFFFF. We will do the same process manually for just one call, to understand the work that ImpRec will do when you will press able to press ok.
Now leave ImpRec as it is and return to read a little of what happens behind the scenes.

Understanding what ImpRec will do
Switch to OllyDbg which is still running in background, with the process stopped at the OEP.

This is the situation you should see now:

004AF0A0 /. 55 PUSH EBP ; Real entry point of SFX code
004AF0A3 |. B9 0B000000 MOV ECX,0B
004AF0A8 |> 6A 00 /PUSH 0
004AF0AA |. 6A 00 |PUSH 0
004AF0AC |. 49 |DEC ECX
004AF0AD |.^ 75 F9 \JNZ SHORT videojoi.004AF0A8
004AF0AF |. 53 PUSH EBX
004AF0B0 |. 56 PUSH ESI
004AF0B1 |. B8 B8ED4A00 MOV EAX,videojoi.004AEDB8
004AF0B6 |. E8 6573F5FF CALL videojoi.00406420
004AF0BB |. 8B35 6C204B00 MOV ESI,DWORD PTR DS:[4B206C] ; videojoi.004B3C14
004AF0C1 |. 33C0 XOR EAX,EAX
004AF0C3 |. 55 PUSH EBP
004AF0C4 |. 68 28F54A00 PUSH videojoi.004AF528
004AF0CC |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
004AF0CF |. 6A 00 PUSH 0 ; /Title = NULL
004AF0D1 |. 68 38F54A00 PUSH videojoi.004AF538 ; |Class = "Super Video Joiner"
004AF0D6 |. E8 B97BF5FF CALL videojoi.00406C94 ; \FindWindowA
004AF0DD |. 76 14 JBE SHORT videojoi.004AF0F3

Go to one of the system calls spread around the code and see how it is done. For example I will follow the first one, FindWindowA, called at 004AF0D6.

Look the call: it is like CALL videojoi.00406C94, where 00406C94 is the called address. At the called address this what we find:

00406C94 $- FF25 04474B00 JMP DWORD PTR DS:[4B4704] ; user32.FindWindowA

the JMP at 00406C94 jumps directly into the user32's FindWindowA starting address. By the way when you are at 00406C94 look around, there are a lot of similar JMPs to the real system calls...

So let try to summarize: we have a CALL to an address (004AF0D6), which contains a JMP to another address (004B4704), so we can see the first called address as a memory pointer to the real called address, which in assembler is as an indirect call.

Its syntax generally is:

CALL [address_containing_the_real_addr_to_call]

or rather, using ImpRec notation, CALL [X]..What the ImpRec is still asking to you? "Get CALL [X] Scheme"...

For example when a registry contains an address of a subroutine to call the ASM instruction will be CALL [EAX], if EAX is the register.


But let take a short break to dig a little this specific argument, I think that could be interesting to know some details about how the calls to imported functions are generated from the compiler and why. Let's examine what the call to an imported API looks like. There are two cases to consider: the efficient way and inefficient way. In the best case, a call to an imported API looks like this:

CALL DWORD PTR [0x00405030]
If you're not familiar with x86 assembly language, this is a call through a function pointer. Whatever DWORD-sized value is at 0x405030 is where the CALL instruction will send control. In the previous example, address 0x405030 lies within the IAT.
The less efficient call to an imported API looks like this:

CALL 0x0040100C
JMP DWORD PTR [0x00405030]

In this situation, the CALL transfers control to a small stub. The stub is a JMP to the address whose value is at 0x405030. Again, remember that 0x405030 is an entry within the IAT. In a nutshell, the less efficient imported API call uses five bytes of additional code, and takes longer to execute because of the extra JMP.
You're probably wondering why the less efficient method would ever be used. There's a good explanation. Left to its own devices, the compiler can't distinguish between imported API calls and ordinary functions within the same module. As such, the compiler emits a CALL instruction of the form


where XXXXXXXX is an actual code address that will be filled in by the linker later. Note that this last CALL instruction isn't through a function pointer. Rather, it's an actual code address. To keep the cosmic karma in balance, the linker needs to have a chunk of code to substitute for XXXXXXXX. The simplest way to do this is to make the call point to a JMP stub, like you just saw.
Where does the JMP stub come from? Surprisingly, it comes from the import library for the imported function. If you were to examine an import library, and examine the code associated with the imported API name, you'd see that it's a JMP stub like the one just shown. What this means is that by default, in the absence of any intervention, imported API calls will use the less efficient form.

Logically, the next question to ask is how to get the optimized form. The answer comes in the form of a hint you give to the compiler. The __declspec(dllimport) function modifier tells the compiler that the function resides in another DLL and that the compiler should generate this instruction


rather than this one:


In addition, the compiler emits information telling the linker to resolve the function pointer portion of the instruction to a symbol named __imp_functionname. For instance, if you were calling MyFunction, the symbol name would be __imp_MyFunction. Looking in an import library, you'll see that in addition to the regular symbol name, there's also a symbol with the __imp__ prefix on it. This __imp__ symbol resolves directly to the IAT entry, rather than to the JMP stub.
So what does this mean in your everyday life? If you're writing exported functions and providing a .H file for them, remember to use the __declspec(dllimport) modifier with the function:

__declspec(dllimport) void Foo(void);

If you look at the Windows system header files, you'll find that they use __declspec(dllimport) for the Windows APIs. It's not easy to see this, but if you search for the DECLSPEC_IMPORT macro defined in WINNT.H, and which is used in files such as WinBase.H, you'll see how __declspec(dllimport) is prepended to the system API declarations.

Terminating the dumping process
It's time now to finish our dumping procedure and to have a fixed working dump ready to be patched, isn't it?

When you press OK in the ImpRec's dialog box discussed above, the program starts to work, and the final result is something which looks like below:

Press the "Show Invalid" button and you should see that there are still a lot on invalid values: are all calls that ImpRec wasn't able to associate to any system call.
No problem, it's obvious and we should have expected it: not all the calls of the type CALL [X] are pointing to the system and some of them are internal to the program, so it's obvious that ImpRec is not able to recognize all of them.

To eliminate them simply right click on one of them and select "Cut Chunk(s)" (see the contextual menu shown few pictures above).

Press "Show Invalid" again and this time you shouldn't get any invalid entry.

The ImpRec log window reports "Congratulation! There is no more invalid pointers, now the question is: Will it work?:-)"

Press Fix Dump and we will answer soon to this question ;-)

Obviously the answer is yes, it works!

3. Patching the Program

Now we have a working dump and we are ready to happily patch the application.

First of all study the protection: there are three limitations to the program, it cannot join more than two files, when you exit there is a messagebox and you cannot enter any registration code you like. All these limitations have very clear Bad Boy messages, which are essential grips to start reversing with Olly.

From earlier beginner tutorials of this series and of ARTeam's tutorials collection, you should have learnt that a Bad Boy is a great place from where to find references to the code to patch, you should also know how to search referenced strings in OllyDbg.

Following this method I found these three points where to patch the application. I will report them briefly without commenting them too much, because are very simple indeed (just some jmps patching). I also anyway reported the referenced strings I used to find the right point.


Original Code:
004A7123 |. /75 14 JNZ SHORT videojoi.004A7139
004A7125 |. |A1 081E4B00 MOV EAX,DWORD PTR DS:[4B1E08]
004A712A |. |8338 00 CMP DWORD PTR DS:[EAX],0
004A712D |. |74 0A JE SHORT videojoi.004A7139
004A712F |. |A1 9C1E4B00 MOV EAX,DWORD PTR DS:[4B1E9C]
004A7134 |. |8338 00 CMP DWORD PTR DS:[EAX],0
004A7137 |. |75 12 JNZ SHORT videojoi.004A714B
004A7139 |> \BA 00724A00 MOV EDX,videojoi.004A7200 ; ASCII "Licence to: Unregister"

Patched Code:
004A7123 . 90 NOP
004A7124 . 90 NOP
004A7125 . A1 081E4B00 MOV EAX,DWORD PTR DS:[4B1E08]
004A712A . 8338 00 CMP DWORD PTR DS:[EAX],0
004A712D . 90 NOP
004A712E . 90 NOP
004A712F . A1 9C1E4B00 MOV EAX,DWORD PTR DS:[4B1E9C]
004A7134 . 8338 00 CMP DWORD PTR DS:[EAX],0
004A7137 . EB 12 JMP SHORT videojoi.004A714B
004A7139 . BA 00724A00 MOV EDX,videojoi.004A7200 ; ASCII "Licence to: Unregister"


Original Code:
004A8CE2 |. /75 18 JNZ SHORT videojoi.004A8CFC
004A8CE4 |. |A1 081E4B00 MOV EAX,DWORD PTR DS:[4B1E08]
004A8CE9 |. |8338 00 CMP DWORD PTR DS:[EAX],0
004A8CEC |. |74 0E JE SHORT videojoi.004A8CFC
004A8CEE |. |A1 9C1E4B00 MOV EAX,DWORD PTR DS:[4B1E9C]
004A8CF3 |. |8338 00 CMP DWORD PTR DS:[EAX],0
004A8CF6 |. |0F85 52020000 JNZ videojoi.004A8F4E
004A8CFC |> \8D45 F0 LEA EAX,[LOCAL.4]
004A8CFF |. BA 28954A00 MOV EDX,videojoi.004A9528 ; ASCII "This trial version only can join less than 2 video files at a time,this limit only can be eliminated when it is registered!"
004A8D04 |. E8 E3B4F5FF CALL videojoi.004041EC

Patched Code:
004A8CE2 . 90 NOP
004A8CE3 . 90 NOP
004A8CE4 . A1 081E4B00 MOV EAX,DWORD PTR DS:[4B1E08]
004A8CE9 . 8338 00 CMP DWORD PTR DS:[EAX],0
004A8CEC . 90 NOP
004A8CED . 90 NOP
004A8CF3 . 8338 00 CMP DWORD PTR DS:[EAX],0
004A8CF6 . E9 53020000 JMP videojoi.004A8F4E
004A8CFB . 90 NOP
004A8CFF . BA 28954A00 MOV EDX,videojoi.004A9528 ; ASCII "This trial version only can join less than 2 video files at a time,this limit only can be eliminated when it is registered!"
004A8D04 . E8 E3B4F5FF CALL videojoi.004041EC


Original Code:
004AB0D4 . /75 12 JNZ SHORT videojoi.004AB0E8
004AB0D6 . |833D FC3C4B00 00 CMP DWORD PTR DS:[4B3CFC],0
004AB0DD . |74 09 JE SHORT videojoi.004AB0E8
004AB0DF . |833D 003D4B00 00 CMP DWORD PTR DS:[4B3D00],0
004AB0E6 . |75 0A JNZ SHORT videojoi.004AB0F2
004AB0E8 > \B8 FCB04A00 MOV EAX,videojoi.004AB0FC ; ASCII "This is a unregistered Version, Don't forget to register it."
004AB0ED . E8 327EF8FF CALL videojoi.00432F24

Patched Code:
004AB0D4 . 90 NOP
004AB0D5 . 90 NOP
004AB0D6 . 833D FC3C4B00 00 CMP DWORD PTR DS:[4B3CFC],0
004AB0DD . 90 NOP
004AB0DE . 90 NOP
004AB0DF . 833D 003D4B00 00 CMP DWORD PTR DS:[4B3D00],0
004AB0E6 . EB 0A JMP SHORT videojoi.004AB0F2
004AB0E8 . B8 FCB04A00 MOV EAX,videojoi.004AB0FC ; ASCII "This is a unregistered Version, Don't forget to register it."
004AB0ED . E8 327EF8FF CALL videojoi.00432F24

You have done it! I hope you understood what I simply pasted here, (sorry, but it's useful to make the whole tutorial shorter). From Ollydbg save the applied patches to a program and call it for exampl dump.patched.exe, then run it.

It works fine with no limitations or annoying nags and allows to join more than two sequences..

4. Creating the Patcher

Also this time we will use Diablo2oo2 Universal Patcher to create the patcher, it has an unique feature to be able to patch packed programs and specifically supports AsPack. The final patch so it will be able to work on the original installed file without having to dump it and reducing the distribution weight.

Anyway this time we will use a different method to create a patcher, the "Search and Replace".

Search and Replace, general considerations
This patching method searches through the target executable file for a specific byte pattern and when if finds it applies the corresponding new pattern. This operation is done blindly for all the occurrences of the specified byte pattern. So it's potentially dangerous if not done on a well thought pattern.
On the other hand if this pattern is well choosen and well formed there is an high probability that the same pattern will be present in future versions of the same program: what often changes among different program's versions are the relative offsets inside the program, used in JMPs, CALLs and MOVs and so on, but the code remains essentially the same (this happens because most often we are changing the registration routines which very often doesn't change, what changes are the features which we leave untouched). Anyone reading this, who cracked two different versions of the same program should easily realize this concept!

This is DuP Search and Replace form:

You should start entering the original byte pattern in 1, the the new one in 2, press the Add button in 3 and Check occourrence of "Search Bytes" in 4. The finally you shold see your result(s) in 5.

By the way, generally speaking if the byte pattern is not unique DuP let you also choose the occourrence number to patch, using the Occourrence box.

Choosing the byte patterns
Before to preceed I need to clarify a thing: each ASM operation has first of all its own op-code (an hex number representing it for the CPU), and then its operands. Ollydbg separates them for your convenience, so an instruction like:


has an op-code equal to A1 (the MOV EAX, DWORD PTR DS:[]), and an operand equal to 081E4B00 (which is 4B1E08 in reverse order).

Given this, we are ready to go further, to understand the way to proceed. For the sake of shortness, I will report here again the Patch1 wrote in Section #3 of this tutorial. I will do the complete steps only for this patch and for the other I will only give to you the final results so you can train yourself.

Original Code:
004A7123 |. /75 14 JNZ SHORT videojoi.004A7139
004A7125 |. |A1 081E4B00 MOV EAX,DWORD PTR DS:[4B1E08]
004A712A |. |8338 00 CMP DWORD PTR DS:[EAX],0
004A712D |. |74 0A JE SHORT videojoi.004A7139
004A712F |. |A1 9C1E4B00 MOV EAX,DWORD PTR DS:[4B1E9C]
004A7134 |. |8338 00 CMP DWORD PTR DS:[EAX],0
004A7137 |. |75 12 JNZ SHORT videojoi.004A714B
004A7139 |> \BA 00724A00 MOV EDX,videojoi.004A7200 ; ASCII "Licence to: Unregister"

which in bytes is as follows:


the yellow part denotes the operands.
Now ask to yourself, what could change across different versions of the program; the answer is: the offsets, the addresses of the strings and of the MOVs...

Well, so cut these things away from the above byte pattern and substitute them with a couple of *


Thinking to operands a little more I can see that we can leave in place some of them, like the first, equal to 14, which is an offset to a relative jmp destination (means 14 bytes forward) because I can suppose that if the code changes it's position in next releases it will do as a whole block so the relative offset of 14 bytes is small enough to be sure that even the destination bytes of the jmp will be there. The operand of the instruction at 004A712A which is 00, is also for sure a think that will be still here in future releases.

So this lead to our final search string:

Original byte sequence:

The concept is: do not include offsets too far away from the peice of code you are going to patch, the other operands can be left.

The patched code is the follow:
004A7123 . 90 NOP
004A7124 . 90 NOP
004A7125 . A1 081E4B00 MOV EAX,DWORD PTR DS:[4B1E08]
004A712A . 8338 00 CMP DWORD PTR DS:[EAX],0
004A712D . 90 NOP
004A712E . 90 NOP
004A712F . A1 9C1E4B00 MOV EAX,DWORD PTR DS:[4B1E9C]
004A7134 . 8338 00 CMP DWORD PTR DS:[EAX],0
004A7137 . EB 12 JMP SHORT videojoi.004A714B
004A7139 . BA 00724A00 MOV EDX,videojoi.004A7200 ; ASCII "Licence to: Unregister"

leads to this string instead:

Patched byte sequence:

Well, enter them into Dup

Note: if you right click on the edit field 1 or 2 DuP it will open a contextual menu which allows to paste the search pattern without having to manually insert it (CTRL-C won't work).

In 5 select the byte pattern you added and press the button in 4 to get this result:

The VA offset at which the pattern is found is 4A7123 which is correct!

To make the story shorter the byte patterns of the other two left patches are:


Original byte sequence:

Patched byte sequence:


Original byte sequence:

Patched byte sequence:

I think you might now rebuild how I got them.

Finally Diablo2oo2 Universal Patcher should look like below:

You are ready to create the patch, remember to tag the "Target is packed" checkbox, save the project and create the patch.

You are now ready to test it!

Of course (should) work.

All the tools you will need can be found online:

As usual first get your program set up and ready to crack. Make a quick backup so we don't screw anything up when working on the file. Now begin by opening Udruler.exe in PEID to see if it is packed

packed. The result:

I recommend reading tutorials #3 and #4 before starting this one. I and Shub-Nigurrath have taught you two ways to unpack packed executables. Because of this I will only quickly cover finding the OEP.

However, before we begin even working with this executable we will first cover the Registers. If you think you already have a good grasp on x86 registers you can go ahead and skip to Unpacking.


The Registers:
To get any further in reversing it is important to understand all the information you have available to you. The registers are the primary information holders when using a debugger. So, we are going to learn what the registers are, and what information they can hold.

The registers are small areas of memory that programs use to store information. I am sure you have heard that Windows is built on x86 architecture. And that the x86 architecture has 32-bit registers. This means that the registers we are looking at can only hold 32-BITS. A BIT is either a 1 or a 0. So a register can only hold a binary value between 00000000000000000000000000000000 - 11111111111111111111111111111111. That means that a register can hold 4,294,967,295 possible combinations. Okay, Why is it when we see the registers in Olly they only hold 8 characters between 0 and F? Because in Olly, we are used to seeing BYTES. BYTES are eight BITS grouped together. And can hold a value from 0 to 255. However to make it easier, instead of writing 8 BITS every time we want to write a BYTE. We use the Hexadecimal format to write a BYTE.

Hexadecimal format is based on the number 16. Now, if you are unfamiliar with the different based number systems pay attention! We use the decimal system which is based on the number 10. That means that whenever we hit the magical increment of 10: we add 1 to the space to the left and start over at zero in the right space. That's all you need to know for Hexadecimal. Just count in increments of the base number. And only add one to the left space when you hit another increment of the base number. Sound confusing? It's not. Example: Start counting from 1 in Hex, 1,2,3,4,5,6,7,8,9,A,B,C,D,E,and F is 15 so 10 is 16. So we count again. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, and hit 1F which is 31. Well we are going to get to another increment of 16 again so add 1 to the left space and start over at zero. 1 + 1 = 2 and start over at zero so we are at 20 in hexadecimal which in decimal is 36. This works for any based number system.

Binary for example. Counting in binary: 0 = 0, 1 = 1, okay we are going to hit 2 so add one to the left digit and start at zero in the right: 10 = 2, 11 = 3, Okay another increment of two so add 1 to the left digit and start at zero. Oops, Not 20, instead notice that by adding 1 to the left digit it has reached an increment of two as well. So add 1 to the left again and start at zero. Now we are at 100 = 4, 101 = 5. Keep this in mind for every base system. When you add 1 to the left digit, if that digit reaches an increment of the base number, add one to the farther left digit and start over at zero for the left hand digit.

I understand that this is a lot to comprehend but it is good to at least understand hexadecimal the farther along you get in reversing.

Okay back to Registers: BYTES are 8 BITS written in hexadecimal. A Register contains 32 BITS which is 4 BYTES. So a register can only hold a value between 00000000 and FFFFFFFF. That's not a lot of room when it comes to memory. Many times the register is broken down into 2 BYTES, and sometimes again into only 1 BYTE.

The general purpose registers are: EAX, EBX, ECX, and EDX. Think of these as REGISTERS A, B, C, and D. When you see EAX in a program they are referring to all 4 bytes of REGISTER A. What if we want to only use half of the register? Well then drop the E and we have AX which is the last 2 BYTES of REGISTER A. To use half of that we have AL and AH. These are one BYTE each, and are the LOW and HIGH bytes of AX. So if you see:
The two instructions are referencing the same register. the first one POP's 4 BYTES off of the stack and puts them in REGISTER A. The second instruction adds one to the last BYTE in REGISTER A. So now we understand how to break down the registers. Let's see what they are commonly used for:

EAX: Known as the Accumulator Register. This register is probably the most popular register. It is used for general calculations and intel has programmed many special assembly instructions that just use EAX. Functions like LODS, STOS, IN, OUT, INS, OUTS, SCAS, and XLAT are used to specifically move memory in and out of the EAX register. Also API functions almost always return their values through EAX.

EDX: Known as the Data Register. This register is traditionally used in conjunction with the EAX register. The EAX register may hold the data to be written and the EDX register may hold the address to write the data to. EDX also often holds the result of mathematical functions. The EDX and EAX registers also can also be used in conjunction to hold 64 bits of information by using EDX:EAX

ECX: Known as the Count Register. This register is true to it's name. As it is often used as a counter for LOOP and REP (repeat) functions. It also has assembly functions written specifically for it. Example: JECXZ jumps if the ECX register equals zero.

EBX: Known as the Base Register. This register used to be the only register that could be used to hold a memory address for access. Memory access occurs when the register is put between square brackets. Example: MOV EAX, EBX moves the value of EBX into EAX. where MOV EAX, [EBX] moves the value stored at the memory address in EBX into EAX. Now Intel has made it so any register can be used as an address for memory access. So EBX is usually used for general purposes.

Hopefully this gives you an idea of the uses of the general purpose registers.We can move on to unpacking this program


**I created this tutorial using Windows 2000, so your offsets may be different than mine. Do not rely on my addresses to guide you, instead rely on the code you see in the pictures.**

Unpacking this program is very similar to unpacking Aspack. However, because we are going to inline patch the program we are not going to dump the executable. Instead we only want to find the OEP of the program. That way we can look through the unpacked program and find the address of registration scheme we need to patch.

Let's begin. Open udruler.exe in Olly. You should be here:
In tutorial #3 we learned what the PUSHAD does and why the unpacking routine uses it. UPX uses the PUSHAD instruction for the same purpose as ASpack. This means we can unpack it the same way.

Press the Step Over button once . Now that we have executed the PUSHAD, our registers are on the stack. We need to break when the registers are POPed off the stack. So Right-Click on the ESP register (Which we know contains the address to the top of the stack) and Follow in Dump. In the Dump window highlight the first four bytes and Right-Click ->Breakpoint ->Hardware, On Access -> DWORD.

Now all we have to do is Press RUN. Wait for the program to be unpacked and we will break on a JMP. Looking at the JMP we see that it jumps to address 004BE9DC. 004E9DC is a completely different part of memory than the one we are in. Maybe it is our OEP! Press Step Into button to follow the Jump.

Looking at the code we see that we are at the beginning of the UDruler executable. (How exactly do I know that this is the beginning? Well, sometimes you aren't 100% sure. But the more experienced you become with unpacking executables you begin to learn what the code at the beginning of a program looks like)

Before continuing on, remember to remove the Hardware Breakpoint we set. You can do so by choosing the Debug menu. Then Hardware Breakpoints from the drop down menu. A box will open with the hardware breakpoints you set. Press the Delete Button beside the breakpoint to remove it.

Defeating the Protection:
We are now inside the unpacked executable. We could use Ollydump and dump the program then patch it that way. But we already learned how to do that in tutorials #3 and #4. Instead, we are going to browse the executable while it is in memory and find where we need to patch the program.

So to begin, let's check the Strings. Right-Click and choose Search for->All referenced Text Strings. Scroll up to the top of the page. One of the first couple strings you see is "REGISTERED VERSION" followed by "UNREGISTERED VERSION". This looks like a very interesting place to start. Double Click "REGISTERED VERSION" you will find yourself here:

Looking at the code we see that a CALL is made to 004BAFF8. The program then tests to see if AL is zero. If AL is zero then it jumps to 004A93AF. What we are going to do is fix the program so that AL is always 1. This will be similar to the approach we took to fix the registration of Lanhelper in Tutorial #3.

Select line 004A9394 (The Call to UDRULER.004BAFF) and Right-Click. Choose Follow from the menu. By following this call we put ourselves in the routine that checks to see if the program is registered. You should currently be here:

This is the beginning of the registration checking function. We want to break here and then follow the code until we see AL being set. Press F2 to set a breakpoint. Now, press Run and UDruler will begin loading.

As UDruler appears in your taskbar Olly will break at the breakpoint we just set. We are now inside the Registration Check for this program. Look at the stack and we will find out where we will return from this registration check. In my case the top of the stack says: RETURN to UDRuler.004BEC6E from UDRuler.004BAFF8. This means that when we are done checking if we are registered, the function will return to 0004BEC6E. The program will then test if AL is 0 and continue accordingly.

Before we go any further select line 004BAFF8 (where we set out breakpoint) and press F2 again to remove the breakpoint. Now, onto fixing the registration check.

To fix this registration check we want to find out where AL is being set. We know that it will probably be one of the last things the function will do before returning to 004BEC6E. Rather then step through all this code we can speed things up by pressing the Execute Till Return button. Go ahead and press it once, give Olly a few seconds and you will break here:

Look at the stack and you can see by following this return we will only return 3 lines down to 004BB330.

Press Step Over to follow the RETN to 004BB330. Continue to press the Step Over button until you reach the next RETN. Looking at the stack again we see that we will RETN to 004BB36D.

Press Step Over one more time until you are at 004BB36D:
This is the code that sets AL. How do I know? Look at the picture and see if it helps you follow along. We see that the first instruction sets EAX equal the the value in EBX. We know that AL is the LOW byte of EAX that means AL will be the same as the LOW byte of EBX. Looking at EBX we see that the LOW byte is 00.

Next there are some POPs. We then reach an instruction that moves the value from EBP into ESP. We know that ESP always points to the top of the stack, so if we move another value into ESP we also change the top of the stack. Look at EBP, in my case the value was 0012FF80. Looking at the stack we see that the line directly below 0012FF80 is the same line we saw when we entered the registration routine. This means that when we hit the RETN we will leave the registration function.

This is the code we will need to patch in order to register our program.

To change the registration check we want to move a 1 into AL. Select line 004BB36D MOV EAX,EBX and press SPACE to Assemble the line. In the box that comes up type MOV AL,01 and press Assemble. Our code should now look like the following:

Pay attention to the code location, and the BYTES that were written into that location. Write down all this information, we will need it when we create our patch.:
004BB36D: B0
004BB36E: 01

Well we patched the registration routine to always return registered. So let's test it out. Press RUN and lets see what happens... After the program loads, Right-click on the UDruler tray icon and choose ABOUT. The About box says we are registered! But what about the rest of the program? If you played around with the program before-hand you would have noticed that some of the functions were limited as a trial version. Example: You were not allowed to find the area and perimiter for the whole screen. So right-click the UDruler tray icon and choose Area+Permiter. The program now allows us to measure the whole screen. We have successfully patched the registration check!


Creating an Inline Patch:
The final step we are going to take is to create an inline patch for this program.
An Inline Patch can be used when a program is packed. We modify the program so that at the end of the unpacking routine, instead of jumping to the OEP, it jumps to our own section of code. We put that code section into a code cave. Our added code patches the now unpacked executable. And, after the executable is patched we jump to the OEP and run our modified program. So the first thing we want to do is find a place in the packed program to insert our own code. This is called a code cave, it is a section of memory in the packed executable that is empty. A code cave may sound like it is going to be hard to find but they are actually pretty easy.

Restart UDruler.exe in Olly. Do not run it, just let it load itself into memory. Now choose VIEW and then Memory from the drop down menu. You should see the following:

We are looking at the sections of memory that make up our executable. Doing the math we see that each section's beginning is at the other sections end. In executable files, often the code inside a section doesn't take up all of the section. That means there is often space at the end of sections that can be used to write code in. We are going to look for a code cave within the last section of this program.

The .rsrc section starts at 00526000 for me. So I'm going to close the Memory window and in the CPU window Right-Click and Go-To ->Expression. Type in 00526000 and press OK. You should end up here:

Now we are going to scroll down until we do not see anymore instructions. Just keep scrolling... When you continuosly see ADD BYTE PTR DS:[EAX],AL you are near the bottom of the section. Scroll back up until you see the last intruction for this section. I found mine here:
This means that all those 0000 instructions under the last instruction can be used for our code cave. I am going to start writing my code at 00528487.

Now before we begin writing code. We need to know what we are going to write. The instruction to overwrite code is a MOV instruction. We use it in the following way:
That instruction will MOVE the BYTE whose value is DATA into location ADDRESS. The DS in front of the ADDRESS just specifies the Data Segment. Each program in Windows memory has its own Data Segment to run in. We include it in front of the address so the program knows to write the information to the ADDRESS in this programs Data Segment.

Okay, remember the addresses and values you wrote down? This is where we use them. We changed the BYTE at ADDRESS 004BB36D to B0. So the first instruction we are going to write is: MOV BYTE PTR DS:[004BB36D], 0B0. (We add the 0 in front of the B so Olly knows that it is a value and not an instruction) Next, we changed the byte at address 004BB36E into 01. So the second instruction we are going to write is MOV BYTE PTR DS:[004BB36E], 01. The last instruction we want to write is a jump to the OEP. Look back at your notes to find the OEP. In my case, my OEP was 004BE9DC. So the last instruction we write is JMP 004BE9DC. When you are done it should look like this:

Now, Select ALL THREE lines you changed and Right-Click. Choose Copy to Executable -> Selection. A new window will open up. In that new window Right-Click and choose Save File. Save the executable as any name you want.

The last thing we need to do is change the Jump at the end of the unpacking routine to jump to our code cave. So gp ahead and close UDRuler and Open up the modified executable you just saved.

Now we need to go to the end of the packing routine. If you have a good memory you will remember that it is at offset 0052553B. If you don't have a good memory you can Right-Click and Search->Command. Type in JMP 004BE9DC. That will search for the instruction that jumps to our OEP. Either way, you end up at 0052553B. We need to change this jump so instead of jumping to the OEP it jumps to the first instruction of our code cave. In my case the first instruction in my code cave is at address 00528487. (Look at the picture above).

To change the line Select it and press SPACE. In the Assemble box type JMP 00528487. Press Assemble. You should see the following:
We are almost done! We just need to save this modification to our file.

Right-Click and choose Copy to Executable. In the window that opens up Right-Click again and choose Save File. I saved mine as UDFinal.exe. Go ahead and close Olly. The last thing to do is test it out! Double-Click your UDFinal.exe and, if you did everything correctly... It Works!!

We learned about the x86 registers. We then applied that knowledge to reversing a registration check. We also learned about code caves and how to find them. Finally we used code caves to create an inline patch for a packed executable. Hopefully with everything you learned you will be able to apply it to other reversing projects.


1. Introduction:

Todays lesson is gonna be about using Memory Breakpoints to get the desired output we want from Lost Marble's Moho v5.1. This not a new concept, but is usually not used the way it should be. The target program is a very cool app. So like usual ..."If you use the software you should buy it". Lets begin with the tutorial.

2. Patching:

We start out like usual.... The EP of the Program.

Now that we have that established... We need to figure out exactly what we are up against here.

So run the victim in Olly and see what kind of things the program will tell us about itself. First thing you see is this:

K... so we need a registration code either for this new version, or from older version. Continue to hit F9 till you reach the fully loaded program by clicking on the "DEMO" button. You will be here soon:

K.. now lets find out what some limitations are if we dont have a serial entered into program.

(this is from Help file, which is online)

"If you haven't purchased a copy of Moho, then the program will be running in "demo" mode. While in demo mode, Moho still allows you access to all features of the program. Anything you can do in the full version you can do in the demo. Also, any files you create with the demo version of Moho will still work fine if you purchase the full version.

The demo version has just two limitations: First, when you render your animation for final output, a "DEMO" watermark will appear on top of your animation. Second, if you export to the SWF (Flash) format, your animation will appear in black & white. If you purchase a copy of Moho, the demo watermark will go away, and you will be able to export SWF files in full color."

So our limitations are:

"DEMO" watermark on animations

Animations will be Black & White if output is in SWF format.

K so now we now what we have to do. We need to register the software. How you say? Well its very easy. :)

Go ahead and restart the victim and when the nag screen comes up enter inthe serial number of your choice. I chose "998899". and you will see another nag popup, saying "we havent entered in a correct serial"

K.. good. Now we have something to go on here. Lets right click in Olly's main CPU window and select "Search for", then "All Referenced Text Strings"

Then once we are brought to the strings screen, scroll up to the top, and search for "Registration".

Then we need to sit and think for a minute here..... Remember the nag at startup? Well.. what would cause that to popup. So our decision if "REGGED/UNREGGED" should take place there. Do you remember anything the nag said. It said something about entering serial, if you had old serial enter it now. Well instead of putting a BP on every REGISTRATION string, why not look for that? So continue to hit CTRL+L till you reach something that is almost like that, after 3 instances you do :) :

You see from above? Lets get into this section, hit "Enter" on any of the strings. I chose to hit Enter on REGISTRATION.

K... Now the idea is simple here. Somehow we reached this section, either by JMP or by Call. So scroll up till you reach the beginning of this section.

Now while on the PUSH -1 , you see in info box? We are called from another area.

So to find this place, right click on the PUSH -1, then "go to" , then "CALL 00448FE8"

Once there we will determine why we were called. Now pupils... we need to stop and really think about this (not too hard though), and figure this out. The main purpose of this tutorial is to show you how to use memory BP's. look below:

Our caller is highlighted in Blue. Above it we see 2 conditional jumps. The one of most interest to us is the TEST AL, AL

JE SHORT moho.00449013

The reason is simple. Since this is our first chance at jumping over nag, so why is it not doing it? Now you can see that it moves the value pointed by 0078058C to AL then tests this for a 0 or 1. So lets see what the offset 0078058C has stored, so we do the following.. right click the instruction, then "follow in dump", then "memory address":

once there we can plainly see that it holds:

hmm... theres our problem.. it is equalto 1, so we dont jump. W need to somehow make it equal 0. to do this we will use memory BP's. So we do the following... in dump hit CTRL+G, then enter in 0078058C, then restart the victim in Olly. Once we are ack at the EP, in dmp hit CTRL+G, then "enter" (cause offset should still be in popup in dump), then on that exact byte set a Memory BP on Write.:

Now we restart it, (in dump) hit CTRL+G, then highlight this first byte, and select "breakpoint", "memory, on write"

then we let the victim run with F9. You should break here:

Do you see anything interesting? hmm... The program moves a 1 to our magic pointer. so.. what do you think we can do ? Well? how about this:

Now we force a 0 upon this pointer. Now go ahead and let it run with F9, and you see something that is great... well nothing (no nag I mean), go ahead and test the limitations. it is fully working now. Only one byte needed.

3. Saving file, Renaming:

Okay now that we know what we need to patch let us save the file, lets say we use the saved name (for example) Moho_crk.exe (which is what i do to less confuse myself)

So on the edited code we right click, then Copy to executable, all modifications.

Then click on save.

So now we have a cracked file, no limitations on it anymore. Go ahead and have fun with it :)

But keep the lesson in mind today.. Memory Breakpoints are our friends.



Well' once since the first tutorial of the beginners series you learnt that there are different breakpoints and that the can be used in different ways, but no one till now (in this series of tutorials of course) told you what are the differencies among all the breakpoints types we can set. Even if you barely know what happens under the hood of breakpoints, it would suffice to understand why there are different usages for each of them.

First of all there's a big distinction between the breakpoints, there are Software Breakpoints and Hardware Breakpoints...

Hardware Breakpoints:

The latter ones, Hardware Breakpoints, are directly supported by the CPU, using some special registers, called debug registers.

There are four debug registers: DR0, DR1, DR2, DR3. They store the linear addresses of four breakpoints. The break conditions of each of these breakpoints are inside a special CPU register, the DR7 register. When any of these conditions are TRUE, the processor throws an INT 1 exception and the control is passed to the debugger. There are four possible breaking conditions foreseen by the CPU:

An instruction is executed
The contents of a memory location is modified
A memory location is read or updated, but not executed
An input-output port is referenced

Once you set an Hardware Breakpoint, the debugger will check to see if the trap bit of the flags register is set. If so, an INT 1 debug exception is generated automatically by the CPU, and the control is passed to the debugger, or generally speaking the exception handler registered in the system.

Since these few details you can see that there is a maximum of four hardware breakpoints you can set and that the number of possible conditions is limited by design.

The advantage on the other hand is that the Hardware Breakpoints are almost undetectable by the software, the only way they can use to detect that an hardware breakpoint is set is to read the DR0..DR7 values: a code could detect tracing (debugging) by analizing the flags register (DR7). Unfortunately, it is only possible to work with these registers in ring0.

As such, we can use some tricks for switching over into ring0. For example I'm reporting here an example taken from the Pavol Cerven's book "Crackproof your Software" (excellent reading I suggest to all of you).


Extrn SetUnhandledExceptionFilter : PROC
Interrupt equ 5 ;the interrupt numbers 1 or 3 will make
;debugging more difficult

message1 db "Debug breakpoint detection",0
message2 db "Debug breakpoint not found",0
message3 db "Debug breakpoint found",0
delayESP dd 0 ;the ESP register saves here
previous dd 0 ;the ESP register will save the address
;of the previous SEH service here

;Sets SEH in case of an error
mov [delayESP], esp
push offset error
call SetUnhandledExceptionFilter
mov [previous], eax

push edx
sidt [delayesp−2] ;reads IDT into the stack
pop edx
add edx, (Interrupt*8)+4 ;reads the vector of the required interrupt
mov ebx,[edx]
mov bx,word ptr [edx−4] ;reads the address of the old service of the
;required interrupt
lea edi,InterruptHandler
mov [edx−4],di
ror edi,16 ;sets the new interrupt service
mov [edx+2],di
push ds ;saves registers for security
push es
int Interrupt ;jumps into Ring0 (a newly defined INT 5h service)
pop es ;restores the registers
pop ds
mov [edx−4],bx ;sets the original INT 5h interrupt service
ror ebx,16
mov [edx+2],bx
push eax ;saves the return value

;Sets the previous SEH service
push dword ptr [previous]
call SetUnhandledExceptionFilter

pop eax ;restores the return value
test eax,eax ;tests to see if eax=0
jnz jump ;if not, the program has found a debug
;breakpoint and it ends

call MessageBoxA,0, offset message2,\
offset message1,0
call ExitProcess, −1

call MessageBoxA,0, offset message3,\
offset message1,0
call ExitProcess, −1

error: ;sets a new SEH service if there is an error
mov esp, [delayESP]
push offset continue

;Your new service INT 5h (runs in Ring0)
mov eax, dr0 ;reads a value from the DR0 debug register
test ax,ax ;tests to see if a breakpoint was set
jnz Debug_Breakpoint ;if so, the program jumps
mov eax,dr1 ;reads a value from the DR1 debug register
test ax,ax ;tests to see if a breakpoint was set
jnz Debug_Breakpoint ;if so, the program jumps
mov eax,dr2 ;reads a value from the DR2 debug register
test ax,ax ;tests to see if a breakpoint was set
jnz Debug_Breakpoint ;if so, the program jumps
mov eax,dr3 ;reads a value from the DR3 debug register
test ax,ax ;tests to see if a breakpoint was set
jnz Debug_Breakpoint ;if so, the program jumps
iretd ;if a breakpoint was not set the program will
;return 0 into eax

mov eax,1 ;sets the value 1 into eax to show that
;breakpoints are active
iretd ;jump back into Ring3

end Start

This technique is one of the few ways to discover debug breakpoints, and it makes possible to delete them without stopping the application in the debugger. However, rather than delete them, usually the application goes to an incorrect ending. Unfortunately, the trick (and all the other similar ones) works only in Windows 9x because of the need to switch over into ring0.

Generally speaking the Cerven's book mentioned describes three ways to switch a normal program running in ring3 into ring0, but only in Windows 9x. Windows NT, 2000, and XP systems were secured against these methods because of the prevalence of viruses that take advantage of them. (Older Windows NT versions did allow this switch, but after it was misused a few times, the possibility was removed from the system).
One still good way to implement these tests in Windows NT, Windows 2000, and Windows XP is to place them into a Sys driver running in ring0.

Concluding this section, then theoretically in order for a debugger to be invisible it needs to recognize the instructions for reading the flags register, emulate their execution and return always zero as value of the trap flags. Not that easy to be done indeed!

There's nothing much than this to say about Hardware breakpoints let move on on the more complex software breakpoint ..

Software Breakpoints:

A Software Breakpoint is the only type of breakpooints that cannot be hidden without writing a full-scale processor emulator. If you place this one byte of code -- 0xCC at the beginning of an instruction, it will cause an INT 0x3 exception when an attempt is made to execute it.

The handler of INT 0x3 gains control and can do whatever it wishes with a program. However, before the interrupt handler is called, the current values of the flags register, the pointer of the code segment (the CS register), and the instruction pointer (the IP register) are placed onto the stack. In addition, the interrupts are disabled (the IF flag is cleared), and the trap flag is cleared. Therefore, a call of the debug interrupt does not differ from a call of any other interrupt.

To learn the point of the program in which the halt has occurred, the debugger pulls the saved values of registers off the stack, taking into account that CS:IP points to the next instruction to be executed.

So generally it is complex to set a breakpoint in an arbitrary place of the program. The debugger should save the current value of the memory location at the specified address, then write the code 0xCC there. Before exiting the debug interrupt, the debugger should return everything to its former place, and should modify IP saved in the stack so that it points to the beginning of the restored instruction. (Otherwise, it points to its middle.)

What are the drawbacks of the breakpoint mechanism of the 8086 processor? The most unpleasant is that the debugger must modify code directly when it sets the breakpoints. It should be self evident that modifying the memory of a process (the 0xCC is written) is something that a program can easily detect and avoid in different ways. There are plenty of tutorials describing more or less smart ways to avoid a program from being "breakpointed". Common actions are to alterate the program's flow consequently or simply rewrite the 0xCC byte with the original value (the debugger will not stop).

For a program bein debugger a possible solution to discover whether at least one point has been set, is to count its checksum. To do this, it may use MOV, MOVS, LODS, POP, CMP, CMPS, or any other instructions.

For example let's take a look to the following simple protection scheme (from Karsperky Book, Haker Disassembling Uncovered), using the XOR trick to decrypt a string.

int main(int argc, char* argv[])
// The ciphered string "Hello, Free World!"
char s0[]="\x0C\x21\x28\x28\x2B\x68\x64\x02\x36\

BeginCode: ; The beginning of the code being debugged
pusha ; All general-purpose registers are saved.
lea ebx, s0 ; ebx=&s0[0]
GetNextChar: ; do
xor eax, eax ; eax = 0;
lea esi, BeginCode ; esi = &BeginCode
lea ecx, EndCode ; The length of code
sub ecx, esi ; being debugged is computed.
HarvestCRC: ; do
lodsb ; The next byte is loaded into al.
add eax, eax ; The checksum is computed.
loop HarvestCRC ; until(--cx>0)
xor [ebx], ah ; The next character is decrypted.
inc ebx ; A pointer to the next character
cmp [ebx], 0 ; Until the end of the string
jnz GetNextChar ; Continue decryption
popa ; All registers are restored.
EndCode: ; The end of the code being debugged
nop ; A breakpoint is safe here.
printf(s0); //The string is diplayed.
return 0;

After starting the program normally, the line "Hello, Free World!" should appear on the screen. But when the program is run under the debugger, even with at least one breakpoint set within the limits of BeginCode and EndCode, senseless garbage like "Jgnnm."Dpgg"Umpnf#0" will show up on the screen. Protection can be strengthened considerably if the procedure computing the checksum is placed into a separate thread engaged in another useful process, making the protective mechanism as unobtrusive as possible.

The above code uses a property of thre XOR operator you might have forgotten, which is A B A = B. That is why it's often used for weak data encoding. If you XOR a plaitext data with a key, you get "ciphertext" back. If you XOR the "ciphertext" with the key, you get the plaintext back. And if you know the ciphertext and the plaintext, you get the key back.

If the above case the key used is directly obtained from the code among the BeginCode and the EndCode addresses

Let see it directly into Olly (using the supplied main.exe into this archive).

You can find again what we just wrote in the C code above. Try excercising yourself with this protection, it's not so uncommon to find it in weak protected programs in real life...if you excercise here, you'll be ready to recognize it whenever you'll find it..

Of course the above sample is simple, consider that the code might be complicated using exception, thread and other amenities to complicate lifes of who, like us, likes to follow the ASM code..

Note for those of you who read the Shub-Nigurrath Oraculum's tutorial
For those of you which have read the ARTeam's Oraculum Tutorial you should also wonder that the "EBFE" trick used there is somehow similar to the memory breakpoints described here. Well the mechanism is similar just for the fact that it writes a value in memory in the place where we want the break to occour. The difference is that there's no exception raising and that the check to suspend the program is simply made looking at the EIP being constant.

This will overcome those protections only checking the exception status or the 0xCC value being present, but not those doing complex checksums on memory.


As you can see there are different usages for breakpoints just because they are implemented differently, but consider that none of them is undetectable, thus do not rely, once a breakpoint is set, on your program to stop on it. Always be aware that the program can detect it's presence and delete it or modify itself behaviour to counteract an attack.

I suggest the following further readings from now on to complete this argument..

Kris Karspersky, Hacking Disassembling Uncovered, a-List Press
Pavol Cerven, Crackproof your software, No Starch Press
Shub-Nigurrath, Oraculum Tutorial With Framework Src V11, ARTeam
Shub-Nigurrath, Gabri3l, Serial Fishing And Oraculum For Weblink, ARTeam
Gabri3l, Writing A Loader 4 Softwrap 6.1.1, ARTeam
and essentially all the tutorials seens around (also others on our tutorials page) which always make use of breakpoints..


The Target:
MP3 Cutter Joiner v1.8
The Tools:
PEID, Ollydbg 1.10, HexWorkshop 4.23
The Protection:
Other Information:
This tutorial combines both Beginner Tutorial #7 and Beginner Tutorial #8. It will cover a protection which I call "Magic Bytes". A program using Magic Byte protection sets a BYTE located somewhere in memory equal to 0 or 1 to represent Unregistered and Registered. If we can locate that BYTE we can reverse it and, like magic, we allow the program to run as Registered. In this tutorial we will take that a step further and locate where the BYTE is written and change the program to always write 1 to that memory location. We will then reverse any attempt to overwrite that byte so we will always stay registered. We will learn more about the program by examining it's API calls. And finally learn how to register the program without changing any bytes in the original executable.

Best viewed in Firefox at 1280x1024


All the tools you will need can be found online:

As usual, first get your program set up and ready to crack. Make a quick backup so we don't screw anything up when working on the file. Now begin by opening MP3 Cutter Joiner.exe in PEID to see if it is packed. The result:

Borland Delphi. There are a few different ways to reverse the protection scheme of a Delphi application A very popular method is to use DeDe. Which is a delphi decompiler. By using DeDe you can decompile the program down to very simple code. You can also recover the forms and find out what functions are called when you click on a button. As useful as DeDe is, we are not going to use it this time. But keep it in mind if you ever encounter a delphi application. For more DeDe information check out Cracking CaptureNPrint By Shub-Nigurrath


Finding the Magic Byte:

I want to start with a little information on what a magic byte represents. The magic byte is also called a Boolean variable. A boolean variable can only have two values: 1 or 0. When writing a computer program you often times want to represent something as TRUE or FALSE. The easiest way to do this is by creating a boolean variable and setting it equal to 0 for False and 1 for True. In this particular program the boolean variable determines whether or not we are registered. So the Magic Byte (Boolean Variable) will be equal to 0 (False) if we are not registered and equal to 1 (True) if we are registered. This type of protection was first introduced to you in Beginner Olly Tutorial Part7 by MaDMAn H3rCuL3s. MaDMAn H3rCuL3s showed you how to find the Boolean Variable by using memory breakpoints. In this tutorial we will use Hardware breakpoints and there will be more than one location we need to patch.

Okay, now that we know what a Magic Byte is, lets start reversing. Open up MP3 Cutter Joiner in Ollydbg. You should be at the OEP:

Figure 1

We are going to begin by seeing if we can locate any interesting strings that may help us reverse this program. Right-Click and choose Search for->All Referenced Text Strings. You should see the following:

Figure 2

We are going to search for a common word that may help us reverse this program: "register". Right-Click->Search for Text and in the box that comes up type "register" without the quotes. UNcheck Case Sensitive and Check Entire Scope. You'll first break on "RegisterAutomation".

Figure 3

That isn't useful. So press CTRL+L to search for the next occurrence of "Register". You will break on "tfm_register". That isn't good either. Continue to press CTRL+L until you see the string: "Sorry, you have converted 30 files. Please register!". (In version 1.08 the string has changed to "Sorry, you have converted 15 files. Please register!") That string looks good, Double-Click it and you will land in the code section. Scroll up until your image matches mine:

Figure 4

I have commented the code to give you a better idea of what is happening. Looking at the code we see that there are two conditional jumps that can jump over the "Sorry you have.." nag. The last conditional jump we see compares the value at 004CEE64 to 1E. Which we know from previous tutorials to equal 30 in decimal. So we can assume that the value at 004CEE64 is used as a counter of how many conversions we have made. When we reach 30 or 1E the program gives us a nag.

But before we get the the comparison jump; the first jump compares the value at location 004CEE56 to 0. If 004CEE56 is not 01 then we continue to the 1E compare. Now if we are registered there is no reason to ever check how many conversions we have made. So obviously that first conditional jump tests if we are registered. If we aren't then the program will test to see if we have reached the limit of 30 conversions. Well we want the program to always think we are registered. The Byte at location 004CEE56 is determining whether or not we are registered. If we can change that byte we can make the program think we are registered. So, in Olly's dump window Right-Click and choose Go To->Expression and type in 004CEE56. You should see the following:

Figure 5
We know that the program will probably test our registration and then write 00 if we are not registered and 01 if we are. We want to try and find out where in the executable 004CEE56 is being written to. We are going to set Olly to break whenever the program writes to location 004CEE56. So choose that BYTE and Right-Click Breakpoint->Hardware, on Access->Byte. The program will now break whenever 004CEE56 is accessed by MP3 Cutter Joiner. For more information on the different types of breakpoints and how to use them be sure you have read Beginner Olly Tutorial Part8 by Shub Nigurrath

Figure 6
We have our breakpoint set on the magic byte. So we can now press RUN and allow the program to load. You should break at the following location. I added a comment, we can see that the program initializes by writing 0 to 004CEE56. Scroll up until your code matches mine:

Figure 7
The program begins by writing a 0 to 004CEE56, that is somewhat smart programming. If the program wrote a 01 to the code location we could bypass the registration scheme and be registered. Let's start by modifying the program to do just that. We are going to change the program so that it will now write a 1 to our magic byte location. Select 004C5070 and press SPACE to Assemble the line. In the box that comes up change MOV BYTE PTR DS:[4CEE56],0 to MOV BYTE PTR DS:[4CEE56],1 and press Assemble. Your code should now look like this:

Figure 8
Since we have already executed the MOV BYTE PTR DS:[4CEE56],0 our magic byte is currently set to 0. So we want to change our Magic Byte to a 01 also. In Olly's dump window, select the BYTE at 004CEE56 and press SPACE. In the box that comes up change the 00 in the HEX section to 01. Press OK to save what you changed.

Figure 9
Before we continue, we are going to think logically. We see by the code in front of us that the program initializes itself by writing 0 to our Magic Byte. However, by looking at the code we see that there are no conditional jumps around so the program is going to write 0 if we are registered or not. This means somewhere else in the code the program tests if we are registered. It will then decide to write a 0 or a 1 on top of our Magic Byte.

Through testing this program I found that our hardware breakpoint does not break the next time our magic byte is accessed. And if we use a Memory Breakpoint as we did in MaDMAn H3rCuL3s' tutorial we will encounter an exception in the program. I will explain why this happened in a few paragraphs. To find where the program writes the 0 or 1 we are going to step through the next couple lines of code. Keep an eye on the Magic Byte in Olly's dump window. Now press F8 to start stepping through the code. After each time you press F8 look at the Magic Byte and make sure it is still 01. Stop pressing F8 when you see it change back to 00. You should be at CMP BYTE PTR DS: [4CEE56],0 when 004CEE56 changes back to 00:

Figure 10
Somehow the program changed our Magic Byte back to 00. And it happened inside CALL MP3_Cutt.0041B4F4. We are going to find out where in that CALL our Magic Byte was changed. Select CALL MP3_Cutt.0041B4F4 and press F2 to set a breakpoint on that CALL. Okay we can remove our Hardware breakpoint by selecting the DEBUG menu and choosing HARDWARE BREAKPOINTS from the dropdown menu. A window will open up with the Hardware Breakpoints you have set. Press the DELETE button next to any breakpoints that are set and press OK. Now, Restart MP3 Cutter Joiner in Olly.

When our program is at the OEP, choose VIEW from Olly's menu and from the dropdown menu choose PATCHES. The Patches window in Olly saves all the changes we made to the code. Instead of trying to find where the program wrote 0 to our Magic Byte again and fixing it again, we can look at the Patches menu and fix it there. In the Patches window choose 004C5070 and press SPACE this will activate the patch:

Figure 11
With our changes now activated close the Patches window and go ahead and press RUN to start MP3 Cutter Joiner.You will break on our CALL MP3_Cutt.0041B4F4. Let's take a look at our Magic Byte; In Olly's dump window Right-Click and choose Go To->Expression and type in 004CEE56. You will see that our Magic Byte is currently 01. That's good, our patch worked so far. Okay, press F7 to step into CALL MP3_Cutt.0041B4F4. You should be here:

Figure 12
Continue to press F7 and when you reach CALL NEAR DWORD PTR DS:[ESI+8] you should Step Into the CALL and be at the following code: If you code does not look like mine you need to remove the Analysis. Right-Click choose Analysis->Remove Analysis from Module

Figure 13
We are going to continue stepping Into the CALL's until we find where our magic byte is being overwritten. Press F7 twice and you will have Stepped Into the CALL MP3_Cutt.00408F88. Continue to press F7 until you reach LEA EAX,DWORD PTR SS:[ESP+4] You should be here:

Figure 14
Because Olly can get confused sometimes we had to remove the code analysis. When Ollydbg applies analysis sometimes it doesn't always get the ASM functions correct. Sometimes it will mistake a series of functions for an ASCII word. When this happens we end up seeing junk code as you saw. We can remove the analysis to help us step through the code. But when we are finished stepping through the code it is best to reaplly the analysis to help us understand what is happening. Since we are outside of the junk code we can now reapply the Analysis. Press CTRL+A to Analyze the code again. Your code should now look like this:

Figure 15
After applying the Analysis we see that we have a call to ReadFile coming up. The function of ReadFile can be found in the Windows API. See Figure 16. Basically ReadFile reads a certain amount of bytes from an address location and it then writes those bytes to a new location. Looking at Figure 16 we can say that ReadFile reads nNumberOfBytesToRead from lpAddressOfBytesRead and it then writes those BYTES into the lpBuffer.

Figure 16
How does the Windows ReadFile know what bytes to read/write? We encountered this in Beginner Tutorial #3 when we modified the MessageBox function in L0pht5. nNumberOfBytesToRead, lpAddressOfBytesRead, lpBuffer, hFile, and lpOverlapped are al variables called Arguments and they are defined by the program calling the function.When a program wants to use an Windows API function it has to pass the function values for each of the functions arguments. However it is important to know that there are two "classic" ways that arguments are passed to API functions. These two methods of passing arguments are called the C Calling Convention and the PASCAL Calling Convention.

The function ReadFile's arguments look like this:
ReadFile (hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped)
To pass these arguments to the function we need to PUSH them onto the stack. The Calling Convention determines in what order variables are PUSHed onto the stack.

The C calling convention PUSHes arguments from Right to Left.
Using the C Calling Convention variables would be passed like so:
PUSH lpOverlapped
PUSH lpNumberOfBytesRead
PUSH nNumberOfBytesToRead
PUSH lpBuffer
PUSH hFile
CALL Kernel32.ReadFile

The PASCAL calling convention is the opposite of the C Calling Convention. The PASCAL calling convention passes arguments from Left to Right. Using the PASCAL Calling Convention variables would be passed like so:
PUSH hFile
PUSH lpBuffer
PUSH nNumberOfBytesToRead
PUSH lpNumberOfBytesRead
PUSH lpOverlapped
CALL Kernel32.ReadFile

By looking at the registers in Olly we can determine the arguments that will be PUSHed onto the stack and what those values mean to the ReadFile function. We can even determine that this program uses the C Calling Convention

PUSH EAX: The ADDRESS to READ the BYTES FROM is EAX: pNumberOfBytesRead = EAX = 0012FA58
PUSH EDI: The NUMBER of BYTES to READ is EDI: nNumberOfBytesToRead = EDI = 00000001
PUSH ESI: Where The BYTES will be WRITTEN is ESI: lpBuffer = ESI = 004CEE56 ***OUR MAGIC BYTE LOCATION!***
PUSH EBX: The HANDLE to the FILE is EBX: hFile = EBX = 00000190

I hope all of that made sense. If you are having a hard time following just press F7 until you reach CALL . Look at the stack window and you will see that the values have filled themselves in:

Figure 17
Looking at the stack we can see that ReadFile will read only 1 byte and then wrote that byte to 004CEE56.
If you remember back I told you that when I set a memory breakpoint on 004CEE56 it threw an exception. Well, this is why. The program used ReadFile to write overtop of our magic byte. However, when a memory breakpoint is set it effectively "reserves" that byte. When it a program tries to access that byte the breakpoint traps that instruction and throws an exception telling the debugger to stop. In this case the memory breakpoint was trying to trap the attempts to write to that location, but when ReadFile tried to write to there, it failed and threw an exception in the ReadFile function rather than in the debugger. This is why we had to step through the code rather than relying on a breakpoint. Now, from the last time we ran the program we know that MP3 Cutter Joiner will overwrote our Magic Byte at 004CEE56 with 00. It did it by using the windows API function ReadFile. We don't want our Byte to be overwritten! There is an easy and elegant fix for this.

Right now the BYTES are being read from EAX and written to ESI. What if we changed the values so that ReadFile read the values from the same place it was writing them to? It would basically make ReadFile do nothing. We can easily do this by changing the register that is PUSHed as the Buffer. We are going to change them so it reads and writes to EAX. Select the PUSH ESI in Olly and press SPACE to Assemble. In the box that opens up change PUSH ESI to PUSH EAX and press Assemble. Your code should now look like this:

Figure 18
The program will not overwrite our Magic Byte anymore. So we should always be registered. Okay, now that we have made that modification; Restart MP3 Cutter Joiner in Olly. When you are at the beginning of the program, apply both Patches from the Patch Window. Go ahead and press RUN...

Figure 19
We did it! We located the Magic Byte. We found out where the program was overwriting the Magic Byte and fixed it to stop overwriting it. Finally we successfully made the program think it is registered by manipulating the Magic Byte to always equal 1.

Further Analysis and Patching:

For all purposes we have defeated the Magic Byte protection scheme. However in this second part we will delve deeper into the program to try and better understand the protection. Let us review what we know about the programs protection:

The program uses a boolean variable to store our registration information
The boolean variable is located at the offset 004CEE56
The program initially writes a 0 to the magic byte location
The program then reads a byte from a second file and writes that byte overtop of our magic byte
There are many weaknesses in this protection scheme. We have already patched the program to write a 1 to the boolean variable location. We then disabled the ReadFile function that was overwriting our magic byte. However there is another weakness in this protection that we have not covered. Instead of patching the program we can instead locate the file that our "unregistered" byte is read from. If we were able to find and patch this second file we could change the 0 in it to a 1. There would be no need for any patching of our original program. This is exactly what we are going to do in this second section.

The first thing we need to do is try and locate the file accessed by ReadFile. To do this we need to learn a little about how the Windows API accesses files. We already learned about how ReadFile works, but ReadFile depends on variables supplied by other Windows API functions. One of the first parameters required by ReadFile is hFile. Looking back at Figure 16 we see that hFile is the handle of the file to read. Well, where does that handle come from and how is it assigned? Before any program can read from or write to a file, Windows first needs to open that specific file. Assume you wrote a program and wanted to open File1 and copy it to File2. Windows opens File1 and assigns it a unique identifier called a handle it then does the same for File2. You can now pass the handle of File1 as a parameter to the ReadFile function. Once Windows reads in the information of File1 you can pass File2's handle to WriteFile. Now windows will write your information to the File identified by the File2 handle. If you switched the handles for File1 and File2, the program would then do the opposite.

We know why the file handle is important, now we need to know where Windows assigns that handle. Windows assigns file handles through the CreateFile API function. Don't be confused, even though the API is called CreateFile it is also used to open already existing files. We can learn more about CreateFile online, Microsoft is kind enough to document most of it's API functions on the internet in what is called the MSDN or Microsoft Developers Network. The CreateFile function is explained here:

The CreateFile function creates or opens a file, file stream, directory, physical disk, volume, console buffer, tape drive, communications resource, mailslot, or named pipe. The function returns a handle that can be used to access an object.
Since the file handle is unique to each opened file. If we know the file handle then we can easily figure out what file it corresponds to.

I think we know everything we need to know right now. So let's begin by opening the original MP3 Cutter Joiner in Olly. When we are at the OEP we are going to put breakpoints on every call to the CreateFile API functions.

Figure 20
Now that we have our breakpoints set go ahead and press RUN. The program will load and you should eventually break here:

Figure 21
If you look down a little bit you can see the CALL to ReadFile that overwrites our Magic Byte. So we know we are in the right place. Look at the stack to determine the arguments that are being passed to CreateFileA:

Figure 22

On the stack you see the argument "FileName" with the value "C:\WINNT\System32\SysCut.dat". So we know that the file to be opened or created is going to be SysCut.dat. Well how are we going to find the Handle that CreateFile assigns? Hopefully, if you read Beginner Tutorial #5 you know that the Windows API functions most commonly return their values through EAX. To get the FileHandle for SysCut.dat all we need to do is execute the CreateFileA function and then look at the value in EAX. Let's do that.
Press the Step Over button One time. CreateFileA should execute and you should be on POP EDI. Now take a look at the Registers Window:

Figure 23

The value of the FileHandle for SysCut.dat in my case is 00000190. Now we need to see if this is the same file that is being accessed by ReadFile. Scroll down and set a breakpoint on the CALL :

Figure 24
Now Press RUN. You should break on CALL . Look at the Stack in Olly to see the arguments for this call to ReadFile:

Figure 25
Take a look at hFile it equals the FileHandle for SysCut.dat. ReadFile is accessing SysCut.dat! However, look at the value for Buffer and the number of BytesToRead. Our Magic Byte isn't being overwritten, instead 4 BYTES are being Read from SysCut.dat and written to 004CEE64. ReadFile is obviously being called more than once. Make a note of the fact that 4 Bytes are being read.

Okay let's press RUN again and try and find when our Magic Byte is being overwritten. You should break on ReadFile again. This time the stack looks like we expected it to:

Figure 26
We have now confirmed that SysCut.dat is the file that holds our registration information. By looking at the stack we see that 1 Byte from SysCut.dat is being used to overwrite our Magic Byte. If we can patch that one byte we can make the program run as registered without changing any patching of the executable at all!

Just to be safe, Press Run again and see if SysCut.dat is accessed again... No, it is not. We can now move on to patching SysCut.dat.

Locate SysCut.dat in you System32 folder, and open it up with HexWorkshop. The first thing you will notice is that it is only 5 Bytes:

Figure 27
Currently SysCut.dat is all 00's, we need to change one of those 00's into a 01. But which one? Well, our first ReadFile accessed 4 Bytes and our second ReadFile accessed only 1 Byte, that was our registration byte. This means that the first 4 Bytes of SysCut.dat are used elsewhere in the program but the 5'th byte in SysCut.dat represents whether or not we are registered. If we change the 5'th Byte in SysCut.dat to a 01. Hopefully we will be registered.

Position your cursor just before the last byte in SysCut.dat and type 01. The file should now look like this:

Figure 28
Choose File->Save and overwrite the original SysCut.dat. We can now test out our ORIGINAL MP3 Cutter Joiner.exe and see if it is registered...

Figure 29
Excellent! We used our knowledge of the Windows API to locate our Magic Byte. We found what file the magic byte was located in, and exactly where in the file it was located. We then successfully registered the program without changing a single byte of the original executable!

You may come across other programs that use a boolean variable to check registration, whether the Magic Byte is located in the executable or in a separate file, hopefully you will be able to apply what you learned here to other targets.