OPCode詳解及彙編與反彙編原理

1. 何爲OPCodejava

在計算機科學領域中,操做碼(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                                  dec ecx                 emit(0x49)
                     0x4a                                  dec ebx                 emit(0x4a)
                     0x4b                                  dec ebx                emit(0x4b)
                     0x4c                                  dec esp                 emit(0x4c)
                     0x4d                                  dec ebp                emit(0x4d)
                     0x4e                                  dec esi                  emit(0x4e)
                     0x4f                                   dec edi                 emit(0x4f)
2. 經常使用單字節OPCode概覽B -- 50~5F
                   opcode                                asm                        using
                     0x50                                  push eax                 emit(0x50)
                     0x51                                  push  ecx                emit(0x51)
                     0x52                                  push  edx                emit(0x52)
                     0x53                                  push  ebx                emit(0x53)
                     0x54                                  push  esp                emit(0x54)
                     0x55                                  push  ebp                emit(0x55)
                     0x56                                  push  esi                 emit(0x56)
                     0x57                                  push  edi                 emit(0x57)
                     0x58                                  pop eax                   emit(0x58)
                     0x59                                  pop  ecx                  emit(0x59)
                     0x5a                                  pop  edx                 emit(0x5a)
                     0x5b                                  pop  ebx                 emit(0x5b)
                     0x5c                                  pop  esp                  emit(0x5c)
                     0x5d                                  pop  ebp                 emit(0x5d)
                     0x5e                                  pop  esi                   emit(0x5e)
                     0x5f                                   pop  edi                  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位地址
結果:
mov dword ptr ds:[1288154], eax     
④. 68 54812801  
 PUSH imm32          
結果:                    
push 1288154
⑤. 8B0D 74812801
8B /r  MOV 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字節
 
 
相關文章
相關標籤/搜索