🎨 颜色标记说明

  • 粉色:特别重要、主线必掌握、优先复盘的内容。
  • 蓝色:核心概念、术语、分类名。
  • 橙色:需要关注的边界、易错点、注意事项。
  • 绿色:解释类内容、帮助理解知识点。

返回:网络安全知识库 · 上一节:内存特性 · 下一节:内存读写与寻址

内存管理的三个动作

对用户态程序来说,使用一块内存通常会经历三个阶段:

  1. 保留(Reserve)一段虚拟地址范围;
  2. 提交(Commit)页面,使其具备实际存储支持;
  3. 使用结束后释放(Release)

调试器显示的是线性的虚拟地址,但操作系统会通过页表把虚拟页映射到物理页或其他后备存储。逆向入门阶段,先掌握“进程地址空间、页面和权限”即可,不需要一开始就陷入完整分页结构。

常见内存区域

区域 主要内容 典型特征
代码区 编译后的机器指令 通常可读、可执行
全局数据区 全局变量、静态变量 生命周期接近整个进程
参数、返回地址、局部变量 每个线程独立,通常向低地址增长
动态申请的数据 生命周期由程序控制
模块映像 EXE、DLL 的映射内容 可按 PE 节区划分

同一种 C/C++ 变量并不必然位于固定区域。存储位置还会受到作用域、存储期、编译优化和链接方式影响。

端序

端序(Endianness)描述多字节数据在内存中的字节排列顺序。

Windows 常见的 x86/x64 环境使用小端序(Little Endian):低有效字节放在低地址,高有效字节放在高地址。

1
2
3
4
5
DWORD value = 0x12345678

低地址 高地址
1000 1001 1002 1003
78 56 34 12

寄存器中把这个数写作 12345678,内存窗口逐字节看到的却是 78 56 34 12

数值没有“倒过来”,改变的只是多字节数值在内存中的排列方式。

大端与小端对比

数值 0x12345678 低地址到高地址
小端序 78 56 34 12
大端序 12 34 56 78

端序只影响多字节数据。单个 BYTE 只有一个字节,不存在字节顺序问题。

从内存还原数值

假设从低地址到高地址读到:

1
34 12 00 00

按小端 DWORD 解释为:

1
0x00001234

可以按下面的方式理解:

1
2
3
4
5
0x34 × 0x100^0
+ 0x12 × 0x100^1
+ 0x00 × 0x100^2
+ 0x00 × 0x100^3
= 0x1234

字符串与端序

ASCII 字符串通常按字符顺序逐字节存放:

1
"ABCD" -> 41 42 43 44 00

如果调试器把这 4 Byte 合并成一个小端 DWORD,可能显示为 44434241。这并不表示字符串反了,而是同一组字节被按整数格式重新解释

调试观察

1
unsigned int value = 0x12345678;

在调试器中同时打开:

  • 寄存器窗口:观察寄存器中的整体数值;
  • 内存窗口:转到 &value,观察四个独立字节;
  • 监视窗口:切换十六进制和十进制显示。

网络协议和文件格式可能自行规定字节序。分析二进制文件或网络数据时,不要因为 CPU 是小端就直接假设所有字段都按小端编码。

学习检查清单

检查项 状态
能说明保留、提交和释放的区别 待复盘
能列出代码区、栈、堆和全局数据区的主要特征 待复盘
能把 0x12345678 写成小端内存字节 待复盘
能由 78 56 34 12 还原 DWORD 数值 待复盘
能解释字符串字节与整数显示结果为何不同 待复盘