x86架构基础知识

作者:Vesper Vei
2 分钟阅读

目录

  1. x86架构基础知识
    1. 进制
    2. 字节序
    3. 程序执行流程
    4. 数据存储
      1. 立即数
      2. 寄存器
      3. 进程空间布局
    5. 汇编指令
      1. 保护方式

x86架构基础知识

进制

二进制这一块,不用多说,需要掌握的就是短除法去10进制 -> 2进制 然后理解门电路如何完成加法的

字节序

程序执行流程

CPU执行程序详解 image.png image.png

数据存储

cpu内部的数据存储

立即数

寄存器

x86-32 位所含有的寄存器有:

进程空间布局

进程空间布局

汇编指令

汇编指令

NOP(nop)

PUSH(push)

PUSH 指令将数据压入栈中。 指令格式为 pushX。 xajEX imm8, imm16, imm32, k/m16, r/m32, r/m64. 栈指针寄存器 ESP(RSP)自动递减。 eg: push eax image.png

POP(pop)

POP指令从栈中弹数据。 指令格式为 popx。 × PJEX r/m16, г/m32, r/m64. 栈指针寄存器 ESP(RSP)自动递增。 eg: pop eax image.png ⚠️注意,这里的 0x0012FF88 处的栈数据不会被清空,但程序正常执行时会覆盖

MOV(mov)

MOV 指令将数据从源操作数移动到目的操作数。

指令格式为 mov x1(目的操作数),x2(源操作数) 意为从x2移动数据到×1。 ×1,×2可以是:

例:

LEA(lea)&

LEA (区地址)指令用于载入有效地址。 指令格式为 lea ×1,X2。 x1 可以是r16/32/64,x2 是内存地址,常用[]语法形式,意为引用求值。 常用于指针运算,有时用于数值计算。 例:ebx=0x2 edx=0×1000

ADD(add)

ADD指令计算加法操作。 指令格式为 add×1,x2。 x1,x2可以是r/m16,r/m32,r/m64,x2还可以是立即数,但二者不能同时是内存操作数。 指令的计算结果将影响 eflags 寄存器,修改 OF, SF, ZF, AF, PF, CE标志位。

例:

SUB(sub)

SUB 指令计算减法操作。

指令格式为 sub ×1,X2。

×1,×2 可以是r/m16,r/m32,r/m64,×2还可以是立即数,但二者不能同时是内存操作数。

指令的计算结果将影响 eflags 寄存器,修改 OF, SF, ZF, AF, PF, CF 标志位。

例:

IMUL/MUL(iml/mul)

IMUL指令用于实现有符号数的乘法运算。

三种指令格式:

MUL指令是无符号乘法。

IDIV/DIV(idiv/div)

DIV 指令用于实现无符号数的除法运算。

两种指令格式

若除数是0,则抛出除零异常.

AND(and)

做&(与)运算 AND 指令实现操作数的逻辑与运算。 指令格式为 and x1,x2. x1.x2可以是r/m16,r/m32,r/m64,x2还可以是立即数,但二者不能同时是内存操作数。

OR(or)

做^(或)运算 OR指令实现操作数的逻辑或运算。 指令格式为 orx1,x2. X1,x2可以是r/m16,r/m32,r/m64,x2 还可以是立即数,但二者不能同时是内存操作数。

XOR(xor)

做异或运算 XOR指令实现操作数的异或运算。 指令格式为 xorx1,x2。 ×1,x2可以是r/m16,r/m32,r/m64,x2 还可以是立即数,但二者不能同时是内存操作数。

注:XOR常用于清零运算,如xor eex,eax,效率高。

NOT(not)

做!(非)运算

SHL(shl)

逻辑左移

SHR(shr)

逻辑右移

JMP(jmp)

无条件的跳转,分三种跳转方式

JCC集(jcc)

有条件的跳转

CMP(cmp)

CMP指令用于两个操作数的大小比较。 指令格式为CWPX1.x2. cmp 指令通过将 x1 减去x2 的方式实现比较,根据减法结果设置 eflags 的相应标志位,且将减法结果丢弃。 cmp < —— > sub:

TEST(test)

保护方式

canary(金丝雀)

NX

PIE和ASLR

在我们编写ROP或者shellcode时,有一个问题是绕不开的,那就是找到函数地址。
PIE指的就是程序内存加载基地址随机化,意味着我们不能一下子确定程序的基地址。
ASLR与其大同小异,ASLR是程序运行动态链接库、栈等地址随机化。
通常来说,CTF中的PWN题与这两个保护打交道的次数最多。
绕过方式就是泄露函数地址,然后通过函数的偏移来确定基地址。

RELRO


关系图谱

Loading graph...