羽夏笔记——硬编码(32位)
写在前面
本笔记是由本人独自整理出来的,图片来源于网络。本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正。 如有好的建议,欢迎反馈。码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作。如想转载,请把我的转载信息附在文章后面,并声明我的个人信息和本人博客地址即可,但必须事先通知我。
本硬编码以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称之为定长。
本文来自博客园,作者:寂静的羽夏 ,一个热爱计算机技术的菜鸟
转载请注明原文链接:https://www.cnblogs.com/wingsummer/p/15247300.html