私の目標は、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 型に変換できる 3 つの便利な関数も用意されています。
Alien.tostring はユーザーデータ (通常はポインターの戻り値を持つ関数から返されます) を受け取り、それを char* にキャストして、Lua 文字列を返します。オプションの size 引数を指定できます (Alien が最初にバッファで strlen を呼び出さない場合)。
Alien.toint は userdata を受け取り、それを int* にキャストし、逆参照して数値として返します。数値を渡すと、ユーザーデータがこの要素数の配列であると想定されます。
Alien.toshort、エイリアン.tolong、エイリアン.tofloat、エイリアン.toダブルは、エイリアン.tointに似ていますが、それぞれの型キャストで動作します。無印版もご用意しております。
それらに関する私の問題は、バイトごとに移動する必要があり、alien.tochar
機能がないことです。また、さらに重要なことに、これでもベース アドレスの外にある要素を取得できるという問題は解決されません。
- バッファ
バッファを作成した後、文字列またはポインタ型の任意の引数の代わりに渡すことができます。
...
バッファまたは他のユーザーデータを構造体型の新しいメソッドに渡すこともできます。この場合、これは作成している構造体インスタンスのバッキング ストアになります。これは、C 関数が返した外部構造体をアンパックするのに役立ちます。
これらは、のalien.buffer
引数としてan を使用できることを示唆しているようです。また、バッファーはバイト配列として記述され、 、 などの表記法を使用してインデックスを付けることができます 。さらに、バッファーはバイト単位で処理されるため、これによりすべての問題が理想的に解決されます。(これを正しく理解している場合)。MODULEINFO
LPVOID lpBaseOfDll
buf[1]
buf[2]
残念ながら、この例はどこにも見つかりません (ドキュメント、stackoverflow、Google などにはありません)。そのため、これを行う方法がわかりません。構文のいくつかのバリエーションを試しましたが、ほぼすべての構文で実行時エラーが発生します (他の構文は単に期待どおりに動作しません)。
mod.lpBaseOfDll
逆参照とポインター演算を介してバイト単位 (C の文字単位) に移動する方法についての洞察はありますか?