返回信息流#include<stdio.h>
void why_here(void)
{
printf("why u here ?!\n");
_exit(0);
}
int main(int argc,char * argv[])
{
int buff[1];
buff[2]=(int)why_here;
return 0;
}
这是一条镜像帖。来源:北邮人论坛 / security / #25900同步于 2009/11/14
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Security机器人发帖
谁能帮我讲讲这是怎么回事儿啊,在内存到底发生了什么?
ggbond
2009/11/14镜像同步8 回复
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
buff[2]=(int)why_here;//此处main函数返回地址被覆盖
return 0;//CPU将跳到main函数的返回地址继续运行,但由于正确的返回地址被why_here函数地址覆盖,所以会跳到why_here函数继续执行。
嗯,在网上搜了一下,好像就是这样。
请问有什么讲解程序在运行时 内存使用情况的资料吗? 就是 代码段 、数据段、堆栈段等的使用的资料。
谢谢。
btw,程序好像是正常终止的。
【 在 smilefufu 的大作中提到: 】
: buff[2]=(int)why_here;//此处main函数返回地址被覆盖
: return 0;//CPU将跳到main函数的返回地址继续运行,但由于正确的返回地址被why_here函数地址覆盖,所以会跳到why_here函数继续执行。
就想 内存溢出... 网上找的例子...
【 在 Keyman 的大作中提到: 】
: 这代码想干嘛?!是把函数的地址放到buff地址后的第8个字节处?
没注意到why_here里用了exit(0)函数……如果没用而是直接return的话,会异常退出的。
资料一时也想不起有啥=。=大概说一下吧:
windows加载你的程序,设置好各种环境,加载好各种必要dll,然后开始准备调用main函数
push argv指针 ;参数2入栈
push argc ;参数1入栈
call main ;调用main函数。注意,此时虽然没有push指令,但其实已经将eip入栈了
other code ;main函数结束后windows必做的扫尾工作。
而在main函数内部,是下面的情况
push ebp ;栈帧移动
mov ebp,esp ;ebp成了新栈帧的栈底
sub esp,xx ;esp向栈顶移动xx个字节,这xx个字节的空间用于存储此函数的局部变量。
......
还记得你申明的第一个变量是 int buff[1]么,这个局部变量就正好是在xx字节空间的最底上。那么现在栈里的情况如下:
……
addr+0 buff[0]
addr+4 前一栈帧的esp
addr+8 call main时的eip,即main函数的返回地址
addr+c argc
addr+10 argv指针
……
(由于不清楚具体运行时的地址是多少,所以我用addr+x来表示地址。x是16进制)
那么再来看return时会做些啥。正常情况下,在执行到return 0;之前,编译器必然会保证堆栈的平衡,并且能让程序接着call main指令下面的指令继续运行。简而言之,main函数结束后,CPU会从addr+8的位置读出main函数的返回地址继续执行。但由于此地址已经被why_here函数地址覆盖,所以return之后不会跳到call main的下一条执行,而是会跳到why_here函数去执行。
嗯,自己开OD调试一下就会比较清楚了。
表达能力有限,讲述不清之处请见谅
【 在 GGBond 的大作中提到: 】
: 嗯,在网上搜了一下,好像就是这样。
: 请问有什么讲解程序在运行时 内存使用情况的资料吗? 就是 代码段 、数据段、堆栈段等的使用的资料。
: 谢谢。
: ...................
【 在 GGBond 的大作中提到: 】
: #include<stdio.h>
: void why_here(void)
: {
: ...................
栈溢出,覆盖掉返回地址。
想知道更多的原因,请首先理解汇编指令 call 的 作用~~
其实本题的结果,完全是跟编译器相关的,没有绝对对否,不同的编译器可能产生不同的结果~~
恩 ,非常感谢。 [em21]
【 在 smilefufu 的大作中提到: 】
: 没注意到why_here里用了exit(0)函数……如果没用而是直接return的话,会异常退出的。
: 资料一时也想不起有啥=。=大概说一下吧:
: windows加载你的程序,设置好各种环境,加载好各种必要dll,然后开始准备调用main函数
: ...................
今年初的《程序员的自我修养》是本很好的书。
讲了程序从编译,装载,连接的很多细节。
【 在 GGBond 的大作中提到: 】
: 嗯,在网上搜了一下,好像就是这样。
: 请问有什么讲解程序在运行时 内存使用情况的资料吗? 就是 代码段 、数据段、堆栈段等的使用的资料。
: 谢谢。
: ...................