Wherein newbie disassembly queries are made

I'm relatively(read: stupid newbie) familiar with disassembly but this bit stumped me: I have a set of save files compressed with zlib and a game that loads them. Their structure is known and once loaded, the structs in memory are identical to their corresponding save files. The issue is that the game was written in an ass-backwards, scripting-only-not language that somehow manages to leave no static pointers. At all. Several dozen people tried, and seemingly static pointer paths would break after minor changes on the same machine. An easy solution would be to just search the process' memory for the contents of the files, but this is a pretty bruteforce solution which I would rather avoid for educational purposes.

The Questions:

  • I'm trying to use OllyDBG. I am terrible at it, but nevertheless managed to make some trivial codecaves that actually worked. Am I using the right tool for the job or am I a stupid newbie? What tools does the modern reverser have in their kit?
  • On a related note, I have to resort to using Cheat Engine(or its cousin MHS) for memory searches. This seems a bit counterintuitive. Does OllyDBG really give you no way to search for values and refine results or am I missing something?
  • How do you set breakpoints on WINAPI? Hell, how does WINAPI look like at assembly level? This is something I haven't managed to find any decent information about and I'm pretty sure that Google has more than enough of it but I just can't seem to type the right words in.
  • Expanding on the above, how does one set dynamic breakpoints? If I am interested in a specific, often called function but only if EAX at that point is equal to a specific value, how would I get Olly(or anything else) break on that condition?
  • Any general books/suggestions/resources on disassembly or low level programming oriented at breaking things.

Disclaimer: game in question is freeware, single-player, author does not disapprove, project intended to extend functionality more than anything. Also first post, hopefully I haven't fumbled too badly. :(

13.10.2009 21:12:17

You have a lot of questions rolled into one. I'll try to answer some.

OllyDBG is a fine free disassembler. Professionals may pay for IDA-Pro, but that's an expensive product.

Regarding searching memory, OllyDBG does provide that feature. In any memory dump window (for example, the memory dump pane of the CPU window), you can: right-click, select "Search for" from the context menu, and then choose either Integer or Binary String. Unlike Cheat Engine, you cannot search for an approximate value with OllyDBG. You might seek a plug-in which does this, not that I am aware of one.

By "WINAPI" I think you might mean the Win32 API. There is probably a component in the game you are looking into named WINAPI. In order to set breakpoints on various Windows APIs, which is what game-client-extenders like to do, you will want to know where the actual Windows API is, so to speak. The functions are not all in one "place." There are various DLL modules which "export" the functions that comprise the Win32 API. For example, MessageBox() is exported from USER32.DLL but ExitProcess() is exported from KERNEL32.DLL.

To set breakpoints on Windows API calls in OllyDBG, you can: View menu, Executable Modules to see all the modules in memory. Right click the USER32.DLL module and select "View Names" from the context menu. There you will see all of the functions exported from USER32.

If the game client were written in C, there would be a list of API functions used in what is called the "import table." This would be found in the .EXE module loaded in memory, or also viewable in the on-disk EXE file using link /dump /imports.

In the case of a scripting language, there is usually not an import table, or if there is an import table, it imports a vast range of functionality that is accessible via the script engine.

I do not think OllyDBG supports conditional breakpoints, unfortunately.

Regarding where to begin learning disassembly, surely the best instruction is to utilize quite a bit of assembly on your own code. Even writing a Windows application which displays only a Message Box bearing "Hello World" will require you to learn about import tables in order to access the MessageBox() API. In fact, writing such an application in C could also be informative to you. However, I recommend you compile the code using only the command-line tools and not the GUI environment. The GUI will hide too much information from you and interfere with the learning. In order to access the USER32.DLL API, you will need to inform the linker that you wish to use the USER32.LIB 'import library' so your C code can transparently call MessageBox().

13.10.2009 22:08:16