Skip to main content

Python bindings for the x86sim C++ library, a cycle-accurate x86-64 simulator based on PTLsim.

Project description

x86sim

x86sim is a cycle-accurate x86-64 simulator, originally developed by Alexis Engelke as a fork of PTLsim by Matt Yourst. This package provides Python bindings to the x86sim C++ library, allowing you to configure the virtual address space, set initial register values, and run simulations of ELF binaries directly from Python.

Installation

The extension is built from the in-tree C++ core via CMake (driven by scikit-build-core). From the repository root:

pip install .

A C++26-capable compiler and CMake >= 3.25 are required.

Features

  • Cycle-accurate simulation of x86-64 instructions.
  • ELF Binary Loading: Parse and load ELF binaries, including segments and debugging information.
  • Custom Memory Management: Map memory segments with specific permissions.
  • Register Access: Read and write CPU registers during simulation.
  • Exception Handling: Detailed exceptions for various fault conditions.
  • Python Binding: Interface directly with the simulator using Python.

Key Components

Machine Class

The main class used to interact with the simulator (x86sim.Machine, a thin wrapper over the compiled x86sim.bindings.Machine). It provides methods to:

  • Load ELF binaries into the simulator.
  • Run the simulation.
  • Access and modify CPU registers.
  • Handle exceptions and retrieve simulation statistics.

ELF Class

Represents an ELF binary and provides methods to:

  • Parse ELF files from bytes and extract segments.
  • Handle debugging information like line mappings.
  • Add trampolines to binaries for controlled execution flow.

Segment Class

Represents a memory segment with attributes:

  • vaddr: Virtual address.
  • prot: Memory protection (read, write, execute).
  • size: Size of the segment.
  • data: Optional data contained in the segment.
  • stack: Indicates if the segment is a stack.

iN Classes (i8, i16, i32, i64)

Represents N-bit integers with proper wrapping and arithmetic operations. Useful for working with register values and ensuring correct bit-width behavior.

Utility Functions

  • simcompile: Context manager to compile code into an ELF binary using appropriate flags.
  • asm_preamble: Generates assembly code preamble with an entry label.
  • asm_stop_sim: Generates assembly instruction to stop the simulator (int 0x80).

Usage

Compiling and Loading an ELF Binary

from x86sim.simcompile import simcompile
from x86sim.elf import ELF
from x86sim import Machine

# Write your assembly code
code = """
.global _start
.intel_syntax noprefix
.text
_start:
    mov rax, -1
    int 0x80
"""

# Compile the code into an ELF binary
with simcompile(code=code) as f:
    elf = ELF.from_file(f)

# Create a simulator instance and load the ELF binary
sim = Machine()
sim.load_elf(elf)

# Run the simulation
sim.run()

# Access register values
print(f"RAX: {sim.registers.rax:#x}")

Accessing Memory

# Map a memory segment
address = sim.memmap(start=0x1000, prot=Prot.RW, length=0x1000)

# Write to memory
address[0x0] = b'\x01\x02\x03\x04'

# Read from memory
data = address.read(size=4)
print(f"Data: {data.hex()}")

Heap and Stream I/O

Machine is a register/memory simulator by default: an int 0x80 stops it and every other syscall raises. Two opt-in features extend it, both off by default:

  • heap=True enables the Linux malloc/free heap for the guest: the brk, mmap/munmap/mremap (anonymous) syscalls are emulated in-process so a guest can grow its heap. With heap=False those syscalls raise.
  • stdin/stdout/stderr route the guest's read(0, ...) / write(1, ...) / write(2, ...) to Python file-like objects (anything exposing .read(n) / .write(bytes), such as io.BytesIO). No host file descriptors are ever touched — Python fully controls the mapping. An fd left as None is unconfigured and a guest I/O on it raises.

These features require the guest to use the 64-bit syscall instruction (the Linux syscall ABI: number in rax, arguments in rdi, rsi, rdx, ...). int 0x80 remains the guest-exit sentinel.

Capturing guest output

import io
from x86sim import Machine

out = io.BytesIO()
sim = Machine(stdout=out)
# ... load a guest that does write(1, msg, len) then exit_group(0) via syscall ...
sim.run()
print(out.getvalue())  # the bytes the guest wrote; the real terminal stays silent

Feeding guest input

import io
from x86sim import Machine

