首页
社区
课程
招聘
[原创]0基础也能看懂的函数栈结构分析
发表于: 2020-8-9 18:46 11688

[原创]0基础也能看懂的函数栈结构分析

2020-8-9 18:46
11688

新手上路,被老师难住。
题曰:看图写结论,写一条得10分,不及格的统统参加补课呀!
图曰:(如图1)

图1

就看见:
1.左边一溜0018XXXX;
2.中间几片CCCCCCCC;
3.右边有几个认识的字母,比如“hell”。
然而:就看见3条,还得不出结论,怎么能及格?!Oh,What the hell!到底有什么子丑寅卯?

看整体布局,有内存地址、有十六进制数据、有字符,初步判断这张图片貌似是用WinHex之类的工具抓取的内存片段。内存里都有啥?代码、数据、栈、堆。那这一段像啥?且瞧瞧去。

0018开头的内存地址是Win7系统栈空间在VC6下的特征,如图2。

图2
VC6下,类似的特征值还有:
WinXP-0x0012XXXX
Win10-0x0019XXXX
在VS的环境下,由于引入了内存地址随机化机制,我们就不能看到固定的特征地址了。

函数局部变量初始化为一片0xCCCCCCCC,符合debug版的特性,这是编译环境为我们调试程序赋予的便利。
有4片0xCCCCCCCC(如图3),说明有4个函数。

图3

18FF88、18FF48、18FED4、18FE74,貌似一串连续的栈底(如图4),形成4个栈结构,且存在函数的嵌套调用,因为四个栈堆起来,如果不是嵌套调用,一个函数执行完毕,栈空间会释放掉,调用下一个函数时,栈还在原来的位置,就不会堆起来。

图4

1.按调用约定传递参数
2.保存返回代码的地址
3.流程转移到被调方代码处
4.保存调用方的栈底
5.更新栈环境为被调函数位置
6.为局部变量申请空间
7.保存CPU环境(/Zi 稳定保存12字节)
8.执行函数体
9.恢复CPU环境
10.释放局部变量空间
11.恢复调用方的栈底
12.取出当前栈顶作为返回地址
13.如果是_stdcall或者_fastcall约定,则此时释放参数空间
14.函数返回,流程回到调用方(如果是__cdecl,则此时释放参数空间)

本图中,由于只体现了函数被调用过程,没有被执行之后的过程,所以简化为:
1.参数入栈
2.返回地址入栈
3.保存栈底
4.变量入栈
5.保存CPU环境(/Zi 稳定保存12字节)
此时,便能按图索骥,去把云里雾里的一片不知道什么鬼,变成可读的、有意义的信息吧!

要知道,main函数是程序员的入口,可不是程序的真正入口,它也是被调用的,它的调用方是mainCRTStartup。main函数有三个参数:命令行个数、命令行字符指针数组、环境变量字符指针数组。三个参数的特征是,第一个是整型十六进制值,后两个是指向堆空间的、离得不太远的两个地址(如图5)。

图5
1.参数入栈--------------------------------------01 00 00 00 B8 0F 2D 00 50 10 2D 00
2.返回地址入栈-------------------------------------------------------------------B9 12 40 00
3.保存栈底-------------------------------------------------------------------------88 FF 18 00
4.变量入栈---------------------------------------------------42 CC CC CC --0A 00 00 00
5.保存CPU环境(/Zi 稳定保存12字节)-----00 00 00 00 00 00 00 00 00 E0 FD 7E
翻译一下:
1.三个参数说明是main函数,命令行个数是1个,命令行字符指针数组和环境变量字符指针数组的首地址分别为0x002D0FB8和0x2D1050;
2.main函数返回地址是0x004012B9;
3.调用方栈底是0x0018FF88;
4.变量看形式有5个,1个int型0A 00 00 00(值为10),1个char型字符串68 65 6C 6C 00(内容为“hell”,00为字符串结束字符‘\0’),1个double型33 33 33 33 33 33 2F 40(值为15.6),1个float型00 00 28 41(值为10.5),1个char型0x42(值为‘B’);
5.当前CPU三个寄存器的值分别为0x7EFDE000、0x00000000、0x00000000。
从main函数自下至上,三个函数暂时称作fun1、fun2、fun3(先声明,再使用)。

fun1被main函数调用,栈结构如图6。

