Wow, it’s been a while since we last blogged. Ok, time to kick off 2011🙂
A lot of excellent stuff has been written about Microsoft’s RTTI format — from the ISS presentations a few years back to igorsk’s excellent OpenRCE articles. In the meantime, RTTI information has “spread” in real-world binaries as most projects are now built on compilers that default-enable RTTI information. This means that for vulnerability development, it is rare to not have RTTI information nowadays; most C++ applications come with full RTTI info.
So what does this mean for the reverse engineer ? Simply speaking, a lot — the above-mentioned articles already describe how a lot of information about the inheritance hierarchy can be parsed out of the binary structures generated by Visual C++ — and there are some pretty generic scripts to do so, too.
This blog article is about a slightly different question:
How can we recover full UML-style inheritance diagrams from executables by parsing the RTTI information ?
To answer the question, let’s review what the Visual C++ RTTI information provides us with:
- The ability to locate all vftables for classes in the executable
- The mangled names of all classes in the executable
- For each class, the list of classes that this class can be legitimately upcast to (e.g. the set of classes “above” this class in the inheritance diagram)
- The offsets of the vftables in the relevant classes
This is a good amount of information. Of specific interest is (3) — the list of classes that are “above” the class in question in the inheritance diagram. Coming from a mathy/CSy background, it becomes obvious quickly that (3) gives us a “partial order”: For two given classes A and B, either A ≤ B holds (e.g. A is inherits from B), or the two classes are incomparable (e.g. they are not part of the same inheritance hierarchy). This relationship is transitive (if A inherits from B, and B inherits from C, A also inherits from C) and antisymmetric (if A inherits from B and B inherits from A, A = B). This means that we are talking about a partially ordered set (POSet)
Now, why is this useful ? Aside from the amusing notion that “oh, hey, inheritance relationships are POSets“, it also provides us with a simple and clear path to generate readable and pretty diagrams: We simply calculate the inheritance relation from the binary and then create a Hasse Diagram from it — in essence by removing all transitive edges. The result of this is a pretty graph of all classes in an executable, their names, and their inheritance hierarchy. It’s almost like generating documentation from code🙂
Anyhow, below are the results of the example run on AcroForm.API, the forms plugin to Acrobat Reader:
A more interactive (and fully zoomable) version of this diagram can also be viewed by clicking here.
For those of you that would like to generate their own diagrams, you will need the following tools:
- My ancient IDAPython scripts: https://github.com/zynamics/rtti-helper-scripts
- The free graph editor yEd, available from http://www.yworks.com/en/products_yed_about.html
- A recent version of IDA