【reverse】逆向4 初识堆栈

【reverse】逆向4 初识堆栈

1、问题引入

假设我们需要一块内存,有如下的要求

  1. 主要用于临时存储一些数据(如果数据很少可以放入寄存器中)
  2. 能够记录存了多少数据
  3. 能够非常快速的找到某个数据

2、模拟堆栈

我们可以设计这样的结构图

【reverse】逆向4 初识堆栈

top:栈顶

base:栈底

【reverse】逆向4 初识堆栈

windows操作系统分配堆栈是从高地址向低地址分配

为了统一,我们也这样模拟

压入数据

第一种添加数据的方式(先存数据再改地址)

【reverse】逆向4 初识堆栈

我们将ebx作为栈底,edx作为栈顶,内存编号都位0x19FF78

将AAAAAAAA数据存入栈中之后,将edx的内存编号减去4

可以看到0019FF74内存编号的数据已经改为了AAAAAAAA

【reverse】逆向4 初识堆栈

第二种添加数据的方式(先改地址再存数据)

【reverse】逆向4 初识堆栈

我们先把edx的地址减去4,用lea的方式

然后再给edx地址存入数据BBBBBBBB

可以看到0019FF70内存编号的数据已经改为了BBBBBBBB

【reverse】逆向4 初识堆栈

弹出数据

第一种弹出数据的方式(先取数据再改地址)

【reverse】逆向4 初识堆栈

我们把栈顶edx的数据取出到eax中

然后再让edx的地址加4

可以看到eax中存入了BBBBBBBB这个数据

【reverse】逆向4 初识堆栈

第二种弹出数据的方式(先改地址再取数据)

【reverse】逆向4 初识堆栈

先让edx的地址加4,再从edx-4的地址中取出数据

可以的看到eax中存入了AAAAAAAA这个数据

【reverse】逆向4 初识堆栈

3、堆栈

在cpu中,有两个寄存器,ebp、esp

我们使用操作系统时,操作系统将ebp当作栈底,esp当作栈顶

汇编语言给我们封装好了push和pop指令

【reverse】逆向4 初识堆栈

我们push两个数据进去,esp的地址减少了8,并且在堆栈窗口可以看到我们push的两个值

【reverse】逆向4 初识堆栈

同时可以看到我们的esp到了0019FF6C也就是存储12345678数值的地址

【reverse】逆向4 初识堆栈

我们再执行

【reverse】逆向4 初识堆栈

可以看到eax和ecx的值都改变了

【reverse】逆向4 初识堆栈

同时esp的位置也加了8,因为pop了两个值

【reverse】逆向4 初识堆栈

push

【reverse】逆向4 初识堆栈

不允许push 8位寄存器

push 16位寄存器,esp地址-2

push 32位寄存器,esp地址-4

push 立即数,esp地址-4

push dword ptr ds:[0x0019FF6C] 压入0x0019FF6C地址连续4字节的数据,esp地址-4

push word ptr ds:[0x0019FF6C] 压入0x0019FF6C地址连续2字节的数据,esp地址-2

pop

【reverse】逆向4 初识堆栈

pop 16位寄存器,esp地址+2

pop 32位寄存器,esp地址+4

pop dword ptr ds:[0x0019FFDC] 将0019FFDC连着的4字节的数据改为被弹出的数据,esp地址+4

pop word ptr ds:[0x0019FFDC] 将0019FFDC连着的2字节的数据改为被弹出的数据的后2字节,esp地址+2

pushad

将8个通用寄存器存入堆栈中,方便修改工作

popad

将8个通用寄存器从堆栈中弹出,还原寄存器现场

【reverse】逆向4 初识堆栈

上一篇:vscode中6个好用的前端重构插件


下一篇:从零开始学“C“语(你有多久没看基础知识了?)