Skip to main content

Sogen Windows user-space emulator bindings

Project description

Sogen

Sogen exposes Python bindings for its Windows userspace emulator. The Python API is meant for scripting runs, building small analysis helpers, and quickly iterating on callbacks and hooks without rebuilding C++.

Install from PyPI:

pip install sogen

Project links:

What you need

The Python package still needs an emulation root at runtime. Download ready-made root here:

Extract it somewhere convenient, for example:

./root

Most examples in this document use:

emulation_root="./root"

Quick start

import sogen

app = sogen.windows.create_application(
    "c:/test-sample.exe",
    emulation_root="./root",
)

app.callbacks.on_stdout = lambda text: print(text, end="")
app.start()
print("exit status:", app.process.exit_status)

Minimal example with file + port mappings

from pathlib import Path
import sogen

app = sogen.windows.create_application(
    "c:/test-sample.exe",
    emulation_root="./root",
    path_mappings={"c:/a.txt": Path("./a.txt")},
    port_mappings={28970: 28980},
)

app.callbacks.on_stdout = lambda text: print(text, end="")
app.start()
print("exit status:", app.process.exit_status)

Choosing backend

sogen.windows.create_empty() and sogen.windows.create_application() accept an explicit backend.

import sogen

emu = sogen.windows.create_empty(
    emulation_root="./root",
    backend=sogen.Backend.unicorn,
)

Available values:

  • sogen.Backend.unicorn
  • sogen.Backend.icicle
  • sogen.Backend.whp

Default is sogen.Backend.unicorn.

High-level structure

Main entry points:

  • sogen.windows.create_empty(...)
  • sogen.windows.create_application(...)

Compatibility aliases currently remain at top level:

  • sogen.create_empty(...)
  • sogen.create_application(...)

Common objects exposed by the bindings:

  • sogen.windows.Emulator / sogen.windows.WindowsEmulator
  • ProcessContext
  • Thread
  • MemoryManager
  • Hooks
  • Callbacks

Common things you will do:

  • run application with app.start()
  • watch output with app.callbacks.on_stdout
  • react to module loads with app.callbacks.on_module_load
  • intercept WinAPI calls with app.hooks.apis[...]
  • read/write emulator memory with read_memory() / write_memory()
  • save and restore state with save_snapshot() / restore_snapshot()

Callbacks

Example: print loaded modules.

import sogen

app = sogen.windows.create_application(
    "c:/test-sample.exe",
    emulation_root="./root",
)


def on_module_load(module):
    print(f"loaded {module.name} @ 0x{module.entry_point:x}")


app.callbacks.on_module_load = on_module_load
app.start()

Useful callback slots include:

  • app.callbacks.on_stdout
  • app.callbacks.on_syscall
  • app.callbacks.on_memory_violate
  • app.callbacks.on_module_load
  • app.callbacks.on_module_unload

API hooks

API hooks are registered through app.hooks.apis.

Use @sogen.windows.api_call(...) to describe calling convention and parameters. Top-level sogen.api_call(...) remains as compatibility alias.

Observe API call, then run original

import ctypes
import sogen

app = sogen.windows.create_application(
    "c:/test-sample.exe",
    emulation_root="./root",
)


@sogen.windows.api_call(cc=sogen.CallingConvention.stdcall, params=[ctypes.c_uint32])
def on_sleep(call, params):
    print(f"Sleep({params[0]})")


app.hooks.apis["Sleep"] = on_sleep
app.start()

Intercept API call and return custom value

import sogen

app = sogen.windows.create_application(
    "c:/hook-sample.exe",
    emulation_root="./root",
)


@sogen.windows.api_call(cc=sogen.CallingConvention.stdcall, params=[])
def on_get_current_process_id(call, params):
    call.return_value = 0xC0FFEE01
    return sogen.ApiContinuation.intercept


app.hooks.apis["GetCurrentProcessId"] = on_get_current_process_id
app.start()
print(app.process.exit_status)

Hook keys can be either:

  • bare API name, for example "Sleep"
  • qualified module form, for example "kernel32!Sleep"

Memory and state

The emulator exposes direct state access.

import sogen

emu = sogen.windows.create_empty(emulation_root="./root")
base = emu.memory.allocate_memory(0x1000, sogen.MemoryPermission.read_write)
emu.write_memory(base, b"ABCD")
print(emu.read_memory(base, 4))

state = emu.serialize_state()
emu.write_memory(base, b"WXYZ")
emu.deserialize_state(state)
print(emu.read_memory(base, 4))

