さちこ(ホームセンター大好き) Lua関連の説明 ●はじめに 「さちこ(ホームセンター大好き)で使えるLua」をここではSachikoC-Luaと表記します。 本ツールでは、入力された内容をUTF-8に変換して、それをLuaに渡して実行します。 よって、シフトJISにまつわる問題は発生しないはずですが、半角英数字以外の文字を処理する場合は色々と注意して下さい。 luaL_openlibsを呼び出しているので、Luaの標準ライブラリが使えます。ただし、動作結果はほとんど未確認です。 また、print("abc")みたいなのは使えません。表示したい内容はRETに代入して下さい。 アルファベット大文字で始まる文字列はSachikoC-Luaの予約語とします。変数名などの先頭はアルファベット小文字にして下さい。 検索ボタンや実行ボタンを一回押すたびに luaL_newstate()、luaL_dostring()、lua_close() を呼び出しています。 よって、変数などを保持しておくことはできません。 lua-5.2.1.tar.gz のソースを無変更のままで組み込んでいます。なので、数値はVC++のdouble型(浮動小数点 64bit)です。 SachikoC-Lua独自の部分以外は、Lua5.2.1用のドキュメントを参照して下さい。 ただし、Luaに用意されているのにSachikoC-Luaで活用できない機能もあります。 ●SachikoC-Lua マクロ SEARCH_ADDRESS_START SEARCH_ADDRESS_END それぞれ、「検索開始アドレス」「検索終了アドレス」に置き換えられます。先頭に0xが付きます。 ""の中に記述されていたり、SEARCH_ADDRESS_START_OLDなどの記述でも、単純処理で置き換えられますので注意して下さい。 ●SachikoC-Lua 関数一覧 value, succeeded = DPEEK1(address) value, succeeded = DPEEK2(address) value, succeeded = DPEEK4(address) 引数:address(数値型)読み出すアドレス 戻り値1:value(数値型)読み出し成功ならば読み出した値、読み出し失敗ならば不定値 戻り値2:succeeded(boolean型)読み出し成功ならばtrue、読み出し失敗ならばfalse ターゲットプロセスのメモリから、それぞれ{1,2,4}バイト読み出します。 リトルエンディアン形式の符号無し整数として解釈して、それをvalueに返します。 本ツールのキャッシュメモリを経由せず、直接読みます。 毎回プロセスメモリを読みに行くので、速度は遅くなります。検索時にはCPEEK系を使って下さい。 value, succeeded = CPEEK1(address) value, succeeded = CPEEK2(address) value, succeeded = CPEEK4(address) 本ツールのキャッシュメモリ経由で読む以外は、DPEEK系と同じです。 もちろん、キャッシュに入るのは全領域のうちの一部分なので、毎回キャッシュメモリから読まれるとは限りません。 POKE系で書き込みを行っても、キャッシュメモリに反映されません。 書き込んだ領域を再び読むような処理の場合は、DPEEK系を使って下さい。 value, succeeded = MPEEK1(address) value, succeeded = MPEEK2(address) value, succeeded = MPEEK4(address) 「ターゲットメモリ(再)記憶」で保存しておいたメモリから読む以外は、DPEEK系やCPEEK系と同じです。 内容が変化したアドレスを検索する場合などの比較対象として使います。 succeeded = POKE1(address, value) succeeded = POKE2(address, value) succeeded = POKE4(address, value) 引数1:address(数値型)書き込むアドレス 引数2:value(数値型)書き込む値 戻り値:succeeded(boolean型)書き込み成功ならばtrue、書き込み失敗ならばfalse ターゲットプロセスのメモリに、それぞれ{1,2,4}バイト書き込みます。 valueの値をリトルエンディアン形式の整数として書き込みます。 本ツールのキャッシュメモリには反映されません。 address, size, addressNext, isRW, isR = MEM_INFO(address) 引数:address(数値型)情報取得するアドレス 戻り値1:address(数値型)情報取得成功ならば引数そのままの値、情報取得失敗ならば0 戻り値2:size(数値型)情報取得成功ならば次のメモリ領域までのサイズ、情報取得失敗ならば0 戻り値3:addressNext(数値型)情報取得成功ならば次のメモリ領域のアドレス、情報取得失敗ならば0 戻り値4:isRW(boolean型)情報取得成功ならば読み書き可能か否か、情報取得失敗ならばfalse 戻り値5:isR(boolean型)情報取得成功ならば読み出し可能か否か、情報取得失敗ならばfalse 指定したアドレスを含むメモリ領域に関して、Win32API(VirtualQueryEx)を用いて ・次のメモリ領域までのサイズ ・次のメモリ領域のアドレス ・読み書き可能か否か ・読み出し可能か否か の情報を取得します。 ただし、VirtualQueryExで取得できる情報とは異なり、アドレスがページ境界に切り下げられるようなことはありません。属性も、「読み書き可能か否か」「読み出し可能か否か」だけです。 同じメモリ領域内は同じ属性になっているので、検索開始アドレスから順にメモリ領域を列挙して「読み書き可能な領域であれば、size分だけforループ」、が検索処理全体の基本の流れになります。(もちろん、Searchタブを使って単純な検索をするのであれば、このようなことは意識しないで済みます。) 情報取得成功した時にaddressNextが0になっている場合は、「次のメモリ領域」が存在しないということになります。 ADRSLIST_FREE() 引数、戻り値:なし 検索結果のアドレス一覧を解放して、「検索を行っていない状態」にします。 Searchタブの「検索結果消去」ボタンと同じ働きです。 ADRSLIST_INIT() 引数、戻り値:なし 検索結果のアドレス一覧を初期化し、件数をゼロ件にします。 検索動作を開始する時に使います。 isExist = ADRSLIST_IS_EXIST() 引数:なし 戻り値:isExist(boolean型)アドレス一覧が存在するならばtrue、存在しないならばfalse 検索ボタンが押された場合に、「初回検索」するべきか「絞り込み検索」するべきかの判断に使われます。 trueの場合は「絞り込み検索」、falseの場合は「初回検索」をするべき、ということになります。 isFull = ADRSLIST_IS_FULL() 引数:なし 戻り値:isFull(boolean型)アドレス一覧がフル状態ならばtrue、空きがあるならばfalse 検索結果のアドレスが最大件数(現仕様では1048576件)記憶されており、さらなる追加ができなければtrueになります。、 length = ADRSLIST_LENGTH() 引数:なし 戻り値:length(数値型)アドレス一覧の記憶されている件数 検索結果のアドレスが記憶されている件数を返します。 ただし、ADRSLIST_IS_EXIST()が false の時には意味を持ちません。 ADRSLIST_ADD(address) 引数:address(数値型)アドレス一覧に追加するアドレス 戻り値:なし 検索結果のアドレス一覧の末尾に、addressを追加します。 ただし、ADRSLIST_IS_FULL()が true の場合には何もしません。 address = ADRSLIST_GET(index) 引数:index(数値型)アドレス一覧に記憶されているアドレスの番号 戻り値:address(数値型)アドレス一覧に記憶されているアドレス 検索結果のアドレス一覧のindex番目に記憶されているアドレスを取得します。 indexの範囲は、0以上ADRSLIST_LENGTH()未満です。 ただし、ADRSLIST_IS_EXIST()が false の時には意味を持ちません。 ADRSLIST_DEL(index) 引数:index(数値型)アドレス一覧に記憶されているアドレスの番号 戻り値:なし 検索結果のアドレス一覧のindex番目に記憶されているアドレスを削除します。 indexの範囲は、0以上ADRSLIST_LENGTH()未満です。 (index+1)番目以降のアドレスを前に詰めるなどの処理はしません。index番目が空きになります。 ADRSLIST_LENGTH()も変化しません。 あとからADRSLIST_DEFRAG()を呼び出して、詰めて下さい。 ADRSLIST_DEFRAG() 引数、戻り値:なし ADRSLIST_DEL()によってできた空きを詰める処理を行います。 詰めた分だけ、ADRSLIST_LENGTH()も変化します。 ●「検索」ボタンと同様の処理を「実行」ボタンで行う 「Search」と同様の処理を「Exec」で行うには、以下のような文字列を「実行コード入力欄」に記述して「実行」ボタンを押して下さい。 なお、「Exec」で「RETの内容(またはエラーの内容)表示欄」に表示される内容は、「Search」ではポップアップダイアログで表示されます。 function COND(AD) (「検索条件入力欄」の内容) end if ADRSLIST_IS_EXIST() then LENGTH = ADRSLIST_LENGTH() for INDEX=0,LENGTH-1 do AD = ADRSLIST_GET(INDEX) if (not COND(AD)) then ADRSLIST_DEL(INDEX) end end ADRSLIST_DEFRAG() else ADRSLIST_INIT() AD_BASE = SEARCH_ADDRESS_START while 1 do AD_BASE,SIZE,AD_NEXT,IS_RW,IS_R = MEM_INFO(AD_BASE) if IS_RW then AD_END = SIZE-1+AD_BASE if (AD_END > SEARCH_ADDRESS_END) then AD_END = SEARCH_ADDRESS_END end for AD=AD_BASE,AD_END do if (COND(AD)) then ADRSLIST_ADD(AD) end end end if (ADRSLIST_IS_FULL()) then break end AD_BASE=AD_NEXT if (AD_BASE==0) then break end if (AD_BASE>SEARCH_ADDRESS_END) then break end end end