利用波动性检查内存转储中的services.exe进程,我建立了一个在进程空间中加载的dll列表。 (这些模块来自InLoadOrder模块列表)

这只是摘录(完整列表:http://pastie.org/8560797):

0x5b860000 netapi32.dll
FileObject @8a3cb028, Name: \WINDOWS\system32\netapi32.dll

0x77f60000 shlwapi.dll
FileObject @8a3e0df0, Name: \WINDOWS\system32\shlwapi.dll


您可以看到在该进程中加载​​了shlwapi.dll。感谢DependencyWalker(查看services.exe的导入),我发现了shlwapi.dll是如何加载的。 (->表示导入)

netapi.dll-> dnsapi.dll-> iphlpapi.dll-> mprapi.dll-> setupapi.dll-> shlapi.dll

但是只加载netapi.dll。 dnsapi.dll未加载,在InLoadOrder模块列表中没有该条目,也没有加载上述“依赖链”中的任何其他dll。

这不仅适用于shlapi.dll,而且适用于许多其他已加载的dll。例如:shell32.dll,psapi.dll ...这两种情况都不会只发生在services.exe进程中。 >非常感谢您的帮助!

#1 楼

netapi.dll可能已经加载了dnsapi.dll以便进行一些网络检查,然后在完成时释放DLL。但是,shlwapi.dll可能由于某种原因而持有一些打开的对象的句柄,或者由于循环加载而具有非零引用计数,因此即使在其他DLL卸载后也仍保留在内存中。卸载请求不能保证一定会得到兑现,也不能阻止请求者先卸载。 user32.dll是另一个通常显示此行为的DLL。

评论


好的,我理解这一点-感谢您向我说明清楚。这使我想到另一个问题。查看由csrss.exe进程加载的dll(实际上仅导入ntdll.dll和csrsrv.dll),我在进程空间中发现了一堆其他dll,即:basesrv.dll,winsrv.dll,user32.dll sxs.dll,kernel32.dll,gdi32.dll,advapi32.dll,rpcrt4.dll。这些进口来自哪里?它们既不是ntdll.dll的依赖项,也不是csrsrv.dll的依赖项。谢谢!

–user3365
2013年12月19日14:16



从Windows XP开始,将kernel32.dll强制加载到所有进程中,以防止进程启动时崩溃(ntdll.dll依赖kernel32.dll)。 kernel32.dll依次加载gdi32.dll,advapi32.dll,rpcrt4.dll等。每个加载项可能会加载其他DLL,最终覆盖整个列表。

–彼得·弗里
2013年12月19日在22:27

我只是检查了kernel32.dll的导入,根据DependencyWalker,kernel32.dll仅依赖于ntdll.dll。

–user3365
2013年12月20日13:00

虽然在您的示例中kernel32.dll可能仅从ntdll.dll导入(Win7才是正确的-然后它也从其他DLL导入),但即使是像WinExec这样的简单API,kernel32.dll也会加载advapi32.dll,该advapi32.dll将会加载rpcrt4等

–彼得·弗里
2013年12月20日在22:42