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.61k stars 1.56k forks source link

ARM Thumb instruction SUB may decode wrong in ADR situation #2197

Closed yakamoz423 closed 1 year ago

yakamoz423 commented 1 year ago

I have an ARM Thumb instruction:

 80001a6:   f2af 0e09   subw    lr, pc, #9

In bits view: image

The Capstone decoded it as a SUB instruction: image

But according to the Arm Architecture Reference Manual for A-profile architecture document, when Rn is PC (15) in T4 format, it should be regarded as ADR instruction. image

Capstone says it insn-mnem is sub. I think it's a mistake. It matters because ADR is 4-byte aligning the PC value, while SUB is not.

The Capstone instance is configured by:

    cs_open(CS_ARCH_ARM, CS_MODE_THUMB, &handle);
    cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
Rot127 commented 1 year ago

It seems to be fixed in the next branch:

./cstool thumbbe f2af0e09
 0  f2 af 0e 09  adr.w  lr, #-9
Rot127 commented 1 year ago

@yakamoz423 Please check for yourself and close the issue if it works as expected.

yakamoz423 commented 1 year ago

@Rot127 Hi, I encountered some issues while compiling the latest next version d3eb79c2aa6511675c2f80eb185cb41bfd61e5ea

$ CC=gcc ./make.sh
  LINK    capstone.
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x0): multiple definition of `llabs'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x0): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x44): multiple definition of `wcscmpi'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x40c): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x50): multiple definition of `strncasecmp'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x418): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x5c): multiple definition of `strcasecmp'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x424): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x68): multiple definition of `vsnwprintf'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x430): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x74): multiple definition of `ftello64'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x43c): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0xa4): multiple definition of `fopen64'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x46c): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0xb0): multiple definition of `putchar'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x478): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0xf4): multiple definition of `putc'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x4bc): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x128): multiple definition of `getchar'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x4f0): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x160): multiple definition of `getc'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x528): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x188): multiple definition of `ulltow'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x550): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x194): multiple definition of `lltow'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x55c): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x1a0): multiple definition of `wtoll'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x568): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x1ac): multiple definition of `ulltoa'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x574): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x1b8): multiple definition of `lltoa'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x580): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x1c4): multiple definition of `atoll'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x58c): first defined here
./arch/AArch64/AArch64DisassemblerExtension.o:AArch64DisassemblerExtension.c:(.text+0x1d0): multiple definition of `_Exit'
./arch/ARM/ARMDisassemblerExtension.o:ARMDisassemblerExtension.c:(.text+0x598): first defined here
collect2: ld returned 1 exit status
make: *** [capstone.] Error 1

Compiler (seems too old):

$ gcc -v
Using built-in specs.
Target: mingw32
Configured with: ../gcc-4.3.3/configure --prefix=/mingw --build=mingw32 --enable-languages=c,c++ --with-bugurl=http://www.simics.net --disable-nls --disable-win32-registry --enable-threads --disable-symvers --enable-cxx-flags='-fno-function-sections -fno-data-sections' --enable-fully-dynamic-string --enable-version-specific-runtime-libs --enable-sjlj-exceptions --with-pkgversion='4.3.3-vt-1 mingw32'
Thread model: win32
gcc version 4.3.3 (4.3.3-vt-1 mingw32)

5.x wasn't like this.

Rot127 commented 1 year ago

Please use cmake (see docs). The make build is deprecated and only there until the bindings are update as well (some when in the future) But yes. gcc is very old in your case. Better use some version >10