【发布时间】:2015-07-04 04:47:51
【问题描述】:
我的目标是调用 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 Documentation 中唯一可以解决我想要做的事情的信息是:
- 指针解包
Alien 还提供了三个方便的功能,让您 取消引用指针并将值转换为 Lua 类型:
alien.tostring 接受一个用户数据(通常从具有指针返回值的函数返回),将其转换为 char*,并返回一个 Lua 细绳。你可以提供一个可选的大小参数(如果你没有 Alien 首先在缓冲区上调用 strlen)。
alien.toint 获取用户数据,将其转换为 int*,取消引用并将其作为数字返回。如果你传递一个数字,它假定 userdata 是一个包含此数量元素的数组。
alien.toshort、alien.tolong、alien.tofloat 和 alien.todouble 与 alien.toint 类似,但可以使用各自的类型转换。 也提供未签名的版本。
我的问题是,我需要逐个字节,并且没有alien.tochar 函数。此外,更重要的是,这仍然不能解决我能够获取基地址之外的元素的问题。
- 缓冲区
创建缓冲区后,您可以将其传递给 字符串或指针类型。
...
您还可以将缓冲区或其他用户数据传递给您的新方法 struct 类型,在这种情况下,这将是 您正在创建的结构实例。这对于打开包装很有用 C 函数返回的外部结构。
这些似乎表明我可以使用alien.buffer 作为MODULEINFO 的LPVOID lpBaseOfDll 的参数。缓冲区被描述为字节数组,可以使用以下符号进行索引:buf[1]、buf[2] 等。此外,缓冲区按字节排列,因此这将理想地解决所有问题。 (如果我理解正确的话)。
不幸的是,我在任何地方都找不到任何示例(不在文档、stackoverflow、Google 等中),所以我不知道该怎么做。我尝试了几种不同的语法,但几乎每一种都会出现运行时错误(其他的根本无法按预期工作)。
关于我如何通过取消引用和指针算法逐字节(C 字符)遍历mod.lpBaseOfDll 有什么见解吗?
【问题讨论】: