闭关学pwn第四天——掌握pwn中需要了解的汇编指令(对第一天栈做相应补充)

补充

这篇最后编辑时间是19年12月。。我居然鸽子了这么久没发!!!
看了下自己大致讲的很详细了,文章后面应该想着自己手绘图然后再多来几个函数调试,不过既然鸽子了就炖汤吧,这篇就不补上了。
准备在闭关学pwn第五天把第三天和第四天两篇文章的内容结合起来,搞一道题来练手什么的[滑稽]

前言

pwn现在卡死在ret2libc,知道是返回,却不懂怎么返回,也不知道怎么搞到shellcode,估计是没有相应基础,所以这回补一波pwn中需要掌握的汇编指令。

———————————————————————————————————

一 、开天辟地

没错我就是来开天辟地的。
首先……
move push add 这些基础指令肯定要看看的吖
不过pwn里好像需要用到的是这些指令:

子程序
算术指令
通用数据传送指令
比较指令

只用看这四个,剩下的好像pwn用不上

栈的结构在闭关学pwn第一天了解过
pwn里最常见的ebp和esp肯定要了解
当时只是学到了栈由高地址向低地址生长,却从没想过为什么要这样
这篇文章里有讲到
https://www.jianshu.com/p/899f34722d57

———————————————————————————————————

二 、女娲补天

开天辟地完了就该女娲补天了
刚才都是理论,这里实际操作一下
gcc编译配合gdb调试还不大熟练
所以就花点功夫找了个在线查看汇编代码的网站
先简单练练手来验证之前的汇编指令

写一段最最最最最简单的代码吧

int main()
{
    int a,b,c;
    a=1;b=2;c=3;
}

然后放进汇编
在这里插入图片描述它很灵性的输入一行就汇编一行出来
边看汇编边学习吧
首先是push rbp

————————————————————————

0x10 push

在这里插入图片描述
在这里插入图片描述
而push是压栈操作,压栈是干什么用的呢?

在调用一个函数时CPU会将当前的环境保存起来我们称之为压栈(Push)

计算机在运算的时候大部分情况会把数据放到寄存器里运算,而调用函数的时候,会有新的数值要使用这些寄存器,所以要把这些寄存器里的内容保存起来,就是保护现场。因为栈的先入后出非常适合这一操作,所以每次函数调用前都有入栈操作,函数返回是出栈还原现场

计算机程序用来放数据的地方有两种,一个是堆,一个是栈。
栈一般用来放一些函数的临时变量,还有中断和调用函数时的返回地址。
因为这些地址都是临时的,所以在栈的出栈和进栈的时候可以动态的进入和删除。
调用函数和中断的时候,临时变量和返回地址就暂存在栈中。
函数调用完了,临时变量和返回地址就从栈删除了。
所以栈一般来说是临时变量,调用函数会自动回收内存。
这就是PUSH  POP 的功能了。
相当于一个暂时保存数据的地方。 
而堆的话一般用来动态分配内存,分配的内存一般不会自动释放。 

也就是,如果对rbp不进行压栈操作,调用完函数以后cpu就找不到路了,不能返回调用函数前的位置继续往下运行了。毕竟电脑比人笨咯,我们要体谅cpu。

push压栈具体步骤如下,先用32位的来解释,毕竟要从32位开始

在这里插入图片描述

栈顶指针esp代表向下拓展了四个字节,就是说,esp往下4个字节,就可以把eax放进去封印起来,最后eax用完了再弄出来,栈先入后出的好处便在这里了。
写段代码当例子

void ha(int m, int n) {
    int a, b;
    a = m;
    b = n;
}
main() {
int m,n;
ha(m, n);
}

汇编代码如下
在这里插入图片描述发现出现了DWORD PTR []
搜索后发现是相当于*p的功能

dword   双字 就是四个字节
ptr     pointer缩写     即指针
[ ]里的数据是一个地址值,这个地址指向一个双字型数据
如mov eax, dword ptr [11111111]  
就是把内存地址11111111中的双字型(32位)数据赋给eax

然后看到在main中,先把这两个int变量从地址拿到寄存器edx和eax中,然后再从edx和eax中赋给esi和edi,也就是存到esi和edi中,这样edx和eax就又空出来可以参加中的运算而不用担心原本的值丢失了。

这时候发现又call指令
————————————————————————

0x20 call

在这里插入图片描述
把之前存到edi里和esi里的再拿出来赋给新的地址

这正说明了真正参与运算的是函数的形参,也跟之前学到的c语言知识相对应

原句是push rbp,push明白了,看rbp
rbp百度到是64位的相当于32位的ebp
在这里插入图片描述
在这里插入图片描述也就是最上面一个栈帧的底部
对栈帧不大了解,以前都是粗略理解为上个函数底部,这回搞懂它。
在这里插入图片描述这样看起来还是很迷糊,加入灵魂
在这里插入图片描述精华:

首先应该明白,栈是从高地址向低地址延伸的。
每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息
寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低地址)
注意:EBP指向当前位于系统栈最上边一个栈帧的底部,而不是系统栈的底部。
严格说来,“栈帧底部”和“栈底”是不同的概念;
ESP所指的栈帧顶部和系统栈的顶部是同一个位置。

在这里插入图片描述
大致自己画出图是这样的
在这里插入图片描述
栈帧n代表套娃n次
因为之前百度百科中也提到栈帧是对应着未完成的函数,比如我运行main函数里面调用了其他函数,那么就是栈帧1(也就是main)跳到栈帧2,如果这个函数里再嵌套进其它函数,那么就继续往下开栈帧。

而并列的函数比如main里有两个函数的话栈ebp是不会变的,只是把esp放出去再“收”回来罢了。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值