經典變長指令ModR/M

Punished 發表於 2021-04-07

變長指令

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

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

經典變長指令ModR/M

 

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

經典變長指令ModR/M

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

 

 因特爾白皮書:

經典變長指令ModR/M

 

 

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

經典變長指令ModR/M

 

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

經典變長指令ModR/M

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

經典變長指令ModR/M

 

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

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

disp32實際上是個偏移

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

 

經典變長指令ModR/M

 

 

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

還是看一下

經典變長指令ModR/M

 

 

 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

經典變長指令ModR/M

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

經典變長指令ModR/M

 

 

 這裡只列舉一個,這個指令與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

經典變長指令ModR/M

 

 

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

經典變長指令ModR/M

 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

經典變長指令ModR/M

 

 

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

經典變長指令ModR/M

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

經典變長指令ModR/M

 

 

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

經典變長指令ModR/M

 

 

 總結

當Mod = 00時,ModR/M位元組通過暫存器直接進行記憶體定址

當Mod = 01時,ModR/M位元組通過暫存器+I8進行記憶體定址(I為立即數,即8位立即數)

當Mod = 10時,ModR/M位元組通過暫存器+I32進行記憶體定址

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