Thank you for the link, it's really useful. I managed to create a function in lua, it is displayed in WoW, but when I try to call it via "/dump txt()" WoW gives an exception "invalid pointer". I check the correctness of the function pointer and pre-display it in the MessageBox to make sure there is no error. The pointer to the exception and the pointer to the WWII error converge, I don't understand what the problem might be.
Perhaps this is due to the fact that I work in a different thread, or I have a serious lack of c++ knowledge
dllmain.cpp
Code:
#include "pch.h"
#include <Windows.h>
#include <string>
#include <iostream>
#include <sstream>
static int testMethodFromDll(lua_State* L)
{
lua_pushnumber(L, 1.f);
return 1;
}
static int reg_lua_function(lua_State* L)
{
luaL_Reg funcs[] = {
{"ttt", testMethodFromDll}
};
for (luaL_Reg func: funcs)
{
void* voidPointer = reinterpret_cast<void*>(testMethodFromDll);
// pointer to LPCWSTR for log
std::ostringstream addressStream;
addressStream << voidPointer;
std::string addressString = addressStream.str();
std::wstring wideString(addressString.begin(), addressString.end());
// pointer to LPCWSTR
LPCWSTR lpcwstr = wideString.c_str();
MessageBox(NULL, lpcwstr, L"Message from DLL", MB_ICONINFORMATION);
lua_pushcfunction(L, func.func);
lua_setglobal(L, func.name);
}
return 0;
}
DWORD WINAPI MainThread(LPVOID lpReserved) {
Sleep(10000);
lua_State* lvm_hnd = GetLuaState();
reg_lua_function(lvm_hnd);
return TRUE;
}
HMODULE ModuleInUse;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
OutputDebugString(L"DLL loaded successfully 11111111111111111\n");
CreateThread(nullptr, 0, MainThread, hModule, 0, nullptr);
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
pch.h
Code:
struct lua_State;
using lua_Number = double;
// Lua
#define lua_pushcfunction(L, f) lua_pushcclosure(L, f, 0);
#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
using lua_CFunction = int(*)(lua_State*);
typedef struct luaL_Reg {
const char* name;
lua_CFunction func;
} luaL_Reg;
#define LUA_GLOBALSINDEX (-10002)
inline void lua_pushcclosure(lua_State* L, lua_CFunction func, int c) { return ((decltype(&lua_pushcclosure))0x0084E400)(L, func, c); }
inline void lua_setfield(lua_State* L, int idx, const char* str) { return ((decltype(&lua_setfield))0x0084E900)(L, idx, str); }
inline void lua_pushnumber(lua_State* L, lua_Number v) { return ((decltype(&lua_pushnumber))0x0084E2A0)(L, v); }
inline lua_State* GetLuaState() { return ((decltype(&GetLuaState))0x00817DB0)(); }
Edited:
As far as I understand it, this is due to the fact that the callback is in the wrong memory section, it is checked and the game throws an exception. Can you tell me which best practices are currently being used? I read about the code cave, about textsection_start and textsection_end, maybe there are other practices to use that are potentially more secure?