【问题标题】:Stub in an executable可执行文件中的存根
【发布时间】:2015-06-03 03:41:17
【问题描述】:

我已经经历过SO question1SO question2 但它们对我的简单问题的描述性要强得多,这里是:

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

我没有得到什么:

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

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

还是我完全糊涂了?

【问题讨论】:

    标签: c++ c dll


    【解决方案1】:

    当您链接到 DLL 时,链接器只会在 PE 文件的导入目录中创建一个条目。没有代码复制,因为这将不必要地复制代码。相反,链接器将创建一个条目,告诉 PE 加载器要加载什么。

    例如,如果您使用 foo.dll 中的函数 foo_bar,链接器会插入指定要加载的 dll 名称 (foo.dll) 的导入描述符 (IMAGE_IMPORT_DESCRIPTOR) 和指定要加载的函数描述符 (IMAGE_THUNK_DATA)函数的名称 (foo_bar)。编译调用foo_bar 的代码时,编译器实际上正在生成一条指令,该指令从IMAGE_THUNK_DATA 条目中调用地址。因此,当您的可执行文件运行时,PE 加载器将检查导入描述符并加载 foo.dll,然后检查函数描述符并从 foo.dll 获取这些函数的地址,并将地址放入 IMAGE_THUNK_DATA 结构中。之后,控制权转移到您的应用程序,并且对foo_bar 的调用将起作用,因为它现在指向foo_bar 的地址。

    【讨论】:

      【解决方案2】:

      DLL 是一个为自身而存在的实体。当您使用导入库时,我将在加载时加载到您的进程中。 Windows API 函数 LoadLibrary 和 GetProcAddress 还允许在运行时加载 DLL。在任何情况下都不会更改 DLL。如果您只调用函数的子集,它仍然提供所有函数。

      链接器不会更改 DLL。它只是将存根代码添加到使用 DLL 函数的程序中。存根

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

      【讨论】:

      • 谢谢!我得到了问题第二部分的答案!入口点(存根)会是什么样子?是函数吗?
      • 链接器不添加代码来加载 dll,它只是为它们创建导入条目。
      猜你喜欢
      • 2014-01-26
      • 2017-11-23
      • 2021-10-28
      • 2015-12-28
      • 1970-01-01
      • 1970-01-01
      • 2020-07-14
      • 2018-02-09
      • 2018-04-17
      相关资源
      最近更新 更多