当前位置 : 主页 > 网络编程 > lua >

指针 – Lua Alien – 指针算术和解除引用

来源:互联网 收集:自由互联 发布时间:2021-06-23
我的目标是调用 Windows‘ GetModuleInformation函数来获取 MODULEINFO结构.这一切都很好.问题来自于我想要对LPVOID lpBaseOfDll进行指针运算和解引用,这是MODULEINFO的一部分. 这是我在Lua中调用函数的
我的目标是调用 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 also provides three convenience functions that let you
dereference a pointer and convert the value to a Lua type:

alien.tostring takes a userdata (usually returned from a function that has a pointer return value), casts it to char*, and returns a Lua
string. You can supply an optional size argument (if you don’t Alien
calls strlen on the buffer first).

alien.toint takes a userdata, casts it to int*, dereferences it and returns it as a number. If you pass it a number it assumes the
userdata is an array with this number of elements.

alien.toshort, alien.tolong, alien.tofloat, and alien.todouble are like alien.toint, but works with with the respective typecasts.
Unsigned versions are also available.

我的问题是,我需要逐字节,并没有alien.tochar函数.而且,更重要的是,这仍然无法解决我能够获取基址之外的元素的问题.

>缓冲区

After making a buffer you can pass it in place of any argument of
string or pointer type.

You can also pass a buffer or other userdata to the new method of your
struct type, and in this case this will be the backing store of the
struct instance you are creating. This is useful for unpacking a
foreign struct that a C function returned.

这似乎表明我可以使用alien.buffer作为MODULEINFO的LPVOID lpBaseOfDll的参数.缓冲区被描述为字节数组,可以使用这种表示法对其进行索引:buf [1],buf [2]等.此外,缓冲区按字节进行,因此这将理想地解决所有问题. (如果我正确理解这一点).

不幸的是,我找不到任何这方面的例子(不是在docs,stackoverflow,谷歌等),所以我不知道如何做到这一点.我尝试了一些语法变体,但几乎每一个都会产生运行时错误(其他人根本没有按预期工作).

有关如何通过解引用和指针算法在mod.lpBaseOfDll中逐字节(C char-by-char)的任何见解?

I need to go byte-by-byte, and there is no alien.tochar function.

听起来像alien.tostring你有没有:

alien.tostring takes a userdata (usually returned from a function that has a pointer return value), casts it to char*, and returns a Lua string. You can supply an optional size argument (if you don’t Alien calls strlen on the buffer first).

Lua字符串可以包含任意字节值,包括0(即它们不像C字符串那样以空值终止),因此只要将size参数传递给alien.tostring,就可以将数据作为字节缓冲区返回,即Lua字符串,并用字节做任何你喜欢的事情.

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

网友评论