汇编语言函数调用小结及缓冲区溢出的利用
2016-11-19 21:41
573 查看
本文以C语言中的
这是我们常见的一个
这个函数有三个参数:文件描述符fd、数组buf的地址、读取数据的长度len。
它的作用是从buf中读取长度len个字节的数据。
举个例子:
这条语句作用是向标准输出中打印
它的汇编代码如下:
从上面的代码中可以发现,在
参数入栈后,执行
参数入栈后栈的情况如下:
其中
现在重新梳理一下,调用
那么如果程序中存在缓存区溢出漏洞(比如
漏洞函数:
我们可以将函数的返回地址覆写为
被修改后的栈是这样的:
当正常的函数调用
现在栈变成了这样:
是不是和上面讲的
不过也不一样,现在这个栈中的
write函数为例,以汇编代码的形式,探讨该函数运行时内存中的情况。
这是我们常见的一个
write()函数:
write(fd,buf,len);
这个函数有三个参数:文件描述符fd、数组buf的地址、读取数据的长度len。
它的作用是从buf中读取长度len个字节的数据。
举个例子:
write(1,"Hello World\n",13);
这条语句作用是向标准输出中打印
"Hello World"
它的汇编代码如下:
从上面的代码中可以发现,在
write函数被调用(
call <write@plt>)之前时,有
3个
MOV指令,先将
write函数的各个参数存入栈中(C语言中参数以从右向左的顺序入栈)。
参数入栈后,执行
call指令,
call相当于
push ip,
jmp <addr>,也就是先将
IP(函数的返回地址,即下一条指令的地址)压入栈中,然后
JMP至被调用函数的地址。
参数入栈后栈的情况如下:
call <write>后栈的情况如下:
其中
0x08048457为
write函数执行完后的返回地址。
现在重新梳理一下,调用
write函数时依次压入栈中的分别是长度
len、数组
buf的首地址、文件描述符
fd、
write函数的返回地址,如下图所示:
那么如果程序中存在缓存区溢出漏洞(比如
read函数读取的数据长度比实际缓存区长时),我们可以通过覆盖函数的返回地址,来控制程序的执行流程。
漏洞函数:
char buffer[100]; read(0,buffer,128);
我们可以将函数的返回地址覆写为
write函数的地址,然后在栈中构造
write函数的返回地址和参数,这样我们便可以使用
write函数来泄露内存中的信息,比如某函数在
libc中的地址等等。
被修改后的栈是这样的:
当正常的函数调用
ret指令返回时,
ret指令相当于
pop ip,也就是说
write的地址会赋给
ip,相当于执行了一条
jmp <write>
现在栈变成了这样:
是不是和上面讲的
write函数的栈一样啦?
不过也不一样,现在这个栈中的
fd,
buf,
len是我们可以任意指定的,即: 指哪儿就可以打哪儿 :)
相关文章推荐
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
- [转]浅析C++中虚函数的调用及对象的内部布局(利用汇编深刻理解C++虚函数底层实现机制)
- 汇编语言函数调用过程
- 为何汇编里调用C函数需要堆栈,而汇编语言的函数的调用却不需要堆栈
- 【龙芯1c库】龙芯1c上c语言写的函数调用汇编语言写的函数
- 32位汇编语言学习笔记(13)--函数的调用
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆
- C/C++与汇编语言的交互之-(2)从C/C++代码调用汇编代码中的函数与变量
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
- 为何C语言(的函数调用)需要堆栈,而汇编语言不需要
- 龙芯汇编语言-利用系统调用复制文件
- 汇编语言函数调用过程(转)
- 汇编语言函数调用过程
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
- ARM基础:为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈(转载)
- 利用汇编语言实现串口的通讯(一)(BISO调用)
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