capstone-engine / capstone

Capstone disassembly/disassembler framework for ARM, ARM64 (ARMv8), Alpha, BPF, Ethereum VM, HPPA, LoongArch, M68K, M680X, Mips, MOS65XX, PPC, RISC-V(rv32G/rv64G), SH, Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86.
http://www.capstone-engine.org
7.34k stars 1.54k forks source link

Incorrect SYSREG enum on thumb "cpsr" op #2418

Closed david942j closed 1 month ago

david942j commented 1 month ago

Work environment

Questions Answers
OS/arch/bits Ubuntu x86 64
Architecture thumb
Source of Capstone git clone
Version/git commit v5.0.1, 1bd2a32f2afc6e08225d7491b82619cf4c8e87d9

Instruction bytes giving faulty results

0x86,0xf3,0x00,0x89

Expected results

It should be:

 0  86 f3 00 89  msr    cpsr_fc, r6
        ID: 115 (msr)
        op_count: 2
                operands[0].type: SYSREG = 144 // <- this value should be 144 but is 9 on v5
                operands[1].type: REG = r6
                operands[1].access: READ
        Registers read: r6
        Groups: thumb2 notmclass

Steps to get the wrong result

With cstool:

cstool/cstool -v
cstool for Capstone Disassembler, v5.0.1
Capstone build: x86=1 arm=1 arm64=1 mips=1 ppc=1 sparc=1 sysz=1 xcore=1 m68k=1 tms320c64x=1 m680x=1 evm=1 wasm=1 mos65xx=1 bpf=1 riscv=1 sh=1 tricore=1

cstool/cstool -d thumb '86f30089'
 0  86 f3 00 89  msr    cpsr_fc, r6
        ID: 115 (msr)
        op_count: 2
                operands[0].type: SYSREG = 9
                operands[1].type: REG = r6
                operands[1].access: READ
        Registers read: r6
        Groups: thumb2 notmclass

The output is correct on the v3/v4/next branches, so it's a v5 only bug.

FYI it should be 144 because it should be the OR value of ARM_SYSREG_CPSR_C | ARM_SYSREG_CPSR_F = 16 | 128

The reported value 9 is ARM_SYSREG_SPSR_C | ARM_SYSREG_SPSR_F.

I also checked the output if passing the instruction with SPSR, the output on v5 is correct (also 9) in this case:

cstool/cstool -d thumb '96f30089'
 0  96 f3 00 89  msr    spsr_fc, r6
        ID: 115 (msr)
        op_count: 2
                operands[0].type: SYSREG = 9
                operands[1].type: REG = r6
                operands[1].access: READ
        Registers read: r6
        Groups: thumb2 notmclass

I also checked other CPSR operands, and it seems all of them are wrongly treated as SPSR, for example:

cstool/cstool -d thumb '86f30083'
 0  86 f3 00 83  msr    cpsr_xc, r6
        ID: 115 (msr)
        op_count: 2
                operands[0].type: SYSREG = 3 // <- This should be 48. 3 is SYSREG_SPSR_C | SYSREG_SPSR_X
                operands[1].type: REG = r6
                operands[1].access: READ
        Registers read: r6
        Groups: thumb2 notmclass
Rot127 commented 1 month ago

Thanks for the issue! I highly recommend you to consider using the next branch for your use case. The ARM module was completely update there and more correct/better tested.