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: Dict[int, Set[int]] = {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: int | None = None instance-attribute

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

after_value_resolved: int | None = None instance-attribute

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

before_value: int | None = 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: int | None = 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: int | None = 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: typing.Any = 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: int property

The immediate value of the operand (if applicable)

mem: typing.Any property

Return the underlying Capstone mem object (if applicable)

reg: int property

The underlying Capstone ID for the register

str: str | None = '' instance-attribute

String representing the operand

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

symbol: str | None = None instance-attribute

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

type: int 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

PwndbgInstruction

address: int = cs_insn.address instance-attribute

annotation: str | None = 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: int | None = 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: str = '%-06s %s' % (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: bytearray property

Raw machine instruction bytes

call_like: bool 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: bool = False instance-attribute

Whether or not this instruction has a single branch delay slot

condition: InstructionCondition = 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: CsInsn = cs_insn instance-attribute

The underlying Capstone instruction, if present. Ideally, only the enhancement code will access the 'cs_insn' property

declare_conditional: bool | None = 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: bool = 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: bool = False instance-attribute

If the enhancement successfully used emulation for this instruction

force_unconditional_jump_target: bool = 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[int] = 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: bool 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: int = 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: bool 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: bool property

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

is_unconditional_jump: bool 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: bool 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: str = cs_insn.mnemonic instance-attribute

Ex: 'MOV'

next: int = 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: str = cs_insn.op_str instance-attribute

Ex: 'RAX, RDX'

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

size: int = cs_insn.size instance-attribute

Length of the instruction

split: SplitType = 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: int | None = None instance-attribute

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

syscall_name: str | None = None instance-attribute

The syscall name as a string

Ex: "openat", "read"

target: int = 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: bool | None = None instance-attribute

Whether the target is a constant expression

target_string: str | None = 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)

make_simple_instruction(address)

Instantiate a PwndbgInstruction for an architecture that Capstone/pwndbg doesn't support (as defined in the CapstoneArch structure)