获取操作码长度,如何

逆向工程 拆卸 部件 x86 x64 操作码
2021-06-16 15:43:39

我显然不太擅长组装,因为我是新手!因此我又想提出一个问题。现在我从这里得到这个来制作类似 LDE(长度反汇编引擎)的东西,因为我了解 C/C++ 和 Object Pascal。

现在我看到这个

http://www.delphibasics.info/home/delphibasicssnippets/magicapihook

我明白了一切,只有得到 upcode 部分

这是

function OpCodeLength(Address:DWORD):DWORD; cdecl; assembler;
const
  O_UNIQUE = 0;
  O_PREFIX = 1;
  O_IMM8 = 2;
  O_IMM16 = 3;
  O_IMM24 = 4;
  O_IMM32 = 5;
  O_IMM48 = 6;
  O_MODRM = 7;
  O_MODRM8 = 8;
  O_MODRM32 = 9;
  O_EXTENDED = 10;
  O_WEIRD = 11;
  O_ERROR = 12;
asm
 pushad
 cld
 xor edx, edx
 mov esi, Address
  mov ebp, esp
 push 1097F71Ch
 push 0F71C6780h
 push 17389718h
 push 101CB718h
 push 17302C17h
 push 18173017h
 push 0F715F547h
 push 4C103748h
 push 272CE7F7h
 push 0F7AC6087h
 push 1C121C52h
 push 7C10871Ch
 push 201C701Ch
 push 4767602Bh
 push 20211011h
 push 40121625h
 push 82872022h
 push 47201220h
 push 13101419h
 push 18271013h
 push 28858260h
 push 15124045h
 push 5016A0C7h
 push 28191812h
 push 0F2401812h
 push 19154127h
 push 50F0F011h
 mov ecx, 15124710h
 push ecx
 push 11151247h
 push 10111512h
 push 47101115h
 mov eax, 12472015h
 push eax
 push eax
 push 12471A10h
 add cl, 10h
 push ecx
 sub cl, 20h
 push ecx
 xor ecx, ecx
 dec ecx
@@ps:
 inc  ecx
 mov  edi, esp
@@go:
 lodsb
 mov  bh, al
@@ft:
 mov  ah, [edi]
 inc  edi
 shr  ah, 4
 sub  al, ah
 jnc  @@ft
 mov al, [edi-1]
 and al, 0Fh
 cmp  al, O_ERROR
 jnz  @@i7
 pop edx
 not edx
@@i7:
 inc edx
 cmp al, O_UNIQUE
 jz @@t_exit
 cmp al, O_PREFIX
 jz @@ps
 add  edi, 51h
 cmp  al, O_EXTENDED
 jz   @@go
 mov edi, [ebp+((1+8)*4)+4]
@@i6:
    inc  edx
    cmp  al, O_IMM8
    jz   @@t_exit
    cmp  al, O_MODRM
    jz   @@t_modrm
    cmp  al, O_WEIRD
    jz   @@t_weird
@@i5:
    inc  edx
    cmp  al, O_IMM16
    jz   @@t_exit
    cmp  al, O_MODRM8
    jz   @@t_modrm
@@i4:
    inc  edx
    cmp  al, O_IMM24
    jz   @@t_exit
@@i3:
    inc  edx
@@i2:
    inc  edx
    pushad
    mov  al, 66h
    repnz scasb
    popad
    jnz  @@c32
@@d2:
    dec  edx
    dec  edx
@@c32:
    cmp  al, O_MODRM32
    jz   @@t_modrm
    sub  al, O_IMM32
    jz   @@t_imm32
@@i1:
    inc  edx
@@t_exit:
    jmp @@ASMEnded
@@t_modrm:
       lodsb
       mov  ah, al
       shr  al, 7
       jb   @@prmk
       jz   @@prm
       add  dl, 4
       pushad
       mov  al, 67h
       repnz scasb
       popad
       jnz  @@prm
@@d3:  sub  dl, 3
       dec  al
@@prmk:jnz  @@t_exit
       inc  edx
       inc  eax
@@prm:
       and  ah, 00000111b
       pushad
       mov  al, 67h
       repnz scasb
       popad
       jz   @@prm67chk
       cmp  ah, 04h
       jz   @@prmsib
       cmp  ah, 05h
       jnz  @@t_exit
@@prm5chk:
       dec  al
       jz   @@t_exit
@@i42: add  dl, 4
       jmp  @@t_exit
@@prm67chk:
       cmp  ax, 0600h
       jnz  @@t_exit
       inc  edx
       jmp  @@i1
@@prmsib:
       cmp  al, 00h
       jnz  @@i1
       lodsb
       and  al, 00000111b
       sub  al, 05h
       jnz  @@i1
       inc  edx
       jmp  @@i42
@@t_weird:
       test byte ptr [esi], 00111000b
       jnz  @@t_modrm
       mov  al, O_MODRM8
       shr  bh, 1
       adc  al, 0
       jmp  @@i5
@@t_imm32:
       sub  bh, 0A0h
       cmp  bh, 04h
       jae  @@d2
       pushad
       mov  al, 67h
       repnz scasb
       popad
       jnz  @@chk66t
@@d4:  dec  edx
       dec  edx
@@chk66t:
       pushad
       mov  al, 66h
       repnz scasb
       popad
       jz   @@i1
       jnz  @@d2
@@ASMEnded:
    mov esp, ebp
    mov [result+(9*4)], edx
    popad
end;

现在我的问题来了,作者此时究竟做了什么?

  O_UNIQUE = 0;
  O_PREFIX = 1;
  O_IMM8 = 2;
  O_IMM16 = 3;
  O_IMM24 = 4;
  O_IMM32 = 5;
  O_IMM48 = 6;
  O_MODRM = 7;
  O_MODRM8 = 8;
  O_MODRM32 = 9;
  O_EXTENDED = 10;
  O_WEIRD = 11;
  O_ERROR = 12;

对于大会的简要细节,他在那里做了什么。我是大会的新手。

2个回答

x86 指令最多可以编码为 15 个字节(AFAIK,当超过 15 个字节的指令长度时,CPU 会捕获未定义的操作码异常)。

O_PREFIX可能是指指令前缀,例如REP,或具有隐式参数的指令。以 1 个字节编码。

O_IMM8 是一个带有一个直接参数的指令,所以它被编码为 2 个字节(一个用于指令,一个用于参数)

O_IMM16 采用 2 个字节(16 位)的立即参数,因此它以 3 个字节编码。

等等。

O_MODRM 根据英特尔手册

许多引用内存中操作数的指令在主操作码之后都有一个寻址形式说明符字节(称为 ModR/M 字节)。ModR/M 字节的某些编码需要第二个寻址字节(SIB 字节)

事情变得复杂了,根据寻址模式,每条指令最多可以有 9 个字节。

不知道O_EXTENDED(MMX?SSE?...)或其他两个。

无论如何,研究英特尔手册,您应该在那里找到所有内容:https : //www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software- developer-vol-2a-manual.pdf

如果您对学习(或使用)x86/x64 的长度反汇编程序感兴趣,那么有很多这样的反汇编程序可供您参考,其中一些提供了完整的教育文档:

  1. https://github.com/zyantific/zydis
  2. https://github.com/greenbender/lend
  3. https://github.com/CasualX/lde