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

我有一个使用修改版Lua 5.2的应用程序。Lua被嵌入到一个exe中,就我所知(使用Dependency Walker),它的Lua函数没有导出符号。我没有此应用程序的源代码。我需要为Lua编写C模块以与此应用程序一起使用。

我已经在此应用程序处理的Lua文件中成功require它,但是一旦我尝试调用任何lua_*函数,应用程序就会崩溃并显示访问冲突错误。

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

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

UPD:就我所知,我得到访问违例,因为我正在尝试使用Lua代理库并且无法传递调用给exe Lua C函数。如果我不使用Proxy DLL,我会收到检测到多个VM。有什么方法可以解决这个问题吗?

我的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, "请给我一个字符串参数!");
        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("在新库之前\n");

#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("在新库之后\n");

    return 1;
}

那些问“什么是Lua代理库”的人:

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

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

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

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

点赞
用户734069
用户734069

我需要为该应用程序编写一个Lua C模块。

额...不行。

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

通过静态链接到Lua,应用程序的开发者使用户几乎无法编写自己的用于其使用Lua的C模块,除非他们破解二进制文件。

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

没有反编译器或真正的汇编技能是做不到的。而且由于链接时优化,即使那些方法可能也会失败,因为其中一些Lua API可能已被内联。

2018-07-22 13:54:25
用户6038447
用户6038447

你肯定可以编写 C 的动态链接库 (dll) ,如果 Lua 环境是一个正确兼容的 Lua 系统,那么你应该能够实现你想要做的事情。但你需要检查一些事情:

  1. 找出你使用的系统中运行的 Lua 版本。 这将让你确定你需要编译的库的类型。
print(_VERSION)
  1. 检查此 Lua 环境使用的其他 dll 模块。使用依赖项查看器或类似工具。它们应该使用 luaopen_() 类型的入口点。如果是这种情况,那么你的上述入口点应该是可以的。

  2. 检查你传递给方法的内容。你 不能 在 Lua 和你的 dll 之间传递轻量级数据 (指针) ,主要是因为它们的分配在不同的空间中。这样会导致访问冲突。

  3. 检查一下 Lua 系统可能使用的外部库。你 经常 会找到一个 lua5.1.dll 或类似的库。你需要链接这个库,以确保你使用的方法在同一个应用程序进程空间中。

通常这样的问题更可能是 Lua 实现被修改过,Lua 字节码和接口不一致,因此非常难以构建。希望这能帮到你。

顺便说一下,使用依赖项查看器查看可用方法的 exe 和 dll。Lua 使用 stdcall 名称修改,因此它们总是可见的。 http://www.dependencywalker.com/

2020-03-17 11:03:07