堆栈

本文最后更新于:2023年12月5日 晚上

什么是堆栈

堆栈 在有些文章中也叫做 栈

可读、可写 这些都是针对正向的,编译器限制的,对于逆向而言,没有这些限制。

BASE 是栈底,TOP 是栈顶

栈底是高位,栈顶是低位,以 4G 内存为例,最高位 FFFFFFFF,最低位 00000000

栈底固定,栈顶不固定

RSP 和 RBP 通用寄存器

rsp 存储栈顶,rbp 存储栈底。

mov rdi,rsp
call 0x7f51189ef050


endbr64    # 0x7f51189ef050
push rbp
mov rbp,rsp
push r15
push r14
push r13
push r12
push rbx
sub rsp, 0x88
mov [rbp-0x88],rdi
rdtsc

...

堆栈操作

push

压栈,可以将寄存器 push 到堆栈,也可以将内存 push 到堆栈

PUSH r32
PUSH r16
PUSH m16
PUSH m32
PUSH imm8/imm16/imm32

push 最少 16 位,不能是 8 位

示例:

push rax   # 将rax复制到堆栈,然后rsp(栈顶)减8,为什么减而不是加,因为栈底在高位,栈顶在低位
push eax    # 将eax复制到堆栈,然后esp(栈顶)减4
push ax    # 将ax复制到堆栈,然后sp(栈顶)减2

pop

出栈,可以 pop 到寄存器,也可以 pop 到内存。

POP r32
POP r16
POP m16
POP m32

pop 最少 16 位,不能是 8 位

示例:

pop rax    # 将栈顶8个字节复制到rax,然后rsp加8

pushad

把当前寄存器全部 push 到栈中,其入栈顺序是:EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI

popad

POPAD 指令则是 PUSHAD 指令的逆操作。以此 pop 出保存的寄存器,顺序为 EDI、ESI、EBP、ESP、EBX、EDX、ECX、EAX.

pushad 和 popad 通常成对出现,作用 保护现场

先使用 pushad 把寄存器保存起来,然后就可以随便修改寄存器了(破坏现场),最后使用 popad 恢复保存的寄存器(恢复现场)


堆栈
http://blog.lujinkai.cn/汇编/堆栈/
作者
像方便面一样的男子
发布于
2022年9月24日
更新于
2023年12月5日
许可协议