Skip to content

Instruction

ALL_JUMP_GROUPS = GENERIC_JUMP_GROUPS | GENERIC_UNCONDITIONAL_JUMP_GROUPS module-attribute

CAPSTONE_ARCH_MAPPING_STRING = {CS_ARCH_ARM: 'arm', CS_ARCH_ARM64: 'aarch64', CS_ARCH_X86: 'x86', CS_ARCH_PPC: 'powerpc', CS_ARCH_MIPS: 'mips', CS_ARCH_SPARC: 'sparc', CS_ARCH_RISCV: 'RISCV'} module-attribute

FORWARD_JUMP_GROUP = {CS_GRP_CALL} | GENERIC_JUMP_GROUPS module-attribute

GENERIC_JUMP_GROUPS = {CS_GRP_JUMP, CS_GRP_BRANCH_RELATIVE} module-attribute

GENERIC_UNCONDITIONAL_JUMP_GROUPS = {CS_GRP_CALL, CS_GRP_RET, CS_GRP_IRET} module-attribute

UNCONDITIONAL_JUMP_INSTRUCTIONS = {CS_ARCH_X86: {X86_INS_JMP}, CS_ARCH_MIPS: {MIPS_INS_J, MIPS_INS_JR, MIPS_INS_JAL, MIPS_INS_JALR, MIPS_INS_BAL, MIPS_INS_B}, CS_ARCH_SPARC: {SPARC_INS_JMP, SPARC_INS_JMPL}, CS_ARCH_ARM: {ARM_INS_TBB, ARM_INS_TBH}, CS_ARCH_ARM64: {ARM64_INS_BL, ARM64_INS_BLR, ARM64_INS_BR}, CS_ARCH_RISCV: {RISCV_INS_JAL, RISCV_INS_JALR, RISCV_INS_C_JAL, RISCV_INS_C_JALR, RISCV_INS_C_J, RISCV_INS_C_JR}, CS_ARCH_PPC: {PPC_INS_B, PPC_INS_BA, PPC_INS_BL, PPC_INS_BLA}} module-attribute

EnhancedOperand

after_value = None instance-attribute

The value of the operand after the instruction executes. Only set when using emulation.

after_value_resolved = None instance-attribute

The 'resolved' value of the operand after the instruction executes.

before_value = None instance-attribute

The value of the operand before the instruction executes. This is set only if the operand value can be reasoned about.

before_value_no_modifiers = None instance-attribute

This is a special field used in some architectures that allow operand modifiers, such as shifts and extends in Arm. Capstone bundles the modifier with the operand, and when we are resolving concrete operand values, we apply the modifier. However, in some annotations we need to un-modified raw register value, which is what this field is for.

before_value_resolved = None instance-attribute

The 'resolved' value of the operand that is actually used in the instruction logic, before the instruction executes. This is the same as before_value if it's not a memory operand, in which cases it's the dereferenced value.

Helpful for cases like cmp byte ptr [rip + 0x166669], 0, where first operand could be a register or a memory value to dereference, and we want the actual value used.

cs_op = cs_op instance-attribute

Underlying Capstone operand. Takes on a different value depending on the architecture.

x86 = capstone.x86.X86Op, arm = capstone.arm.ArmOp, mips = capstone.mips.MipsOp

imm property

The immediate value of the operand (if applicable)

mem property

Return the underlying Capstone mem object (if applicable)

reg property

The underlying Capstone ID for the register

str = '' instance-attribute

String representing the operand

Ex: "RAX", or "[0x7fffffffd9e8]". None if value cannot be determined.

symbol = None instance-attribute

Colorized symbol name for this operand, if .before_value is set and symbol exists, else None.

type property

CS_OP_REG | CS_OP_MEM | CS_OP_IMM | CS_OP_INVALID | CS_OP_FP

__init__(cs_op)

__repr__()

InstructionCondition

Bases: Enum

FALSE = 2 class-attribute instance-attribute

TRUE = 1 class-attribute instance-attribute

UNDETERMINED = 3 class-attribute instance-attribute

ManualPwndbgInstruction

Bases: PwndbgInstruction

address = address instance-attribute

annotation = None instance-attribute

annotation_padding = None instance-attribute

asm_string = f'{self.mnemonic} {self.op_str}' instance-attribute

bytes property

call_like property

causes_branch_delay = False instance-attribute

condition = InstructionCondition.UNDETERMINED instance-attribute

cs_insn = None instance-attribute

declare_conditional = None instance-attribute

declare_is_unconditional_jump = False instance-attribute

