經典變長指令ModR/M

變長指令

不是所有的指令都是,看到opcode就知道有多長(定長指令),當指令中出現內存操作對象的時候,就需要在操作碼後面附加一個位元組來進行補充說明,這個位元組被稱為ModR/M。

該位元組的8個位被分成了三部分:

 

其中,Reg/Opcode(第3、4、5位,共3個位元組)描述指令中的G部分,即寄存器

Mod(第6、7位)和R/M(第0、1、2位)共同描述指令中的E部分,即寄存器/內存

 

 因特爾白皮書:

 

 

MOV變長指令

0x88  MOV Eb, Gb          G:通用寄存器

0x89  MOV Ev, Gv           E:寄存器/內存

0x8A  MOV Gb, Eb           b:位元組

0x8B  MOV Gv, Ev           v:Word, doubleword or quadword(這個看操作系統,是多少位就多少位)

0x88

0x88 01

MOV Eb, Gb: Gb決定了是8位的通用寄存器,具體是哪一個通用寄存器還要看ModR/M的3,4,5部分

01:00   000    001

前兩位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M

由上面可以知道 Reg/Opcode部分是 000,相當於0號寄存器,即[EAX],但是由於是8位,所以是AL

012位和67位組合起來是00 001

 

 是[ECX],所以這條指令應該是:mov byte ptr ds:[ECX],AL

0x88 15

MOV Eb, Gb: Gb決定了是8位的通用寄存器,具體是哪一個通用寄存器還要看ModR/M的3,4,5部分

01:00   010    101

前兩位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M

由上面可以知道 Reg/Opcode部分是 001,相當於2號寄存器,即[ECX],但是由於是8位,所以是CL

012位和67位組合起來是00 101

 

可以看到這裡並不是我們想的EBP,這是因為EBP指向棧底,而[EBP]通常存儲上一個EBP,所以[EBP]無數據操作意義,Inter將這個編碼廢棄,改為立即數尋址

例如當操作指令為88 81 12 34 56 78時,其對應的彙編為MOV BYTE PTR DS:[ECX+78563412],AL

disp32實際上是個偏移

再看這幾個 ESP都沒有對應的值

 

 

 

 這是因為:ESP指向棧頂,是浮動的,不確定的,Inter將這個編碼廢棄,由另外的格式來說明。

還是看一下

 

 

 0x89

0x89 03

MOV Ev, Gv : Gv與我當前的x32dedug決定了是32位的通用寄存器,具體是哪一個通用寄存器還要看ModR/M的3,4,5部分

01:00   000    011

前兩位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M

由上面可以知道 Reg/Opcode部分是 000,相當於0號寄存器,即EAX

012位和67位組合起來是00 011

所以是[EBX],這條指令是:mov dword ptr ds:[ebx],eax

 

 

 這裡只列舉一個,這個指令與0x88區別就是位數的差別

 0x8A

0x8A 07

MOV Gb, Eb: Gb決定了是8位的通用寄存器,具體是哪一個通用寄存器還要看ModR/M的3,4,5部分

01:00   000    111

前兩位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M

由上面可以知道 Reg/Opcode部分是 000,相當於0號寄存器,即EAX,但我們這裡是byte所以是al

012位和67位組合起來是00 111

 

 

 是EDI,這條指令命令為:mov al,byte ptr ds:[edi]

 0x8B

0x8B 26

MOV Gv, Ev : Gv與我當前的x32dedug決定了是32位的通用寄存器,具體是哪一個通用寄存器還要看ModR/M的3,4,5部分

01:00  100  110

前兩位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M

由上面可以知道 Reg/Opcode部分是 100,相當於5號寄存器,即ESP

012位和67位組合起來是00 110

 

 

 esi,mov esp,dword ptr ds:[esi]

0x8B 66 12

MOV Gv, Ev : Gv與我當前的x32dedug決定了是32位的通用寄存器,具體是哪一個通用寄存器還要看ModR/M的3,4,5部分

01:01  100  110

前兩位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M

由上面可以知道 Reg/Opcode部分是 100,相當於5號寄存器,即ESP

012位和67位組合起來是01 110

 

 

 [esi+12],mov esp.dword ptr ds:[esi+12]

 

 

 總結

當Mod = 00時,ModR/M位元組通過寄存器直接進行內存尋址

當Mod = 01時,ModR/M位元組通過寄存器+I8進行內存尋址(I為立即數,即8位立即數)

當Mod = 10時,ModR/M位元組通過寄存器+I32進行內存尋址

當Mod = 11時,ModR/M位元組直接操作兩個寄存器

Tags: