暗号化等が施されたLuaファイルの読み込み方法
今回はファイル読み込みのお話です。暗号化の話ではないのであしからず。
通常Luaファイルの読み込みは、以下の関数やマクロを使用して行います。
luaL_loadfile(L, filename) luaL_dofile(L, filename)
テキストで書かれたLuaファイルをロードする場合は上記を使えば十分でしょう。
しかし実際にソフトウェアを配布するときはユーザーからLuaスクリプトの
内容が見えないように暗号化したり、1つのファイルにパッキングするのが普通です。
そのため、まずはC言語側の配列にファイル内容をロードして復号等の処理を
施した後にLuaスクリプトをロードさせるような処理を行う必要があります。
具体的な流れとしては、以下のような感じです。
1. バイナリレベルでファイルオープンして配列に格納する 2. 配列に対して復号等の処理を行う。 (これで配列の内容がLuaのインタプリタが解釈可能なコードになる) 3. 配列のコードをLuaスクリプトとしてロード・実行する
とにかくソース
お待ちかね(?)のソースコード(C++)です。
lua_Stateのセットアップとかは過去の記事を参照してください。
ファイルの読み込みにはWin32のAPIを使用しています。
読み込むファイル名は「map1.dat」とします。
// ファイルの読み込み HANDLE hFile = ::CreateFile( "map1.dat", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL ); if ( hFile == INVALID_HANDLE_VALUE ) { fprintf( stderr, "Luaファイルの読み込み失敗(%d)", GetLastError() ); return -1; } DWORD dwFileSize = ::GetFileSize( hFile, NULL ); if ( dwFileSize == -1 ) { fprintf( stderr, "Luaファイルのサイズ取得失敗(%d)", GetLastError() ); return -1; } DWORD dwRead; char* pTemp = new char[dwFileSize+1]; int rc = ::ReadFile( hFile, pTemp, dwFileSize, &dwRead, NULL ); if ( rc == 0 || dwFileSize != dwRead ) { rc = GetLastError(); fprintf( stderr, "Luaファイルの読み込みに失敗(%d)", GetLastError() ); goto Cleanup; } // TODO:ここに復号等の処理を行うコードを書く rc = luaL_loadbuffer( L, const_cast<const char*>(pTemp), dwFileSize, NULL ); if ( rc != 0 ) { fprintf( stderr, "Luaファイルの読み込み失敗(オンメモリ)(%d)", rc ); goto Cleanup; } // ロードされている関数を実行 rc = lua_pcall( L, 0, LUA_MULTRET, 0 ); if ( rc != 0 ) { fprintf( stderr, "Luaファイルの読み込み失敗(pcall)(%d)", rc ); goto Cleanup; } // TODO:ここにLuaファイル内の関数をコールする処理等のコードを書く Cleanup: if ( pTemp != NULL ) { delete [] pTemp; pTemp = NULL; } return rc;
暗号化・復号については各自お気に入りのものを選んでくださいね。