Background: I want to convert Qt RTTI into symbols, to more easily navigate a large executable.
If you don't know already, Qt is a C++ application framework based on a message passing system. Since C++ has very little in the way of introspection and reflection, which are important features for an expressive message passing system, Qt comes with a tool called moc (Meta Object Compiler), which parses your source files and builds an index of classes, methods, properties etc. that need to be enumerated, resolved, etc. at runtime. Sadly, the metadata generated by moc is optimized for runtime access (in part because of limitations of the C++ language) and is slightly hostile to static analysis. In particular, you'd expect method tables like this (pseudocode):
methods = {
"frob" -> &frob,
"fuzz" -> &fuzz
}
but for several boring reasons, moc generates a dispatch method instead (pseudocode again):
dispatch(method, args) {
switch(method) {
case "frob": return frob(args)
case "fuzz": return fuzz(args)
default: return -1
}
}
Needless to say, decompiling even simple, machine-generated code is much, much harder than analyzing static data.
Conceptually, it's simple: find all dispatch functions, and run each of them in a simulator until it performs a call or returns; extract the method implementation address from the call opcode, write to symbol/map file with the method name. I already have a quick hack to identify dispatch functions (a hacked QtCore4.dll that hooks all objects and dumps their metadata), but I don't know what to use to decompile them.
The question: what (free) tools would you recommend to do this programmatically? At a minimum, I'd need a PE loader and an x86 simulator, Python preferred.
I've been pointed to angr, which is impressive, and among other things translates code to a platform-independent IR, which increases the chances that I could actually release my code as a general purpose tool, but angr seems designed to do the complete opposite of what I need. Not only its documentation is sparse and impenetrable, but considering it's designed to derive the data from the code (and I already have the data!), it seems overengineered for my use case and would probably be unbearably slow even if I figured it out.