为什么ILT和IAT分开存储?

huangapple go评论61阅读模式
英文:

Why are the ILT and IAT separate tables?

问题

关于PE格式,特别是关于导入表的设计,我有一个关于IAT和ILT设计的问题:为什么它们需要分开成两个表?

据我理解,在磁盘上它们是相同的,当PE加载到内存时,IAT中的每个条目都会被加载器替换为被导入函数的实际地址。

根据PE格式

"导入地址表的结构和内容与导入查找表的相同,直到文件被绑定。在绑定过程中,导入地址表中的条目将被覆写为正在导入的符号的32位(对于PE32)或64位(对于PE32+)地址。"

我的问题是:为什么不能对ILT执行相同的操作?而不是拥有两个表,我们可以移除其中一个表,比如我们移除IAT:这样当PE加载时,ILT的条目将被实际地址替代,从而节省了不需要IAT的空间。

我一直在思考在执行过程中需要保存ILT的值的情况,但我想不出来。我相信这个设计背后一定有合理的理由。我已经阅读了msdn上的“PE格式”文章,各种博客和这里的答案,但找不到答案。

英文:

I am learning about the PE format, specifically about the design of imports, and I have a question about the design of the IAT and ILT. why do they need to be separate tables?
To my understanding, they are identical on disk, and when the PE is loaded to memory, each entry in the IAT is replaced by the loader to the actual address of the imported function. PE format:
> "The structure and content of the import address table are identical to those of the import lookup table, until the file is bound. During binding, the entries in the import address table are overwritten with the 32-bit (for PE32) or 64-bit (for PE32+) addresses of the symbols that are being imported."

my question is:
why can't this be done to the ILT instead? instead of having two tables, remove one table, lets say we remove the IAT: so now when the PE is loaded the entries of the ILT are replaced by the actual addresses, and we save space by not having the IAT.

I've been trying to think of a need to save the values of the ILT during execution but can't think of nothing. I'm sure there is a rational behind this design. I've read the "PE format" article on msdn, various blogs and answers on here but couldn't find an answer.

答案1

得分: 1

你可以使用BindImage API进行绑定。根据BindImageEx的说明:

绑定图像的过程包括计算每个导入函数的虚拟地址。计算出的虚拟地址然后保存在导入图像的导入地址表(IAT)中。因此,图像加载得快得多,特别是如果它使用了许多DLL,因为系统加载程序不必计算每个导入函数的地址。

因此,我认为这是因为绑定在加载程序加载之前将IAT重写为实际地址之前。如果DLL被更新并且实际地址发生变化,会使用ILT。这就是为什么它们有ILT和IAT的原因,我明白了。

英文:

You can bind by using BindImage API. According to BindImageEx:

>The process of binding an image consists of computing the virtual address of each imported function. The computed virtual address is then saved in the importing image's Import Address Table (IAT). As a result, the image is loaded much faster, particularly if it uses many DLLs, because the system loader does not have to compute the address of each imported function.

Therefore, I think it's because the binding rewrites the IAT to the actual address before being loaded by the loader.
If the DLL is updated, and the actual address is changed, uses ILT. That's why they have ILT and IAT, I understand.

huangapple
  • 本文由 发表于 2023年4月13日 22:49:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76006865.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定