Skip to content

feat(emu,frida): capture Windows TEB and seed x86 segment base#13

Merged
ricardojrdez merged 1 commit into
mainfrom
feat/teb-segment-base
Jun 27, 2026
Merged

feat(emu,frida): capture Windows TEB and seed x86 segment base#13
ricardojrdez merged 1 commit into
mainfrom
feat/teb-segment-base

Conversation

@ricardojrdez

@ricardojrdez ricardojrdez commented Jun 27, 2026

Copy link
Copy Markdown
Member

What

Frida's CpuContext exposes no segment base, so every Frida-acquired slice had
fs/gs base = 0 and peb = None, and the Unicorn emulator could not run x86 SEH
prologues that read the TEB via fs:[0].

  • Capture (frida_bridge): on Windows, resolve each thread's TEB via
    OpenThread + NtQueryInformationThread(ThreadBasicInformation) and record it as
    gs_base (x64) / fs_base (ia32). Version-robust export resolution across Frida
    API generations.
  • Emulator (emu/engine): in 32-bit mode Unicorn ignores
    UC_X86_REG_FS_BASE/GS_BASE, so install a synthetic GDT (flat ring-3 data
    descriptor) for each captured base and load the matching selector;
    segment_base()/peb_address() now work on x86. x64 already honored gs_base
    directly.

Verification

  • Confirmed empirically that Frida's CpuContext exposes no segment base (attaching
    to a live x64 process: fs/gs/fs_base/gs_base all undefined).
  • Unicorn 2.1.4: x64 honors gs_base; on x86 the fs_base write is a no-op → the GDT
    trick fixes it.
  • New tests: x86 GDT path (fs:[0x30]→PEB), no-base case (no regression), and
    segment-base flow through the Frida bridge.
  • Full suite: 1142 passed / 10 skipped, ruff clean. JS validated by loading it in
    the real Frida engine.

🤖 Generated with Claude Code

Frida's CpuContext carries no segment base, so every Frida-acquired slice
had fs/gs base = 0 and peb = None, and the Unicorn emulator could not run
x86 SEH prologues that read the TEB via fs:[0].

Capture side (frida_bridge): on Windows, resolve each thread's TEB via
OpenThread + NtQueryInformationThread(ThreadBasicInformation) and record it
as gs_base (x64) / fs_base (ia32). Adds version-robust export resolution.

Emulator side (emu/engine): in 32-bit mode Unicorn ignores
UC_X86_REG_FS_BASE/GS_BASE, so install a synthetic GDT (flat ring-3 data
descriptor) for each captured base and load the matching selector; expose it
through segment_base()/peb_address(). x64 already honored gs_base directly.

Tests for the x86 GDT path (fs:[0x30] -> PEB), the no-base no-regression
case, and segment-base flow through the Frida bridge. README updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ricardojrdez ricardojrdez merged commit 52d423b into main Jun 27, 2026
7 checks passed
@ricardojrdez ricardojrdez deleted the feat/teb-segment-base branch June 28, 2026 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant