MCPcopy Index your code
hub / github.com/bootleg/ret-sync

github.com/bootleg/ret-sync @ext_ghidra_10.1_PUBLIC_20211210

Chat with this repo
repository ↗ · DeepWiki ↗ · release ext_ghidra_10.1_PUBLIC_20211210 ↗ · + Follow
912 symbols 2,250 edges 50 files 60 documented · 7%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

ret-sync

ret-sync stands for Reverse-Engineering Tools SYNChronization. It is a set of plugins that help to synchronize a debugging session (WinDbg/GDB/LLDB/OllyDbg/OllyDbg2/x64dbg) with a disassembler (IDA/Ghidra/Binary Ninja). The underlying idea is simple: take the best from both worlds (static and dynamic analysis).

Debuggers and dynamic analysis provide us with:

  • local view, with live dynamic context (registers, memory, etc.)
  • built-in specialized features/API (ex: WinDbg's !peb, !drvobj, !address, etc.)

Disassemblers and static analysis provide us with:

  • macro view over modules
  • code analysis, signatures, types, etc.
  • fancy graph view
  • decompilation
  • persistent storage of knowledge within IDBs/GPRs

Key features:

  • synchronize graph and decompilation views with debugger's state
  • no need to deal with ASLR, addresses are rebased on-the-fly
  • pass data (comment, command output) from debugger to disassembler
  • multiple IDBs/GPRs can be synced at the same time allowing to easily trace through multiple modules
  • disassembler and debugger can be on different hosts / VMs

ret-sync is a fork of qb-sync that I developed and maintained during my stay at Quarkslab.


Table of contents


Repository content

The debugger plugins:

  • ext_windbg/sync: WinDbg extension source files, once built: sync.dll
  • ext_gdb/sync.py: GDB plugin
  • ext_lldb/sync.py: LLDB plugin
  • ext_olly1: OllyDbg 1.10 plugin
  • ext_olly2: OllyDbg v2 plugin
  • ext_x64dbg: x64dbg plugin

The disassembler plugins:

  • ext_ida/SyncPlugin.py
  • ext_ghidra/dist/ghidra_*_retsync.zip: Ghidra plugin
  • ext_bn/retsync: Binary Ninja plugin

And the library plugin:

  • ext_lib/sync.py: standalone Python library

General prerequisites

IDA and GDB plugins require a valid Python setup. Python 2 (>=2.7) and Python 3 are supported.

Binary release

Pre-built binaries for WinDbg/OllyDbg/OllyDbg2/x64dbg debuggers are proposed through an Azure DevOps pipeline: Build Status

Select the last build and check the artifacts under the Related section: 6 published.

A pre-built plugin archive of the Ghidra plugin is provided in ext_ghidra/dist.

ret-sync configuration

ret-sync should work out of the box for most users with a typical setup: debugger and disassembler(s) on the same host, module names matching.

Still, in some scenarios a specific configuration may be used. For that, extensions and plugins check for an optional global configuration file named .sync in the user's home directory. It must be a valid .INI file.

Additionally, the IDA and Ghidra plugins also look for the configuration file in the IDB or project directory (<project>.rep) first to allow local, per-IDB/project, settings. If a local configuration file is present, the global configuration file is ignored.

Values declared in these configuration files override default values. Please note, that no .sync file is created by default.

Below we detail, three common scenarios where a configuration file is useful/needed:

  • Remote debugging
  • Modules names mismatch
  • Missing PID

Remote debugging: debugger and disassembler are on different hosts

The [INTERFACE] section is used to customize network related settings. Let's suppose one wants to synchronize IDA with a debugger running inside a virtual machine (or simply another host), common remote kernel debugging scenario.

Simply create two .sync file:

  • one on the machine where IDA is installed, in the IDB directory:
[INTERFACE]
host=192.168.128.1
port=9234

It tells ret-sync IDA plugin to listen on the interface 192.168.128.1 with port 9234. It goes without saying that this interface must be reachable from the remote host or virtual machine.

  • one on the machine where the debugger is executed, in the user's home directory:
[INTERFACE]
host=192.168.128.1
port=9234

It tells ret-sync debugger plugin to connect to the ret-sync IDA plugin configured previously to listen in this interface.

NOTE: You must specify a real IP here, and not use 0.0.0.0. This is because the variable is used by multiple sources both for binding and connecting, so using 0.0.0.0 will result in weird errors.

IDB and debugger modules names are different

[ALIASES]
ntoskrnl_vuln.exe=ntkrnlmp.exe

The [ALIASES] section is used to customize the name which is used by a disassembler (IDA/Ghidra) to register a module to its dispatcher/program manager.

By default, disassembler plugins use the name of the input file. However one may have renamed the file beforehand and it doesn't match anymore the name of the actual process or loaded module as seen by the debugger.

Here we simply tell to the dispatcher to match the name ntkrnlmp.exe (real name) instead of ntoskrnl_vuln.exe (IDB name).

gdb with Qt Creator debugging frontend

The Qt Creator debugging frontend changes the way gdb command output is logged. Since this would interfere with the synchronization an option exists to use the raw gdb output for synchronization instead of a temporary file. In the .sync configuration file use

[GENERAL]
use_tmp_logging_file=false

if you wish to use the Qt debugging frontend for the target.

Embedded devices and missing /proc/<pid>/maps

In some scenarios, such as debugging embedded devices over serial or raw firmware in QEMU, gdb is not aware of the PID and cannot access /proc/<pid>/maps.

In these cases, The [INIT] section is used to pass a custom context to the plugin. It allows overriding some fields such as the PID and memory mappings.

.sync content extract:

    [INIT]
    context = {
          "pid": 200,
          "mappings": [ [0x400000, 0x7A81158, 0x7681158, "asav941-200.qcow2|lina"] ]
      }

Each entry in the mappings is: mem_base, mem_end, mem_size, mem_name.

Installation

IDA extension

IDA prerequisites

IDA 7.x branch is required. For older versions (6.9x) please see archived release ida6.9x.

Install the IDA extension

For IDA installation, copy Syncplugin.py and retsync folder from ext_ida to IDA plugins directory, for example:

  • C:\Program Files\IDA Pro 7.4\plugins
  • %APPDATA%\Hex-Rays\IDA Pro\plugins
  • ~/.idapro/plugins

Run the IDA extension

  1. Open IDB
  2. Run the plugin in IDA (Alt-Shift-S) or Edit -> Plugins -> ret-sync
[sync] default idb name: ld.exe
[sync] sync enabled
[sync] cmdline: "C:\Program Files\Python38\python.exe" -u "C:\Users\user\AppData\Roaming\Hex-Rays\IDA Pro\plugins\retsync\broker.py" --idb "target.exe"
[sync] module base 0x100400000
[sync] hexrays #7.3.0.190614 found
[sync] broker started
[sync] plugin loaded
[sync] << broker << dispatcher not found, trying to run it
[sync] << broker << dispatcher now runs with pid: 6544
[sync] << broker << connected to dispatcher
[sync] << broker << listening on port 63107

IDA plugin troubleshooting

To troubleshoot issues with the IDA extension two options are available in the file retsync/rsconfig.py:

LOG_LEVEL = logging.INFO
LOG_TO_FILE_ENABLE = False

Setting LOG_LEVEL value to logging.DEBUG makes the plugin more verbose.

Setting LOG_TO_FILE_ENABLE value to True triggers the logging of exception information from broker.py and dispatcher.py into dedicated files. Log file are generated in the %TMP% folder with a name pattern retsync.%s.err .

Ghidra extension

Build the Ghidra extension

Either use the pre-built version from the ext_ghidra/dist folder or follow the instruction to build it. Each extension build only supports the version of Ghidra specified in the plugin's file name. E.g. ghidra_9.1_PUBLIC_20191104_retsync.zip is for Ghidra 9.1 Public.

  1. Install Ghidra
  2. Install gradle
apt install gradle
  1. Build extension for your Ghidra installation (replace $GHIDRA_DIR with your installation directory)
cd ext_ghidra
gradle -PGHIDRA_INSTALL_DIR=$GHIDRA_DIR

Install the Ghidra extension

  1. From Ghidra projects manager: File -> Install Extensions..., click on the + sign and select the ext_ghidra/dist/ghidra_*_retsync.zip and click OK. This will effectively extract the retsync folder from the zip into $GHIDRA_DIR/Extensions/Ghidra/
  2. Restart Ghidra as requested
  3. After reloading Ghidra, open a module in CodeBrowser. It should tell you a new extension plugin has been detected. Select "yes" to configure it. Then tick "RetSyncPlugin" and click OK. The console should show something like:
[*] retsync init
[>] programOpened: tm.sys
    imageBase: 0x1c0000000
  1. From Ghidra CodeBrowser tool: use toolbar icons or shortcuts to enable (Alt+s)/disable (Alt+Shift+s)/restart (Alt+r) synchronization.

A status window is also available from Windows -> RetSyncPlugin. You generally want to drop it on the side to integrate it with the Ghidra environment windows.

Binary Ninja extension

Binary Ninja support is experimental, make sure to backup your analysis databases.

Binary Ninja prerequisites

ret-sync requires Binary Ninja version 2.2 at minimum as well as Python 3 (Python 2 is not supported).

Install the Binary Ninja extension

ret-sync is not yet distributed through the Binary Ninja's Plugin Manager; a manual installation is required. Simply copy that content of the ext_bn folder into Binary Ninja's plugins folder, for example:

%APPDATA%\Binary Ninja\plugins

After restarting Binary Ninja, the following output should be present in the console window:

[sync] commands added
Loaded python3 plugin 'retsync'

WinDbg extension

Build the WinDbg extension

Either use pre-built binaries or use the Visual Studio 2017 solution provided in ext_windbg, (see https://docs.microsoft.com/en-us/visualstudio/releasenotes/vs2017-relnotes if needed).

This will build the x64\release\sync.dll file.

Install the WinDbg extension

You will need to copy the resulting sync.dll file into the appropriate Windbg extension path.

  • WinDbg Classic:

For earlier versions of Windbg this is is something like this (be careful of x86/x64 flavours), for example

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext\sync.dll

  • Windbg Preview

The folder for storing extension seems to be based on the PATH, so you need to put it one of the queried locations.

One example is to put it here:

C:\Users\user\AppData\Local\Microsoft\WindowsApps\sync.dll

Run the WinDbg extension

  1. Launch WinDbg on target
  2. Load extension (.load command)
    0:000> .load sync
    [sync.dll] DebugExtensionInitialize, ExtensionApis loaded
  1. Sync WinDbg
      0:000> !sync
      [sync] No argument found, using default host (127.0.0.1:9100)
      [sync] sync success, sock 0x5a8
      [sync] probing sync
      [sync] sync is now enabled with host 127.0.0.1

E.g. in IDA's Output window

      [*] << broker << dispatcher msg: add new client (listening on port 63898), nb client(s): 1
      [*] << broker << dispatcher msg: new debugger client: dbg connect - HostMachine\HostUser
      [sync] set debugger dialect to windbg, enabling hotkeys

If Windbg's current module matches IDA file name

      [sync] idb is enabled with the idb client matching the module name.

WinDbg installation troubleshooting

Note: If you get the following error, it is because you haven't copied the file to the right folder in the above steps.

0: kd> .load sync
The call to LoadLibrary(sync) failed, Win32 error 0n2
    "The system cannot find the file specified."
Please check your debugger configuration and/or network access.

The error below usually means that Windbg tried to load the incorrect flavour of the extension, ex: x86 in place of the x64 sync.dll.

0:000> .load sync
The call to LoadLibrary(sync) failed, Win32 error 0n193
    "%1 is not a valid Win32 application."
Please check your debugger configuration and/or network access.

GNU gdb (GDB) installation

  1. Copy the ext_gdb/sync.py to the directory of your choice
  2. Load the e

Core symbols most depended-on inside this repo

FAILED
called by 111
ext_windbg/sync/sync/sync.cpp
rs_log
called by 99
ext_ida/retsync/rsconfig.py
dbgout
called by 78
ext_olly2/tunnel.c
rs_log
called by 53
ext_gdb/sync.py
dbgout
called by 52
ext_olly1/tunnel.c
rs_log
called by 43
ext_bn/retsync/retsync/rsconfig.py
TunnelSend
called by 26
ext_windbg/sync/sync/tunnel.cpp
rs_log
called by 22
ext_lldb/sync.py

Shape

Method 471
Function 232
Class 205
Enum 3
Route 1

Languages

Python51%
C++31%
Java11%
C8%

Modules by API surface

ext_gdb/sync.py104 symbols
ext_bn/retsync/sync.py98 symbols
ext_ida/SyncPlugin.py92 symbols
ext_olly2/plugin.h90 symbols
ext_lldb/sync.py53 symbols
ext_windbg/sync/sync/sync.cpp46 symbols
ext_ida/retsync/dispatcher.py41 symbols
ext_x64dbg/x64dbg_sync/core.cpp40 symbols
ext_olly1/plugin.h32 symbols
ext_ghidra/src/main/java/retsync/RetSyncPlugin.java30 symbols
ext_olly2/sync.c26 symbols
ext_ida/retsync/broker.py25 symbols

For agents

$ claude mcp add ret-sync \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page