我的目标是调用 Windows 的GetModuleInformation函数来获取MODULEINFO结构。这一切都很好。问题是由于我想对LPVOID lpBaseOfDll
作为MODULEINFO
.
这是我在 Lua 中调用函数的代码:
require "luarocks.require"
require "alien"
sizeofMODULEINFO = 12 --Gotten from sizeof(MODULEINFO) from Visual Studio
MODULEINFO = alien.defstruct{
{"lpBaseOfDll", "pointer"}; --Does this need to be a buffer? If so, how?
{"SizeOfImage", "ulong"};
{"EntryPoint", "pointer"};
}
local GetModuleInformation = alien.Kernel32.K32GetModuleInformation
GetModuleInformation:types{ret = "int", abi = "stdcall", "long", "pointer", "pointer", "ulong"}
local GetModuleHandle = alien.Kernel32.GetModuleHandleA
GetModuleHandle:types{ret = "pointer", abi = "stdcall", "pointer"}
local GetCurrentProcess = alien.Kernel32.GetCurrentProcess
GetCurrentProcess:types{ret = "long", abi = "stdcall"}
local mod = MODULEINFO:new() --Create struct (needs buffer?)
local currentProcess = GetCurrentProcess()
local moduleHandle = GetModuleHandle("myModule.dll")
local success = GetModuleInformation(currentProcess, moduleHandle, mod(), sizeofMODULEINFO)
if success == 0 then --If there is an error, exit
return 0
end
local dataPtr = mod.lpBaseOfDll
--Now how do I do pointer arithmetic and/or dereference "dataPtr"?
在这一点上,mod.SizeOfImage
似乎给了我期望的正确值,所以我知道正在调用函数并且正在填充结构。但是,我似乎无法对指针进行运算,mod.lpBaseOfDll
因为它是一个UserData
.
外星人文档中唯一可以解决我正在尝试做的事情的信息是:
- 指针解包
Alien 还提供了三个方便的函数,可让您取消引用指针并将值转换为 Lua 类型:
alien.tostring 接受一个用户数据(通常从具有指针返回值的函数返回),将其转换为 char*,并返回一个 Lua 字符串。您可以提供一个可选的大小参数(如果您不先在缓冲区上调用 Alien 的 strlen)。
alien.toint 获取一个用户数据,将其转换为 int*,取消引用并将其作为数字返回。如果你给它传递一个数字,它假定 userdata 是一个具有这个元素数量的数组。
alien.toshort、alien.tolong、alien.tofloat 和 alien.todouble 类似于 alien.toint,但可以与各自的类型转换一起使用。未签名的版本也可用。
我的问题是,我需要一个字节一个字节地去,而且没有任何alien.tochar
功能。此外,更重要的是,这仍然不能解决我能够获取基地址之外的元素的问题。
- 缓冲器
创建缓冲区后,您可以将其传递给字符串或指针类型的任何参数。
...
您还可以将缓冲区或其他用户数据传递给您的结构类型的新方法,在这种情况下,这将是您正在创建的结构实例的后备存储。这对于解压缩 C 函数返回的外部结构很有用。
这些似乎表明我可以使用 analien.buffer
作为MODULEINFO
's的论点LPVOID lpBaseOfDll
。缓冲区被描述为字节数组,可以使用以下符号进行索引: buf[1]
,buf[2]
等。此外,缓冲区按字节排列,因此这将理想地解决所有问题。(如果我理解正确的话)。
不幸的是,我在任何地方都找不到任何这样的例子(不在文档、stackoverflow、谷歌等中),所以我不知道该怎么做。我尝试了几种语法变体,但几乎每个都给出了运行时错误(其他的根本无法按预期工作)。
关于我如何能够mod.lpBaseOfDll
通过取消引用和指针算术逐字节(C char-by-char)的任何见解?