2008-10-07 44 views

回答

1

当对象在同一个房间内加载进程(即从一个DLL)时,可能会有一些技巧可以在内存中找到DLL。例如,如果您查看虚拟方法表(vtable)中的代码指针进入活动对象,它们通常会指向DLL。然后,您可以使用一些系统调用来确定代码是哪个加载的DLL。

但是有很多潜在的缺陷。如果您必须将这些对象加载到单独的单元中,那么代码指针将指向一个存根,而不是实际的代码。另外,许多COM库实际上都在运行时提供的包装类中实现公共接口,因此很可能会在许多常见用例中给出错误信息。 (也就是说,你最终会得到运行时DLL的信息,通常是MFC或ATL)。

当一个对象被加载出过程(即从一个EXE)时,我不知道任何可行的方法来追查哪个EXE对应于活动对象。 (很明显,这些数据必须存在于你的进程或COM运行时的某个地方,但它被埋在存根之下的某个地方,并且可能取决于你正在运行的Windows的版本)。

所以,除非您正在查看一组非常有限的对象(与您在同一间公寓内加载的所有进程中),否则最好的办法是使用注册表中的注册信息查找您需要的内容。这很麻烦,因为这是可能从操作系统的版本到版本之间发生变化的事情之一,但幸运的是COM已经存在了很长时间,以至于这些年来这一切都没有改变。

给你从Component Categories Manager得到了一个对象的CLSID,你会查找对应的二进制文件,如下所示:

  1. 打开注册表项HKEY_CLASSES_ROOT\CLSID\{xxxxxxxxx-yyyyy-zzzz-aaaa-bbbbbbbbbbbbbb}其中括号内字符串的的CLSID你想找到的对象。
  2. 如果这是一个进程内对象,将会有一个名为InProcServer32的子项,其“default”REG_SZ包含您需要的DLL的完整路径。
  3. 如果这是一个超出proc的对象,将会有一个名为LocalServer32的子项,其“default”REG_SZ包含您需要的EXE的完整路径。在某些情况下,您可能不得不修剪掉这个字符串的命令行开关以获得EXE路径。
  4. 使用以前步骤中的DLL或EXE,可以在Win32中调用GetFileVersionInfo()(如果有.NET,则使用System.Diagnostics.FileVersionInfo.GetVersionInfo)以从可执行文件中检索版本信息结构,该版本信息结构中将包含版本和说明。
0

假设它只用于记录目的,获取此信息的一种方法是简单地等待所有初始化完成,然后枚举加载的模块,并将每个日志文件的详细信息转储到日志文件。

显然,这只适用于inproc对象,如果应用程序非常动态,它将不起作用,但它也会捕获非COM DLL。