Skip to main content
Sogen implements the GDB Remote Serial Protocol, allowing you to debug emulated Windows programs using industry-standard debugging tools like GDB, LLDB, IDA Pro, and Visual Studio Code.

Overview

The GDB stub integration provides:
  • Full register access (read/write)
  • Memory inspection and modification
  • Breakpoint support (software and hardware)
  • Single-stepping execution
  • Thread enumeration and switching
  • Library/module information

Enabling GDB Mode

Basic GDB Mode

Start the analyzer in debug mode:
analyzer.exe -d myapp.exe
By default, Sogen listens on 127.0.0.1:28960 for GDB connections.

Custom Host and Port

Specify a custom bind address:
analyzer.exe -d --bind 0.0.0.0 --port 2345 myapp.exe
Binding to 0.0.0.0 exposes the debugger to your network. Only use this in trusted environments.

GDB Connection Flow

1
Start analyzer in debug mode
2
analyzer.exe -d --port 28960 c:/target.exe
3
The analyzer waits for a debugger connection:
4
Waiting for GDB connection on 127.0.0.1:28960...
5
Connect your debugger
6
From GDB:
7
gdb
(gdb) target remote 127.0.0.1:28960
8
Begin debugging
9
The emulator starts execution when the debugger connects. Use standard GDB commands to control execution.

Using GDB

Connecting to Sogen

# Start GDB without a local binary
gdb

# Connect to the Sogen emulator
(gdb) target remote 127.0.0.1:28960

# Check current state
(gdb) info registers
(gdb) info threads

Basic Debugging Commands

# Continue execution
(gdb) continue

# Single step
(gdb) step
(gdb) stepi

# Set breakpoint
(gdb) break *0x140001000

# Examine memory
(gdb) x/16xb 0x140001000
(gdb) x/s 0x140001000

# Examine registers  
(gdb) info registers
(gdb) print $rax
(gdb) set $rax = 0x1234

# Backtrace
(gdb) backtrace

Thread Debugging

# List all threads
(gdb) info threads

# Switch to thread
(gdb) thread 2

# Show current thread
(gdb) thread

Using LLDB

LLDB also supports the GDB remote protocol:
# Start LLDB
lldb

# Connect to Sogen
(lldb) gdb-remote 127.0.0.1:28960

# Set breakpoint
(lldb) breakpoint set --address 0x140001000

# Continue
(lldb) continue

# Read memory
(lldb) memory read 0x140001000

# Read registers
(lldb) register read

Using IDA Pro

IDA Pro provides excellent integration with GDB remote debugging.
1
Start Sogen in debug mode
2
analyzer.exe -d --port 28960 c:/malware.exe
3
Configure IDA Pro
4
  • Open IDA Pro
  • Go to Debugger → Select debugger → Remote GDB debugger
  • Go to Debugger → Process options
  • Set:
    • Hostname: 127.0.0.1
    • Port: 28960
  • 5
    Start debugging
    6
  • Press F9 or click Debugger → Start process
  • IDA connects to Sogen and begins debugging
  • 7
    Use IDA’s debugging features
    8
  • Set breakpoints (F2)
  • Step over (F8) / Step into (F7)
  • Run to cursor (F4)
  • View registers and stack in real-time
  • Analyze loaded modules
  • Using Visual Studio Code

    VS Code can debug Sogen using the Native Debug extension.

    Install Extension

    1. Install the “Native Debug” extension
    2. Create a .vscode/launch.json configuration

    Configuration

    .vscode/launch.json
    {
      "version": "0.2.0",
      "configurations": [
        {
          "name": "Sogen GDB",
          "type": "gdb",
          "request": "attach",
          "executable": "./target.exe",
          "target": "127.0.0.1:28960",
          "remote": true,
          "cwd": "${workspaceRoot}",
          "valuesFormatting": "parseText"
        }
      ]
    }
    

    Debugging Workflow

    1
    Start Sogen
    2
    analyzer.exe -d c:/target.exe
    
    3
    Launch VS Code debugger
    4
  • Open the Run and Debug panel (Ctrl+Shift+D)
  • Select “Sogen GDB” configuration
  • Click Start Debugging (F5)
  • 5
    Debug normally
    6
    Use VS Code’s debugging interface:
    7
  • Set breakpoints
  • View variables and call stack
  • Step through execution
  • GDB Stub Implementation Details

    The GDB stub is implemented in /src/gdb-stub/ and provides:

    Supported Commands

    • Memory operations: Read (m), Write (M, X)
    • Register operations: Read all (g), Write all (G), Read single (p), Write single (P)
    • Breakpoints: Set (Z), Delete (z) for all types
    • Execution control: Continue (c), Step (s), Continue with signal (S)
    • Thread operations: Query (qfThreadInfo), Switch (H)
    • Information queries: Target description (qXfer:features), Libraries (qXfer:libraries), Executable path (qXfer:exec-file)

    Breakpoint Types

    enum class breakpoint_type : uint8_t
    {
        software = 0,           // Software breakpoint (INT3)
        hardware_exec = 1,      // Hardware execution breakpoint
        hardware_write = 2,     // Hardware write watchpoint
        hardware_read = 3,      // Hardware read watchpoint
        hardware_read_write = 4 // Hardware access watchpoint
    };
    

    Target Architecture

    Sogen exposes x86-64 (AMD64) architecture to the debugger with full register set including:
    • General purpose registers (RAX, RBX, RCX, etc.)
    • Segment registers (CS, DS, SS, ES, FS, GS)
    • Control registers
    • Instruction pointer (RIP)
    • Flags register (RFLAGS)

    Advanced Debugging Techniques

    Conditional Breakpoints

    # Break when RAX equals specific value
    (gdb) break *0x140001000 if $rax == 0x1234
    
    # Break when memory contains value
    (gdb) break *0x140001000 if *(long*)0x140020000 == 0x5678
    

    Watchpoints

    # Watch memory location for changes
    (gdb) watch *(long*)0x140020000
    
    # Watch memory for reads
    (gdb) rwatch *(long*)0x140020000
    
    # Watch for reads or writes
    (gdb) awatch *(long*)0x140020000
    

    Scripting

    Automate debugging with GDB Python scripts:
    debug_script.py
    import gdb
    
    class BreakpointHandler(gdb.Breakpoint):
        def __init__(self, spec):
            super().__init__(spec)
            
        def stop(self):
            rax = gdb.parse_and_eval('$rax')
            print(f"RAX = {rax}")
            return True  # Stop execution
    
    # Set breakpoint with handler
    BreakpointHandler('*0x140001000')
    
    # Continue execution
    gdb.execute('continue')
    
    Load the script in GDB:
    (gdb) source debug_script.py
    

    Troubleshooting

    Connection Refused

    If the debugger cannot connect:
    1. Check that analyzer is running in debug mode (-d)
    2. Verify the correct host and port
    3. Check firewall settings
    4. Ensure no other service is using the port

    Symbols Not Loading

    The GDB stub provides basic module information, but doesn’t include full symbol data. To get symbols:
    1. Load the executable in your debugger separately
    2. Use IDA Pro to analyze the binary and debug simultaneously
    3. Generate symbol files from the PE executable

    Breakpoints Not Working

    If breakpoints aren’t triggering:
    1. Verify the address is within executable code
    2. Check that the module is loaded
    3. Use hardware breakpoints for memory-mapped regions
    4. Ensure the code hasn’t been relocated

    Build docs developers (and LLMs) love