IAT 与 GOT 地址解析:默认情况下,哪些在运行时解析,哪些在加载时解析?

逆向工程 视窗 linux 记忆 聚乙烯 小精灵
2021-06-17 11:54:46

因此,根据我对 Windows 应用程序的了解,据我所知,当加载库时,IAT 会填充正确的地址(如果我错了,请纠正我)

现在在 linux 中,他们使用 GOT,再次根据我的知识,默认情况下 GOT 会在运行时填充,这意味着我们首先跳入 PLT,然后我第一次使用函数(例如 puts)时,我们首先调用动态加载器通过跳入PLT的开头并填充GOT中的相应地址,下次我调用puts然后我进入PLT后直接跳入

所以这意味着默认情况下,windows 会在加载时填充 IAT 中的所有地址,但 linux 不会,对吗?

如果是这样,那么这对 linux 来说不是一个安全风险吗?因为在 Windows 中 IAT 位于 rdata 部分内并且是只读的,但在 linux 中是读写的!例如,如果我们有一个格式字符串漏洞,那么我们可以在 GOT 上写,但这不会发生在 Windows 中,我在这里遗漏了什么吗?

1个回答

你的理解是正确的:

  • PE 的 IAT 由系统加载程序解析,之后可以设为只读。

  • ELF 的 GOT 条目最初指向 PLT 存根,并在第一次调用时被最终地址覆盖。这意味着 GOT 需要保持可写。

Writable GOT 确实是一个已知的漏洞来源,这就是引入RELRO缓解措施的原因

请注意,PE 还可以使用延迟加载导入,其工作方式类似于 GOT+PLT(首次调用时的解析),并且可能会遇到类似问题。