一、IDA 中看到的地址:静态分析的 “偏移基准”

IDA 是静态反编译工具,显示的地址是基于 ELF 文件本身的虚拟地址(VA)相对偏移(RVA)(取决于程序是否开启 PIE 保护),核心作用是:

1. 定位关键函数 / 数据的 “偏移值”

  • 找到漏洞函数(如gets/scanf/strcpy等危险函数)的位置,确定缓冲区溢出的偏移(比如栈上返回地址距离输入点的字节数)。
  • 找到核心目标地址:比如system函数、/bin/sh字符串、main函数、exit函数等在程序 /libc 中的偏移(而非实际地址)。
  • 找到 ROP gadget 的偏移:IDA 可以通过 ROPgadget 插件或手动查找各类指令片段(如pop rdi; ret)的偏移,这是构造 ROP 链的基础。

2. 识别程序的保护机制与内存布局

  • 看程序的加载基址:如果 IDA 中.text段起始地址是0x08048000(32 位)或0x400000(64 位),说明程序未开启 PIE(位置无关执行),IDA 地址就是固定的;如果起始地址是0x00000000,说明开启了 PIE,IDA 显示的是相对偏移(需结合 pwndbg 的实际基址计算)。
  • 分析 libc 的静态偏移:如果题目给了 libc 文件,用 IDA 打开 libc 可以查到systemputsfree等函数的偏移值(比如system在 libc 中的偏移是0x45390),这是后续计算 libc 基址的关键。

3. 计算 “地址差”

  • 比如泄露了 libc 中puts函数的实际地址后,用puts实际地址 - IDA中puts的偏移 = libc基址,再用libc基址 + IDA中system的偏移 = system实际地址

二、pwndbg 中看到的地址:动态调试的 “实际地址”

pwndbg 是动态调试工具,显示的是程序运行时真实的虚拟内存地址,核心作用是验证、修正、补充 IDA 的静态分析结果:

1. 验证静态偏移的正确性

  • 调试时通过cyclic+cyclic -l确认溢出偏移:比如 IDA 估算返回地址偏移是 120 字节,pwndbg 中触发崩溃后,用cyclic -l 0x61616161验证实际偏移是否一致(避免 IDA 静态分析的误差)。
  • 断点调试:在漏洞函数处下断点(b *0x地址),查看栈布局(stack 20)、寄存器值(reg),确认返回地址、栈帧、全局变量的实际位置

2. 获取动态变化的 “基址”

  • 处理 PIE 保护:开启 PIE 的程序,每次运行加载基址随机化,pwndbg 中用vmmap查看.text段的实际起始地址(比如0x555555554000),结合 IDA 的偏移(比如0x1234),计算真实地址:0x555555554000 + 0x1234
  • 处理 ASLR 保护:libc 的加载地址随机化,pwndbg 中先泄露某个 libc 函数的实际地址(比如通过puts函数泄露puts@plt的地址),再结合 IDA 中该函数的偏移,计算 libc 基址。

3. 查看内存布局与权限

  • vmmap命令查看程序各段的实际地址和权限:比如栈的起始地址(0x7ffffffde000)、堆的地址(0x555555756000)、libc 的加载地址(0x7ffff7a0d000),确定 payload 中要覆盖的地址范围。
  • 验证 payload 是否生效:构造 exp 后,在 pwndbg 中运行,查看寄存器(如rdi是否被 ROP 链赋值为/bin/sh地址)、内存是否被正确覆盖,调试 payload 的错误(比如偏移错误、地址错误)。

三、核心场景:两类地址的结合使用

表格

程序保护机制 IDA 地址的作用 pwndbg 地址的作用 最终地址计算
无 PIE + 无 ASLR 直接作为实际地址 验证偏移是否正确 IDA 地址 = 实际地址
有 PIE + 无 ASLR 提供各函数 / 数据的偏移 查看程序加载基址 基址 + IDA 偏移 = 实际地址
无 PIE + 有 ASLR 提供 libc 函数的偏移 泄露 libc 某函数实际地址,计算 libc 基址 libc 基址 + IDA 中 system 偏移 = system 实际地址
有 PIE + 有 ASLR 提供程序和 libc 的偏移 查看程序基址 + 泄露 libc 基址 程序基址 + 程序偏移、libc 基址 + libc 偏移

示例(64 位程序,开启 PIE+ASLR):

  1. IDA 中查到:程序.textmain函数偏移是0x1122,libc 中system偏移是0x45390/bin/sh偏移是0x1b40fa

  2. pwndbg 中用vmmap查到程序加载基址是0x555555554000,泄露puts实际地址是0x7ffff7a50690

  3. 计算 libc 基址:0x7ffff7a50690 - IDA中puts偏移(0x80690) = 0x7ffff79d0000

  4. 计算实际地址:

    • main实际地址:0x555555554000 + 0x1122 = 0x555555555122
    • system实际地址:0x7ffff79d0000 + 0x45390 = 0x7ffff7a15390
    • /bin/sh实际地址:0x7ffff79d0000 + 0x1b40fa = 0x7ffff7b840fa

总结

  1. IDA 的核心价值:提供所有关键地址的静态偏移,是构造 payload 的 “基准值”,解决 “用什么偏移” 的问题;
  2. pwndbg 的核心价值:提供运行时的实际基址内存布局,验证偏移正确性,解决 “实际地址是多少” 的问题;
  3. 两者结合是 PWN 解题的核心:静态分析定偏移,动态调试定基址,基址 + 偏移 = 可直接使用的真实地址,最终构造出能精准触发漏洞的 payload。