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.dev3973.tar.gz (44.7 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.dev3973-cp39-cp39-win_amd64.whl (4.9 MB view details)

Uploaded CPython 3.9Windows x86-64

sogen-0.0.1.dev3973-cp39-cp39-manylinux_2_39_x86_64.whl (8.6 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.39+ x86-64

sogen-0.0.1.dev3973-cp39-cp39-macosx_15_0_x86_64.whl (6.8 MB view details)

Uploaded CPython 3.9macOS 15.0+ x86-64

sogen-0.0.1.dev3973-cp39-cp39-macosx_15_0_arm64.whl (5.8 MB view details)

Uploaded CPython 3.9macOS 15.0+ ARM64

File details

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

File metadata

  • Download URL: sogen-0.0.1.dev3973.tar.gz
  • Upload date:
  • Size: 44.7 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.dev3973.tar.gz
Algorithm Hash digest
SHA256 12db5c377e102597a1949ed67baf1d8c4475652c2d92996a074c0a3eeea8e181
MD5 8954cd37315d0c41308a735b31c545d3
BLAKE2b-256 afb0d4414d9f7eb5e70f59cd14bda7f520c7a99ea8657ef35e3d6a0e3618b2eb

See more details on using hashes here.

Provenance

The following attestation bundles were made for sogen-0.0.1.dev3973.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.dev3973-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for sogen-0.0.1.dev3973-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 28ef67a6c2db88510f0961a34264b017deda4fb661b905c95a6ef7a3869c1399
MD5 fbfd3671c892f887db3cd1456d3c268a
BLAKE2b-256 d47ab77fe79f3a6cc47241442c18d321de7304942c2b36a0e935c898a8ac5d85

See more details on using hashes here.

Provenance

The following attestation bundles were made for sogen-0.0.1.dev3973-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.dev3973-cp39-cp39-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for sogen-0.0.1.dev3973-cp39-cp39-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 f7de9c3750a426fbd56813489198fed4942fdf255df6d514e2f559604f918244
MD5 362e07909190952780c3bbe8baee064a
BLAKE2b-256 76b7029740af08fb44839f5774864c88f5483b297d48c93c84d9be1af00ba70c

See more details on using hashes here.

Provenance

The following attestation bundles were made for sogen-0.0.1.dev3973-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.dev3973-cp39-cp39-macosx_15_0_x86_64.whl.

File metadata

File hashes

Hashes for sogen-0.0.1.dev3973-cp39-cp39-macosx_15_0_x86_64.whl
Algorithm Hash digest
SHA256 7cb8bbffd0ed54b6522021ad9125e236da11b77e7a061a75146fbaf96e872b7e
MD5 b783180e93f66ea32668accf8a1f195b
BLAKE2b-256 9d1e7fc313998c368666c1af6653bccfcfc5f6ac2cbd331955decf4c4547eab0

See more details on using hashes here.

Provenance

The following attestation bundles were made for sogen-0.0.1.dev3973-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.dev3973-cp39-cp39-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for sogen-0.0.1.dev3973-cp39-cp39-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 1a3dac3d2eb0630caca7c496222639dcd30a09698e375d67936f446982dd4a53
MD5 ecd4e695e7a198c988d2d2ab4b8a2de9
BLAKE2b-256 c5fcbe7514229065a155d4b02a1e07ec051ce5e85b6e9b3c054c5491f3c5438c

See more details on using hashes here.

Provenance

The following attestation bundles were made for sogen-0.0.1.dev3973-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