免费注册 查看新帖 |

Chinaunix

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

求高手代码分析一段堆栈溢出代码 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2007-04-21 14:45 |只看该作者
原帖由 okyzx 于 2007-4-21 14:31 发表
谢谢各位。
手上暂时没有你们推荐的书。能否帮小弟简单讲下函数调用时栈的情况,谢谢


函数调用可能是寄存器传值,也可能是栈传值,或者是两者都有。简单的说一下x86上函数调用(栈传值)吧。

例如:

  1. void test(int a, char b, long c)
  2. {
  3. .................
  4. }
复制代码


调用test时,首先是参数c压栈(使用push类指令),其次是参数b压栈,再其次是参数a压栈, 然后用call指令调用函数,call指令会把函数的返回地址压栈。
test函数一开始会把ebp(框架指针)寄存器压栈,然后把esp(栈指针)赋值给ebp,然后把esp减去一个定值(分配栈了),最后通过ebp加偏移量就可以访问参数。

上述过程就生成了我前面发的栈图。

想要好好了解还是应该看书,动手写点程序尝试。手上没有,下电子版嘛。

论坛徽章:
0
22 [报告]
发表于 2007-04-21 15:07 |只看该作者
非常感谢大家,特别是 zx_wing (骑着猪的青蛙)、flw2

论坛徽章:
0
23 [报告]
发表于 2007-04-21 19:02 |只看该作者

此程序,在64bit core cpu 上无效!

此程序,在64bit core cpu 上无效!

论坛徽章:
0
24 [报告]
发表于 2007-04-21 19:16 |只看该作者
问个问题,i386下不压段地址啊?那段间如何调用?

论坛徽章:
0
25 [报告]
发表于 2007-04-21 19:20 |只看该作者
原帖由 exir 于 2007-4-21 19:16 发表
问个问题,i386下不压段地址啊?那段间如何调用?

在linux下,段的地址是个固定基地址的值0
不需要换段地址

论坛徽章:
0
26 [报告]
发表于 2007-04-21 19:32 |只看该作者
原帖由 flw2 于 2007-4-21 19:20 发表

在linux下,段的地址是个固定基地址的值0
不需要换段地址

怎么压栈应该和操作系统无关吧,硬件决定的吧。
记得实模式下要先压偏移再压段,保护模式下段的长度和偏移量不一样,
还真没想过段间调用怎么压栈?

论坛徽章:
0
27 [报告]
发表于 2007-04-21 20:11 |只看该作者
压栈 压段?

论坛徽章:
0
28 [报告]
发表于 2007-04-21 20:21 |只看该作者
查了下资料,拿出来show show。
<<INSTRUCTION SET REFERENCE, A-M>> 3-88 Vol. 2

When executing a far call in realaddress or virtual-8086 mode, the
processor pushes the current value of both the CS and EIP registers
on the stack for use as a return-instruction pointer.

保护模式差不多:
A far call to the same privilege level in protected mode is very similar
to one carried out in real-address or virtual-8086 mode.
当然这是有很多条件的:不因特权级和权限产生异常,不采用调用门,无32、16位
混合调用。
Call的伪代码写了9页,i386体系结构复杂不是盖的。

论坛徽章:
0
29 [报告]
发表于 2007-04-21 20:24 |只看该作者
对了由于段地址只有16位,压入栈时高16位要填0

论坛徽章:
0
30 [报告]
发表于 2007-04-21 21:55 |只看该作者
通过局部变量修改返回值不实用,推荐通过参数修改返回值


  1. int copy(int foo)
  2. {
  3.     int *p = &foo - 1;
  4.     *p = foo;

  5.     return 0;
  6. }


  7. int hacked(void)
  8. {
  9.     printf("这里是堆栈溢出程序.看到我了吧.\n");
  10.     exit(0);
  11. }

  12. int main(int argc, char* argv[])
  13. {
  14.     copy((int)hackstr);

  15.     return 0;
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP