LockResource() 中的数据指针不是预期的 VS_VERSION_INFO 结构

问题描述 投票:0回答:1

我想从外部 EXE 文件加载 VERSION 资源的二进制数据。这应该相当简单:

var
  hFile: HMODULE;  // File=image to load
  hR: HRSRC;  // Resource handle
  hG: HGLOBAL;  // Loaded resource
  p: Pointer;  // Actual accessible data to the resource
  sDebug: AnsiString;
  sFile: Widestring;
begin
  // Commonly known to every Windows installation, 32-bit version.
  sFile:= 'C:\Windows\SysWOW64\calc.exe';

  // WinAPI and https://stackoverflow.com/a/23035857/4299358 want both flags.
  hFile:= LoadLibraryExW( PWideChar(sFile), 0, LOAD_LIBRARY_AS_DATAFILE or LOAD_LIBRARY_AS_IMAGE_RESOURCE );

  // 2nd param=resource name/ID; 3rd param=resource type. Unlike FindResourceExA() where these are swapped.
  hR:= FindResourceA( hFile, PAnsiChar('#1'), PAnsiChar('#16') );  

  // Same results as above: returns valid handle. Just another valid way of wanting numeric IDs.
  {hR:= FindResourceA( hFile, PAnsiChar(1), PAnsiChar(16) );}

  // Both succeed in returning a valid handle and a non-empty pointer.
  hG:= LoadResource( hFile, hR );
  p:= LockResource( hR );

  // AnsiString will have the bytes $f0 $b2 $0b $00 $84 $03 $00, but not the
  // expected $bd $04 $ef $fe from VS_FIXEDFILEINFO.dwSignature after about 40 bytes.
  SetString( sDebug, PAnsiChar(p), 50 );

我一直得到有效的句柄,还有一个非

nil
指针。出于调试目的,我将字节填充到
AnsiString
中,然后查看其内容。如果我在文件中搜索这些字节,我会发现它们距离我想要的资源(文件位置 $585c0)很远 - 而且这是这些字节的唯一出现:

pointer to $585c0 in CALC.EXE

我想要的

VS_VERSION_INFO
资源后来在 $b96f0 处找到了 388 KiB(人们甚至可以发现存储 PNG 文件的前一个资源 - 请注意
IEND
块,很可能是它的图标之一)。 40 个字节后可以看到来自
$bd $04 $ef $fe
的预期字节
VS_FIXEDFILEINFO.dwSignature

actual VERSIONINFO at $b96f0

这也得到了 Resource Hacker 的证实,显示了资源在二进制文件中的位置(请参阅文件位置为“B96F0”的状态栏) - 它还确认资源的名称为

1
(与许多其他资源一样)并且是唯一的
VERSION
资源,所以我不会意外地找到不同的资源:

Resource Hacker confirms $b96f0

我错过了什么?

LockResource()
清楚地解释了:

返回值是指向资源第一个字节的指针

所以我没有遗漏要添加的偏移量。我期望这些字节包含

VS_FIXEDFILEINFO
结构,它应该位于
VS_VERSIONINFO
伪结构
的 38 字节之后(3
WORD
s + 15
WCHAR
s = 36 字节,至少带有可变填充) ).

不想想要使用

GetFileVersionInfoW()
VerQueryValueW()
,因为我想避免Windows成为中间人并且因为文件版本只是一步 - 我的目标是阅读任何资源可靠(不仅仅是那些 WinAPI 提供辅助函数的情况)。

我在Windows 7x64上使用Delphi 7,因此调试的EXE是32位的,并且加载的CALC.EXE也确保是32位的(尽管这不重要)。我也无法访问其他 32 位 EXE 文件的版本资源的预期字节。

delphi winapi delphi-7 embedded-resource fileversioninfo
1个回答
0
投票

您向

LockResource()
传递了错误的参数。您应该通过
hG
而不是
hR

© www.soinside.com 2019 - 2024. All rights reserved.