我们有一个包含许多(数百个)DLL 的应用程序。 EXE 直接依赖于其中的一部分(通过其导入表),而后者又依赖于另一部分(通过其导入表),依此类推。在所有这些 DLL 中,有一个是 EXE 和大多数 DLL 都依赖的。该 DLL 是应用程序启动时最先(静态)加载的 DLL 之一。
根据我所知的描述进程加载的所有来源,必须在进程的主线程上调用此 DLL 的 DLL_PROCESS_ATTACH 条目。 @MSalters 的回答和 @RbMm 对我的其他问题的评论也证实了这一点。但如果这是真的,那么如何解释我从一位同事那里收到的调试器“线程”窗口的以下快照(该快照是通过在 DLL_PROCESS_ATTACH 之后放置 MessageBox() 语句并附加 VS 调试器获得的): 在此快照中,您可以看到主线程卡在“ThreadStart”函数中,而 DLL 正在由工作线程加载。同样奇怪的是,我们看到一个调试器线程,而通常 VS 调试器不显示其线程。
如果有人有解释,我很高兴听到。
DLL可以在进程中被工作线程静态加载吗 启动?
不,不能
当工作线程加载 DLL 时。
如果线程入口点是
LoadLibraryWStub
(这与LoadLibraryW
相同) - 这意味着另一个进程调用CreateRemoteThread
,并以LoadLibraryW
作为线程启动例程。这是 dll 注入的经典方式。当然 - 可能的,您的进程中的某些代码使用 CreateThread
调用 CreateRemoteThread
或 LoadLibraryW
,但这是非常不寻常的。无论如何 - 系统/加载程序(ntdll 代码)永远不会这样做。
同样奇怪的是,我们看到一个调试器线程,而通常 VS 调试器不显示其线程。
DbgUiRemoteBreakin
- 通过调用 DbgUiIssueRemoteBreakin
创建的具有此类入口点的线程,它只需使用 DbgUiRemoteBreakin
在目标进程中创建线程。这个线程只需调用 DbgBreakPoint
并退出。 DebugActiveProcess
称为 DbgUiDebugActiveProcess
又称为 DbgUiIssueRemoteBreakin
- 所以也没什么不寻常的。在你的情况下,3个线程(包括DbgUiRemoteBreakin
)甚至几乎没有开始执行,因为等待加载器关键部分