Intel指令解析規則,反彙編引擎工作原理

一、Intel保護模式、實地址模式和虛擬8086模式指令格式(x86)

  

                圖在Intel手冊Volume2 2.1章節

  1.1)Instruction Prefixes:指令前綴,可選項,每個前綴一個字節,可選0個前綴到4個不等;指令前綴分爲四組,每組都允許設置指定的前綴代碼。

    Group 1:鎖定和重複前綴。

    Group 2:段覆蓋前綴。

    Group 3:操作數大小覆蓋前綴。

    Group 4:地址大小覆蓋前綴。

  1.2)Opcode:操作碼,這是唯一不可省略的項,1、2或3個字節,在某些情況下會有額外的三個位作爲補充opcode,這三個位是ModR/M中的Reg/Opcode域。

  1.3)ModR/M:一共有三個域,Mod,Reg/Opcode, R/M。

    Reg/Opcode在特定情況下作爲Opcode的補充操作碼,特定情況下作爲第一個或第二個操作數寄存器。

    

    對於89 /r,Reg/Opcode表示第二個操作數寄存器,而對於8B /r,Reg/Opcode則表示第一個操作數寄存器。

  • Mod字段與R/M字段組合形成32個可能的值:八個寄存器和24個尋址模式。

  • Reg/Opcode字段指定一個寄存器或三位操作碼信息。Reg/Opcode字段的用途在主操作碼中指定。

  • R/M字段可以爲存器指定操作數,也可以將其與Mod字段組合形成編碼尋址模式。有時,Mod字段和R/M字段的某些組合用於表示某些指令的操作碼信息。

    ModR/M字節的某些編碼需要第二個尋址字節(SIB字節),32位尋址的base-plus-index和scale-plus-index形式需要SIB字節。SIB字節包括以下字段:

  • "scale"字段指定比例因子。

  • "index"字段指定索引寄存器的寄存器索引

  • "base"字段指定基本寄存器的寄存器索引

  • 有關ModR/M和SIB字節的編碼,請參見第2.1.5節

  1.4)SIB:定義ModR/M的尋址方式的補充尋址方式,使用"Base + Scaled Index"格式。

  1.5)Displacement:偏移,可選,0,1,2,4個字節。

  1.6)Immediate:立即數,可選,0,1,2,4個字節。

二、IA-32e模式指令格式(x64)

  

              圖在Intel手冊Volume2 2.2.1章節

  2.1)IA-32e模式有兩個子模式

    Compatibility Mode:使64位操作系統能夠不加修改地運行大多數傳統保護模式軟件。

    64-Bit Mode:使64位操作系統能夠運行爲訪問64位地址空間而編寫的應用程序。

  2.2)REX Preflx

  REX前綴是在64位模式下使用的指令前綴字節,與x86模式的不同之處就是多了這個REX Preflx,其他基本與x86相同。它有以下作用:

  • 指定GPRs和SSE寄存器

  • 指定64位操作數大小

  • 指定擴展寄存器

    並非所有指令都需要64位模式下的REX前綴。 僅當一條指令引用擴展寄存器之一或使用64位操作數時,才需要前綴。 如果在沒有含義的情況下使用REX前綴,則將其忽略。

三、使用ModR/M字節的32位尋址

      圖在Intel手冊Volume2 2.5.1章節Addressing-Mode Encoding of ModR/M and SIB Bytes

  解釋:

  3.1)[--][--]:表示使用SIB結構。

  3.2)disp32:表示32位偏移。

  3.3)[--][--]+disp8:表示使用SIB結構,且SIB結構後面有一個8位的偏移。

  3.4)[--][--]+disp32:表示使用SIB結構,且SIB結構後面有一個32位的偏移。

   

ModR/M.mod

 尋址模式

 描述

00

[base]

 提供 [base] 形式的 memory 尋址

01

[base + disp8]

 提供 [base + disp8] 形式的 memory 尋址

10

[base + disp32]

 提供 [base + disp32] 形式的 memory 尋址

11

register

 提供 register 尋址。

