C++-在没有自定义.lib文件的情况下从Lua C模块调用Lua函数

C++ - call Lua functions from Lua C module without custom .lib file

本文关键字:Lua 模块 函数 调用 情况下 自定义 文件 lib C++-      更新时间:2023-10-16

我有一个应用程序,它使用了Lua 5.2的修改版本。Lua嵌入在exe中,据我所见(使用Dependency Walker(,它的Lua函数没有导出符号。我没有此应用程序的来源。我需要为Lua编写C模块,以便与此应用程序一起使用。

我成功地在该应用程序处理的Lua文件中require它,但一旦我尝试调用任何lua_*函数,应用程序就会崩溃,并出现访问违规错误。

有没有一种方法可以找到嵌入Lua函数的地址/名称并调用它们?

我问应用程序开发人员是否允许我这样做,他们似乎并不在乎。唯一的问题是禁止修改应用程序本身。

UPD:据我所见,我遇到了访问违规,因为我试图使用Lua proxy lib,但它无法将调用传递给exe Lua C函数。如果我没有使用代理DLL,我会检测到多个虚拟机。有什么办法解决这个问题吗?

我的Lua C模块代码:

#if defined(WIN32) || defined(_WIN32)
#  define LUA_BUILD_AS_DLL   /* for #define LUA_API __declspec(dllimport) */
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <lua.h>
#include <lauxlib.h>
#ifdef __cplusplus
}
#endif
#if defined(WIN32) || defined(_WIN32)
#  ifdef __cplusplus
#    define MY_LUA_API   extern "C" __declspec(dllexport)
#  else
#    define MY_LUA_API   __declspec(dllexport)
#  endif
#else
#  define MY_LUA_API     extern "C"
#endif
using namespace std;
static int Lmytest_test(lua_State *L) {
// Check the arguments.
int argn = lua_gettop(L);
if (argn != 1 || !lua_isstring(L, 1)) {
lua_pushstring(L, "Give me one string argument please!");
lua_error(L);
}
lua_pushstring(L, "Hello world!");
return 2;
}
static const struct luaL_Reg lib[] = {
{ "test", Lmytest_test },
{ NULL, NULL }
};
MY_LUA_API int luaopen_mytest(lua_State* L) {
printf("Before newlibn");
#if LUA_VERSION_NUM >= 502
luaL_newlib(L, lib);
#else
lua_createtable(L, 0, sizeof(lib) / sizeof(lib[0]));
luaL_register(L, NULL, lib);
#endif
printf("After newlibn");
return 1;
}

对于那些询问what is Lua proxy lib:的人

http://lua-users.org/wiki/LuaProxyDll

http://lua-users.org/wiki/LuaProxyDllTwo

http://lua-users.org/wiki/LuaProxyDllThree

http://lua-users.org/wiki/LuaProxyDllFour

我需要为Lua编写C模块,以便与此应用程序一起使用。

嗯。。。你不能。

如果他们的程序不导出Lua的DLL接口,也不加载Lua的DLL,那么这意味着它与Lua静态链接。除非你真的破解了可执行文件,否则你的DLL模块将与主可执行文件没有使用的Lua实现对话。这就是运行时崩溃的原因;两段不同的代码与同一个内存对话是行不通的。

通过静态链接到Lua,应用程序的开发人员基本上不可能让用户在不破解二进制文件的情况下编写自己的C模块来使用Lua。

有没有办法找到嵌入Lua函数的地址/名称并调用它们?

没有反编译器或真正优秀的汇编技能。多亏了链接时间优化,即使是那些也可能会让你失败,因为一些LuaAPI可能已经内联了。

你当然可以写一个C dll,如果Lua环境是一个适当兼容的Lua系统,那么你应该能够实现你想要做的事情

  1. 准确了解您使用的系统中运行的Lua版本。这将使您能够确定需要针对哪种类型的库进行编译
print( _VERSION )
  1. 检查Lua环境正在使用的其他dll模块。使用依赖助行器或类似工具。它们应该使用luaopen_((类型的入口点。如果是这样的话,那么你上面的入口点应该是可以的

  2. 检查传递给方法的内容。您不能在Lua和dll之间传递lightdata(指针(,主要是因为它们的分配将在不同的空间中。您将从中获得访问违规。

  3. 检查Lua系统可能正在使用的任何外部库。常见,您会发现一个lua5.1.dll或类似程序。您需要与此链接,以确保您使用的方法将在同一应用程序进程空间内。

像这样的问题通常更可能是Lua实现被修改了,Lua字节码和接口不一致,因此很难构建。希望这能有所帮助。

Btw。使用依赖项助行器查看exe和dll中的可用方法。Lua使用stdcall名称mangling,因此它们总是可见的。http://www.dependencywalker.com/