Small and Cute Execution Tracer

A couple of months ago I wrote a small tool to help me find the functions hit during the execution of an arbitrary program. It became obvious that with some small modifications it could be used to perform differential debugging, analog to what Zynamics BinNavi does. This little tool is based on the awesome WinAppDbg from Mario Vilas, a Python interface to the Windows Debugging API.

After developing a little bit more than initially intended, it turned out pretty nice so I decided to write about it. Maybe it could be useful to somebody.

The following screenshot shows the options available:

Here are a couple of things you can do with it:

Differential Debugging

Generating some noise

s:\> python Tracer.py –noise -p putty.exe -f putty_exported_functions.txt

The option (-p, –program) is mandatory in every case and references the name of the executable to analyze. No path is necessary, only the program’s name.

The options (-n, –noise) and (-s, –signal) are the most relevant for this mode. They do esentially the same, that is, logging the functions hit during execution to a file. The only difference is which file they log to, signal.txt or noise.txt.

Now, the (-f, –funcfile) parameter refers to a file containing all the program’s function addresses. In order to instrument every function and log whether it has been hit it’s necessary to know the function addresses beforehand. This is obviously the main drawback of this technique. There are more sophisticated methods involving DBI but this is not the topic right now.

How to get this list of function addresses? Well, IDA Pro comes to the rescue!

Open the executable in IDA Pro and once the initial autoanalysis is finished, run the following Python code:

filename = idc.AskFile(1, "*.*", "File to export functions to?")

f = open(filename, "w")
print "Exporting function addresses to %s\n" % filename

idx = 0

# The string format is:
# 0xAAAAAAAA-0xBBBBBBBB {ea_start, ea_end}

for function_start in Functions():
    function_end = GetFunctionAttr(function_start, FUNCATTR_END)
    # Below I've just stripped the leading '0x' chars
    addr_interval_string = str(hex(function_start)).split('0x')[1] + '-' + str(hex(function_end)).split('0x')[1]

    f.write(addr_interval_string + '\n')
    idx += 1

f.close()

print "%d functions written to disk" % idx

You can save this to a file and execute the script within IDA with “File/Script File” or Alt+F7. This will generate a text file with all the function addresses, ready to be processed by Tracer.py

Now the signal

Let’s generate another file containing the addresses of interesting functions. Remember that in this context, interesting means “responsible for a feature we are interested in”, for example “which functions are being executed when I click this button?”.

Similarly to the last paragraph:

s:\> python Tracer.py –signal -p putty.exe -f putty_exported_functions.txt

Of course the output file (signal.txt) will contain the interesting functions along with several others implementing all kinds of irrelevant functionality (initialization, GUI stuff, etc.) How are we going to filter out these? Very easily.

Filtering out the noise

Although doing this is about ten lines of python, there’s another very convenient switch (-c, –compare):

s:\> python Tracer.py -c

Execute this on the same directory as the previous noise.txt and signal.txt since by default the program will look for these two and write the output to specific_functions.txt

And here you are! It was rather easy, wasn’t it?

It’s not a bullet-proof method but it can be useful in some situations. For a nice example check this other post.

Another goodies

I plan to extend this tool with a couple of other useful options, one of them the ability of dereference arguments during function calls and look for specific ASCII strings. The syntaxis is as follows:

s:\>python Tracer.py -a -w string_to_look_for -p putty.exe -f file_with_func_addresses

The two new parameters are (-a, –argument) which indicates I want to trace and dereference addresses instead of the normal mode. The parameter (-w, –search_pattern) specify the ASCII string to look for.

Check this screenshot where I look for a certain username being used as argument:

The method is far from perfect. Since I don’t know how many arguments each function has I just dereference the first 5 DWORDS on the stack after the saved EIP.

Clumsy and prone to false positives but it could point you in the right direction during an initial analysis.

A way to improve this is to export the number/type of arguments in IDA Pro and use this info to better target our search . It’s on my TODO :)

Do you want to play?

In case you want to play with it, you will need the following:

  • WinAppDbg 1.4 (downloadable here)
  • Python (I tested it with 2.5 and 2.7 under Windows)
  • The code for Tracer.py itself! (download from GitHub)

Have fun!

Advertisements

2 thoughts on “Small and Cute Execution Tracer

  1. What about using winappdbg to disassemble binaries then search all “call” instructions and set breakpoints on every “call” instruction. When breakpoints hit log every function address to file.
    If so ,you can integrate all features to one python program,no ida ,no idc. Is there any drawback in this solution?

    1. Hi,

      this is indeed a good idea. I wasn’t sure if the disassembly capabilities of winappdbg were better that those of IDA (I still don’t know) so I decided to take this intermediate step. Anyway it could be an improvement, thanks for the comment!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s