🎨 颜色标记说明

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

返回:网络安全知识库 · 上一节:标志寄存器 · 下一节:内存管理与端序

内存是什么

内存(Memory)是 CPU 执行程序时临时保存代码和数据的空间。站在程序视角看,它更像一排连续编号的存储单元:编号是地址,单元中保存的是数据

在 Windows 用户态调试器中看到的地址,通常是进程的虚拟地址,不是可以直接拿来表示物理内存条位置的物理地址。

概念 说明 示例
地址 存储单元的编号 00401000
内容 该地址当前保存的数据 55 8B EC
宽度 一次解释或访问多少位 BYTE、WORD、DWORD、QWORD
权限 页面允许的操作 读、写、执行

地址本身也是一个整数。在 32 位进程中,指针通常占 4 Byte;在 64 位进程中,指针通常占 8 Byte。

字节编址

x86/x64 使用字节编址:每个地址对应 1 Byte,相邻地址相差 1。

1
2
3
4
5
地址        内容
00401000 55
00401001 8B
00401002 EC
00401003 83

如果从 00401000 开始按 DWORD 读取,会一次取得 4 Byte;如果按 BYTE 读取,则只取得第一个字节。

易错点:地址递增 1 表示向后移动 1 Byte,不是移动 1 Bit,也不是自动移动一个 int

虚拟地址空间

Windows 会为每个进程提供相对独立的虚拟地址空间。相同数值的虚拟地址出现在两个进程中,不代表它们一定指向同一块物理内存。

一个进程常见的内存区域包括:

  • 可执行模块的代码和全局数据;
  • 线程栈;
  • 进程堆;
  • 动态链接库;
  • 内存映射文件和系统分配区域。

逆向时先判断地址属于哪个模块或区域,再解释其中的数据。只看一个裸地址,很容易把代码、指针、整数和字符串混在一起。

页面属性

操作系统以页(Page)为基本单位管理虚拟内存。页面会带有访问属性,常见组合如下:

属性 含义 常见区域
R 可读 常量、代码
W 可写 全局变量、堆、栈
X 可执行 代码段
Guard 保护页,首次访问触发异常 栈边界等
No Access 不允许访问 未提交或保护区域

不能仅凭“地址存在”就认为它可读写。访问未映射页面、向只读页写入、从不可执行页取指,都可能触发访问异常。

调试器中的观察顺序

看到一个陌生地址时,可以按下面的顺序判断:

  1. 看地址位于主模块、DLL、栈还是堆。
  2. 看该区域的页面属性和边界。
  3. 分别按 BYTE、WORD、DWORD 尝试解释数据。
  4. 检查内容是否像指针,继续跟随一次引用。
  5. 对照反汇编,确认是读取、写入还是执行。
1
mov eax, dword ptr [00403000h]

这条指令表示:把地址 00403000h 开始的 4 Byte 读入 EAX。

1
mov dword ptr [00403000h], eax

这一条则相反:把 EAX 的 4 Byte 写入该地址。

小实验

1
2
int value = 0x12345678;
int *pointer = &value;

调试时分别记录:

  • value 的数值;
  • &value 的地址;
  • pointer 自己保存的内容;
  • &pointer 的地址。

变量地址、指针保存的地址、指针变量自己的地址是三个不同概念。

学习检查清单

检查项 状态
能区分地址、内容和访问宽度 待复盘
能说明调试器中看到的通常是虚拟地址 待复盘
能判断 R、W、X 页面属性的含义 待复盘
能解释 mov eax, [address] 的读取过程 待复盘
能区分变量地址与指针变量自身地址 待复盘