OPCode详解及汇编与反汇编原理
1. 何為OPCode
在計算機科學領域中,操作碼(Operation Code, OPCode)被用于描述機器語言指令中,指定要執行某種操作的那部分機器碼,構成OPCode的指令格式和規范由處理器的指令規范指定。除了指令本身以外通常還有指令所需要的操作數,可能有的指令不需要顯示的操作數。這些操作數可能是寄存器中的值,堆棧中的值,某塊內存的值或者IO端口中的值等等。
OPCode在不同的場合中通常具有不同的含義,例如PHP虛擬機(Zend VM)、java虛擬機(JVM)以及一些軟件保護虛擬機中的最小操作單元都可以稱之為OPCode。
在本節課中,介紹的是Intel 80x86 CPU的OPCode
2. 常用單字節OPCode概覽A -- 40~4F
opcode asm using
0x40 inc eax emit(0x40)
0x41 inc ecx emit(0x41)
0x42 inc edx emit(0x42)
0x43 inc ebx emit(0x43)
0x44 inc esp emit(0x44)
0x45 inc ebp emit(0x45)
0x46 inc esi emit(0x46)
0x47 inc edi emit(0x47)
0x48 dec eax emit(0x48)
0x49 dececx emit(0x49)
0x4a decebx emit(0x4a)
0x4b decebx emit(0x4b)
0x4c decesp emit(0x4c)
0x4d decebp emit(0x4d)
0x4e decesi emit(0x4e)
0x4f decedi emit(0x4f)
2. 常用單字節OPCode概覽B -- 50~5F
opcode asm using
0x50 push eax emit(0x50)
0x51 pushecx emit(0x51)
0x52 pushedx emit(0x52)
0x53 pushebx emit(0x53)
0x54 pushesp emit(0x54)
0x55 pushebp emit(0x55)
0x56 pushesi emit(0x56)
0x57 pushedi emit(0x57)
0x58 pop eax emit(0x58)
0x59 popecx emit(0x59)
0x5a popedx emit(0x5a)
0x5b popebx emit(0x5b)
0x5c popesp emit(0x5c)
0x5d popebp emit(0x5d)
0x5e popesi emit(0x5e)
0x5f popedi emit(0x5f)
2. 常用單字節OPCode概覽C -- 70~7F
opcode asm using
0x70 0x12 Jo 0x12 {_emit(0x70)}{_emit(0x12)}
0x71 ... Jno ... ... ...
0x72 ... Jb ... ... ...
0x73 ... Jae ... ... ...
0x74 ... Je ... ... ...
0x75 ... Jne ... ... ...
0x76 ... Jbe ... ... ...
0x77 ... Ja ... ... ...
0x78 ... Js ... ... ...
0x79 ... Jns ... ... ...
0x7a ... Jp ... ... ...
0x7b ... Jnp ... ... ...
0x7c ... Jl ... ... ...
0x7d ... Jge ... ... ...
0x7e ... Jle ... ... ...
0x7f ... Jg ... ... ...
短跳: 2字節
第一個字節: 操作碼
第二個字節: 跳轉偏移
2. 常用單字節OPCode概覽D -- 90~9F
Opcode asm Using
0x90 Nop/xchg eax,eax _emit(0x90)
0x91 Xchg eax,ecx
0x92 Xchg eax,edx
0x93 Xchg eax,ebx
0x94 Xchg eax,esp
0x95 Xchg eax,ebp
0x96 Xchg eax,esi
0x97 Xchg eax,edi
3. OPCode與指令的對應關系
同類型的指令OPCode不一定相同
B8 01000000 mov eax, 1
8B C3 mov eax, ebx
8B C7 mov eax, edi
OPCode相同的情況下指令也不一定相同
90 nop
90 xchg ax, ax
90 xchg eax, eax
結論: OPCode與匯編指令并非是單純的對應關系
4. OPCode詳解A -- 主要數據域
以上數據域只有Code域是必須存在的,其他數據域視指令格式而定,或有或無
一個指令的長度在1Byte~16Byte之間
實際正常的最長指令是,13Byte
4. OPCode詳解B -- 前綴
前綴(Prefixes)的大小為1Byte,用于描述指令的前綴情況,他們可以被劃分為5個集合:
66 -- 切換操作數大小
67 -- 切換地址大小
F2/F3 -- 重復操作前綴
2E/36/3E/26/64/65 -- 修改默認段
F0 -- 鎖定前綴
所以指令獨此一份,不可能為其他機器碼
注意:
a. "切換"的意思是將其在兩種狀態間來回切換,而并非特指某種狀態
b. 將默認值修改為其他段的操作稱之為"修改默認段"
c. 一個OpCode可能會有幾個Prefixes
d. 如果有多個Prefixes,那么它們的順序可能打亂
e. 如果Prefixes不能對隨它之后的OpCode起作用,那么它就會被忽略
4. OPCode詳解C -- 前綴
切換操作數大小
40 INC EAX
66 40 INC AX
切換順序: 從大到小
無效的前綴應用
8AC1 MOV AL, CL
66 BAC1 MOV AL, CL
重復操作段前綴
F3 66 AD REP LODSW
F2 AC REPNE LODSB
段超越前綴
8B 03 MOV EAX, [DWORD DS:EBX]
658B 03 MOV EAX, [DWORD GS:EBX]
4. OPCode詳解D -- ModR/M
OPCode的主要解析邏輯都集中在ModR/M域,我們可以通過對照Intel手冊中的表來解析OPCode中的ModR/M域來確定指令的具體格式
例如:
89 D8 mov eax, ebx
D8 = 11011000
Mod Reg R/M
11 011 000
4. OPCode詳解E -- Opcode小注
/0~7: 此ModR/M只使用R/M域的信息
/r : 此ModR/M同時使用R/M域與Reg域信息
+rb: 寄存器碼, 此碼將加載OPCode原有值上
AL = 0, CL = 1, DL = 2, BL = 3, AH = 4, CH = 5, DH = 6, BH = 7
+rw: 寄存器碼,此碼將加載OPCode原有值上
AX = 0, CX = 1, DX = 2, BX = 3, SP = 4, BP = 5, SI = 6, DI = 7
+rd: 寄存器碼,此碼將加載OPCode原有值上
EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7
+i: 僅限于浮點計算時,增加的數可以是0~7, 用于標記當前使用的FPU
堆棧,此碼將加載OPCode原有值上
4. OPCode詳解F -- 高大上指令賞析
13字節匯編指令賞析
F0:26:C7 8491AA000000 11000000
LOCK MOV DWORD PTR ES: [EDX*4 + ECX + 0AA], 11
Prefix OPCode ModR/M SIB Displacement Immediate
F0:26: C7 84 91 AA000000 01000000
注1 注2 注3 注4 偏移 立即數
注1: 鎖定前綴 + ES段超越
注2: MOV r/m32, imm32
注3: R/M = disp32[--][--] Mod != EAX
注4: Index = [EDX*4] r32 = ECX
84 91 AA000000 --> [EDX*4 + ECX +0xAA]
5. 練習
①. 83C4 04
分析:
83 /0 ib: ADD r/m32,imm8 ;/0~7 只使用R/M信息
C4: ESP
結果:
add esp, 04
②. A1 78812801
A1 :MOV EAX,moffs32* ;Move doubleword at (seg:offset) to EAX,moffs32為32位地址
結果:
mov eax, dword ptr ds:[1288178]
③. A3 54812801
A3 MOV moffs32*,EAX ;Move EAX to (seg:offset),moffs32為32位地址
結果:
movdword ptr ds:[1288154], eax
④.68 54812801
PUSH imm32
結果:
push 1288154
⑤.8B0D 74812801
8B /rMOV r32,r/m32 ;/r同時使用R/M域與Reg域信息
OD 有效地址:disp32 REG: ECX
結果:
mov ecx, dword ptr ds:[1288174]
⑥.51
50+rdPUSH r32 ;EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7
結果:
push ecx
⑦.68 48812801
68 PUSH imm32
結果:
push 1288148
⑧.FF15 A4922801
FF /3CALL m16:32 ;/0~7 只使用R/M信息
15 有效地址:disp32
結果:
call dword ptr cs:[12892A4]
總結:
ModR/M信息與確認是否有SIB字節
當Mod != 11b并且R/M的值為100b的時候,表示指令后續有SIB字節,并且該內存操作對象由SIB編碼。
MODR/M里有三種情況會有SIB字節
總結
以上是生活随笔為你收集整理的OPCode详解及汇编与反汇编原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 绯色回响怎么买时装
- 下一篇: 跨域失败 过滤器_Spring Boot