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 型に変換できる 3 つの便利な関数も用意されています。

Alien.tostring はユーザーデータ (通常はポインターの戻り値を持つ関数から返されます) を受け取り、それを char* にキャストして、Lua 文字列を返します。オプションの size 引数を指定できます (Alien が最初にバッファで strlen を呼び出さない場合)。

Alien.toint は userdata を受け取り、それを int* にキャストし、逆参照して数値として返します。数値を渡すと、ユーザーデータがこの要素数の配列であると想定されます。

Alien.toshort、エイリアン.tolong、エイリアン.tofloat、エイリアン.toダブルは、エイリアン.tointに似ていますが、それぞれの型キャストで動作します。無印版もご用意しております。

それらに関する私の問題は、バイトごとに移動する必要があり、alien.tochar機能がないことです。また、さらに重要なことに、これでもベース アドレスの外にある要素を取得できるという問題は解決されません。

  1. バッファ

バッファを作成した後、文字列またはポインタ型の任意の引数の代わりに渡すことができます。

...

バッファまたは他のユーザーデータを構造体型の新しいメソッドに渡すこともできます。この場合、これは作成している構造体インスタンスのバッキング ストアになります。これは、C 関数が返した外部構造体をアンパックするのに役立ちます。

これらは、のalien.buffer引数としてan を使用できることを示唆しているようです。また、バッファーはバイト配列として記述され、 、 などの表記法を使用してインデックスを付けることができます 。さらに、バッファーはバイト単位で処理されるため、これによりすべての問題が理想的に解決されます。(これを正しく理解している場合)。MODULEINFOLPVOID lpBaseOfDllbuf[1]buf[2]

残念ながら、この例はどこにも見つかりません (ドキュメント、stackoverflow、Google などにはありません)。そのため、これを行う方法がわかりません。構文のいくつかのバリエーションを試しましたが、ほぼすべての構文で実行時エラーが発生します (他の構文は単に期待どおりに動作しません)。

mod.lpBaseOfDll逆参照とポインター演算を介してバイト単位 (C の文字単位) に移動する方法についての洞察はありますか?

4

1 に答える 1

1

バイト単位で処理する必要がありますが、alien.tochar 関数はありません。

alien.tostringあなたがカバーしたように聞こえます:

Alien.tostring はユーザーデータ (通常はポインターの戻り値を持つ関数から返されます) を受け取り、それを char* にキャストして、Lua 文字列を返します。オプションの size 引数を指定できます (Alien が最初にバッファで strlen を呼び出さない場合)。

Lua 文字列には、0 を含む任意のバイト値を含めることができます (つまり、C 文字列のように null で終了しません)。そのため、size 引数を渡す限り、alien.tostringデータをバイト バッファー (別名 Lua 文字列) として取得できます。バイトは何でも構いません。

指定されたポインターアドレスからの任意のオフセットから開始するように指示できないようです。ドキュメントに記載されていない場合、確実に確認する最も簡単な方法は、ソースを確認することです。オフセット パラメータを追加するのはおそらく簡単です。

于 2015-04-27T22:35:26.160 に答える