« January 2008 | Main | March 2008 »

February 18, 2008

Easy structure types

I'm happy to tell you that a new build of the decompiler is ready! It introduces new easily accessible commands to manipulate structure pointers. First, a variable can be converted into a structure pointer with one click. Also, new the structure types can be build on the fly by the decompiler. As usual, any type or name can be modified any time. All this makes using the decompiler really agreeable. Please watch a short demo:

This text is replaced by the Flash content.

Another nice improvement is how the decompiler handles zero offset fields in structure types. Below are two screenshots. Before:

After:

Please note that all casts has gone. They have been replaced by direct references to the first field of the structure type. Needless to say, the second text is much clearer than the first one.

As usual, all discovered and reported bugs have been fixed. If you have an old version, please update (especially before sending us bug reports).

Thank you!

February 13, 2008

MRXDAV.SYS and Hex-Rays Decompiler

I wanted to present you a new plugin today. It was about switch idioms (jump tables). I spent a few hours trying to find a problematic x86 sample file but could not locate anything impressive. All jump tables were nicely recognized. This certainly does not mean that IDA handles them perfectly, but rather that my search methods must be improved.

Anyway, things were going nowhere and I decided to make a micro-break. It really helps to unblock the thought process (sometimes my entire working day consists of innumerable micro-breaks :)

I remembered that it is time to install security updates so I quickly downloaded them and looked into the details. This one looked interesting.

Sometimes I use the decompiler to find out the differences between programs: decompile two files and use a text comparison on the pseudocode. This simple approach works ok for short files: I found out the modified functions. There were two of them, the most interesting one named MRxDAVPrecompleteUserModeQueryDirectoryRequest() (what a name!)

The MS08-007 vulnerability is a classic buffer overflow: two unicode strings get concatenated into a buffer of a fixed size. The application checks the size before copying, so in theory there shouldn't be any problems. I think that by looking at the following two screenshots you can tell why it didn't work quite well. Before:

The old version was checking that the sum of the input string lengthes is acceptable. Unfortunately, the case of integer overflow is not handled.

After:

The new version checks three things: the length of each input string and their sum all must be acceptable.

A single highlight of 0x208 is enough to notice the difference. In the old version, only tot2 is checked against the limit.

Well, my micro-break turned into a blog post. Back to the plugin: I'll find a nice sample file for jump tables and post a short video here. Stay tuned.

February 03, 2008

Debugger and process memory

Just a small note about the debugger plugins and events. Many users who try to develop a plugin for the debugger notice that IDA behaves slightly differently in the notification callbacks than anywhere else.

For example, IDA might claim that EIP points to an address without a segment, or none of exported names of a loaded DLL are available.

This happens because of the database synchronization. When you query IDA about a segment or a name, the information from the database is returned. The database is not (and can not be) always in sync with the process memory. The debugged process might allocate or free memory chunks thousands of times per second. The synchronization operation is very expensive: it requires enumerating all memory regions and collecting information about their types, permissions, etc. That's why IDA tries to perform it as rarely as possible.

We tried to save the end user from this problem: the database gets synchronized as soon as the process is suspended. This is the expected behavior, so far so good.

Alas, we can not provide plugin writers with the same virtual reality: there are two distinct entities, the process memory and the program segmentation. The latter is stored in the database and it can go out of sync with the former. As a plugin writer, you have the following choices:

  • Bypass the database and talk directly to the debugger module using the dbg->read_memory() and dbg->write_memory() functions.
    Advantages: no synchronization issues
    Disadvantages: only memory read/write functions are available, names, functions, and other high level abstractions are not; also, direct calls are not cached.

  • Explicitly synchronize the database with the process memory.
    Advantages: all high level abstractions are available, repetitive "read memory" requests will be cached by the kernel (especially useful for remote debugging); breakpoints in the process memory are hidden
    Disadvantages: slow

  • Do not synchronize.
    Advantages: fast
    Disadvantages: occasionally a call to an IDA function might fail (e.g. getseg() might return NULL for a valid address); nevertheless, this approach can be used if you know in advance that the memory config won't change or the changes are irrelevant to your analysis

Feel free to use the best method depending on your needs. When you need to force a synchronization, use this:
invalidate_dbgmem_config(); isEnabled(any_address);
Or maybe a better approach exists?.. ;)
Latest news: Hex-Rays decompiler has been released!