emulated = False instance-attribute

force_unconditional_jump_target = False instance-attribute

groups = set() instance-attribute

has_jump_target property

id = -1 instance-attribute

is_conditional_jump property

is_conditional_jump_taken property

is_unconditional_jump property

jump_like property

mnemonic = asm[0].strip() instance-attribute

next = address + self.size instance-attribute

op_str = asm[1].strip() if len(asm) > 1 else '' instance-attribute

operands = [] instance-attribute

size = ins['length'] instance-attribute

split = SplitType.NO_SPLIT instance-attribute

syscall = None instance-attribute

syscall_name = None instance-attribute

target = self.next instance-attribute

target_const = None instance-attribute

target_string = None instance-attribute

__init__(address)

This class provides an implementation of PwndbgInstruction for cases where the architecture at hand is not supported by the Capstone disassembler. The backing information is sourced from GDB/LLDB's built-in disassemblers.

Instances of this class do not go through the 'enhancement' process due to lacking important information provided by Capstone. As a result of this, some of the methods raise NotImplementedError, because if they are called it indicates a bug elsewhere in the codebase.

op_count(op_type)

op_find(op_type, position)

PwndbgInstruction

Bases: Protocol

address instance-attribute

annotation instance-attribute

annotation_padding instance-attribute

asm_string instance-attribute

bytes property

call_like property

causes_branch_delay instance-attribute

condition instance-attribute

cs_insn instance-attribute

declare_conditional instance-attribute

declare_is_unconditional_jump instance-attribute

emulated instance-attribute

force_unconditional_jump_target instance-attribute

groups instance-attribute

has_jump_target property

id instance-attribute

is_conditional_jump property

is_conditional_jump_taken property

is_unconditional_jump property

jump_like property

mnemonic instance-attribute

next instance-attribute

op_str instance-attribute

operands instance-attribute

size instance-attribute

split instance-attribute

syscall instance-attribute

syscall_name instance-attribute

target instance-attribute

target_const instance-attribute

target_string instance-attribute

op_count(op_type)

op_find(op_type, position)

PwndbgInstructionImpl

Bases: PwndbgInstruction

address = cs_insn.address instance-attribute

annotation = None instance-attribute

The string is set in the "DisassemblyAssistant.enhance" function. It is used in the disasm print view to add context to the instruction, mostly operand value. This string is not used for all cases - if the instruction is a call or a jump, the 'target'. variables is used instead. See 'pwndbg.color.disasm.instruction()' for specific usage.

annotation_padding = None instance-attribute

The left adjustment padding that was used to previously print this. We retain it so the output is consistent between prints

asm_string = f'{self.mnemonic} {self.op_str}' instance-attribute

The full string representing the instruction - mov rdi, rsp with appropriate padding.

This is syntax highlighted during enhancement.

This is additionally modified during enhancement for the purposes of replacing immediate values with their corresponding symbols

bytes property

Raw machine instruction bytes

call_like property

True if this is a call-like instruction, meaning either it's a CALL or a branch and link.

Checking for the CS_GRP_CALL is insufficient, as there are many "branch and link" instructions that are not labeled as a call

causes_branch_delay = False instance-attribute

Whether or not this instruction has a single branch delay slot

condition = InstructionCondition.UNDETERMINED instance-attribute

Does the condition that the instruction checks for pass?

For example, "JNE" jumps if Zero Flag is 0, else it does nothing. "CMOVA" conditionally performs a move depending on a flag. See 'condition' function in pwndbg.aglib.disasm.x86 for example on setting this.

UNDETERMINED if we cannot reason about the condition, or if the instruction always executes unconditionally (most instructions).

TRUE if the instruction has a conditional action, and we determine it is taken.

FALSE if the instruction has a conditional action, and we know it is not taken.

cs_insn = cs_insn instance-attribute

The underlying Capstone instruction object. Only the enhancement code should access the 'cs_insn' property

declare_conditional = None instance-attribute

This field is used to declare if the instruction is a conditional instruction. In most cases, we can determine this purely based on the instruction ID, and this field is irrelevent. However, in some arches, like Arm, the same instruction can be made conditional by certain instruction attributes. Ex: Arm, bls instruction. This is encoded as a b (Capstone ID 11) under the code, with an additional condition code field. In this case, sometimes a b instruction (ID 11) is unconditional (always branches), in other cases it is conditional. We use this field to disambiguate these cases.

True if we manually determine this instruction is a conditional instruction False if it's not a conditional instruction None if we don't have a determination (most cases)

