From 58ab1383dd004c1fa15d79bd4f1210ac3506abee Mon Sep 17 00:00:00 2001 From: OBarronCS <55004530+OBarronCS@users.noreply.github.com> Date: Fri, 16 Aug 2024 08:43:58 -0700 Subject: [PATCH] AArch64 Conditional Instructions + More (#2368) * lint * Revert accidental change --- pwndbg/gdblib/disasm/aarch64.py | 49 ++++++++++++++++++++++++++++++++- pwndbg/gdblib/disasm/mips.py | 5 ++++ pwndbg/gdblib/disasm/riscv.py | 22 ++++++++++++--- 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/pwndbg/gdblib/disasm/aarch64.py b/pwndbg/gdblib/disasm/aarch64.py index 23789f351..f54f2fc20 100644 --- a/pwndbg/gdblib/disasm/aarch64.py +++ b/pwndbg/gdblib/disasm/aarch64.py @@ -75,6 +75,43 @@ AARCH64_SINGLE_STORE_INSTRUCTIONS: Dict[int, int | None] = { ARM64_INS_STLXR: None, } +CONDITIONAL_SELECT_INSTRUCTIONS = { + ARM64_INS_CSEL, + ARM64_INS_CSINC, + ARM64_INS_CSINV, + ARM64_INS_CSNEG, + ARM64_INS_CSET, + ARM64_INS_CSETM, + ARM64_INS_CINC, + ARM64_INS_CINV, + ARM64_INS_CNEG, +} + +AARCH64_EMULATED_ANNOTATIONS = CONDITIONAL_SELECT_INSTRUCTIONS | { + ARM64_INS_SXTB, + ARM64_INS_SXTH, + ARM64_INS_SXTW, + ARM64_INS_UXTB, + ARM64_INS_UXTH, + ARM64_INS_UXTW, + ARM64_INS_RBIT, + ARM64_INS_CLS, + ARM64_INS_CLZ, + ARM64_INS_BFXIL, + ARM64_INS_UBFIZ, + ARM64_INS_UBFM, + ARM64_INS_UBFX, + ARM64_INS_SBFIZ, + ARM64_INS_SBFM, + ARM64_INS_SBFX, + ARM64_INS_BFI, + ARM64_INS_NEG, + ARM64_INS_NEGS, + ARM64_INS_REV, + ARM64_INS_BIC, + ARM64_INS_BICS, +} + # Parameters to each function: (value, shift_amt, bit_width) AARCH64_BIT_SHIFT_MAP: Dict[int, Callable[[int, int, int], int]] = { ARM64_SFT_LSL: bit_math.logical_shift_left, @@ -100,8 +137,11 @@ AARCH64_EXTEND_MAP: Dict[int, Callable[[int], int]] = { AARCH64_MATH_INSTRUCTIONS = { ARM64_INS_ADD: "+", + ARM64_INS_ADDS: "+", ARM64_INS_SUB: "-", + ARM64_INS_SUBS: "-", ARM64_INS_AND: "&", + ARM64_INS_ANDS: "&", ARM64_INS_ORR: "&", ARM64_INS_ASR: ">>s", ARM64_INS_ASRV: ">>s", @@ -215,6 +255,8 @@ class DisassemblyAssistant(pwndbg.gdblib.disasm.arch.DisassemblyAssistant): instruction.operands[-1].before_value, AARCH64_MATH_INSTRUCTIONS[instruction.id], ) + elif instruction.id in AARCH64_EMULATED_ANNOTATIONS: + self._common_generic_register_destination(instruction, emu) else: self.annotation_handlers.get(instruction.id, lambda *a: None)(instruction, emu) @@ -271,8 +313,13 @@ class DisassemblyAssistant(pwndbg.gdblib.disasm.arch.DisassemblyAssistant): if op_val is not None and bit is not None: return boolean_to_instruction_condition(not ((op_val >> bit) & 1)) + elif instruction.id in CONDITIONAL_SELECT_INSTRUCTIONS: + # Capstone places the condition to be satisfied in the `cc` field of the instruction + # for all conditional select instructions + flags = self._read_register_name(instruction, "cpsr", emu) - # TODO: Additionally, the "conditional comparisons" and "conditional selects" support conditional execution + if flags is not None: + return resolve_condition(instruction.cs_insn.cc, flags) return super()._condition(instruction, emu) diff --git a/pwndbg/gdblib/disasm/mips.py b/pwndbg/gdblib/disasm/mips.py index 32913c055..e58e5b0d9 100644 --- a/pwndbg/gdblib/disasm/mips.py +++ b/pwndbg/gdblib/disasm/mips.py @@ -77,6 +77,7 @@ MIPS_SIMPLE_DESTINATION_INSTRUCTIONS = { MIPS_INS_SLTI, MIPS_INS_SLTIU, MIPS_INS_SLTU, + MIPS_INS_MOVN, # Rare - unaligned read - have complex loading logic MIPS_INS_LDL, MIPS_INS_LDR, @@ -129,6 +130,10 @@ MIPS_BINARY_OPERATIONS = { MIPS_INS_SLLV: "<<", MIPS_INS_DSLL: "<<", MIPS_INS_DSLLV: "<<", + MIPS_INS_SRL: ">>", + MIPS_INS_SRLV: ">>", + MIPS_INS_DSRL: ">>", + MIPS_INS_DSRLV: ">>", } diff --git a/pwndbg/gdblib/disasm/riscv.py b/pwndbg/gdblib/disasm/riscv.py index 6812a112f..8d744be24 100644 --- a/pwndbg/gdblib/disasm/riscv.py +++ b/pwndbg/gdblib/disasm/riscv.py @@ -106,6 +106,13 @@ RISCV_MATH_INSTRUCTIONS = { RISCV_INS_C_SUBW: "-", } +RISCV_EMULATED_ANNOTATIONS = { + RISCV_INS_SLT, + RISCV_INS_SLTU, + RISCV_INS_SLTI, + RISCV_INS_SLTIU, +} + class DisassemblyAssistant(pwndbg.gdblib.disasm.arch.DisassemblyAssistant): def __init__(self, architecture) -> None: @@ -121,6 +128,7 @@ class DisassemblyAssistant(pwndbg.gdblib.disasm.arch.DisassemblyAssistant): RISCV_INS_C_LI: self._common_move_annotator, # LUI RISCV_INS_LUI: self._lui_annotator, + RISCV_INS_C_LUI: self._lui_annotator, } @override @@ -193,6 +201,8 @@ class DisassemblyAssistant(pwndbg.gdblib.disasm.arch.DisassemblyAssistant): instruction.operands[-1].before_value, RISCV_MATH_INSTRUCTIONS[instruction.id], ) + elif instruction.id in RISCV_EMULATED_ANNOTATIONS: + self._common_generic_register_destination(instruction, emu) else: self.annotation_handlers.get(instruction.id, lambda *a: None)(instruction, emu) @@ -298,16 +308,20 @@ class DisassemblyAssistant(pwndbg.gdblib.disasm.arch.DisassemblyAssistant): return (instruction.address + instruction.op_find(CS_OP_IMM, 1).imm) & ptrmask # Determine the target address of the indirect jump - if instruction.id in (RISCV_INS_JALR, RISCV_INS_C_JALR): - if (target := instruction.op_find(CS_OP_REG, 1).before_value) is None: + if instruction.id == RISCV_INS_JALR: + if (target := instruction.op_find(CS_OP_REG, 2).before_value) is None: return None - if instruction.id == RISCV_INS_JALR: - target += instruction.op_find(CS_OP_IMM, 1).imm + target += instruction.op_find(CS_OP_IMM, 1).imm target &= ptrmask # Clear the lowest bit without knowing the register width return target ^ (target & 1) + if instruction.id == RISCV_INS_C_JALR: + if (target := instruction.op_find(CS_OP_REG, 1).before_value) is None: + return None + return target ^ (target & 1) + return super()._resolve_target(instruction, emu) @override