四、使用SIB字節的32位尋址

  

      圖在Intel手冊Volume2 2.5.1章節Addressing-Mode Encoding of ModR/M and SIB Bytes

  SIB結構使用"Base + Scaled Index"格式。

  Base的可選值爲:

  Scaled Index的可選值爲:none、[REG]、[REG*2]、[REG*4]、[REG*8],REG爲實際的某個寄存器。

  none表示沒有Scaled Index,即Scaled Index的爲0。

  [REG]表示使用一個寄存器如[EAX]、[ECX]和[EDX]等等。

  [REG*2]表示使用寄存器乘以2如[EAX*2]、[ECX*2]和[EDX*2]等等。

五、MOVE-Move指令格式

  

                圖在Intel手冊Volume2 4.3章節MOV-Move小節

  解釋:

  5.1)r:寄存器,r8表示8位寄存器,r16表示16位寄存器,r32和r64依次類推。

  5.2)m:內存地址,m8表示8位地址,m16表示16位地址,m32和m64依次類推。

  5.3)r/m:寄存器或內存

  5.4)/r:表示操作碼有ModR/M結構,且ModR/M結構的Reg/Opcode域爲Reg,表示第二個操作碼寄存器。

  5.4)REX:表示該操作碼有REX Preflx字段。

  5.5)REG.W:表示該操作碼有REX Preflx字段且W位值爲1。

  5.6)rb:表示使用byte寄存器,即8位寄存器。

  5.7)ib:表示使用byte立即數,即8位立即數。

  5.8)rw:表示使用word寄存器,即16位寄存器。

  5.9)iw:表示使用word立即數,即16位立即數。

  5.10)rd:表示使用dword寄存器,即32位寄存器。

  5.11)id:表示使用dword立即數,即32位立即數。

  5.12)/0:表示指定有ModR/M選項。

  完整解釋請看Intel手冊Volume2第3.1.1.1章節Opcode Column in the Instruction Summary Table (Instructions without VEX Prefix)

六、ADD-Add指令格式

              圖在Intel手冊Volume2 3.2章節ADD-Add小節

七、MOVSX/MOVSXD指令格式

  

      圖在Intel手冊Volume2 4.3章節MOVSX/MOVSXD—Move with Sign-Extension小節

八、與之相關的註冊碼

  

  

    完整解釋請看Intel手冊Volume2 第3.1.1.1章節Opcode Column in the Instruction Summary Table (Instructions without VEX Prefix)

    在64位模式下,使用RAX/RCX/RDX/RBX/RSP/RBP/RSI/RDI不需要REX Prefix,而使用R8 ~ R15則是必須的

九、示例代碼分析

  9.1)示例一(x86環境)

012E17DD 8B 45 EC mov eax,dword ptr [ebp-14h]

  解析mov eax,dword ptr [ebp-14h]的機器代碼:

    eax爲32位寄存器,[ebp-14h]是一個內存地址,所以指令應該是"MOV r32,m32",根據第五節 MOVE-Move指令格式,符合條件的只有

    

    通過8B /r進行分析

    Instruction Prefixes:該操作碼沒有Instruction Prefixes。

    Opcode:操作碼爲8B。

    ModR/M:/r表示操作碼有ModR/M結構,且ModR/M結構的Reg/Opcode域爲Reg,表示第一個操作碼寄存器。

        第一個操作碼寄存器爲eax,根據第三節 ModR/M字節的32位尋址表,Reg域爲000,[ebp-14h]是相對寄存器尋址,所以Mod域爲01,R/M域爲101,最後的ModR/M爲01 000 101,即45H。

    SIB:無。
    Displacement:相對ebp寄存器的偏移爲-14h,-14h的源碼爲0001 0100,反碼爲1110 1011,補碼爲1110 1100,即EC。

    Immediate:無。

    最後的機器碼爲:8B 45 EC

    

  9.2)示例二(x86環境)

012E17E3 89 45 EC mov dword ptr [ebp-14h],eax

  解析mov dword ptr [ebp-14h],eax的機器代碼:

  [ebp-14h]是一個內存地址,eax爲32位寄存器,所以指令應該是"MOV m32,r32",根據第五節 MOVE-Move指令格式,符合條件的只有

  

  通過89 /r進行分析

  Instruction Prefixes:該操作碼沒有Instruction Prefixes。

  Opcode:操作碼爲89H。

  ModR/M:/r表示操作碼有ModR/M結構,且ModR/M結構的Reg/Opcode域爲Reg,表示第二個操作碼寄存器。

    第二個操作碼寄存器爲eax,根據第三節 ModR/M字節的32位尋址表,Reg域爲000,[ebp-14h]是相對寄存器尋址,所以Mod域爲01,R/M域爲101,最後的ModR/M爲01 000 101,即45H。

  SIB:無。
  Displacement:相對ebp寄存器的偏移爲-14h,-14h的源碼爲0001 0100,反碼爲1110 1011,補碼爲1110 1100,即EC。

  Immediate:無。

  最後的機器碼爲:89 45 EC

    

  9.3)示例三(x86環境)

