免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4455 | 回复: 10
打印 上一主题 下一主题

请教一个关于函数调用过程中压栈相关问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-28 21:36 |只看该作者 |倒序浏览
c的默认函数压栈
参数是从右向左压栈的,暂时不讨论对齐相关的问题(参数是默认四字节对齐,函数里边定义的变量是默认对齐方式----变量首地址是自身结构体里边最大标准数据类型字节的整数倍)

程序在运行中崩溃了,但是release版本没有相关的符号表,不能定位到具体那一行崩溃;
这个时候就得分析函数栈,而函数栈是一些bit串,没有具体的含义,要想分析他,就要清楚函数调用中
每个变量的实现细节,才能定位到栈区那个内存对应什么变量的值;

我分析出,崩溃的栈里边是从右向左压栈的,如果参数非4字节,会自动补齐,比如试验四个参数,
每个参数都是字节类型,一样占用16字节的数据,而函数体里边的变量是默认对齐的方式,一个字节变量,两个字节变量,四个字节变量占用的是12个字节,只有一个默认的填充字节;

对于具体变量对齐以及存放压栈的方式我已经搞清楚的了,不清楚的是函数压栈的时候,占用的不是函数指针4字节大小的栈区,函数指针压栈的地方,下边有一个4字节以及上边有3个四字节的数据,不知道这个是做什么的,???????除去参数,函数指针,函数体里边的局部变量,还有什么会压栈呢??

论坛徽章:
0
2 [报告]
发表于 2010-08-28 21:48 |只看该作者
举例
test1(int i1,int i2,int i3,int *pi)
{
int i=1;
int j=2;
test2(3,4,5,(int *)pData);
....
}
test2(int i1,int i2,int i3,int *pi)
{
int i=7;
int j=8;
assert(0);------在此挂起
....
}

栈区内容:

--------
00000008
00000007
00000003
00000004
00000005
00fb4050
########----------------------为什么在压栈test1的时候,还压栈其它奇怪的数据,才到压栈相关的参数以及局部变量呢/是什么呢?
########----------------------
########----------------------
******** test1地址
########----------------------
00000002
00000001
*******  test1 参数1
*******  test1 参数2
*******  test1 参数3
*******  test1 参数4
-------

论坛徽章:
0
3 [报告]
发表于 2010-08-28 21:49 |只看该作者
函数压栈前后有一些奇怪的数据不是参数也不是局部变量,这个是一些什么东西呢?------

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
4 [报告]
发表于 2010-08-29 00:51 |只看该作者
编译器不保证所有栈变量连续, 他可能会搞一些这样的空洞区, 里面内容我觉得可能是随机的; 至于为什么, 或许是为了防止hack吧, 比如让你摸不准返回地址在哪里, 也就没办法去有意修改返回地址跳到其他地址了

论坛徽章:
0
5 [报告]
发表于 2010-08-29 09:47 |只看该作者
堆栈申请的空间一般要多。所以没有用的就是随机值,不影响
Lz的堆栈错了吧

7                            低地址  
8
test1的帧指针                     
返回地址  
00000003
00000004
00000005
00fb4050

*******    /*多余的空间,对齐的需要*/
00000002
00000001
*******  test1 参数1
*******  test1 参数2
*******  test1 参数3
*******  test1 参数4   高地址

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
6 [报告]
发表于 2010-08-29 17:18 |只看该作者
cc -S 看一下汇编代码就知道了。

论坛徽章:
0
7 [报告]
发表于 2010-08-29 19:46 |只看该作者
回复 5# wkq5325


    不是随机的吧,会不会是寄存器内容被压栈了,变量是连续的没有问题,空间分配也正常,只是函数附近有一些奇怪的东东-----
我写了几个测试函数测试过的了,arrsert(0),自己定义的变量值都是0x44444444;0xaaaaaaaa这样一眼就看到的值,借此了解压栈的东东,
进一步分析异常断言的时候-------寄存器里边和栈里边的内容-------进一步定位问题,要是有随机的东西进去的话,就没有办法分析了-----还有系统就是汇编,调用者
函数要负责清空相关的栈的~~~~~~

论坛徽章:
0
8 [报告]
发表于 2010-08-29 19:48 |只看该作者
回复 6# yulihua49


    好办法,只是对于一个工程来说,代码很大,根本不知道哪里对应哪里,要是向vc--alt+8,一个语句对应一个汇编这样的书写,就清楚的多的了~~~~~

论坛徽章:
0
9 [报告]
发表于 2010-08-29 19:56 |只看该作者
objdump 就有这个功能

论坛徽章:
0
10 [报告]
发表于 2010-08-29 20:40 |只看该作者
想开启release模式下的调试功能,首先把-s(消除字符串)的参数去掉,然后加上-g,就可以断点调试了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP