堆栈
什么是堆栈
堆栈 在有些文章中也叫做 栈
可读、可写 这些都是针对正向的,编译器限制的,对于逆向而言,没有这些限制。
BASE 是栈底,TOP 是栈顶
栈底是高位,栈顶是低位,以 4G 内存为例,最高位 FFFFFFFF,最低位 00000000
栈底固定,栈顶不固定
RSP 和 RBP 通用寄存器
rsp 存储栈顶,rbp 存储栈底。
1 | mov rdi,rsp |
堆栈操作
push
压栈,可以将寄存器 push 到堆栈,也可以将内存 push 到堆栈
1 | PUSH r32 |
push 最少 16 位,不能是 8 位
示例:
1 | push rax # 将rax复制到堆栈,然后rsp(栈顶)减8,为什么减而不是加,因为栈底在高位,栈顶在低位 |
pop
出栈,可以 pop 到寄存器,也可以 pop 到内存。
1 | POP r32 |
pop 最少 16 位,不能是 8 位
示例:
1 | 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 恢复保存的寄存器(恢复现场)