0

第一件事:

我这里有几行我写的 hack:

这是一个 makro 的定义,luaL_openlib它实际上是一个指向的函数指针0x0090DE00

/*
Type definitions for function signatures
*/
typedef int (luaL__openlib) (lua_State *L, const char *libname, const luaL_reg *l, int nup);


/*
Intercepting macros for function calls.
*/
#define luaL_openlib(L, libname, l, nup) ((luaL__openlib*) 0x0090DE00)(L, libname, l, nup)

这就是我所说的:

static int luaAi_helloworld(lua_State *L)
{
    MessageBox(NULL, L"Hello World", L"", MB_OK);
    return 1;
}

static const luaL_reg ai_funcs[] = {
    { "helloworld", luaAi_helloworld },
    { NULL, NULL }
};

void open_ailib(lua_State *L)
{
    luaL_openlib(L, "ai", ai_funcs, 0);
}

上面的代码被编译成一个 DLL。DLL 由我的目标进程加载,为此我稍微修改了 .exe 文件。

然而:这行得通!

结果是我能够调用ai.helloworld()计算机游戏的脚本来显示“Hello World”消息框。


实际情况:

现在,代码看起来有点混乱,但它正在做完全相同的事情:

static int scse_helloworld (lua_State *L)
{
    MessageBox(NULL, L"Hello World", L"", MB_OK);
    return 1;
}

static luaL_reg scselib[] = {
    {"helloworld", scse_helloworld},
    {NULL, NULL}
};

/*
Type definitions for function signatures
*/
typedef int (luaL__openlib)(lua_State *L, const char *libname, const luaL_reg *l, int nup);

/*
Intercepting macros for function calls.
*/
#define luaL_openlib2(L, libname, l, nup) ((luaL__openlib*) 0x0090de00)(L, libname, l, nup)

SCSE_API int luaopen_scse(lua_State *L)
{
    SIZE_T numBytes;
    const int num_bytes = 16;
    unsigned char hook[num_bytes];

    HANDLE process = GetCurrentProcess();
    ReadProcessMemory(process, (LPVOID)(0x0090de00), &hook, sizeof(hook), &numBytes);
    LOGGER.LogMessage("Memory at 0x0090de00 is:\n\n");

    for (int i = 0; i < num_bytes; i++) {
        LOGGER.LogMessage("%2X ", hook[i]);
    }

    // Link lua linker functions with Supreme Commander lua functions
    if(LuaLinker::Link())
    {
        LOGGER.LogMessage("Lua linker functions successefully linked with Supreme Commander Lua functions.\n");

        LOGGER.LogMessage("luaL_openlib2()");
        luaL_openlib2(L, "scse", scselib, 0); 

        // Spoiler: This is never reached
        LOGGER.LogMessage("SCSE library successefully opened.\n");
    }
    else { 
        LOGGER.LogMessage("ERROR: Couldn't link lua linker functions with Supreme Commander Lua functions!\n");
    }

    return 1;
}

另外出现的是我在读取内存0x0090de00。我可以事先给你结果:

Memory at 0x0090de00 is:

53 8B 5C 24 14 55 56 8B 74 24 10 57 8B 7C 24 18 

正如我们在 OllyDbg 中看到的那样,这是正确的——尽管我已经知道:

在此处输入图像描述

那么,你为什么在这里?

问题是,您可能看到了上面的剧透评论,之后的日志消息luaL_openlib2永远不会被打印出来。在我的日志文件中,我看到的是:

Lua linker functions successefully linked with Supreme Commander Lua functions.
luaL_openlib2()

游戏加载开始屏幕但停止运行。按钮不显示等。它不会崩溃,但它基本上已经死了。当我关闭它时,我得到的只是最后一声求救:

在此处输入图像描述

我正在寻找解释 - 我不明白为什么这不起作用。我只有一个猜测:

我正在加载的 DLL不是由我加载的。它实际上是由游戏的脚本引擎加载的。实际上,应该不可能从游戏中加载 DLL。但是,由于执行了上面的代码,因此加载了 DLL。因此,如果加载了 DLL,可能是内存搞砸了?不,至少不是我所针对的函数的前 16 个字节,所以我假设,其余的也会很好,除此之外,实际上应该改变什么——没有什么可以改变的。

我不确定是否有人可以在这里帮助我,但这对我来说似乎是一个棘手的问题。

有人吗?

顺便说一句:抱歉标题 - 随时提出建议,如果你还没有尝试最高指挥官,那就去吧!

4

1 回答 1

-1

如果游戏应用程序加载了 DLL,则 DLL 在单独的进程中运行。您的应用程序正在不同的进程中运行。在第一种情况下,DLL 和您的应用程序在同一个进程中运行。

于 2016-12-14T23:52:13.527 回答