c++程序内嵌lua字节码
前言
從google找到的資料看,c++和lua交互的經典用法,都是c++調用lua腳本文件.
但是c++程序內,嵌入lua編譯好的字節碼緩沖區,也是一種用場.
下載的lua官方包里,沒有例子程序了.
對于開源程序,自帶豐富的例子,是很重要的事情. 雖然說”源碼面前沒有秘密”, 但實際情況心里還是萬馬奔騰,讓人崩潰.
還是M$做的好,每個API都能在MSDN或WDK中找到可以run的例子.
找到了lua歷史版本下載頁: https://www.lua.org/versions.html
試驗記錄
自己編譯出lua.exe
http://blog.csdn.net/lostspeed/article/details/52904410
寫lua文件
假設文件為TaskBegin.lua, 里面只有一個c++注冊的接口.
fnTaskBegin()編譯lua文件為目標文件
rem file : build_lua.cmd mylua.exe -o TaskBegin.dat TaskBegin.lua pause將目標文件制作成數組
可以搞個小工具來做,我直接用WinHex將TaskBegin.dat拖進, 復制拷貝成c數組
這一步可以考慮用對稱加密算法,將數組加密, 處理后,靜態分析PE時, 就不知道這是lua的字節碼了.
在程序中加入lua引擎
對于lua5.3.3分2步
* 包含src目錄下的所有文件(.h, .c), 將.c的編譯選項改成不支持預編譯頭文件
* 將.c中的main注釋掉
在c++程序中調用嵌入的lua字節碼數組
int __cdecl fnTaskBegin(lua_State* L) {TCHAR* pszBuf = NULL;size_t nLenBuf = 0;if (fnProcRegistr(&pszBuf, nLenBuf)) {fnProcRegOk(&pszBuf, nLenBuf);} else {fnProcRegFail(&pszBuf, nLenBuf);}fnClearBuf(&pszBuf, nLenBuf);lua_pushnumber(L, LUA_OK); // 壓入返回值給.luareturn LUA_YIELD; // ! 不能是 LUA_OK }void fnLuaProc() {lua_State* L = NULL;int iLuaErr = 0;// 創建lua新環境. lua_open被廢棄了L = luaL_newstate();if (NULL != L) {luaL_openlibs(L); // 打開lua庫// 注冊宿主程序的接口函數給lua用lua_register(L, "fnTaskBegin", fnTaskBegin);// iLuaErr = luaL_dofile(L, LUA_FILE_NAME); // 載入lua文件iLuaErr = luaL_loadbuffer(L, (const char*)g_AryLuaObj, sizeof(g_AryLuaObj), NULL);if (LUA_OK != iLuaErr) {// printf("%s\r\n", luaL_checkstring(L, -1));} else {// 調用luaL_loadbuffer后, 要調用lua_pcall, 才能調用buffer中的lua接口// 這是文檔中沒有的, 機智啊:Plua_pcall(L, 0, LUA_MULTRET, 0);}lua_close(L); // 關閉lua環境} }總結
在業務邏輯的調用點上, 調用lua處理函數fnLuaProc(), 不熟悉lua或沒有源碼的逆向分析師只能去跟lua的實現, 將對抗強度轉嫁給lua了.
可以考慮修改lua源碼, 增加免查處理, 用來躲過掃描lua特征的工具. 讓他不知道我用的lua版本和lua關鍵函數.
在沒有這種工具樣本的前提下,可以自己先修改一下lua源碼, 提前做個準備.
總結
以上是生活随笔為你收集整理的c++程序内嵌lua字节码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wget 下载 设置cookie
- 下一篇: 校园网络构建方案设计