【问题标题】:Getting Version of already loaded DLL (Windows API)获取已加载 DLL 的版本(Windows API)
【发布时间】:2015-12-18 03:14:02
【问题描述】:

好的,在加载之前获取 dll 的文件版本很容易。我正在使用 GetFileVersionInfoSize + GetFileVersionInfo + VerQueryValue,它就像一个魅力。

但是如果 dll 已经加载了怎么办?我知道您可以使用 LoadLibrary + IMAGE_DOS_HEADER + IMAGE_NT_HEADERS 来检索某些信息,例如函数名称等。我注意到 IMAGE_OPTIONAL_HEADER 具有不同的版本字段,例如 MajorImageVersion 和 MinorImageVersion 等。我尝试了几乎所有内容,但这些字段并不总是设置和当它们存在时,它们与 GetFileVersionInfo 返回的值不匹配。所以我猜我找错地方了。有什么想法吗?

【问题讨论】:

  • GetModuleFileName 会给你文件名。 LoadLibrary首先如果你不知道加载的dll的HMODULE。
  • 谁说过文件名?我正在尝试获取已加载的 dll 的文件版本。
  • 一旦你有了名字,你就可以使用你已经拥有的任何GetFileVersionInfoSize + GetFileVersionInfo + VerQueryValue 代码。就获取版本信息而言,.dll 是否已经加载并不重要。
  • 是的,我刚刚明白你想说的话,正准备编辑我的评论。我已经知道文件名,所以调用 GetFileVersionInfo 不会有问题。但这不是我正在寻找的解决方案。加载 dll 时,其所有信息都已存储在内存中。我试图找出在内存中哪里可以找到文件版本信息。但也许我错了,也许你不能通过简单地使用 IMAGE_NT_HEADERS 等来访问它。
  • 加载 .dll 后,它已经被映射到进程的内存空间,并且(其中一些)已经从磁盘读取。一旦您通过GetFileVersionInfo 访问同一个文件,它将访问相同的内存缓存,因此以官方方式执行此操作几乎不会受到任何惩罚。

标签: winapi dll version loadlibrary


【解决方案1】:

加载 DLL 后,您可以这样做:

  1. 使用GetModuleHandle() 获取DLL 的句柄。

  2. 将该句柄与FindResource()/LoadResource()/LockResource() 一起使用以访问DLL 的RT_VERSION 资源数据。

  3. 将该资源数据复制到您分配的内存块(重要!)。使用SizeofResource() 知道要分配和复制多少字节。

  4. 将该内存块传递给VerQueryValue() 以访问其VS_FIXEDFILEINFO 结构,其中包含DLL 的版本号。

第 3 步很重要,因为VerQueryValue() 需要访问可写内存(它依赖于在内存内容中进行的各种修复)。 LockResource() 返回的内存指针指向只读内存。如果尝试直接使用资源指针,VerQueryValue() 会崩溃。

【讨论】:

  • 感谢您的帮助。这听起来是个不错的方法。然而,我想知道是否有一个“更简单”的,而不需要额外的 api 调用。看起来您可以通过将 IMAGE_DIRECTORY_ENTRY_RESOURCE 常量传递给 IMAGE_OPTIONAL_HEADER 中的 DataDirectory 字段来访问资源数据。现在我要玩一下它并尝试让它工作。
  • 使用我描述的技术比直接深入 PE 标头更容易、更安全。导航 PE 很复杂。
  • 是的,我知道,但我试图更好地了解整个 pe 的疯狂。如果您已经知道答案,这很容易,但我想我只是喜欢挑战自己。
  • 听起来你想探索PE文件。有很多关于这方面的好文章。随意阅读它们。但请不要将其与您提出的问题的答案混为一谈。这是哪个。
  • 嗯,Remy Lebeau 的方法显然没有任何问题。它就像一个魅力。但我只是喜欢有各种选择。这取决于您使用叉子或勺子的食物。编程也是如此。你学得越多,你在不同情况下就会做出更好的选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
  • 1970-01-01
  • 2011-12-29
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多