标记为 RWX 的合法内存页?

逆向工程 x86 记忆 二进制
2021-06-19 00:29:40

在 windows 和 linux x86(包括 x86_64)的世界中,是否有任何合法的二进制文件(即由典型的编译 - 组装 - 链接流程生成的程序二进制文件,并且在二进制文件生成后没有对其进行手动编辑)在之后会有 RWX 内存页?正在加载?如果是,用例是什么?

3个回答

注意:此答案对应于原始问题

进程段权限可能因架构和实现而异。例如,预计在更新的 x86 Linux 系统上,GCC 会创建具有不可执行堆栈的二进制文件。与此相反,过去 MIPS 甚至不支持不可执行的堆栈——换句话说,每个MIPS 二进制文件都将其堆栈权限设置为 RWE。

MIPS 浮点支持要求任何不能由 FPU 直接执行的指令都由内核模拟。此仿真的一部分涉及执行落在 FP 分支指令延迟槽中的非 FPU 指令。 从 MIPS/Linux 时代开始,这是通过将指令放在用户空间线程堆栈上并在那里执行来完成的,因为指令必须在接收仿真的线程的 MM 上下文中执行。

因此,事实上的 MIPS Linux 用户空间 ABI 要求用户空间线程具有可执行堆栈这是事实上的,因为它没有写在任何地方都必须是这种情况,但这绝不是一个要求。[1]

必须开发内核补丁以支持 MIPS 可执行堆栈保护:

以下系列在 MIPS 中实现了一个可执行堆栈保护。

它设置了一个每线程的“VDSO”页面和适当的 TLB 支持。页面被设置为对用户写保护,并通过内核 VA 维护。MIPS FPU 仿真被转移到新页面,堆栈被释放以执行保护,就像 ELF 二进制初始化期间默认设置中的所有数据页面一样。真正的保护是由 GLIBC 控制的,它现在可以像在其他架构中那样进行堆栈保护,我今天了解到 GLIBC 团队已经为此做好了准备。

注意:当然,实际的执行保护取决于硬件能力。

MIPS R6 架构上的 MIPS32/64 R2 仿真需要此补丁。[2]

这是一个具体的例子,使用来自中兴路由器的 MIPS ELF 二进制文件:

$ file cspd 
cspd: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, stripped

注意段的权限GNU_STACK

$ readelf -l cspd 

Elf file type is EXEC (Executable file)
Entry point 0x59d790
There are 8 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00400034 0x00400034 0x00100 0x00100 R E 0x4
  INTERP         0x000134 0x00400134 0x00400134 0x00014 0x00014 R   0x1
      [Requesting program interpreter: /lib/ld-uClibc.so.0]
  REGINFO        0x000148 0x00400148 0x00400148 0x00018 0x00018 R   0x4
  LOAD           0x000000 0x00400000 0x00400000 0x1ef050 0x1ef050 R E 0x10000
  LOAD           0x1ef050 0x005ff050 0x005ff050 0x148e2 0x2a070 RW  0x10000
  DYNAMIC        0x000160 0x00400160 0x00400160 0x00130 0x00130 RWE 0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4    <---
  NULL           0x000000 0x00000000 0x00000000 0x00000 0x00000     0x4

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .reginfo 
   03     .interp .reginfo .dynamic .hash .dynsym .dynstr .init .text .MIPS.stubs .fini .rodata 
   04     .data.rel.ro .data .rld_map .got .sbss .bss 
   05     .dynamic 
   06     
   07     


1. Patchwork MIPS:允许 FPU 模拟器使用非堆栈区域。

2. MIPS 可执行堆栈保护

即时编译支持可能是将页面合法标记为 RWX 的原因之一。在 iOS 中,MobileSafari 是少数具有“动态代码设计”权利的 Apple 应用程序之一,该权利允许映射 RWX 页面。尽管存在潜在危险,但 JavaScript 性能太重要了,不能没有这些页面。这使得 Safari 成为攻击的理想目标。有关最近攻击 Safari 的 RWX 页面的 iOS 漏洞的更多信息,请阅读Pegasus 技术报告

似乎一些 .NET 本机二进制文件,例如System.ni.dll 有一个 RWX.xdata部分,尽管我相信它们不是由正常的编译工作流程生成的(它们由ngenAFAIK 生成),因此它们可能没有包含在当前版本的问题中。