存根在可执行文件中

Stub in an executable

我已经完成了 SO question1 and SO question2,但它们更能描述我的简单问题,这里是:

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

我没有得到的:

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

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

还是我完全糊涂了?

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

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

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

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

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

的地址