Tutorial: Codecaves in Ollydbg

Hi all.

 First off: what is a codecave?

A rough description of a codecave would be a bunch of addresses usually set with a value of 0 (add [eax],al) in succession - basically an area with a bunch of unused memory. Using Ollydbg, we can modify a program's instructions, and redirect flow of execution. A codecave allows us to write our own code into its space, since nothing important is really occupying it. By combining these two things we can successfully modify the code of many programs, including online games, by redirecting the flow of execution and jumping to our own instructions that we write into a codecave.

So, open or download OllyDbg and run it. Then run your desired process and go to File -> Attach on Olly's menu, and attach it to your process. You should then see a ton of stuff in Olly's windows - this is the process' addresses and instructions, and alot more. What we want to do is find what address the game starts at. Do this by opening cheat engine and pressing "Memory view", the first address it shows in the top window will be its entry. In our case, we want this because we are going to call a function right when the game begins, using a codecave. For DragonNest, the entry address is currently 0x013D3000. Then go to this address in olly by right clicking and going to Goto -> Expression, then put the address in the box and it will go to it.

When you get to your address in Olly, scroll down the list until you find a codecave, as seen in the following screenshot:



So, we're going to use this space to put in some custom code. For this example we'll be using the Messagebox function. It would look like for us: MessageBox(0,"Hello",0,0) - very simple parameters. All we have to do is put a call to the messagebox with those parameters into our codecave. We have to do this in assembly language. We need to push the parameters on the stack, then call the function, since memory reads downwards, you cant call a function without having the parameters in place first!

PUSH 0 <--- refers to function's LAST parameter
PUSH 0 <---- Second last parameter
PUSH 013d310E <--- second parameter, the messagebox text.
PUSH 0 <--- First parameter
CALL MessageBoxA <--- call to the function

This equates to: MessageBox(0,"Hello",0,0) in C++. Because we need to store the text "Hello" somewhere, we need to also put this in some area of the memory: the codecave, once again. So you can right click on some bytes, click "binary -> Edit" and write some text in the ascii box as to what you want your Msgbox to say, after unticking "fix to size". We then PUSH the address containing our text to the stack as the second parameter.

So, edit the codecave as follows in the screenshot:



Now, we needed the programs startup address so that we could directly jump to our codecave, so go to your starting address (0x013d3000 for DN), and click on the assembly instruction and change it to JMP XXXXXXXX, where X is the address of the first "PUSH 0" in your codecave. Congrats, this is enough to get the program to open the messagebox as soon as it starts. But since we overwrote the bytes that are normally there, we need to stick them onto the end of our codecave so that our process still executes normally after calling the messagebox, or else it wont run, or will crash.

If you check out the first assembly instructions at 0x013d3000, youll see: sub ESP,4 in the first line, PUSH eax in the second, and PUSH ebx in the third. Since in assembler a JMP-to-address takes up 5 bytes, we need to make sure that the 5 bytes that this jmp takes up are placed after our messagebox call.

So, we can now put Sub ESP,4 into the line under Call MessageBoxA in our codecave, and below that, put PUSH eax, then PUSH ebx. These 3 lines combined takes up 5 bytes - the exact number that we overwrote with our jmp call - perfect! we want to execute these three instructions after our messagebox, then jmp back to our entry address + 5.why? because if we jumped back to the origin, it would just be jumping back to our messagebox, since we modified the origin to jump to our messagebox. Since the jmp is 5 bytes we need to return to the 5 bytes after it when we've executed the overwritten code, so the program can keep working. So once again, change the instructions in your code cave according to the highlighted lines in screenshot:



Since all your changed code will be in red (mine isn't in the last SS, dont worry), you can now drag the mouse and go over all of it, then right click and select copy to executable -> Selected. After the new child window pops up, click the "X" button to destroy it, say yes to the dialog and enter a name for the new executable. If all has gone well, You should get a messagebox saying "Hello" when you open DragonNest.

Tutorial open to any critique or relevant additions. Thanks for reading.

1 comment:

  1. could you give a pratical example, what code you could put into the CodeCave and execute ?
    Some fancy hack or using Win API ?

    ReplyDelete