针对x86_64架构,不同系统的SYSTEM_INFO dwPageSize能否做假设?
x64平台页面大小与自定义段加载的问题解答
核心结论
不能假设所有x64系统的页面大小都是4096字节或更小——部分场景下页面大小会更大,硬编码4096的逻辑会导致权限设置失败、RIP相对寻址错误。
具体原因
- Windows x64环境:默认页面大小为4KB,但支持2MB/1GB的大页面(通过系统配置或
VirtualAlloc指定MEM_LARGE_PAGES参数启用);部分服务器版Windows可能默认使用更大页面优化性能。 - Linux/UNIX x64环境:常见页面大小为4KB,但部分架构(如某些ARM64衍生架构)或自定义内核配置下,页面大小可设为8KB、16KB甚至更大。
如果编译时硬编码4096作为页面大小,当目标系统页面更大时:
- 拆分的code、cdata、静态变量段可能被合并到同一个大页面中,无法通过
VirtualProtect分别设置不同的内存保护属性。 - 编译时预设的RIP相对寻址偏移会与实际内存布局不匹配,导致访问错误。
正确处理方式
- 动态获取页面大小:加载时调用
GetSystemInfo(Windows)或sysconf(_SC_PAGESIZE)(Linux)获取目标系统的实际页面大小,以此作为内存分配和段对齐的依据。 - 段地址对齐与独立页面分配:确保每个段的起始地址对齐到系统页面大小,且段的总长度不超过单个页面(或按页面大小分配足够空间),保证各段分属独立页面。
- 动态修正RIP相对偏移:加载完成后,根据各段的实际内存地址,重新计算RIP相对寻址的偏移量,替换编译时的硬编码值。
内容的提问来源于stack exchange,提问作者Juliean
相关产品推荐
相关产品推荐

