免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: GoldenSoldier
打印 上一主题 下一主题

Linux堆栈溢出的经典问题,欢迎围观!大牛前进 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2009-11-26 21:08 |只看该作者
原帖由 mik 于 2009-11-26 21:00 发表


对于用户程序的入口函数,即:main(), gcc 一般作 16 bytes 对齐。其它函数,不作 16 bytes 对齐


非常感谢你的帮助!

受教了,原来如此!
不知mik大牛如何知道这么多,问一下有这方面的书籍或者技术资料参考一下么?
谢谢

另外,mik知道可以如何对上述代码进行修改,使得main函数可以正常返回么?
请不吝赐教


[ 本帖最后由 GoldenSoldier 于 2009-11-26 21:53 编辑 ]

论坛徽章:
0
22 [报告]
发表于 2009-11-26 21:22 |只看该作者
原帖由 mik 于 2009-11-26 20:53 发表



这和 LZ 的错误有什么关系呢?


呵呵, 这位老兄比较深藏不露, 发了几次问, 最终还是没弄清楚他要表达什么...

mik兄的回复... 学习了~

论坛徽章:
0
23 [报告]
发表于 2009-11-26 22:03 |只看该作者
原帖由 GoldenSoldier 于 2009-11-26 21:08 发表


非常感谢你的帮助!

受教了,原来如此!
不知mik大牛如何知道这么多,问一下有这方面的书籍或者技术资料参考一下么?
谢谢

另外,mik知道可以如何对上述代码进行修改,使得main函数可以正常返回么? ...


我不是牛人

牛人可不是随便就能叫的。

论坛徽章:
0
24 [报告]
发表于 2009-11-26 22:12 |只看该作者
原帖由 GoldenSoldier 于 2009-11-26 21:08 发表


非常感谢你的帮助!

受教了,原来如此!
不知mik大牛如何知道这么多,问一下有这方面的书籍或者技术资料参考一下么?
谢谢

另外,mik知道可以如何对上述代码进行修改,使得main函数可以正常返回么? ...


在你的代码里,你要使用 main() 正常退出,

必须把 调用 foo() 时的返回地址交由 yaya() 函数来返回

void foo()
{
       int c_foo = 1;

      int yaya_ret = (int) *(& c_foo + 2);
      *(& c_foo + 2) = (int)attack;
      *(& c_foo + 3) = (int)yaya;
      *(& c_foo + 4) = (int)yaya_ret;
  
}

void main(){
   /*  int a_main=1; */
   /* a_main=(int)yaya; */

    foo();
}

}

论坛徽章:
0
25 [报告]
发表于 2009-11-26 22:20 |只看该作者

回复 #21 GoldenSoldier 的帖子

像你这些代码,是很笨拙的

通过 “利用局部变量偏移量改变” 返回地址的方法是很笨拙的

论坛徽章:
0
26 [报告]
发表于 2009-11-27 14:50 |只看该作者
原帖由 mik 于 2009-11-26 22:20 发表
像你这些代码,是很笨拙的

通过 “利用局部变量偏移量改变” 返回地址的方法是很笨拙的


嘿嘿,版主教训的是!
我是新手学习,只能先以后难吧,我就是先理解一下Linux堆栈的细节而已。

>>通过 “利用局部变量偏移量改变” 返回地址的方法是很笨拙的
还有其他的好的方法?
诚心请教一下
拜。(莫不是内嵌汇编?)

论坛徽章:
0
27 [报告]
发表于 2009-11-27 15:25 |只看该作者
原帖由 mik 于 2009-11-26 22:12 发表


在你的代码里,你要使用 main() 正常退出,

必须把 调用 foo() 时的返回地址交由 yaya() 函数来返回

void foo()
{
       int c_foo = 1;

      int yaya_ret = (int) *(& c_foo + 2);
      * ...

明白你的意思了 ,就是把存储a_main的地址里的内容换成main函数返回的地址。
我尝试了一下,见下:
  1. void foo()
  2. {
  3.   int c_foo=1;
  4.   int main_ret=(int)*(& c_foo +2);
  5.   *(& c_foo +2)=(int)attack;
  6.   *(& c_foo +4)= (int) main_ret;
  7. }
复制代码
其他的代码都没变。
这样就OK了,最后测试通过,没有出现段错误! 嘿嘿

[ 本帖最后由 GoldenSoldier 于 2009-11-27 15:27 编辑 ]

论坛徽章:
0
28 [报告]
发表于 2009-11-27 17:41 |只看该作者
unsigned long get_ebp(void)
{
        __asm__("movl %ebp, %eax");
}


要想学会这个汇编必不可少

[ 本帖最后由 学与思 于 2009-11-27 17:42 编辑 ]

论坛徽章:
0
29 [报告]
发表于 2009-11-27 18:06 |只看该作者
不过对于你这个问题,更好的办法是利用函数的第一个参数的地址来获取函数的返回地址的地址

论坛徽章:
0
30 [报告]
发表于 2009-11-30 00:20 |只看该作者
四不像
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP