因此,根据我对Windows应用程序的了解,据我所知,在加载库时,IAT充满了正确的地址(如果我输入错了,请更正我)

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

,所以这意味着默认情况下,windows在加载时填充了IAT中的所有地址时间,但是Linux不正确吗?

,如果是的话,这对Linux来说不是安全隐患吗?因为在Windows中,IAT位于rdata节内并且是只读的,但是在Linux中则是读写的!例如,如果我们使用格式字符串漏洞利用,那么我们可以在GOT上编写代码,但是这不会在Windows中发生,我在这里遗漏了什么吗?

#1 楼

您的理解是正确的:


PE的IAT由系统加载程序解决,并且之后可以设为只读。
ELF的GOT条目最初指向PLT存根,并被覆盖

可写GOT确实是已知的漏洞来源,这就是为什么引入了诸如RELRO这样的缓解措施的原因。

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

评论


但是,为什么他们默认不加载整个东西呢?考虑使用Windows并不会对性能产生重大影响,为什么不这样做并提高安全性呢?

– OneAndOnly
19年11月14日在14:57