分类: C/C++
2008-03-14 14:51:39
本文前面讨论了用几种不同的方法来获取进程及其相关 DLLs 的信息,例如通过 PSAPI、NTDLL 以及TOOLHELP32 库提供的 APIs,在这一部分,作者给出了几种获得系统级信息的非常规方法,你可以轻松将它们集成到自己的工具包中。本文范例包含三个实用工具:
本文前面的部分讨论了如何用有着良好文档描述的 API 函数来获取运行进程列表以及它们加载的 DLLs 信息。接下来我将用不同的方法,或者说是非正式的方法来获取系统级信息,首先,我将深入分析 Win32 调试 API 以及 Windows 加载器(Windows Loader)提供的痕迹来揭示给定进程是如何加载 DLL 的。我将借助我的 CApplicationDebugger 可重用类,用几种不同的方法来分析 DLL 重定位的原因。 typedef struct _LOAD_DLL_DEBUG_INFO { HANDLE hFile; LPVOID lpBaseOfDll; DWORD dwDebugInfoFileOffset; DWORD nDebugInfoSize; LPVOID lpImageName; WORD fUnicode; } LOAD_DLL_DEBUG_INFO, *LPLOAD_DLL_DEBUG_INFO;被加载的DLL的路径名就包含在此内存块中。MSDN 在线帮助文档是这样描述 IpImageName 的:
OnLoadDLLDebugEvent 可重写方法将上述解释翻译为在 99% 的情况下可工作的纯 C++ 代码。其余 1% 不工作的情况是指加载 ntdll.dll:这种情况既是文档中所说的第一个 DLL 事件。即使延迟到下一个被调试程序事件发生时(参见 CLoadLibraryDebugger 的 OnDebugEvent)才获取路径名。在文档的描述中,可以调用 SearchPath 从模块名获得全路径名,“system32”对于 ntdll.dll 并不感到惊讶。这个 API 函数使用与 LoadLibrary 同样的算法在文件系统中查找某个 DLL。从理论上讲,因为它是由调试器调用的,有可能返回的文件并不是被调试程序加载的那个文件——例如,在调试器文件夹中存在另外一个版本的 ntdll.dll。在实际应用中,ntdll.dll 得不到打补丁的机会,并且被拷贝到了某个与 system32 不同的目录。 参考资料 在后续文章中,我将介绍 Windows Loader,它知道一切。 | |
作者简介 Christophe Nasarre 是法国 Business Objects 公司的技术经理(technical manager)。他在 Windows 平台上(3.0 以后的版本)编写了若干个低级工具。他的联系方式:cnasarre@montataire.net. . | |
本文出自 的 期刊,可通过当地报摊获得,或者最好是 |