寫在前面
本筆記是由本人獨自整理出來的,圖片來源於網絡。本人非計算機專業,可能對本教程涉及的事物沒有了解的足夠深入,如有錯誤,歡迎批評指正。 如有好的建議,歡迎反饋。碼字不易,如果本篇文章有幫助你的,如有閑錢,可以打賞支持我的創作。如想轉載,請把我的轉載信息附在文章后面,並聲明我的個人信息和本人博客地址即可,但必須事先通知我。
本硬編碼以32位Intel為准進行介紹
☀️ 指令編碼(硬編碼)的結構
☀️ 前綴指令是分組的
- LOCK和REPEAT前綴指令:
LOCK(F0)、REPNE/REPNZ(F2)、REP/REPZ(F3) - 段前綴指令:
cS(2E)、SS(36)、DS(3E)、ES(26)、FS(64)、GS(65) - 操作數寬度前綴指令:66
- 地址寬度前綴指令:67
☀️ PUSH/POP
硬編碼 | 指令 |
---|---|
0x50 | PUSH EAX |
0x51 | PUSH ECX |
0x52 | PUSH EDX |
0x53 | PUSH EBX |
0x54 | PUSH ESP |
0x55 | PUSH EBP |
0x56 | PUSH ESI |
0x57 | PUSH EDI |
0x58 | POP EAX |
0x59 | POP ECX |
0x5A | POP EDX |
0x5B | POP EBX |
0x5C | POP ESP |
0x5D | POP EBP |
0x5E | POP ESI |
0x5F | POP EDI |
☀️ INC/DEC
硬編碼 | 指令 |
---|---|
0x40 - 0x47 | INC ERX |
0x48 - 0x4F | DEC ERX |
☀️ MOV Rb,lb
硬編碼 | 指令 |
---|---|
0xb0 - 0xb7 | MOV Rb, lb |
☀️ MOV ERX, ld
硬編碼 | 指令 |
---|---|
0xb8 - 0xbF | MOV ERX, ld |
☀️XCHG EAX,ERX
硬編碼 | 指令 |
---|---|
0x90 - 0x97 | XCHG EAX, ERX |
☀️ 0x70 -0x7F
1、條件跳轉,后跟一個字節立即數的偏移(有符號),共兩個字節。
2、如果條件成立,跳轉到當前指令地址+當前指令長度+lb。
3、最大值:向前跳 7f (ff - 80),向后跳 80 。
硬編碼 | 指令 |
---|---|
0x70 | JO |
0x71 | JNO |
0x72 | JB/JNAE/JC |
0x73 | JNBJAE/JNC |
0x74 | JZIJE |
0x75 | JNZJNE |
0x76 | JBEJNA |
0x77 | JNBE/JA |
0x78 | JS |
0x79 | JNS |
0x7A | JP/JPE |
0x7B | JNP/JPO |
0x7C | JL/JNGE |
0x7D | JNl/JGE |
0x7E | JLE/JNG |
0x7F | JNLE/JG |
☀️ 0x0F 0x80- 0x0F 0x8F
1、條件跳轉,后跟四個字節立即數的偏移(有符號),共五個字節。
2、 如果條件成立,跳轉到當前指令地址+當前指令長度+ld
3、最大值:向前跳7FFFFFFFF,向后跳80000000
硬編碼 | 指令 |
---|---|
0x0F 0x80 | JO |
0x0F 0x81 | JNO |
0x0F 0x82 | JB/JNAE/JC |
0x0F 0x83 | JNB/JAE/JNC |
0x0F 0x84 | JZ/JE |
0x0F 0x85 | JNZ/JNE |
0x0F 0×86 | JBE/JNA |
0x0F 0x87 | JNBE/JA |
0x0F 0x88 | JS |
0x0F 0x89 | JNS |
0x0F 0x8A | JPIJPE |
0x0F 0×8B | JNP/JPO |
0x0F 0x8C | JL/JNGE |
0x0F 0x8D | JNLJGE |
0x0F O×8E | JLE/JNG |
0x0F 0x8F | JNLE/JG |
☀️ 其他指令
硬編碼 | 指令 | 說明 |
---|---|---|
0xE0 | LOOPNE/LOOPNZ lb (Jb) | ECX = ECX -1當ZF =0 && ECX!= 0時跳轉到當前指令地址+當前指令長度+lb |
0XE1 | LOOPE/LOOPZ lb (Jb) | ECX = ECX -1當ZF = 1&& ECX !=0時跳轉到當前指令地址+當前指令長度+lb |
0XE2 | LOOP Ib (Jb) | ECX = ECX -1當 ECXI=0時跳轉到當前指令地址+當前指令長度 +lb |
0XE3 | JrCXZ Ib (Jb)(在32位模式中,rCX為ECX) | 當ECX=0時跳轉到當前指令地址+當前指令長度+lb(自己控制步長) |
0xE8 | CALL ld (Jd) | CALL指令的下一條指令地址入棧后,跳轉到當前指令地址+當前指令長度+ld |
0xE9 | JMP Id (Jd) | 跳轉到當前指令地址+當前指令長度+ld |
0xEA | JMPAp (Ap:六字節長度的直接地址) | JMP CS:ld 將Ap中的高2位賦值給CS,低4位直接賦值給EIP,即跳轉 |
0xEB | JMP Ib (Jb) | 挑轉到當前指令地址+當前指令長度+lb |
0xC3 | RET | EIP出棧 |
0xC2 | RET lw | EIP出棧后,ESP = ESP+lw |
0XCB | RETF (return far) | 出棧8個字節,低4個字節賦值給EIP,高4個字節中低2位賦值給Cs |
OxCA | RETF Iw | 出棧8個字節,低4個字節賦值給EIP,高4個字節中低2位賦值給CS后,ESP = ESP + w |
8個段寄存器:ES cs ss DS FS GS LDTR TR(順序固定)
☀️ 經典變長指令 ModR/M
☀️ 回顧ModR/M結構
1、Mod與R/M共同描述E的意義(內存或者通用寄存器)。
2、Reg/Opcode描述了G的意義(通用寄存器)。但3-5字段,並不僅僅用來標識寄存器,有些時候,用來標識Opcode。
☀️ RegOpcode
☀️ RegOpcode的舉例說明
dis8:八位的地址偏移
80 65 08 FF
查表步驟:
1、第一個字節為80查Table-2表,得到對應結構:Eb, Ib
2、第二個字節為MoR/M字段,所以拆分65得:01 100 101,Mod與R/字段查Table2-2得到對應的結構:[EBP+DIS8]
3、100字段查表TableA-6得到對應操作碼為:AND
4、最終的指令格式:
AND [ebp+dis8], Ib
AND BYTE PTR SS:[EBP+08], 0xFF
☀️ 硬編碼碎碎念
☀️ 指令長度不會超過15個字節,最少一個字節
☀️ 變長還是定長由opcode本身的值決定;沒有ModR/M稱之為定長。