For checkpoint-style workflows, use snapshots:

emu.save_snapshot()
# ... mutate state ...
emu.restore_snapshot()

Examples

Small runnable example:

  • examples/python/basic_usage.py

Example setup notes:

  • examples/python/README.md

Current limitations / expectations

  • bindings require an emulation root
  • samples in this repo assume Windows-style guest paths like c:/...
  • some workflows are easiest to validate against repo sample binaries such as test-sample.exe and hook-sample.exe
  • backend availability depends on platform and how Sogen was built

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sogen-0.0.1.dev3706.tar.gz (25.1 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

sogen-0.0.1.dev3706-cp39-cp39-win_amd64.whl (3.7 MB view details)

Uploaded CPython 3.9Windows x86-64

sogen-0.0.1.dev3706-cp39-cp39-manylinux_2_39_x86_64.whl (6.7 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.39+ x86-64

sogen-0.0.1.dev3706-cp39-cp39-macosx_15_0_x86_64.whl (5.5 MB view details)

Uploaded CPython 3.9macOS 15.0+ x86-64

sogen-0.0.1.dev3706-cp39-cp39-macosx_15_0_arm64.whl (4.7 MB view details)

Uploaded CPython 3.9macOS 15.0+ ARM64

File details

Details for the file sogen-0.0.1.dev3706.tar.gz.

File metadata

  • Download URL: sogen-0.0.1.dev3706.tar.gz
  • Upload date:
  • Size: 25.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sogen-0.0.1.dev3706.tar.gz
Algorithm Hash digest
SHA256 40336da9821b4740379f10ee9832b858c1291383cf8e466f7a58e227f79550f4
MD5 c3f42d3306ad2fb04ce2584b9ccab13f
BLAKE2b-256 9917167568a40c122cccdb2aec8e0339661f3c2d9d4eececf3995b26a5d5c633

See more details on using hashes here.

Provenance

The following attestation bundles were made for sogen-0.0.1.dev3706.tar.gz:

Publisher: build-push.yml on momo5502/sogen

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sogen-0.0.1.dev3706-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for sogen-0.0.1.dev3706-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 ae114a252b625b23e93f50c7b188dc533c361d075216d1b5f1be9b7bd634ac03
MD5 bf88bd571bb84ad26b1e7dec1b13e45e
BLAKE2b-256 0fd0c4902116c80e28ccd4b8bfdfbc75e420c0a5315bbf258ea3ab9a14c110dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for sogen-0.0.1.dev3706-cp39-cp39-win_amd64.whl:

Publisher: build-push.yml on momo5502/sogen

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sogen-0.0.1.dev3706-cp39-cp39-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for sogen-0.0.1.dev3706-cp39-cp39-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 b4a0622d4f10c3c0669f37a727fc04fd9d1f06bfc85ce1b55af2a0cab1fbc090
MD5 3e2bf4427e466b06ca9deed6f1e34021
BLAKE2b-256 e580073095b3d57850c93b2a5b410e9cbc417444699957230f081463a2f10b71

See more details on using hashes here.

Provenance

The following attestation bundles were made for sogen-0.0.1.dev3706-cp39-cp39-manylinux_2_39_x86_64.whl:

Publisher: build-push.yml on momo5502/sogen

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sogen-0.0.1.dev3706-cp39-cp39-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for sogen-0.0.1.dev3706-cp39-cp39-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 461249d6704551b7e4f7fe0a0e5ae72dd2b882886ebe10be4359cf14bf67e705
MD5 3b5160a2886fa9005248032970be77cd
BLAKE2b-256 a94440142fa03e10099e99bbf61bf2e88464ea530a683a75b1c11d84b165fa3b

See more details on using hashes here.

Provenance

The following attestation bundles were made for sogen-0.0.1.dev3706-cp39-cp39-macosx_15_0_x86_64.whl:

Publisher: build-push.yml on momo5502/sogen

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sogen-0.0.1.dev3706-cp39-cp39-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for sogen-0.0.1.dev3706-cp39-cp39-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 c8708bc450151835f2b92926ae2c48d3af53243c4148897f2af294901922a253
MD5 a8a5aca922b5f5f92c731cbbaccd6679
BLAKE2b-256 247bc4af9e920d2ecbfb877f7eb25bab67ff150d9e36f9586e686415fc0794c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for sogen-0.0.1.dev3706-cp39-cp39-macosx_15_0_arm64.whl:

Publisher: build-push.yml on momo5502/sogen

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page