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

Disassembly Error, missing one operand in some long multi-byte NOPs #539

Open
Mar3yZhang opened this issue Nov 22, 2024 · 0 comments
Open
Labels
A-decoder Area: Decoder

Comments

@Mar3yZhang
Copy link

Mar3yZhang commented Nov 22, 2024

Work environment

Questions Answers
OS/arch/bits x86_64 Ubuntu 20.04
Architecture x86_64
Source of Capstone git clone, default on master branch.
Version/git commit v4.1.0, bffbb6

Instruction bytes giving faulty results

0f 1a de

Expected results

It should be:

nop esi, ebx

Steps to get the wrong result

With ZydisInfo:

./ZydisInfo -64 "0f 1a de"
== [    BASIC ] ============================================================================================
   MNEMONIC: nop [ENC: DEFAULT, MAP: 0F, OPC: 0x1A]
     LENGTH:  3
        SSZ: 64
       EOSZ: 32
       EASZ: 64
   CATEGORY: WIDENOP
    ISA-SET: PPRO
    ISA-EXT: BASE
 EXCEPTIONS: NONE
 ATTRIBUTES: HAS_MODRM
  OPTIMIZED: 0F 18 C3

== [ OPERANDS ] ============================================================================================
##       TYPE  VISIBILITY  ACTION      ENCODING   SIZE  NELEM  ELEMSZ  ELEMTYPE                        VALUE
--  ---------  ----------  ------  ------------   ----  -----  ------  --------  ---------------------------
 0   REGISTER    EXPLICIT       R     MODRM_REG     32      1      32       INT                          ebx
--  ---------  ----------  ------  ------------   ----  -----  ------  --------  ---------------------------

== [      ATT ] ============================================================================================
   ABSOLUTE: nop %ebx
   RELATIVE: nop %ebx

== [    INTEL ] ============================================================================================
   ABSOLUTE: nop ebx
   RELATIVE: nop ebx

== [ SEGMENTS ] ============================================================================================
0F 1A DE
:     :..MODRM
:..OPCODE

Additional Logs, screenshots, source code, configuration dump, ...

x86 (and x86_64) processors have single-byte NOP instructions and various multi-byte NOP-like instructions. Real-world compilers sometimes use multi-byte NOPs for code alignment and performance optimization purposes. Please refer to the StackOverflow post for more details. Zydis thinks the raw bytes "0f 1a de" have only one operand "ebx". But it has two operands "esi" and "ebx" according to the ModR/M encoding shown below:

  • The ModR/M byte DE translates to binary 11011110 (0xDE).
    • Bits 7-6 (Mod): 11 (binary) = 3 (decimal)
      Indicates register-direct addressing mode.
    • Bits 5-3 (Reg): 011 (binary) = 3 (decimal)
      Corresponds to the EBX (or RBX in 64-bit mode) register.
    • Bits 2-0 (R/M): 110 (binary) = 6 (decimal)
      Corresponds to the ESI (or RSI in 64-bit mode) register.

XED also translate "0f 1a de" into "nop esi, ebx".

@athre0z athre0z added the A-decoder Area: Decoder label Nov 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-decoder Area: Decoder
Projects
None yet
Development

No branches or pull requests

2 participants