如何通过GCC或手动链接调整GOT内存偏移量以防护ret2dlresolve攻击
调整GOT偏移防护ret2dlresolve的GCC原生实现方案
最优方案(ld 2.30及以上版本支持)
GNU ld 2.30开始原生提供--plt-got-gap参数,直接指定PLT段与GOT段的固定间距,无需编写完整链接脚本,也不会破坏libc的正常链接规则,天然满足GOT偏移独立于可执行段基址的要求。
编译时直接添加对应参数透传给链接器即可:
gcc 你的源码文件.c -o 目标程序 -Wl,--plt-got-gap=你需要的间距字节数
- 示例:如果需要PLT与GOT间距为65536字节(0x10000),参数改为
-Wl,--plt-got-gap=65536即可。
兼容旧版本ld的方案
如果使用的ld版本低于2.30不支持上述参数,可使用ld的增量链接脚本特性,仅追加GOT段的位置规则,不覆盖默认链接逻辑,不会影响libc链接:
- 新建名为
got_adjust.lds的脚本片段,内容如下:
SECTIONS { .got ALIGN(0x1000) : AT(ADDR(.plt) + SIZEOF(.plt) + 你需要的间距字节数) { *(.got) } } INSERT AFTER .plt;
- 编译时将该脚本作为输入文件传给GCC即可:
gcc 你的源码文件.c got_adjust.lds -o 目标程序
效果验证
编译完成后可通过以下命令确认配置生效:
- 查看PLT与GOT段的偏移差是否符合预期:
readelf -S 目标程序 | grep -E '.plt|.got' - 确认libc链接正常:
ldd 目标程序 - 测试程序运行无异常,确认GOT表功能正常。
注意事项
- 开启PIE保护时,可执行段基址会随机化,但PLT与GOT的固定间距不会改变,不影响ret2dlresolve的防护效果
- 建议设置的间距按内存页大小(通常为4096字节,即0x1000)对齐,避免出现内存访问异常
内容的提问来源于stack exchange,提问作者Zopazz
相关产品推荐
相关产品推荐

