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 | 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
¶
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