sim = Machine(stdin=io.BytesIO(b"hello"))
# ... load a guest that does read(0, buf, n) via syscall ...
sim.run()
# the guest buffer now contains b"hello"

Enabling malloc/free (heap)

from x86sim import Machine

sim = Machine(heap=True)
# ... load a guest that calls brk / anonymous mmap (e.g. via malloc) ...
sim.run()  # heap syscalls succeed; with Machine() (heap=False) they would raise

Working with Registers

# Set register values
sim.registers.rax = 0xdeadbeef

# Get register values
rip = sim.registers["rip"]
print(f"RIP: {rip:#x}")

Handling Exceptions

The simulator provides detailed exceptions for various fault conditions, such as PageFaultException, InvalidOpcodeException, etc. These can be caught and handled appropriately. In case that the address space of the simulator was populated with an ELF binary that contains debugging information, the exception will contain the file and linenoand line attributes that can be used to provide more context about the fault. Either all three attributes are present or none of them.

try:
    sim.run()
except RaspsimException as e:
    print(f"Simulation error: {e}")
    if hasattr(e, 'lineno'):
        print(f"At {e.file}:{e.lineno}: {e.line}")

Command-Line Interface

You can use x86sim as a command-line tool to simulate code directly from the terminal.

python -m x86sim << EOF
.global _start
.intel_syntax noprefix
.text
_start:
    mov rax, 1
    int 0x80
EOF

Contributing

Contributions are welcome! Please submit pull requests or open issues for any bugs or feature requests at the GitHub repository.

Project details


Download files

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

Source Distribution

x86sim-0.1.0.tar.gz (299.2 kB view details)

Uploaded Source

Built Distributions

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

x86sim-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

x86sim-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

x86sim-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

x86sim-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (2.2 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

File details

Details for the file x86sim-0.1.0.tar.gz.

File metadata

  • Download URL: x86sim-0.1.0.tar.gz
  • Upload date:
  • Size: 299.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for x86sim-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ae274ffd9f1e41f0f6097a5c93123f643fb09d39b773c6a857203c81503f66a9
MD5 8868b6c5412f278f022588cf481cf9fa
BLAKE2b-256 89073deef4b04bcee4adfda5ced2b4230426a0f494c36b3088fc27719935e4cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for x86sim-0.1.0.tar.gz:

Publisher: bindings.yml on rotmanjanez/x86sim

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

File details

Details for the file x86sim-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for x86sim-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 20e82952b115c5402b6f82f5b59f58b03679729c23eb687b0de4508eb6fafa91
MD5 93999ec18fc020cc3e1f6f3863d41362
BLAKE2b-256 66da2525a0871f8d4801df1d9e6ac7aa5b11cc547e7b68d8464ff0c65f55f80f

See more details on using hashes here.

Provenance

The following attestation bundles were made for x86sim-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: bindings.yml on rotmanjanez/x86sim

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

File details

Details for the file x86sim-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for x86sim-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3d595a5c591f348311339b137d09d896206720c7e2480aef0a5446addef16a80
MD5 15edc73776b0b717c31747638af1f8c2
BLAKE2b-256 183a98b07b624a96e442d910cd109b638252ce41afd03e39b86aa4f39078310c

See more details on using hashes here.

Provenance

The following attestation bundles were made for x86sim-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: bindings.yml on rotmanjanez/x86sim

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

File details

Details for the file x86sim-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for x86sim-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c25b342ce1d07c110e8d89929ca38c755d3b43e02bfebd5099200b9dbdeceb86
MD5 269e24279adcbef6457b28ce2b325181
BLAKE2b-256 cc921c689d13f354c25478437beafc6634dd4af36c7d061c69891e4c401e8295

See more details on using hashes here.

Provenance

The following attestation bundles were made for x86sim-0.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: bindings.yml on rotmanjanez/x86sim

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

File details

Details for the file x86sim-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for x86sim-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2bc61e91b398ddb033d6ff6f39612e80c8a7be1e9c4e50c91ed61cde07d52bd7
MD5 d324fcd1e8b8f5555deac68d1da5d138
BLAKE2b-256 845ff9783b07b3f5c09295e4bd7d55c1d1d3bd0911d49e0934a53fd6621ffc23

See more details on using hashes here.

Provenance

The following attestation bundles were made for x86sim-0.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: bindings.yml on rotmanjanez/x86sim

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