羽夏笔记——硬编码(32位)

写在前面

  本笔记是由本人独自整理出来的,图片来源于网络。本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正。 如有好的建议,欢迎反馈。码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作。如想转载,请把我的转载信息附在文章后面,并声明我的个人信息和本人博客地址即可,但必须事先通知我

本硬编码以32位Intel为准进行介绍

☀️ 指令编码(硬编码)的结构

☀️ 前缀指令是分组的

  1. LOCK和REPEAT前缀指令:
    LOCK(F0)、REPNE/REPNZ(F2)、REP/REPZ(F3)
  2. 段前缀指令:
    cS(2E)、SS(36)、DS(3E)、ES(26)、FS(64)、GS(65)
  3. 操作数宽度前缀指令:66
  4. 地址宽度前缀指令: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称之为定长。

posted @ 2021-09-10 10:13  寂静的羽夏  阅读(1228)  评论(0编辑  收藏  举报