php 缓冲区溢出,C 语言缓冲区溢出的实战

该内容源码参考了 [3.10.3]

学习该章节之前,一直有个疑问,Segmentation fault 这样的错误会具体引发的原因是啥, 可不可以从汇编代码的层面进行一个学习和了解. 所有就有了这篇文章, 纯属个人学习研究.

完整的测试源码

#include

#include

#include

/*

*/

char* gets(char* s)

{

int c;

char *dest = s;

// read c char write to dest memory;

while((c = getchar()) != '\n' && c != EOF)

{

*dest++= c;

}

if(c == EOF && dest == s)

{

return NULL;

}

*dest++ ='\0';

return s;

}

void echo(){

char buf[8];

gets(buf);

puts(buf);

}

int main()

{

echo();

return 0;

}

编译过程,

shell>gcc -g demo.c -o demo

程序编译成功后,随便输入几个字符, 可以正常的回显, 但是超过某个长度就会出现文章开始的问题, 那么新的问题来了,

这个长度是不是就是代码中定义的buf的长度呢, 会不会有其他问题发生,

验证思路:

1 通过汇编代码, 查看寄存器地址中的内容, 直接明了的去观察, 那么就存在一个对比的过程,

第一遍的时候是正常的输入, 不会发生错误,

第二遍会输入较长的内容, 对比寄存器中的值.

正常输入时,

在没有输入任何字符的时候, 相关的寄存器的值,

这个是在程序调用getchar() 函数前寄存器的值.

(gdb) ir ebp

ebp 0xbfffea680xbfffea68

(gdb) x/16cb 0xbfffea68

0xbfffea68:120 'x'-22 '\352'-1 '\377'-65 '\277'100 'd'-124 '\204'4 '\004'

8 '\b'

0xbfffea70:0 '\000' -106 '\226'117 'u'0 '\000' -112 '\220'-22 '\352'-1 '\377

'-65 '\277'

(gdb) i r esp

esp 0xbfffea500xbfffea50

(gdb) x/16cb 0xbfffea50

0xbfffea50:-12 '\364'-1 '\377'-118 '\212'0 '\000' 4 '\004' -30 '\342'

-118 '\212'0 '\000'

0xbfffea58:-120 '\210'-22 '\352'-1 '\377'-65 '\277'-87 '\251'-124 '\204'

4 '\004' 8 '\b'

(gdb) i r eax

eax 0xbfffea600xbfffea60

(gdb) x/16cb 0xbfffea60

0xbfffea60:37 '%'-98 '\236'121 'y'0 '\000' 28 '\034'-21 '\353'-1 '\377'

-65 '\277'

0xbfffea68:120 'x'-22 '\352'-1 '\377'-65 '\277'100 'd'-124 '\204'4 '\004'

8 '\b'

开始调用getchar() 函数

此时有个隐藏的信息是, gets() 函数中, 参数s的地址是 0xbfffea60, 这个需要知道, 就是这个参数出现了问题,

gdb> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

在输入完成后,

再次查看寄存器的内容,

(gdb) x/16cb 0xbfffea68

0xbfffea68:97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'

0xbfffea70:97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'

(gdb) x/32cb 0xbfffea50

0xbfffea50:96 '`'-22 '\352'-1 '\377'-65 '\277'4 '\004' -30 '\342'-118 '\2

12'0 '\000'

0xbfffea58:-120 '\210'-22 '\352'-1 '\377'-65 '\277'-87 '\251'-124 '\204'

4 '\004' 8 '\b'

0xbfffea60:97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'

0xbfffea68:97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'

(gdb) x/16cb 0xbfffea60

0xbfffea60:97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'

0xbfffea68:97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'97 'a'

对比发现 0xbfffea68 地址中的内容被改写了, 这个地址是程序被调用时的入栈地址, 在gets()函数内部把值改写了,

导致程序返回的时候,出现了问题,

如果用户输入了缓冲区大小内的内容后, 则器寄存器中的值为

(gdb) x/16cb 0xbfffea60

0xbfffea60:97 'a'97 'a'97 'a'97 'a'97 'a'0 '\000' -1 '\377'-65 '\277'

0xbfffea68:120 'x'-22 '\352'-1 '\377'-65 '\277'100 'd'-124 '\204'4 '\004'

8 '\b'

可以发现 0xbfffea68地址中的值和原来的值是一致的, 此时程序退出则是正常的,

具体可以使用的空间的大小的问题, 什么时候,会触发返回地址被改写.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值