Whether you do malware/vulnerability/crash analysis and/or exploit development on Windows platforms, two tools are somehow inescapable:
- IDA Pro, a disassembler, for static analysis (it is not in my habits to use it as a debugger)
- Windbg, a debugger for dynamic analysis
Using these tools with a dual-screen configuration is a usual and comfortable setup. Nevertheless the situation gets vicious when you want to share information between the tools; situations where you'd like to:
- enjoy IDA's graph view while single-stepping a sensitive piece of code with Windbg: you end-up manually adjusting IDA's view to match you position in Windbg
- save live information from Windbg to your idb: let's say sensitive register value/memory content at a certain address, object dynamic type or vtable entry pointer for C++ code, etc. : again you end-up manually copy-pasting information from one window to the other.
It gets even worse when IDA and Windbg are not on the same host, for example when using a virtual machine (eventually trashed/reset after usage).
qb-sync has been developed to ease these issues and prevent these tedious, boring manipulations. Its purpose is to add some helpful glue between the debugger and the disassembler. qb-sync's core feature is to dynamically synchronize IDA's graph windows with Windbg's position: the current instruction is highlighted and centered on in IDA's graph view. The plugin (couple of plugins would be more accurate) is made of three components:
- ext_windbg/sync: WinDbg extension source files, native code, once built: sync.dll (require WinDDK, Debugging Tools). Export commands available through the debugger's command line and automatically send status update to the broker
- ext_ida/SyncPlugin.py: IDA plugin, python code, receive async events from broker, update graph view, interact with the idb.
- ext_ida/broker.py: python code, bind a TCP socket on port 9100, receive events from the debugger (socket) and forward them to the disassembler (stdout)
qb-sync is meant to be intuitive, its usage should be as transparent as possible. One only has to load the plugins in their respective environments.
For the IDA side:
IDA File-> Script File -> SyncPlugin.py (Alt-F7) [sync] form create [*] initBroker, "Y:Python27python.exe" -u "Y:syncext_idabroker.py" [sync] path Y:target [sync] name target.exe [sync] module base 0x400000 callui 0xf10ca0 grentry 0xfd17b0 curr tform * 0x960e538 find tform * 0x404e678 (IDA View-A) graph viewer 0xc74c50 ret 0x0 [*] broker started [*] broker announcement: broker listening
For the Windbg side:
0:000> !load sync [sync.dll] DebugExtensionInitialize, ExtensionApis loaded 0:000> !sync [sync.dll] sync function called !sync: No argument found, using default host (localhost) [sync.dll] Tunnel created [sync.dll] Sync is now enable with host 127.0.0.1
And that's all. A few extra sugar commands are available directly from the debugger's command line:
!cmt [-a address] <string> => add comment at current eip in IDA !rcmt [-a address] => reset comment at current eip in IDA !fcmt [-a address] <string> => add a function comment for function in which current eip is located !cmd <string> => execute a command in WinDbg and add its output as comment at current eip in IDA !bc <on|off|> => enable/disable path coloring in IDA. This is NOT a code tracing tool, there are efficient tools for that. Each manually stepped instruction is colored in the graph. Color a single instruction at current eip if called without argument.
As stated previously qb-sync is meant to be as simple as possible, no complex features, trivial data formats. It can also easily be extended to support synching with others debuggers (provided that they have a decent API). As an example a GDB sample plugin is provided the archive.
See README for more information about how to build/install/use the plugin. Project is still in beta, feedbacks or suggestions/comments about potential bugs are appreciated. Source code is available (GNU GPL v3 license):
Update: thanks to @lclee_vx for reporting typo in sync.cpp, archive updated.