环境:
gcc
测试c代码如下overflow.c:
练习的目的是在foo中对数组越界溢出,让程序打印出hello。
首先 :gcc -g -fno-stack-protector overflow.c -o overflow
再查看:objdump -d overflow
查看两个函数的反汇编如下:
测试下foo()中栈的使用,修改下foo(),如下:
重新反汇编看foo()中栈的使用,如下:
这样,就能看出buf1在栈中的位置为当前栈底指针%ebp-0xc开始的4个字节。
比较奇怪的是buf1[4]指向了%ebp的位置(很奇怪为什么会这样,C语言中数组不是连续存储的吗?按照我原来的理解buf1[4]会是%ebp-0x10);不过这样就能推测出buf1[n]的值了。
目标是修改main()调用foo()函数的换回地址为print()的地址0x080483a4。这个返回地址应当是在调用foo()时压栈的,在栈中的位置为当前%ebp+0x4(因为调用foo后foo首先把原来的%ebp压栈),所以只要将栈中%ebp+0x4这个地址中的值改为print()的入口地址0x80483a4就ok了。
在小端系统中,低字节在低位,所以,修改foo()如下:
编译后,执行:./overflow,输入如下:
打印出了“hello”.不过也出现了段错误。这个没有仔细跟,如果不想看见断错误,可以将foo()的buf1[8] = 0xaa(即对应调用系统print()函数的部分),此时就可以输出“hello”,而不出现断错误: