-
-
[讨论]c语言栈学习记录和疑问
-
发表于:
2021-12-16 21:39
7972
-
栈结构分析
前言
本人最近刚刚开始学习逆向,纯纯的逆向小白。此贴只做记录,如有不对烦请指正,万分感谢!
已知内容
代码编译的语言为c,截图时程序挂起在子程序中,环境确认为vc6.0或者vs2019两者中的一个。没有源代码,只有一张栈结构图。
原图片
分析main函数区域
上图标红色的为main函数的具体内存区域
可以看到开头有一个40 68 00 00,明显是一个单精度浮点型数字
40 68 00 00 后面一大堆未初始化的空间,可以直接跳过
19FEE0到19FEEB这一块明显是保存寄存器的值,剩下的应该都是参数了
40000000,浮点类型2.0,40800000浮点类型4.0,40680000已经在main函数内存中出现过,推断是局部变量3.625,还剩下一个41000000应该就是8.0了
004011E8和0019FF30这两个根据肯定就是main的栈底和返回地址了。
伪代码内容如下:
1 2 3 4 5 6 7 | / / void只是猜测,具体返回类型未知
void foo1( float f1, float f2, float f3, float f4);
int main()
{
float f = 3.625f ;
foo(f, 8.0 , 4.0 , 2.0 );
}
|
分析函数1
- 函数堆栈区域全部都是未使用,可以断定没有使用局部变量
- 19FE87到19FE7C为寄存器的值,其他四个应该就是下一个函数的参数了
- 40800000浮点4.0,41000000浮点8.0,40680000浮点3.625,00401179是一个地址,因为没有局部变量,推测应该是一个常量字符数组
- 0019FEC8和41E80000就是函数1的栈底和返回地址了
- 得到伪代码内容如下:
1 2 3 4 5 6 | / / void只是猜测,具体返回类型未知
void foo2(char * pStr, float f1, float f2, float f3);
void foo1( float f1, float f2, float f3, float f4)
{
foo2("", f1, f2, f3);
}
|
分析函数2
- 函数堆栈区域全部都是未使用,可以断定没有使用局部变量
- 19FE23到19FE19为寄存器值,剩下三个应该是下一个函数的参数了
- 40800000浮点4.0,自身参数f3,41E80000浮点29.0怀疑为自身参数f1*f2,00401125一个数据地址,因为没有局部变量,怀疑为字符数组常量
- 19FE68和42040000就是自身的栈底和函数返回地址了
- 得出伪代码如下:
1 2 3 4 5 | void foo3(char * pStr, float f1, float f2);
void foo2(char * pStr, float f1, float f2, float f3)
{
foo3("", f1 * f2, f3);
}
|
分析函数3
- 局部变量区域暂时没有使用,判定没有局部变量
- 19FDB4到19FDBF为保存的寄存器的值
- 004010A6应该为参数地址,因为没有使用局部变量,暂时判断为常量
- 19FE08和429A30应该就是自身的栈底和函数返回变量了
- 1A应该是下一个函数的局部变量10了
- 得出伪代码如下:
1 2 3 4 5 6 7 8 9 | / / 返回值未知,只是暂时写做void
void foo4(char * pStr)
{
int i = 10 ;
}
void foo3(char * pStr, float f1, float f2)
{
foo4("");
}
|
最终结果
伪代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | / / 返回值未知,只是暂时写做void
void foo4(char * pStr)
{
int i = 10 ;
}
void foo3(char * pStr, float f1, float f2)
{
foo4("");
}
void foo2(char * pStr, float f1, float f2, float f3)
{
foo3("", f1 * f2, f3);
}
void foo1( float f1, float f2, float f3, float f4)
{
foo2("", f1, f2, f3);
}
int main()
{
float f = 3.625f ;
foo(f, 8.0 , 4.0 , 2.0 );
}
|
- 全部未初始化变量都是cc,判断编译环境为Debug版本
- 编译时可能关闭了随机地址,或者编译后修改了pe头为固定地址
疑惑
原图中在1A0000处出现了main的栈底和返回地址,不清楚是什么,有了解的大佬麻烦指点指点。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)