我已经完成了SO question1和SO question2但是它们对我的简单问题更具描述性,并且在这里它是:
我有一个动态链接到共享对象(.dll,.so或其他!)的应用程序。我知道工具链在我们的应用程序中留下了一个 stub ,它将由动态链接器填充。票价足够!!
我没得到的:
1)存根会是什么样的(我知道这是一种奇怪的方式)?我可以
猜测它是我们应用程序的入口点,但它是我们所说的
的后门?
2)假设我们正在寻找函数printf()
的目标代码,但是
我们链接到的动态库,比如mylib.dll
包含对象
printf()
的代码,但不限于此。当链接发生时
链接器足够聪明,可以单独或将复制printf()
的目标代码
它将整个动态库复制到应用程序?
还是我完全糊涂了?
答案 0 :(得分:1)
链接DLL时,链接器只在PE文件的导入目录中创建一个条目。没有代码复制,因为这将不必要地复制代码。相反,链接器将创建一个条目,告诉PE加载器要加载什么。
例如,如果您使用foo_bar
中的函数foo.dll
,则链接器会插入导入描述符(IMAGE_IMPORT_DESCRIPTOR),该描述符指定要加载的DLL的名称(foo.dll
)和函数描述符(IMAGE_THUNK_DATA),指定函数的名称(foo_bar
)。当编译调用foo_bar
的代码时,编译器实际上生成一条从IMAGE_THUNK_DATA条目调用地址的指令。因此,当您的可执行文件运行时,PE加载程序将检查导入描述符并加载foo.dll
,然后检查函数描述符并从foo.dll
获取这些函数的地址,并将地址放在IMAGE_THUNK_DATA结构中。之后,控制权转移到您的应用程序,对foo_bar
的调用将起作用,因为它现在指向foo_bar
的地址。
答案 1 :(得分:0)
DLL是一个自身存在的实体。当您使用导入库时,我将在加载时加载到您的进程中。 Windows API函数LoadLibrary和GetProcAddress还允许在运行时加载DLL。在任何情况下,DLL都不会被更改。如果只调用该函数的一个子集,它仍然提供所有函数。
链接器不会更改DLL。它只是将存根代码添加到使用DLL函数的程序中。存根