Skip to content

Emulator

Emulation assistance from Unicorn.

ARM_BANNED_INSTRUCTIONS = {C.arm.ARM_INS_MRC, C.arm.ARM_INS_MRRC, C.arm.ARM_INS_MRC2, C.arm.ARM_INS_MRRC2} module-attribute

BANNED_INSTRUCTIONS = {'mips': {C.mips.MIPS_INS_RDHWR}, 'arm': ARM_BANNED_INSTRUCTIONS, 'armcm': ARM_BANNED_INSTRUCTIONS} module-attribute

DEBUG = NO_DEBUG module-attribute

arch_to_SYSCALL = {U.UC_ARCH_X86: [C.x86_const.X86_INS_SYSCALL, C.x86_const.X86_INS_SYSENTER, C.x86_const.X86_INS_SYSEXIT, C.x86_const.X86_INS_SYSRET, C.x86_const.X86_INS_IRET, C.x86_const.X86_INS_IRETD, C.x86_const.X86_INS_IRETQ, C.x86_const.X86_INS_INT, C.x86_const.X86_INS_INT1, C.x86_const.X86_INS_INT3], U.UC_ARCH_MIPS: [C.mips_const.MIPS_INS_SYSCALL], U.UC_ARCH_SPARC: [C.sparc_const.SPARC_INS_T], U.UC_ARCH_ARM: [C.arm_const.ARM_INS_SVC], U.UC_ARCH_ARM64: [C.arm64_const.ARM64_INS_SVC], U.UC_ARCH_PPC: [C.ppc_const.PPC_INS_SC], U.UC_ARCH_RISCV: [C.riscv_const.RISCV_INS_ECALL]} module-attribute

arch_to_UC = {'i386': U.UC_ARCH_X86, 'x86-64': U.UC_ARCH_X86, 'mips': U.UC_ARCH_MIPS, 'sparc': U.UC_ARCH_SPARC, 'arm': U.UC_ARCH_ARM, 'armcm': U.UC_ARCH_ARM, 'aarch64': U.UC_ARCH_ARM64, 'rv32': U.UC_ARCH_RISCV, 'rv64': U.UC_ARCH_RISCV} module-attribute

arch_to_UC_consts = {'i386': parse_consts(U.x86_const), 'x86-64': parse_consts(U.x86_const), 'mips': parse_consts(U.mips_const), 'sparc': parse_consts(U.sparc_const), 'arm': parse_consts(U.arm_const), 'armcm': parse_consts(U.arm_const), 'aarch64': parse_consts(U.arm64_const), 'rv32': parse_consts(U.riscv_const), 'rv64': parse_consts(U.riscv_const)} module-attribute

arch_to_reg_const_map = {'i386': create_reg_to_const_map(arch_to_UC_consts['i386']), 'x86-64': create_reg_to_const_map(arch_to_UC_consts['x86-64'], {'FSBASE': U.x86_const.UC_X86_REG_FS_BASE, 'GSBASE': U.x86_const.UC_X86_REG_GS_BASE}), 'mips': create_reg_to_const_map(arch_to_UC_consts['mips']), 'sparc': create_reg_to_const_map(arch_to_UC_consts['sparc']), 'arm': create_reg_to_const_map(arch_to_UC_consts['arm']), 'armcm': create_reg_to_const_map(arch_to_UC_consts['armcm']), 'aarch64': create_reg_to_const_map(arch_to_UC_consts['aarch64'], {'CPSR': U.arm64_const.UC_ARM64_REG_NZCV}), 'rv32': create_reg_to_const_map(arch_to_UC_consts['rv32']), 'rv64': create_reg_to_const_map(arch_to_UC_consts['rv64'])} module-attribute

blacklisted_regs = ['ip', 'cs', 'ds', 'es', 'fs', 'gs', 'ss'] module-attribute

e = pwndbg.emu.emulator.Emulator() e.until_jump()

Emulator

arch = pwndbg.aglib.arch.current instance-attribute

const_regs = arch_to_reg_const_map[self.arch] instance-attribute

last_pc = None instance-attribute

last_single_step_result = InstructionExecutedResult(None, None) instance-attribute

last_step_succeeded: bool property

regs: pwndbg.lib.regs.RegisterSet = pwndbg.aglib.regs.current instance-attribute

uc = U.Uc(arch_to_UC[self.arch], self.uc_mode) instance-attribute

uc_mode = self.get_uc_mode() instance-attribute

valid = True instance-attribute

__getattr__(name)

__init__()

__repr__()

dumpregs()

emu_start(*a, **kw)

emu_stop(*a, **kw)

emulate_with_hook(hook, count=512)

format_telescope(address, limit)

format_telescope_list(chain, limit, enhance_string_len=None)

get_reg_enum(reg)

Returns the Unicorn Emulator enum code for the named register.

Also supports general registers like 'sp' and 'pc'.

get_uc_mode()

Retrieve the mode used by Unicorn for the current architecture.

hook_add(*a, **kw)

hook_del(*a, **kw)

hook_intr(uc, intno, user_data)

We never want to emulate through an interrupt. Just stop.

hook_mem_invalid(uc, access, address, size, value, user_data)

map_page(page)

mem_read(*a, **kw)

memory_read_string(address, max_string_len=None, max_read=None)

read_memory(address, size)

read_register(name)

read_thumb_bit()

Return 0 or 1, representing the status of the Thumb bit in the current Arm architecture

This reads from the emulator itself, meaning this can be read to determine a state transitions between non-Thumb and Thumb mode

Return None if the Thumb bit is not relevent to the current architecture

Mimics the read_thumb_bit function defined in aglib/arch.py

single_step(pc=None)

Steps one instruction.

Yields:

Type Description
int

Each iteration, yields a tuple of (address_just_executed, instruction_size).

int

Returns (None, None) upon failure to execute the instruction

single_step_hook_code(_uc, address, instruction_size, _user_data)

single_step_iter(pc=None)

telescope(address, limit, read_size=None)

telescope_enhance(value, code=True, enhance_string_len=None)

trace_hook(_uc, address, instruction_size, _user_data)

until_call(pc=None)

until_jump(pc=None)

Emulates instructions starting at the specified address until the program counter is set to an address which does not linearly follow the previously-emulated instruction.

Parameters:

Name Type Description Default
pc(int)

Address to start at. If None, uses the current instruction.

required
types(list,set)

List of instruction groups to stop at. By default, it stops at all jumps, calls, and returns.

required
Return

Returns a tuple containing the address of the jump instruction, and its target in the format (address, target).

If emulation is forced to stop (e.g., because of a syscall or invalid memory access) then address is the instruction which could not be emulated through, and target will be None.

Notes

This routine does not consider 'call $+5'

until_jump_hook_code(_uc, address, instruction_size, _user_data)

until_syscall(pc=None)

Emulates instructions starting at the specified address until the program counter points at a syscall instruction (int 0x80, svc, etc.).

until_syscall_hook_code(uc, address, size, user_data)

update_pc(pc=None)

InstructionExecutedResult

Bases: NamedTuple

address: int instance-attribute

size: int instance-attribute

create_reg_to_const_map(base_consts, additional_mapping=None)

debug(debug_type, fmt, args=())

parse_consts(u_consts)

Unicorn "consts" is a python module consisting of a variable definition for each known entity. We repack it here as a dict for performance.

Maps "UC_*" -> integer value of the constant