declare_is_unconditional_jump = False instance-attribute

This field is used to declare that this instruction is an unconditional jump. Most of the type, we depend on Capstone groups to check for jump instructions, but sometimes these are lacking, such as in the case of general-purpose instructions where the PC is the destination register, such as Arm add, sub, ldr, and pop instructions.

In these cases, we want to forcefully state that this instruction mutates the PC, so we set this attribute to True.

This helps in two cases: 1. Disassembly splits 2. Instructions like stepuntilasm work better, as they detect these as branches to stop at.

emulated = False instance-attribute

If the enhancement successfully used emulation for this instruction

force_unconditional_jump_target = False instance-attribute

This asserts that the .target attribute is the real target of the instruction. This is only relevent in the edge case that the target is the next instruction in memory (address + size). The normal check for "target" checks that the target is NOT the next address in memory, and here we can assert that even if that is the case, we know that the jump really does just go to where self.target is.

groups = set(cs_insn.groups) instance-attribute

Capstone instruction groups that we belong to. Groups that apply to all architectures: CS_GRP_INVALID | CS_GRP_JUMP | CS_GRP_CALL | CS_GRP_RET | CS_GRP_INT | CS_GRP_IRET | CS_GRP_PRIVILEGE | CS_GRP_BRANCH_RELATIVE

has_jump_target property

True if we have determined that this instruction can explicitly change the program counter, and we have determined the jump target.

Edge case - the jump target MAY be the next address in memory - so we check force_unconditional_jump_target

id = cs_insn.id instance-attribute

The underlying Capstone ID for the instruction Examples: X86_INS_JMP, X86_INS_CALL, RISCV_INS_C_JAL

is_conditional_jump property

True if this instruction can change the program counter conditionally.

This is used, in part, to determine if the instruction deserves a "checkmark" in the disasm view.

This does not imply that we have resolved the .target

is_conditional_jump_taken property

True if this is a conditional jump, and we predicted that we will take the jump

is_unconditional_jump property

True if we know the instruction can change the program counter, and does so unconditionally.

This includes things like RET, CALL, and JMP (in x86).

This property is used in enhancement to determine certain codepaths when resolving .next for this instruction.

This does not imply that we have resolved the .target

jump_like property

True if this instruction is "jump-like", such as a JUMP, CALL, or RET. Basically, the PC is set to some target by means of this instruction.

It may still be a conditional jump - this property does not indicate whether the jump is taken or not.

mnemonic = cs_insn.mnemonic instance-attribute

Ex: 'MOV'

next = self.address + self.size instance-attribute

This is the address that the instruction pointer will be set to after using the "nexti" GDB command. This means it is the address of the next instruction to be executed in all cases except "call" instructions.

Typically, it is self.address + self.size (the next instruction in memory)

If it is a jump and we know it is taken, then it is the value of the jump target.

Not set to "call" instruction targets, to indicate we will eventually (probably) return to this address

op_str = cs_insn.op_str instance-attribute

Ex: 'RAX, RDX'

operands = [EnhancedOperand(op) for op in self.cs_insn.operands] instance-attribute

size = cs_insn.size instance-attribute

Length of the instruction

split = SplitType.NO_SPLIT instance-attribute

The type of split in the disasm display this instruction causes:

Text Only
1
2
3
NO_SPLIT            - no extra spacing between this and the next instruction
BRANCH_TAKEN        - a newline with an arrow pointing down
BRANCH_NOT_TAKEN    - an empty newline

syscall = None instance-attribute

The syscall number for this instruction, if it is a syscall. Otherwise None.

syscall_name = None instance-attribute

The syscall name as a string

Ex: "openat", "read"

target = None instance-attribute

This is target of instructions that change the PC, regardless of if it's conditional or not, and whether or not we take the jump. This includes "call" and all other instructions that set the PC

If the instruction is not one that changes the PC, target is set to "next"

target_const = None instance-attribute

Whether the target is a constant expression

target_string = None instance-attribute

String representation of the target address.

Colorized symbol if a symbol exists at address, else colorized address

__init__(cs_insn)

__repr__()

op_count(op_type)

Return number of operands having same operand Capstone type 'op_type'

op_find(op_type, position)

Get the operand at position @position of all operands having the same type @op_type

SplitType

Bases: Enum

BRANCH_NOT_TAKEN = 3 class-attribute instance-attribute

BRANCH_TAKEN = 2 class-attribute instance-attribute

NO_SPLIT = 1 class-attribute instance-attribute

boolean_to_instruction_condition(condition)