硬编码学习笔记(一)—— 经典定长指令
硬編碼學(xué)習(xí)筆記(一)—— 經(jīng)典定長(zhǎng)指令
- 前言
- 指令結(jié)構(gòu)
- 符號(hào)說明
- 尋址符號(hào)
- 操作數(shù)符號(hào)
- 上標(biāo)符號(hào)
- One-Byte Opcode Map
- 經(jīng)典定長(zhǎng)指令:修改寄存器
- 0x40~0x47
- 0x48~0x4F
- 0x50~0x57
- 0x58~0x5F
- 0x90~0x97
- 0xB0~0xB7
- 0xB8~0xBF
- 經(jīng)典定長(zhǎng)指令:修改EIP
- 0x70~0x7F
- 0x0F80~0x0F8F
- 0xE0
- 0xE1
- 0xE2
- 0xE3
- 0xE8
- 0xE9
- 0xEA
- 0xEB
- 0xC2
- 0xC3
- 0xCA
- 0xCB
前言
本次學(xué)習(xí)僅基于intel x86模式
指令結(jié)構(gòu)
描述:對(duì)于任何一條指令,都由以下幾部分組成,但不是每部分都必須存在
長(zhǎng)度:最短1個(gè)字節(jié),最長(zhǎng)15個(gè)字節(jié)
Instruction Prefixes:指令前綴
Opcode: 主操作碼
ModR/M:在內(nèi)存中引用一個(gè)操作數(shù)的許多指令都有一個(gè)尋址方式的指定符字節(jié)(稱為ModR/M字節(jié))跟隨在主操作碼之后
SIB:ModR/M字節(jié)的某些編碼需要第二個(gè)尋址字節(jié)(SIB字節(jié))
Displacement:一些尋址方式包含緊跟ModR/M字節(jié)(或者SIB字節(jié),如果有的話)的位移
Immediate:立即數(shù)
符號(hào)說明
尋址符號(hào)
| A | 直接尋址 |
| C | 控制寄存器 |
| D | 調(diào)試寄存器 |
| E | 寄存器/內(nèi)存 |
| F | EFLAGS/RFLAGS寄存器 |
| G | 通用寄存器 |
| I | 立即數(shù) |
| J | 要添加到指令指針寄存器的相對(duì)偏移量 |
| M | ModR/M字節(jié)可能僅指向內(nèi)存。 |
| N | MMX 技術(shù)寄存器 |
| O | 該指令沒有ModR/M字節(jié)。操作數(shù)的偏移量在指令中被編碼為一個(gè)字或雙字(取決于地址大小屬性)。 |
| P | ModR/M字節(jié)的reg字段選擇一個(gè)打包的四字MMX技術(shù)寄存器 |
| Q | ModR/M字節(jié)跟隨操作碼并指定操作數(shù)。該操作數(shù)要么是MMX技術(shù)寄存器,要么是內(nèi)存地址。 |
| R | ModR/M字節(jié)的R/M字段可能僅指一個(gè)通用寄存器 |
| S | ModR/M字節(jié)的reg字段選擇一個(gè)段寄存器 |
| U | ModR/M字節(jié)的R/M字段選擇一個(gè)128位的XMM寄存器。 |
| V | ModR/M字節(jié)的reg字段選擇一個(gè)128位的XMM寄存器。 |
| W | ModR/M字節(jié)跟隨操作碼并指定操作數(shù)。操作數(shù)要么是一個(gè)128位的XMM寄存器要么是一個(gè)內(nèi)存地址。 |
| X | 由DS:rSI寄存器對(duì)尋址的內(nèi)存 |
| Y | 由ES:rDI寄存器對(duì)尋址的內(nèi)存 |
操作數(shù)符號(hào)
| a | 內(nèi)存中的兩個(gè)單字操作數(shù)或內(nèi)存中的兩個(gè)雙字操作數(shù),具體取決于操作數(shù)大小屬性(僅由BOUND指令使用) |
| b | 字節(jié) |
| c | 字節(jié)/字 |
| d | 雙字 |
| dq | 四字 |
| p | 32位/48位/80位指針 |
| pd | 128位封裝的雙精度浮點(diǎn)數(shù)據(jù) |
| pi | 雙四字,MMX技術(shù)寄存器(例如:mm0) |
| ps | 128位封裝的單精度浮點(diǎn)數(shù)據(jù) |
| q | 四字 |
| s | 6字節(jié)或10字節(jié)的偽描述符 |
| ss | 128位打包的單精度浮點(diǎn)數(shù)據(jù)的標(biāo)量元素 |
| si | 雙字整數(shù)寄存器(例如:eax) |
| v | 字、雙字或四字(取決于當(dāng)前CPU的模式) |
| w | 字 |
| z | 16位操作數(shù)大小的字或32位或64位操作數(shù)大小的雙字 |
上標(biāo)符號(hào)
| 1A | ModR/M字節(jié)的第5、4和3位用作操作碼擴(kuò)展 |
| 1B | 使用0F0B操作碼(UD2指令)或0FB9H操作碼時(shí),故意嘗試生成無效的操作碼異常(#UD) |
| 1C | 在Pentium III處理器中添加的一些指令可以使用相同的雙字節(jié)操作碼。如果指令有變化,或者操作碼代表不同的指令,則使用ModR/M字節(jié)來區(qū)分指令。 |
| i64 | 該指令無效或在64位模式下不可編碼。40到4F(單字節(jié)INC和DEC)是64位模式下的REX前綴組合(對(duì)INC和DEC使用FE/FF Grp 4和5)。 |
| o64 | 指令僅在64位模式下可用。 |
| d64 | 當(dāng)處于64位模式時(shí),指令默認(rèn)為64位操作數(shù)大小,并且不能對(duì)32位操作數(shù)大小進(jìn)行編碼。 |
| f64 | 在64位模式下,操作數(shù)大小被強(qiáng)制為64位操作數(shù)大小(在64位模式下,該指令會(huì)忽略改變操作數(shù)大小的前綴)。 |
One-Byte Opcode Map
經(jīng)典定長(zhǎng)指令:修改寄存器
0x40~0x47
指令長(zhǎng)度:共1個(gè)字節(jié)
40 INC EAX 41 INC ECX 42 INC EDX 43 INC EBX 44 INC ESP 45 INC EBP 46 INC ESI 47 INC EDI0x48~0x4F
指令長(zhǎng)度:共1個(gè)字節(jié)
48 DEC EAX 49 DEC ECX 4A DEC EDX 4B DEC EBX 4C DEC ESP 4D DEC EBP 4E DEC ESI 4F DEC EDI0x50~0x57
指令長(zhǎng)度:共1個(gè)字節(jié)
50 PUSH EAX 51 PUSH ECX 52 PUSH EDX 53 PUSH EBX 54 PUSH ESP 55 PUSH EBP 56 PUSH ESI 57 PUSH EDI0x58~0x5F
指令長(zhǎng)度:共1個(gè)字節(jié)
58 POP EAX 59 POP ECX 5A POP EDX 5B POP EBX 5C POP ESP 5D POP EBP 5E POP ESI 5F POP EDI0x90~0x97
指令長(zhǎng)度:共1個(gè)字節(jié)
90 NOP //XCHG EAX, EAX 91 XCHG EAX,ECX 92 XCHG EAX,EDX 93 XCHG EAX,EBX 94 XCHG EAX,ESP 95 XCHG EAX,EBP 96 XCHG EAX,ESI 97 XCHG EAX,EDI0xB0~0xB7
指令長(zhǎng)度:共2個(gè)字節(jié)
B0 00 MOV AL,0x0 B1 01 MOV CL,0x1 B2 02 MOV DL,0x2 B3 03 MOV BL,0x3 B4 04 MOV AH,0x4 B5 05 MOV CH,0x5 B6 06 MOV DH,0x6 B7 07 MOV BH,0x70xB8~0xBF
指令長(zhǎng)度:共5個(gè)字節(jié)
B8 00 00 00 10 MOV EAX,0x10000000 B9 01 00 00 10 MOV ECX,0x10000001 BA 02 00 00 10 MOV EDX,0x10000002 BB 03 00 00 10 MOV EBX,0x10000003 BC 04 00 00 10 MOV ESP,0x10000004 BD 05 00 00 10 MOV EBP,0x10000005 BE 06 00 00 10 MOV ESI,0x10000006 BF 07 00 00 10 MOV EDI,0x10000007經(jīng)典定長(zhǎng)指令:修改EIP
0x70~0x7F
指令長(zhǎng)度:共2個(gè)字節(jié)
偏移量:1個(gè)字節(jié)
當(dāng)偏移量<0x80時(shí):EIP = 當(dāng)前指令地址+當(dāng)前指令長(zhǎng)度+偏移量
當(dāng)偏移量>0x80時(shí):EIP = 當(dāng)前指令地址+當(dāng)前指令長(zhǎng)度-偏移量
0x0F80~0x0F8F
指令長(zhǎng)度:共6個(gè)字節(jié)
偏移量:4個(gè)字節(jié)
EIP = 當(dāng)前指令地址+當(dāng)前指令長(zhǎng)度+偏移量
0xE0
指令長(zhǎng)度:共2個(gè)字節(jié)
LOOPNE/LOOPNZ Ib(Jb)當(dāng)ZF==0&&ECX!=0時(shí):EIP=當(dāng)前指令地址+當(dāng)前指令長(zhǎng)度+Ib;ECX=ECX-1
0xE1
指令長(zhǎng)度:共2個(gè)字節(jié)
LOOPE/LOOPZ Ib(Jb)當(dāng)ZF==1&&ECX!=0時(shí):EIP=當(dāng)前指令地址+當(dāng)前指令長(zhǎng)度+Ib;ECX=ECX-1
0xE2
指令長(zhǎng)度:共2個(gè)字節(jié)
LOOP Ib(Jb)當(dāng)ECX!=0時(shí):EIP=當(dāng)前指令地址+當(dāng)前指令長(zhǎng)度+Ib;ECX=ECX-1
0xE3
指令長(zhǎng)度:共2個(gè)字節(jié)
JrCXZ Ib(Jb) //在32位模式中,rCX為ECX當(dāng)ECX==0時(shí):EIP=當(dāng)前指令地址+當(dāng)前指令長(zhǎng)度+Ib
0xE8
指令長(zhǎng)度:共5個(gè)字節(jié)
CALL Id(Jd)下一條指令地址入棧;EIP=當(dāng)前指令地址+當(dāng)前指令長(zhǎng)度+Id
0xE9
指令長(zhǎng)度:共5個(gè)字節(jié)
JMP Id(Jd)EIP=當(dāng)前指令地址+當(dāng)前指令長(zhǎng)度+Id
0xEA
指令長(zhǎng)度:共7個(gè)字節(jié)
JMP Ap //Ap為六字節(jié)長(zhǎng)度的直接地址 JMP CS:Id //將Ap中的高2位賦值給CS,低4位賦值給EIP0xEB
指令長(zhǎng)度:共2個(gè)字節(jié)
JMP Ib(Jb)EIP=當(dāng)前指令地址+當(dāng)前指令長(zhǎng)度+Ib
0xC2
指令長(zhǎng)度:共3個(gè)字節(jié)
RET Iw //POP EIP;ESP=ESP+Iw0xC3
指令長(zhǎng)度:共1個(gè)字節(jié)
RET //POP EIP0xCA
指令長(zhǎng)度:共1個(gè)字節(jié)
RETF //POP EIP;POP CS0xCB
指令長(zhǎng)度:共3個(gè)字節(jié)
RETF Iw //POP EIP;POP CS;ESP=ESP+Iw總結(jié)
以上是生活随笔為你收集整理的硬编码学习笔记(一)—— 经典定长指令的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Fuzz学习笔记(一)—— WinAFL
- 下一篇: 硬编码学习笔记(二)—— 经典变长指令