Skip to content

An unconnected string of thoughts about BinNavi 2.1

Staying true to our 6 months release cycle we will probably release BinNavi 2.1, the latest version of our binary code reverse engineering tool, next week. After BinNavi 1.5 and BinNavi 2.0 this is the third release of BinNavi I have been in charge of. I want to take this opportunity to talk about the features I like most in BinNavi 2.1. You can actually find a more or less complete list of what is new in BinNavi 2.1 compared to BinNavi 2.0 over here.

The feature I like most in the new version of BinNavi is the ability to write programs and scripts that access the BinNavi API without actually having to start BinNavi itself. Or as Matt Drudge would say

 Breaking News: BinNavi lead dev says that the best part of the new version of BinNavi that you do not have to run BinNavi anymore

My colleague Vincenzo Iozzo actually requested this feature because he is currently working on combining BinNavi with a fuzzer to combine static and dynamic analysis in some way (the exact details still elude me at this point). Running scripts from inside BinNavi and pushing disassembly data to an external process is tedious to implement because you need some way of inter-process communication. Having a stand-alone version of the BinNavi plugin API would be significantly easier. It only took like 10 minutes to implement this feature but its usefulness is immense. You can now write Jython (or JRuby, or Java, or ... ) programs, run them from your standard shell and access the whole BinNavi API and all disassembled data managed by BinNavi without actually having to start BinNavi. Not only does that allow you to get BinNavi disassembly data into other programs (like fuzzers) very easily, you can also do other cute stuff like accessing all of the disassembly data from your standard programming language shell. Below you can see how to access BinNavi disassembly data from the Jython 2.5b3 shell to count the mnemonic distribution of a disassembled function. Another side-effect of this feature is that you can use Jython 2.5 to access BinNavi data while scripts executed from inside BinNavi support only Jython 2.2 so far.

>>> import sys
>>> sys.path.append("F:\BinNavi\BinNavi.jar")
>>> sys.path.append("F:\BinNavi\REIL.jar")
>>> sys.path.append("F:\BinNavi\mysql-connector-java-5.1.7-bin.jar")
>>> from BinNavi.API.plugins import StandAlone
*sys-package-mgr*: processing new jar, 'F:\BinNavi\BinNavi.jar'
*sys-package-mgr*: processing new jar, 'F:\BinNavi\REIL.jar'
*sys-package-mgr*: processing new jar, 'F:\BinNavi\mysql-connector-java-5.1.7-bin.jar'
>>> pi = StandAlone.getPluginInterface()
>>> print pi
BinNavi Plugin Interface
>>> pi.databaseManager.addDatabase("", "com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test_disassembly", "root", "aaaaa", False, False)Database '' [Unloaded]
>>> db = pi.databaseManager.databases[0]
>>> print db

