使用 AND 运算符查找堆分配大小,Fermin 公式

逆向工程 视窗 调试 风袋 开发
2021-06-29 07:02:13

我遇到了这种技术,利用 Windows 调试工具的 gflags 中的 HPA 功能(堆页面分配器,称为 PageHeap)来查找堆分配的大小:

假设您在程序 X 上发现了一个 use-after-free,其中在某个时候它正在取消引用一个寄存器和一个偏移量。

你可以:

1)打开IDA查找创建对象的位置以查看分配的大小。

2) 使用页堆、windbg 并查看分配堆栈跟踪

3) Windbg !heap -p -a

或者...我今天使用的一个快速技巧,利用页面堆将对象放在页面末尾以捕获缓冲区溢出。

1:022:x86> ? 0x1000-(ebx&0x00000FFF) 求值表达式:88 = 00000058 <--- 块大小 1:022:x86>

Fermin J. Serna - @fjserna

为什么有效?

这是我的理解:

  • 每页为 0x1000 字节 (4kb)。
  • 每个小于 0x1000 的块将从页尾向后分配。
  • 因此,通过获取页​​面大小并从中减去块大小,从块地址中检索我们使用 & 运算符获得的最后 3 位数字,您将得到它的实际大小。

这似乎有点巫术,因为:

  1. 为了使减法工作,检查的分配块地址必须与 1000 对齐。HPA 是否以某种方式对齐页面中的所有内容?我没有找到任何包含足够信息的资源。HPA 是否还有其他方法可以使此公式适用?

  2. AND 运算符实际上如何使值仅返回最后 3 位数字?我不明白它的逻辑。

有没有好心人可以为我们解释一下这些事情?

0个回答
没有发现任何回复~