存根在可执行文件中
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
.
的地址
我已经完成了 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
.