我们可以通过检查磁盘映像(磁盘中的文件)直接查看局部变量吗?

逆向工程 视窗
2021-07-04 19:15:51

据我所知,全局变量和静态变量存储在堆内存中,而局部变量存储在堆栈内存中。我认为当我们谈论位于内存中的二进制文件(如 PE)时就是这种情况。如果这是正确的,我想知道:本地和全局变量是否直接存储在磁盘映像(磁盘中的二进制文件)中,我们可以通过检查磁盘映像直接看到它们吗?

2个回答

首先,局部变量不需要存储在堆栈中。现代编译器将首先尝试使用 CPU 寄存器来存储局部变量。

其次,堆和栈是与虚拟内存相关的术语。当操作系统创建进程时,虚拟内存开始存在。当文件仅在磁盘上时它不存在。因此,您永远无法在磁盘上看到变量。

现在,@user2073973留下了一条评论,指出变量存储在该.data部分中。这通常是正确的,但是

  • 编译器不需要生成.data节,如果他可以通过其他方式避免它。
  • 没有符号,该.data部分只是数据。您不知道哪个部分将构成变量。AB12CD34EF可能是 5 bytes 或 1 int+ 1 byte

现代操作系统上的数据存储及其适当的文件格式远比这复杂得多。

有多个位置可以存储变量,其中最主要的是:

  1. 堆栈这是通常存储小范围变量的地方,通常在函数或代码块级别定义。这些变量的分配相对“便宜”,但它们的范围有限且不灵活。堆栈的大小有些限制,分配过多的大变量可能会导致堆栈溢出崩溃。
  2. 堆允许对变量留下的范围进行更多控制和灵活性,但代价是潜在的错误(内存泄漏、堆损坏)和安全漏洞。在性能方面分配也稍微“昂贵”一些。当通过使用页面文件(在 Linux/Mac 中称为交换)来缓解 RAM 限制时,堆仅购买地址空间大小和可用 RAM 是有限的。
  3. 虚拟内存(直接)与堆非常相似,但不是使用操作系统的灵活大小的堆块分配,而是手动分配整个页面并管理它们的分区。这非常相似,很少用于日常程序。
  4. 预分配区域一些全局范围的变量(全局和静态变量存储在这里,而不是在堆上)通常分配在为变量指定的 PE 区域内。这些区域通常分为未初始化部分和已初始化部分。

最后一个,预分配区域,是唯一一种直接编码在 PE 文件中的变量存储类型,也是唯一一种可以从硬盘驱动器访问的变量存储,但只有初始值是可读的。您不能使用它来读取当前变量值(因为这些值只会存储在内存中)。