汇编语言函数调用小结及缓冲区溢出的利用

本文以C语言中的write函数为例,以汇编代码的形式,探讨该函数运行时内存中的情况。

这是我们常见的一个write()函数:

write(fd,buf,len);

这个函数有三个参数:文件描述符fd、数组buf的地址、读取数据的长度len。
它的作用是从buf中读取长度len个字节的数据。

举个例子:

write(1,"Hello World\n",13);

这条语句作用是向标准输出中打印"Hello World"
它的汇编代码如下:

asm

从上面的代码中可以发现,在write函数被调用(call <write@plt>)之前时,有3MOV指令,先将write函数的各个参数存入栈中(C语言中参数以从右向左的顺序入栈)。

参数入栈后,执行call指令,call相当于push ip, jmp <addr> ,也就是先将IP(函数的返回地址,即下一条指令的地址)压入栈中,然后JMP至被调用函数的地址。

参数入栈后栈的情况如下:
args

call <write>后栈的情况如下:
write
其中0x08048457write函数执行完后的返回地址。

现在重新梳理一下,调用write函数时依次压入栈中的分别是长度len、数组buf的首地址、文件描述符fdwrite函数的返回地址,如下图所示:
stack

那么如果程序中存在缓存区溢出漏洞(比如read函数读取的数据长度比实际缓存区长时),我们可以通过覆盖函数的返回地址,来控制程序的执行流程。
漏洞函数:

char buffer[100];
read(0,buffer,128);

bof

我们可以将函数的返回地址覆写为write函数的地址,然后在栈中构造write函数的返回地址和参数,这样我们便可以使用write函数来泄露内存中的信息,比如某函数在libc中的地址等等。

leak

被修改后的栈是这样的:
chg

当正常的函数调用ret指令返回时,ret指令相当于pop ip,也就是说write的地址会赋给ip,相当于执行了一条jmp <write>

现在栈变成了这样:
chg
是不是和上面讲的write函数的栈一样啦?

不过也不一样,现在这个栈中的fd,buf,len是我们可以任意指定的,即: 指哪儿就可以打哪儿 :)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TaQini852

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值