Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing Operands in ARM Thumb Mode Disassembly with Capstone 5.0.1280 #2280

Open
AntoineBlaud opened this issue Feb 23, 2024 · 4 comments
Open
Labels
ARM Arch bug python bindings
Milestone

Comments

@AntoineBlaud
Copy link

Issue Description:

When disassembling ARM Thumb instructions using Capstone with the CS_MODE_THUMB mode enabled, there is a problem where some instructions have missing operands.

Observed Behavior:

Some instructions, particularly ldr and str, when disassembled using Capstone with ARM Thumb mode, have only one operand reported, missing the memory operand information which includes the base register, index register, scale, and displacement.

Environment:

  • Capstone version: 5.0.1280
  • Capstone version: 4.0.1024

Code Snippet:

from capstone import *
from capstone.arm_const import ARM_OP_MEM, ARM_OP_REG, ARM_OP_IMM

CODE = b'\x00h\x00h\x07\x90\x0bhk\xb1\x87I\x02\xad\x87J'

def get_reg_name(cs, reg):
    name = cs.reg_name(reg)
    if isinstance(name, str):
        return name.upper()
    return None

print("Capstone", cs_version())

md = Cs(CS_ARCH_ARM, CS_MODE_THUMB)
md.detail = True
for insn in md.disasm(CODE, 0x1000):
    print("0x%x:\t%s\t%s" %(insn.address, insn.mnemonic, insn.op_str))
    print("  Number of Operands:", len(insn.operands))
    for op in insn.operands:
        if op.type == ARM_OP_MEM:
            print("  Operand Type: Memory")
            print("  Base Register:", get_reg_name(md, op.mem.base))
            print("  Index Register:", get_reg_name(md, op.mem.index))
            print("  Scale:", op.mem.scale)
            print("  Disp:", op.mem.disp)
        elif op.type == ARM_OP_REG:
            print("  Operand Type: Register")
            print("  Register:", get_reg_name(md, op.reg))
        elif op.type == ARM_OP_IMM:
            print("  Operand Type: Immediate")
            print("  Value:", op.imm)
        else:
            print("  Operand Type:", op.type)

Output:
Capstone version: 4.0.1024

Capstone (4, 0, 1024)
0x1000: ldr     r0, [r0]
  Number of Operands: 2
  Operand Type: Register
  Register: R0
  Operand Type: Memory
  Base Register: R0
  Index Register: None
  Scale: 1
  Disp: 0
0x1002: ldr     r0, [r0]
  Number of Operands: 2
  Operand Type: Register
  Register: R0
  Operand Type: Memory
  Base Register: R0
  Index Register: None
  Scale: 1
  Disp: 0
0x1004: str     r0, [sp, #0x1c]
  Number of Operands: 2
  Operand Type: Register
  Register: R0
  Operand Type: Memory
  Base Register: SP
  Index Register: None
  Scale: 1
  Disp: 28
0x1006: ldr     r3, [r1]
  Number of Operands: 2
  Operand Type: Register
  Register: R3
  Operand Type: Memory
  Base Register: R1
  Index Register: None
  Scale: 1
  Disp: 0
0x1008: cbz     r3, #0x1026
  Number of Operands: 2
  Operand Type: Register
  Register: R3
  Operand Type: Immediate
  Value: 4134
0x100a: ldr     r1, [pc, #0x21c]
  Number of Operands: 2
  Operand Type: Register
  Register: R1
  Operand Type: Memory
  Base Register: PC
  Index Register: None
  Scale: 1
  Disp: 540
0x100c: add     r5, sp, #8
  Number of Operands: 3
  Operand Type: Register
  Register: R5
  Operand Type: Register
  Register: SP
  Operand Type: Immediate
  Value: 8
0x100e: ldr     r2, [pc, #0x21c]
  Number of Operands: 2
  Operand Type: Register
  Register: R2
  Operand Type: Memory
  Base Register: PC
  Index Register: None
  Scale: 1
  Disp: 540

Capstone version: 5.0.1280

Capstone (5, 0, 1280)
0x1000: ldr     r0, [r0]
  Number of Operands: 1
  Operand Type: Register
  Register: R0
0x1002: ldr     r0, [r0]
  Number of Operands: 1
  Operand Type: Register
  Register: R0
0x1004: str     r0, [sp, #0x1c]
  Number of Operands: 1
  Operand Type: Register
  Register: R0
0x1006: ldr     r3, [r1]
  Number of Operands: 1
  Operand Type: Register
  Register: R3
0x1008: cbz     r3, #0x1026
  Number of Operands: 2
  Operand Type: Register
  Register: R3
  Operand Type: Immediate
  Value: 4134
0x100a: ldr     r1, [pc, #0x21c]
  Number of Operands: 2
  Operand Type: Register
  Register: R1
  Operand Type: Memory
  Base Register: PC
  Index Register: None
  Scale: 1
  Disp: 540
0x100c: add     r5, sp, #8
  Number of Operands: 3
  Operand Type: Register
  Register: R5
  Operand Type: Register
  Register: SP
  Operand Type: Immediate
  Value: 8
0x100e: ldr     r2, [pc, #0x21c]
  Number of Operands: 2
  Operand Type: Register
  Register: R2
  Operand Type: Memory
  Base Register: PC
  Index Register: None
  Scale: 1
@AntoineBlaud AntoineBlaud changed the title Title: Missing Operands in ARM Thumb Mode Disassembly with Capstone 5.0.1280 Missing Operands in ARM Thumb Mode Disassembly with Capstone 5.0.1280 Feb 23, 2024
@Rot127
Copy link
Collaborator

Rot127 commented Feb 28, 2024

Can you please check those instructions against the current next branch? There is a huge update for ARM in v6 and hence in the next branch.

@udiboy1209
Copy link

Maybe related to #2260. @AntoineBlaud please try the cstool of your installed capstone version and check if it gives the correct output. I am trying to debug this issue and more info will be helpful.

@AntoineBlaud
Copy link
Author

AntoineBlaud commented Mar 19, 2024

Hello @udiboy1209 ,

I suspect the error originates from the Python library bindings. While version 5.0.0 functions correctly, version 5.0.1 triggers the reported error with the same Capstone library version (5.0.1280)

@Rot127 Rot127 added this to the v5.0.2 milestone Mar 19, 2024
@Rot127 Rot127 added bug ARM Arch python bindings labels Mar 19, 2024
@AntoineBlaud
Copy link
Author

However, I tried using cstool, but the results completely mismatch the decompilation results provided so far. I tested both ARM and Thumb modes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ARM Arch bug python bindings
Projects
None yet
Development

No branches or pull requests

3 participants