Database '' [Unloaded]
>>> db.connect()
>>> db.load()
>>> for m in db.modules:
...     print m.name
...
NOTEPAD.EXE
kernel32.dll
>>> notepad = db.modules[0]
>>> notepad.load()
>>> random_function = notepad.views[200]
>>> print random_function
View sub_1002B87
>>> random_function.load()
>>> print random_function.graph
Viewgraph [96 function nodes, 150 edges]
>>> count = { }
>>> for node in random_function.graph:
...     for instruction in node.instructions:
...         if count.has_key(instruction.mnemonic):
...             count[instruction.mnemonic] = count[instruction_mnemonic] + 1
...         else:
...     count[instruction.mnemonic] = 1
>>> print count
{'neg': 2, 'movzx': 1, 'lea': 12, 'jle': 2, 'stosw': 1, 'rep stosd': 1, 'push':
153, 'leave': 1, 'pop': 4, 'jmp': 27, 'sub': 10, 'inc': 3, 'jz': 37, 'cmp': 27,
'jnz': 12, 'add': 1, 'mov': 98, 'dec': 10, 'xor': 7, 'test': 10, 'call': 68, 'se
tz': 1, 'sbb': 1, 'jg': 4, 'and': 1, 'retn': 1}

Another thing I really like about this release of BinNavi is the improved REIL support. REIL is our Reverse Engineering Intermediate Language which we use for static code analysis. You can get slides about REIL from a talk given at CanSecWest here and you can get a paper that describes REIL here. Not only did we add REIL support for major parts of the 32-bit PowerPC and the 32-bit ARM instruction set (in addition to the 32-bit x86 support we already had in BinNavi 2.0) but we also added MonoREIL. MonoREIL is a static analysis framework based on abstract interpretation. The purpose of MonoREIL is to make it easier to write static analysis algorithms to detect security-relevant defects in code on assembly level. Of course REIL and MonoREIL can be accessed fully from the BinNavi plugin API. For more information about REIL and MonoREIL please check out this part of the BinNavi manual.

One of the applications of MonoREIL is register tracking, another new GUI feature which is pretty useful. Assume you have an interesting value (for example a pointer to unvalidated user input) in a given register. Now it is pretty useful to know how this value propagates through the program. To what other registers is this value written and how does this value effect flags and therefore control flow. This can be done with register tracking. You simply click on an instruction in the BinNavi graph view and choose the operand you want to track. The register tracking algorithm then calculates all influenced instructions and highlights them in the graph view. In the screenshot below you can see an example of register tracking (click for bigger).

What happened here is that in instruction 0x7C855EF7 the lpContext function argument of kernel32!BackupSeek is written to EAX. For whatever reason I have decided to track the value of EAX from this point on. That's why this instruction is highlighted in green. Two instructions below, this value of EAX is used as a pointer to load a value. Light blue means that the original tracked register influences this instruction in some way and because ESI depends on the original EAX the value in ESI is tracked too from this point on. The next instruction is interesting. It overwrites the tracked register EAX. That's why it is highlighted in a light red. There is also dark red highlighting (not shown in the screenshot) which means that all effects of the tracked registers are cleared at this point and the original tracked value has no effects beyond this instruction. Some more instructions are highlighted in light blue. These instructions are highlighted because they indirectly - through ESI - depend on the tracked value EAX. All instructions not highlighted do not depend on the original value of EAX in any way.

Note that register tracking does not track values written to memory. That's why it's called register tracking, not value tracking. Nevertheless I want to stress that register tracking is platform-independent (thanks to REIL) and also works with PowerPC and ARM programs.

There are many, many other potential uses for REIL and MonoREIL which we will hopefully develop and publish in the next few months. Another one we mentioned in the CanSecWest slides was an analysis algorithm we developed to find array accesses through negative indices. This helped us to find the MS08-67 vulnerability automatically without doing any manual work except for verifying the output of the algorithm and the existence of the vulnerability. Of course hindsight was 20:20 for the MS08-67 example. By the time we wrote the analysis algorithm this vulnerability was already publicly known and documented. Nevertheless our algorithm is generic and we hope to detect similar negative-index array-access bugs in the future. Note that this analysis algorithm is not included in BinNavi 2.1 but we hope to include it in our fall release of BinNavi later this year.

There are a few other useful features in BinNavi 2.1 which are worth mentioning. First, we added the ability to group arbitrary graph nodes into groups and collapse these groups. This feature is obviously copied straight from IDA Pro where it is one of my favourite features. We also have a dedicated stack view in the BinNavi debugger now where you can follow changes on the stack. The scripting dialog (where you run Jython/JRuby/... scripts from inside BinNavi) was improved a lot too. For example you can now configure startup scripts which are executed every time a scripting dialog is opened. That way you can generically set up a few variables or functions you regularly use for scripting.

If you have any questions about BinNavi 2.1 please leave a comment or contact me using any of the options listed in the navigation bar on the right side of this website.

Trackbacks

No Trackbacks

Comments

Display comments as Linear | Threaded

No comments

Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
BBCode format allowed
Form options

Submitted comments will be subject to moderation before being displayed.