Files
Willi Ballenthin 38b1baa98c Migrate API handlers to ctx.args
Handlers set the report display of an argument through ctx.args, by
parameter name where the signature is usable on x86 and x64 and by slot
index otherwise. argv holds the raw slots, and the transitional copy of
argv writes in handle_import_func is gone. Variadic handlers use
ctx.args.clear() and append(); delegating handlers pass ctx, so the
inner handler's displays apply to the outer call.

The display setter ignores values that are not strings, such as None
from a failed constant lookup or the raw pointer of a NULL string
argument.

API hooks get raw argv. WindowsEmulator.get_api_args() returns the
arguments of the hooked call as the report shows them, and the
emu_dll and dbgview examples use it.
2026-10-08 20:08:50 +01:00

1.8 KiB

Python library usage

You can use Speakeasy as a Python library through the speakeasy.Speakeasy interface.

Minimal DLL emulation flow

import speakeasy

se = speakeasy.Speakeasy()
module = se.load_module("sample.dll")
se.run_module(module, all_entrypoints=True)
report = se.get_report()
se.shutdown()

Calling a specific export

import speakeasy

se = speakeasy.Speakeasy()
module = se.load_module("sample.dll")
se.run_module(module)

for export in module.get_exports():
    if export.name == "myexport":
        se.call(export.address, [0x0, 0x1])

report = se.get_report()
se.shutdown()

Library options you may want

  • pass config= to control environment and analysis
  • pass argv= to populate emulated process arguments
  • pass volumes= to mount host paths into emulated filesystem
  • pass gdb_port= to block for GDB attach before execution; gdb_host= controls the bind address and defaults to 127.0.0.1

API hooks

se.add_api_hook(cb, "user32", "MessageBox*") calls cb(emu, api_name, func, params) in place of the handler. params holds the raw argument slots, and func(params) runs the handler. After that call, emu.get_api_args() returns the arguments as the report shows them, with the values the handler decoded:

def hook_messagebox(emu, api_name, func, params):
    rv = func(params)
    print(emu.get_api_args()[1].display)  # the lpText string
    return rv

For runnable scripts, see ../examples.