OllyDbg (http://www.ollydbg.de/) is an application debugger with support for limited code analysis. A lot of professionals swear by OllyDbg, and as a debugger it's easy to see why. From a code analysis standpoint, it's lacking when compared with IDA Pro, but as a debugger, IDA Pro can't hold a candle to OllyDbg. By using the two programs together, you get the best of both worlds. Whenever I'm tasked with quickly reverse engineering a binary, I usually have IDA Pro open in one window and OllyDbg open in another.
If you've ever used a graphical debugger before, then OllyDbg's interface will already be somewhat familiar to you. It has all the standard windows and tracing features that you would expect from a modern debugger.
Like most debuggers, OllyDbg supports both software and hardware-assisted breakpoints and watchpoints. To set a breakpoint, click on the line that has the address you want to set the break or watchpoint at, right-click and select Breakpoint → Toggle. You can also set conditional breakpoints by choosing Breakpoint → Conditional. Setting watchpoints or hardware-assisted breakpoints is done by selecting the appropriate options from this menu.
OllyDbg supports all the standard stepping options: F7 will step info, F8 will step over, Ctrl-F9 will run until return. There is also the option to run until the program reaches user code by pressing Alt-F9. This feature can be useful if you find yourself tracing deep into a system library and want to quickly return to the application's code.
There is another set of stepping routines that is somewhat unique. OllyDbg lets you step into and over code by pressing Ctrl-F7 and Ctrl-F8. This will perform the stepping operation just as you would expect, only it will do it slowly enough that you can actually see the instructions executing one by one. This can be useful if you want to quickly get a handle on how the execution flows through a small region of code without taking the time to set up trace points and watch the log.
Most of the data you will need while debugging can be found on the CPU menu, either in the context-specific information displayed beneath the disassembly window, in the memory window, or in the registers window. If you need to view memory in a memory segment other than the one currently displayed in the CPU window, you can open up a dump window for the other segment by double-clicking on the segment you want in the segment window.
Compared with IDA Pro, navigating the disassembly is a bit limited but it has just about everything you need. To see the basic options for navigation, go to the CPU window and right-click; then select "Go to". Here previous and next work just like forward and back do in IDA Pro. You can also choose to go back and forth through the function calls the process has made by selecting "Next procedure" and "Previous procedure." You can specify a location to return to at any point by right-clicking and selecting "New origin here." Then when you are ready to return to this point, right-click and select Go to → Origin.
If you find yourself in need of more than one origin, you can set a location as a bookmark. This is useful when you have a complicated program where you need to keep track of several points of interest. To set a bookmark, right-click on the location and select Bookmark → "Insert bookmark". Later, when you want to recall the bookmark, choose Plugins → Bookmarks → Bookmarks to open the bookmarks list.
The ability to edit a running program's memory, code, and register values is probably the thing that OllyDbg does best. To edit code or register values, double-click on the entry you wish to change. For code sections, it will actually let you specify the new value as an assembly mnemonic. This makes patching a running executable very easy. If you want to edit data, you will need to select the region you wish to edit and then right-click and choose Binary → Edit.
Another useful editing feature supported by OllyDbg is the ability to copy sections of code or data and paste them back later. This makes the task of adjusting code by a few bytes to insert an instruction or two much easier. In the next section, you will see how useful this can be when modifying code. To copy binary data, select the data you wish to copy, right-click, and choose Binary → Binary Copy. To later paste it back, select the entire region you would like to paste it back to and again right-click and choose Binary → Binary Paste. Be sure you select a large enough region to paste or it will only paste in part of the binary data.
As you make changes to the code sections of the binary, the patches window will contain a listing of modifications you've made. You can enable and disable these edits at any time by toggling them in the patches window. They will even remain saved for future debugging sessions on the same executable so you don't have to redo tedious edits every time.
If at any point you find that you've edited something that you shouldn't have, you can revert the changes by selecting the effected areas, right-clicking, and choosing "Undo selection".
Often when you edit a binary, you want to make those changes permanent. OllyDbg will let you save your changes to the executable so they remain changed for future executions. To save them, select the effected areas of code, right-click, and choose "Copy to executable" → Selection. You should then see a dump window; right-click anywhere on this window and choose "Save file" to save the file to disk.
Earlier, while using IDA Pro, we found some bugs in the FreeCiv server that would let us trick the server into giving us lots of gold and giving an AI player lots of debt. In this section, I'm going to show you how to use OllyDbg to implement this hack.
We need to edit some code in the client because it is programmed to not allow us to send the kind of invalid data we need to. The code we need to edit is part of the diplomacy screen. The plan is to replace the code to send one of the treaty options with code to send the negative gold amount that triggers the integer overflow. This code is at address .text:004A2A40
and should look like this:
push ebp mov ecx,50 mov ebp,esp sub esp,18 mov eax,dword ptr ss:[ebp+8] mov dword ptr ss:[esp+4],ecx mov dword ptr ss:[esp],eax call <jmp.&libgobject-2.0-0.g_type_check> mov dword ptr ss:[esp],eax mov edx,civclien.004E65B0 mov dword ptr ss:[esp+4],edx call <jmp.&libgobject-2.0-0.g_object_get>xor ecx,ecx
mov edx,8
mov dword ptr ss:[esp+10],ecx mov dword ptr ss:[esp+C],edx mov eax,dword ptr ds:[eax] mov dword ptr ss:[esp+8],eax mov eax,dword ptr ss:[ebp+C] mov eax,dword ptr ds:[eax+4] mov eax,dword ptr ds:[eax] mov dword ptr ss:[esp],civclien.0053E9E0 mov dword ptr ss:[esp+4],eax call civclien.0045EC90 leave retn
Here the two highlighted lines must be changed to this:
mov ecx, 0x800000FF mov edx, 1
The first change will set the amount of gold to be large enough to trigger the overflow; the second changes the type sent to the server from shared vision to gold. So after the modification, if you set a treaty option for shared vision, it will send the hacked message instead.
Open civclient.exe in OllyDbg; after it has paused the executable, right-click on the CPU window and choose "Go to" → Expression. In the box, type 4A2A40
and press Enter. You should now see the code you need to edit. Start by selecting the first line you want to edit (xor ecx, ecx
). Right-click on it and choose Binary → "Fill with NOPs". You should now see it replaced with two NOP instructions. The next thing to do would be to insert the replacement instruction, but if you try, you will find out that the new instruction needs five bytes and the old only took two. We must use the padding at the end of the function to steal the three bytes we need.
First we will need to copy the binary section for the bottom half of the function so we can move it and create the room we need. Do this by selecting all the lines starting from mov edx, 8
and ending with retn
. Then right-click and choose Binary → "Binary copy". Now select mov edx, 8
, right-click, and choose Binary → "Fill with NOPs". We now have room enough to edit the first instruction. Double-click on the first NOP and enter the replacement instruction.
We now need to move the remaining code down three bytes. To fit it in, we will need to take up some of the pad space at the end of the function. After retn
, you should see some instructions used for alignment. Right-click on the first line after the retn
and using the same procedure as before, fill it with NOP instructions. We now have room enough to paste the remaining code back. Select all the lines from the first remaining NOP instructions to the last NOP instructions you just created. Right-click and choose Binary → "Binary paste" from the drop-down menu to paste the code back. Now that you've pasted that data back, double-click on mov edx, 8
and change the 8
to a 1
.
If you were to run this now, it would crash because the binary paste we did made an exact copy of the code that used to be there. The problem here is that most compilers generate relative call
instructions, so if the function call that is made at the end of this routine is run now, it would be accessing a location that was three bytes off from where it should be. To fix this, you need to patch the call
instruction and subtract 3 from the offset to which it is calling. Once that is done, you should have a working exploit.
The procedure to run the newly hacked client to exploit the bugs we've found is as follows. First, declare war on an AI player in order to have a guaranteed bargaining penalty when negotiating a treaty. Use that penalty calculation to trigger the integer overflow. Second, go to the players' screen and open a meeting between you and the AI player; add a peace treaty to the offering. Third, add shared vision to the offer. The hack we have made has replaced the shared vision offer with an invalid offer of gold. You should now see that you are offering a massive debt and mysteriously, the AI player is eager to accept the deal. Accept the deal: you will get rich, the AI player will be poor, and the peace treaty will be signed before the turn is over. This is why no one will ever play me at online games; at least no one that knows me.