4

我的目标是调用 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.

外星人文档中唯一可以解决我正在尝试做的事情的信息是:

  1. 指针解包

Alien 还提供了三个方便的函数,可让您取消引用指针并将值转换为 Lua 类型:

alien.tostring 接受一个用户数据(通常从具有指针返回值的函数返回),将其转换为 char*,并返回一个 Lua 字符串。您可以提供一个可选的大小参数(如果您不先在缓冲区上调用 Alien 的 strlen)。

alien.toint 获取一个用户数据,将其转换为 int*,取消引用并将其作为数字返回。如果你给它传递一个数字,它假定 userdata 是一个具有这个元素数量的数组。

alien.toshort、alien.tolong、alien.tofloat 和 alien.todouble 类似于 alien.toint,但可以与各自的类型转换一起使用。未签名的版本也可用。

我的问题是,我需要一个字节一个字节地去,而且没有任何alien.tochar功能。此外,更重要的是,这仍然不能解决我能够获取基地址之外的元素的问题。

  1. 缓冲器

创建缓冲区后,您可以将其传递给字符串或指针类型的任何参数。

...

您还可以将缓冲区或其他用户数据传递给您的结构类型的新方法,在这种情况下,这将是您正在创建的结构实例的后备存储。这对于解压缩 C 函数返回的外部结构很有用。

这些似乎表明我可以使用 analien.buffer作为MODULEINFO's的论点LPVOID lpBaseOfDll。缓冲区被描述为字节数组,可以使用以下符号进行索引: buf[1]buf[2]等。此外,缓冲区按字节排列,因此这将理想地解决所有问题。(如果我理解正确的话)。

不幸的是,我在任何地方都找不到任何这样的例子(不在文档、stackoverflow、谷歌等中),所以我不知道该怎么做。我尝试了几种语法变体,但几乎每个都给出了运行时错误(其他的根本无法按预期工作)。

关于我如何能够mod.lpBaseOfDll通过取消引用和指针算术逐字节(C char-by-char)的任何见解?

4

1 回答 1

1

我需要逐字节进行,并且没有 alien.tochar 函数。

听起来alien.tostring你有没有涵盖:

alien.tostring 接受一个用户数据(通常从具有指针返回值的函数返回),将其转换为 char*,并返回一个 Lua 字符串。您可以提供一个可选的大小参数(如果您不先在缓冲区上调用 Alien 的 strlen)。

Lua 字符串可以包含任意字节值,包括 0(即它们不像 C 字符串那样以 null 结尾),因此只要将 size 参数传递给alien.tostring您就可以将数据作为字节缓冲区(也称为 Lua 字符串)取回,然后执行无论你喜欢什么字节。

听起来你不能告诉它从给定指针地址的任意偏移量开始。如果文档没有告诉您,最简单的确定方法是查看源代码。添加偏移参数可能很简单。

于 2015-04-27T22:35:26.160 回答