012E17E6 01 04 8E add dword ptr ds:[esi+ecx*4],eax

   解析add dword ptr ds:[esi+ecx*4],eax的機器代碼:

  [esi+ecx*4]是一個內存地址,eax爲32位寄存器,所以指令應該是"ADD m32,r32",根據第五節 ADD-Add指令格式,符合條件的只有

  

  通過01 /r進行分析

  Instruction Prefixes:該操作碼沒有Instruction Prefixes。

  Opcode:操作碼爲01H。

  ModR/M:/r表示操作碼有ModR/M結構,且ModR/M結構的Reg/Opcode域爲Reg,表示第二個操作碼寄存器。

    第二個操作碼寄存器爲eax,根據第三節 ModR/M字節的32位尋址表,Reg域爲000,[esi+ecx*4]是寄存器間接尋址且且使用SIB結構

  

    所以Mod域爲00,R/M域爲100,最後的ModR/M爲00 000 100,即04H。

  SIB:根據[esi+ecx*4],SS爲10,Index爲001,r32爲esi寄存器即110,所以SIB爲10 001 110 = 8EH。
  Displacement:無。

  Immediate:無。

  最後的機器碼爲:01 04 8E

    

  9.4)示例四(x64環境)

000000013F3D1212 48 63 4C 24 20 movsxd rcx, dword ptr [esp+20h]

   解析movsxd rcx, dword ptr [esp+20h]的機器代碼:

  rcx爲64位寄存器,[esp+20h]是一個內存地址,esp爲32位寄存器,內存地址是32位地址,所以指令應該是"movsxd r64,mr32",根據第七節 MOVSX/MOVSXD—Move with Sign-Extension指令格式,符合條件的只有

  

  通過REX.W + 63 /r進行分析

  Legacy Prefixes:無。

  REX Prefixes:REX.W表示操作碼有REX Prefixes結構,且W位爲1,則REX Prefixes爲 0100 1000,即48H。

  Opcode:操作碼爲63H。

  ModR/M:/r表示操作碼有ModR/M結構,且ModR/M結構的Reg/Opcode域爲Reg,表示第一個操作寄存器。

    第一個操作寄存器爲rcx,根據第三節ModR/M字節的32位尋址表,Reg域爲001,[esp+20h]是相對寄存器尋址,所以Mod域爲01,表中找不到esp寄存器,所以R/M域爲100。

    

  最後的ModR/M爲01 001 100,即4CH。

  SIB:根據[--][--]+disp8可以看出,一定有SIB結構,SIB結構爲"Base + Scaled Index",[esp+20h]沒有Scaled Index,所以SS爲00,Index爲100,Base爲esp寄存器即100,最後SIB爲00 100 100 = 24H。

  Displacement:相對esp寄存器的偏移爲+20h,+20h的補碼爲0010 0000,即20H。

  Immediate:無。

  最後的機器碼爲:48 63 4C 24 20

    

參考:

  1)[原創]X86彙編之指令格式解析:https://bbs.pediy.com/thread-191802.htm

  2)[原創]X64彙編之指令格式解析:https://bbs.pediy.com/thread-206780.htm

  3)X86指令編碼內幕 --- 指令格式:https://blog.csdn.net/xfcyhuang/article/details/6228030

  4)Intel硬編碼(一):Opcode Map、定長指令與指令前綴:https://blog.csdn.net/apollon_krj/article/details/77524601

  5)Intel硬編碼(二):不定長指令、ModR/M與SIB詳解(基於P6微架構):https://blog.csdn.net/apollon_krj/article/details/77524601

  6)英特爾64與IA-32體系結構軟件開發人員手冊:https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4

  7)英特爾64與IA-32體系結構優化參考手冊:https://software.intel.com/sites/default/files/managed/9e/bc/64-ia-32-architectures-optimization-manual.pdf

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章