首页
社区
课程
招聘
[讨论]c语言栈学习记录和疑问
发表于: 2021-12-16 21:39 7967

[讨论]c语言栈学习记录和疑问

2021-12-16 21:39
7967

栈结构分析

前言

本人最近刚刚开始学习逆向,纯纯的逆向小白。此贴只做记录,如有不对烦请指正,万分感谢!

已知内容

代码编译的语言为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);
}
  1. 全部未初始化变量都是cc,判断编译环境为Debug版本
  2. 编译时可能关闭了随机地址,或者编译后修改了pe头为固定地址

疑惑

原图中在1A0000处出现了main的栈底和返回地址,不清楚是什么,有了解的大佬麻烦指点指点。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 177
活跃值: (335)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
main的上层调用函数,退出的地方下个断点单步出去就能看到了
2021-12-17 07:26
0
游客
登录 | 注册 方可回帖
返回
//