存根于可执行文件

时间:2015-06-03 03:41:17

标签: c++ c dll

我已经完成了SO question1SO question2但是它们对我的简单问题更具描述性,并且在这里它是:

我有一个动态链接到共享对象(.dll,.so或其他!)的应用程序。我知道工具链在我们的应用程序中留下了一个 stub ,它将由动态链接器填充。票价足够!!

我没得到的:

1)存根会是什么样的(我知道这是一种奇怪的方式)?我可以 猜测它是我们应用程序的入口点,但它是我们所说的 的后门

2)假设我们正在寻找函数printf()的目标代码,但是 我们链接到的动态库,比如mylib.dll包含对象 printf()的代码,但不限于此。当链接发生时 链接器足够聪明,可以单独或将复制printf()的目标代码 它将整个动态库复制到应用程序?

还是我完全糊涂了?

2 个答案:

答案 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函数的程序中。存根

  • 将DLL加载到进程
  • 使用DLL的导入表将函数指针调整到DLL中的实际实现。