图6
1.参数入栈--------------------------------------------------------------------------2C FF 18 00
2.返回地址入栈---------------------------------------------------------------------02 11 40 00
3.保存栈底--------------------------------------------------------------------------48 FF 18 00
4.变量入栈-------------------------------------------------------CD CC 5C 41 0A 00 00 00
5.保存CPU环境(/Zi 稳定保存12字节)------48 FF 18 00 00 00 00 00 00 E0 FD 7E
翻译一下:
1.参数是0x0018FF2C,是指向main函数char型变量的地址,由此可以推断main函数的5个变量有可能是一个结构体的5个成员,否则,仅仅传地址要么造成后面的变量无意义,要么造成不合理的指针运算;
2.fun1函数返回地址是0x00401102;
3.fun1函数的调用方main函数的栈底是0x0018FF48;
4.变量有两个,1个int型0A 00 00 00(值为10),1个float型CD CC 5C 41(值是13.8f);
5.当前CPU三个寄存器的值分别为0x7EFDE000、0x00000000、0x0018FF48,此时fun1的栈顶被更新为其栈底保存的值。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 18
支持
分享
打赏 + 2.00雪花
打赏次数 1 雪花 + 2.00
 
赞赏  惊澜来   +2.00 2020/11/21 感谢分享,醍醐灌顶
最新回复 (31)
雪    币: 440
活跃值: (1163)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2

我零基础,为什么看不懂

最后于 2020-8-9 20:25 被猫子编辑 ,原因:
2020-8-9 20:19
3
雪    币: 47147
活跃值: (20450)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
学了1个月逆向能有这水平还是不错的,鼓励一下,继续加油!
2020-8-9 20:32
0
雪    币: 1375
活跃值: (1062)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
kanxue 学了1个月逆向能有这水平还是不错的,鼓励一下,继续加油!
感谢您的鼓励,我会继续好好学习、天天向上的!
2020-8-9 20:53
0
雪    币: 1375
活跃值: (1062)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
那是我写的还需要改进
2020-8-9 20:54
0
雪    币: 7009
活跃值: (3317)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
后辈威武,壮哉科锐。
2020-8-9 22:04
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
给学妹点个赞
2020-8-9 22:23
0
雪    币: 34
活跃值: (250)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学妹学的很认真哦  加油
2020-8-9 22:45
0
雪    币: 287
活跃值: (583)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
我0基础为什么看不懂
2020-8-9 22:51
3
雪    币: 1375
活跃值: (1062)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
感谢老师教得好
2020-8-9 22:56
0
雪    币: 1375
活跃值: (1062)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
多谢鼓励
2020-8-9 22:57
0
雪    币: 4883
活跃值: (18890)
能力值: ( LV13,RANK:317 )
在线值:
发帖
回帖
粉丝
12
点赞,加油!
2020-8-10 08:22
0
雪    币: 881
活跃值: (9856)
能力值: ( LV13,RANK:385 )
在线值:
发帖
回帖
粉丝
13
学妹
2020-8-10 09:06
0
雪    币: 1819
活跃值: (2733)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14

学姐 很棒

最后于 2021-8-7 05:43 被旺仔_小可爱编辑 ,原因:
2020-8-10 09:32
1
雪    币: 168
活跃值: (152)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
15
虽然我看不懂,但是学妹的这篇文章确实厉害了!
加油!
2020-8-10 13:59
0
雪    币: 1
活跃值: (423)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
2020-8-10 17:14
0
雪    币: 282
活跃值: (236)
能力值: ( LV3,RANK:37 )
在线值:
发帖
回帖
粉丝
17
我找回密码啦~支持支持,写的灰常好~~
2020-8-10 18:00
0
雪    币: 10845
活跃值: (1054)
能力值: (RANK:190 )
在线值:
发帖
回帖
粉丝
18
学妹学得真快
2020-8-10 23:38
0
雪    币: 90
活跃值: (51)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
我们做个好朋友吧、嘻嘻嘻
2020-8-11 00:28
0
雪    币: 2882
活跃值: (1279)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yjd
20
这是手撕二进制,"0基础"
2020-8-11 01:04
0
雪    币: 300
活跃值: (2477)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
感谢分享
2020-8-11 09:16
0
雪    币: 3496
活跃值: (749)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
不错,赞\(≧▽≦)/赞
2020-8-11 09:48
0
雪    币: 1420
活跃值: (2171)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
23
学妹???
2020-8-11 10:25
0
雪    币: 281
活跃值: (201)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
24
不明觉厉.jpg
2020-8-12 16:28
0
雪    币: 3623
活跃值: (656)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
25
这也太抽象了
2020-8-12 16:43
0
游客
登录 | 注册 方可回帖
返回
//