C#でLua: LuaInterfaceの後継NLua

C#Luaを利用するためのライブラリを探していたところ、LuaInterfaceというものが一般的に使われているということがわかった。

luainterface - A library for integration between the Lua language and Microsoft .NET platform's Common Language Runtime (CLR) - Google Project Hosting

公式サイトに行ってみたところ、LuaInterfaceからforkされたNLuaというライブラリを作者がおすすめしていたので、そちらを使ってみることとした。プロジェクトページによると、Android/iOS/WPなど様々な環境で動作するらしい。

NLua/NLua · GitHub

ダウンロード

NLua/NLua · GitHub
README.mdに記載されているダウンロードボタンからダウンロードすれば良い

参照の追加

Visual Studio 2012: プロジェクト→参照の追加→参照

基本的な使い方

基本的にLuaInterfaceと同様の使い方が可能のようだ。
おさきまっくら [C#][Lua]Luaのあれこれおぼえがき
2012-03-31 - 結果だけでなく過程も見てください

ただ一点注意として、Lua5.2を利用しているということが挙げられる。
ネット上にある多くのLuaInterfaceに関する記事はLua5.1向けに書かれており、そのままだと動かないことがある。

Lua5.1とLua5.2の違いについては以下のサイトを参照
Lua 5.1とLua5.2の違い - エンジニアのソフトウェア的愛情

staticメゾットの登録

あるクラスのstaticメゾットを登録したい場合以下のようにすれば良い。

オーバーロードがあるメゾットの登録

オーバーロードがあるメゾットはGetMethodの第二引数に対象メゾットの引数のタイプを指定してあげて特定すれば良い

モジュール

Lua5.2からはmoduleというものが使えなくなったらしい。
少し調べてみたが、代替機能が見つからなかったので、次のサイトを参考にmoduleを代替した。
Luaのモジュールを穴が空くまで見つめてみる - プログラミングの魔物

読み込み先ディレクトリを追加するにはpackage.pathを使う
requireのパスあれこれ | -闘いたい過去-
(注) ただし上記のサイトに書かれてるobj.getinfoはLua5.2で動かないっぽい

とりあえずこんな感じで使ってる

他プロセスのメモリを読む(C++編)

メモリの読み込み自体はWin32APIのReadProcessMemoryを使えば良い。
ただし、WindowsVista以降ではASLR(Address space layout randomization)機能により、実行ファイルなどの配置アドレスがランダムになっている。そのため、まずはその実行ファイルのメインモジュールの先頭アドレスを取得し、そこからの相対位置指定でメモリを読むことにする。


メインモジュールの先頭アドレスはPEB(Process Enviroment Block)内のImageBaseAddressの値を見れば良い。
(その他にGetModuleHandler(NULL)でも取得できるらしい)

ターゲットプロセスのハンドルを取得

プロセスのベースアドレスを取得

プロセスハンドルからNtQueryInformationProcessを使ってPROCESS_BASIC_INFORMATIONを取得する。
その中にPBEのベースアドレスがあるので、それを利用してReadProcessMemoryを行う

PBE構造体

既存の定義ではImageBaseAddressが載っていないので、以下の構造体定義を行う。

ベースアドレス取得

実際にメモリ内容を取得してみる

ドライバの自己署名

ドライバの自己署名で一部詰まったので、ここに残しておく

自己署名参考サイト

Microsoft Technet
http://technet.microsoft.com/ja-jp/library/dd919238(v=ws.10).aspx

詰まったところと解決法

inf2catが見つからない

inf2catにパスが通ってなかった。環境変数に追加するか、直接以下の場所で実行する

c:\Program Files (x86)\Windows Kits\8.0\Tools\x64> inf2cat /driver:"c:\tmp\vmulti" /os:7_x64

inf2catが見つからない(2)

cmd.exeだと実行できないっぽい?のでVSのコマンドプロンプトで起動する

スタートメニュ → すべてのプログラム → Microsoft Visual Studio 2012
→ Visual Studio Tools→ VS2012 x64 Native Tools コマンド プロンプトを開く

inf2catを実行すると「<ファイル名> does not exist」というエラーがでる

下記のように実行するとエラーが出た。

c:\Program Files (x86)\Windows Kits\8.0\Tools\x64> inf2cat /driver:"c:\tmp\vmulti\vmulti.inf" /os:7_x64
c:\tmp\vmulti\vmulti.inf does not exist.

inf2catのdriverに指定するのは、.infファイル名ではなく、.infファイルがあるフォルダパスである。
直感的ではないので要注意

inf2catを実行すると「Parameter format not correct.」というエラーがでる

c:\Program Files (x86)\Windows Kits\8.0\Tools\x64> inf2cat /driver:"c:\tmp\vmulti\" /os:7_x64
Parameter format not correct.

先ほどのエラーと異なるので、.infの読み込みまではいったと勘違いしてしまったため、かなり時間を消費してしまった。
結論としては、指定したパスの最後が「\」で終わってることが原因であった。
「\」を削除して「c:\tmp\vmulti」に変更したら問題なくなった。

inf2catを実行すると「DriverVer set to incorrect date」というエラーがでる

c:\Program Files (x86)\Windows Kits\8.0\Tools\x64> inf2cat /driver:"c:\tmp\vmulti" /os:7_x64
......................
Signability test failed.

Errors:
22.9.7: DriverVer set to incorrect date (postdated DriverVer not allowed) in \vmulti.inf. The current date (UTC) is 9/2/2013.

今回は、エラーメッセージが親切である。.infファイル内のDriverVerを表示されている日時(UTC)より前に修正してやれば良い。
.infを自動生成した時に、DriverVerにJSTでの現在時刻が挿入されたことが原因であった。
DriverVerにはUTCで記述する必要がある