#include "pch.h"
#include "asmData.h"
#include "CWOWinHook.h"
#include <tchar.h>
#include "MyLua.h"
#include <vector>
#include <iostream>
#include "PECodeHook.h"
TCHAR g_path[MAX_PATH];
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
) {
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
::GetModuleFileName(hModule, g_path, MAX_PATH);
ASMDataInit();
if (IWoWinHook::Intance()->HookMe())
{
IWoWinHook::Intance()->AllocConsole();
InitAndGetMCAddr();
}
else {
return FALSE;
}
break;
}
}
return TRUE;
}
char* WCharToChar(const wchar_t* wstr) {
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[size_needed];
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, size_needed, NULL, NULL);
return str;
}
bool WINAPI IsHasConsole() {
TCHAR xpath[MAX_PATH];
_tcscpy_s(xpath, g_path);
_tcscat_s(xpath, TEXT(".ini"));
char* ppath = WCharToChar(xpath);
char ps[1024] = { 0 };
::GetPrivateProfileStringA("config", "console", "", ps, 1023, ppath);
//MessageBox(NULL, xpath, 0, 0);
//MessageBoxA(0, ps, "console", 0);
if (ps[0]) return true;
return false;
}
DWORD64 g_dwLUACallTime = 0;
extern "C" {
void ASMDataInit()
{
gASMBaseWow =(DWORD64) GetModuleHandle(NULL);
}
typedef int(*lua_CFunction)(void* L);
struct LUAReg {
const char* pname;
lua_CFunction pfn;
};
int LUA_FunTest(void* L) {
g_dwLUACallTime = GetTickCount64();
return 0;
}
int LUA_FunTest2(void* L) {
g_dwLUACallTime++;
return 0;
}
const char* gPGStr = "_G";
typedef void (*HookOpenLib)(void* L, const char* libname,
const void* l, int nup);
LUAReg gPLuaFun[3] = {
{"test", &LUA_FunTest}
,
{"test2", &LUA_FunTest2}
,
{NULL,NULL}
};
typedef const char*(*fnFindTable)(void* L, int idx,
const char* fname, int szhint);
typedef void (*fnLuaGetField)(void* L, int idx, const char* k);
typedef int (*fnLua_Type)(void* L, int idx);
typedef void (*fnLua_pop)(void* L, int idx);
typedef int (*fnLuaError)(void* L, const char* fmt, ...);
typedef void (*fnLua_pushvalue)(void* L, int idx);
typedef void (*fnLua_insert)(void* L, int idx);
typedef void (*fnLua_setfield)(void* L, int idx, const char* k);
typedef void (*fnLua_pushcclosure)(void* L, lua_CFunction fn, int n);
typedef void (*fnLua_remove)(void* L, int idx);
fnFindTable luaFindTable = nullptr;
fnLuaGetField luaGetField = nullptr;
fnLua_Type luaType = nullptr;
fnLua_pop luaPop = nullptr;
fnLuaError luaError = nullptr;
fnLua_pushvalue luaPushValue = nullptr;
fnLua_setfield luaSetField = nullptr;
fnLua_pushcclosure luaPushCClosure = nullptr;
fnLua_insert luaInsert = nullptr;
fnLua_remove luaRemove = nullptr;
}
BOOL WINAPI Msg(HWND, HINSTANCE, LPCSTR pstr, int) {
MyLua::InitLua();
if (!MyLua::DoString(" local startPos, endPos = string.find('bb', '* *((NOISa'); ")) {
MyLua::DoString(" a= c+b;");
}
return TRUE;
}
// 生成KMP算法的部分匹配表(next数组)
std::vector<BYTE> computeLPS(const std::vector<unsigned char>& pattern) {
size_t m = pattern.size();
std::vector<BYTE> lps(m, 0);
int len = 0; // 最长公共前后缀长度
int i = 1;
while (i < m) {
if (pattern[i] == pattern[len]) {
len++;
lps[i] = len;
i++;
}
else {
if (len != 0) {
len = lps[len - 1];
}
else {
lps[i] = 0;
i++;
}
}
}
return lps;
}
// KMP算法实现二进制匹配
int KMPSearch(BYTE* text,size_t tlen,
const std::vector<unsigned char>& pattern) {
if (pattern.empty()) return 0;
if (tlen < pattern.size()) return -1;
size_t n = tlen;
size_t m = pattern.size();
std::vector<BYTE> lps = computeLPS(pattern);
int i = 0; // text索引
int j = 0; // pattern索引
while (i < n) {
if (text[i] == pattern[j]) {
i++;
j++;
}
if (j == m) {
return i - j; // 返回匹配起始位置
}
else if (i < n && text[i] != pattern[j]) {
if (j != 0)
j = lps[j - 1];
else
i++;
}
}
return -1; // 未找到匹配
}
std::vector<BYTE> GetOpenBaseStartMC() {
TCHAR xpath[MAX_PATH];
_tcscpy_s(xpath, g_path);
_tcscat_s(xpath, TEXT(".ini"));
char* ppath = WCharToChar(xpath);
char ps[1024] = { 0 };
::GetPrivateProfileStringA("memdata", "openbase", "", ps, 1023, ppath);
if(strlen(ps)>0){
std::vector<BYTE> mc;
char* p = ps;
while (*p) {
while (*p == ' ') p++;
if (!*p) break;
BYTE b = (BYTE)strtoul(p, &p, 16);
mc.push_back(b);
}
return mc;
}
else {
//默认值
return std::vector<BYTE>{
0x48, 0x89, 0x5D, 0x10, 0xBA, 0xEE, 0xD8, 0xFF,
0xFF, 0x48, 0x8B, 0xD9, 0xE8, 0xE4, 0xE4, 0xEC,
0xFC
};
}
}
std::vector<BYTE> GetStateLMC() {
TCHAR xpath[MAX_PATH];
_tcscpy_s(xpath, g_path);
_tcscat_s(xpath, TEXT(".ini"));
char* ppath = WCharToChar(xpath);
char ps[1024] = { 0 };
::GetPrivateProfileStringA("memdata", "statel", "", ps, 1023, ppath);
if (strlen(ps) > 0) {
std::vector<BYTE> mc;
char* p = ps;
while (*p) {
while (*p == ' ') p++;
if (!*p) break;
BYTE b = (BYTE)strtoul(p, &p, 16);
mc.push_back(b);
}
return mc;
}
else {
//默认值
return std::vector<BYTE>{
0x48, 0x8B, 0x0D, 0xB4, 0x75, 0xCB, 0x04,
0x88, 0x1D
/*, 0x6F, 0x75, 0xCB, 0x04, 0xE8,
0x91, 0xE9, 0x01, 0x00*/
};
}
}
std::vector<BYTE> GetLuaFindTableMC() {
TCHAR xpath[MAX_PATH];
_tcscpy_s(xpath, g_path);
_tcscat_s(xpath, TEXT(".ini"));
char* ppath = WCharToChar(xpath);
char ps[1024] = { 0 };
::GetPrivateProfileStringA("memdata", "findtable", "", ps, 1023, ppath);
if (strlen(ps) > 0) {
//return wow.findtable machine code
std::vector<BYTE> mc;
char* p = ps;
while (*p) {
while (*p == ' ') p++;
if (!*p) break;
BYTE b = (BYTE)strtoul(p, &p, 16);
mc.push_back(b);
}
return mc;
}
else {
//return hex binary 41 B9 01 00 00 00 4C 8D 05 07 5B EC 00 BA F0 D8 FF FF E8
return std::vector<BYTE>{
0x41, 0xB9, 0x01, 0x00, 0x00, 0x00, 0x4C, 0x8D, 0x05, 0x07, 0x5B, 0xEC, 0x00, 0xBA, 0xF0, 0xD8, 0xFF, 0xFF, 0xE8
};
}
}
void InitAndGetMCAddr() {
std::vector<BYTE> openBaseMC = GetOpenBaseStartMC();
std::vector<BYTE> stateLMC = GetStateLMC();
auto luaFindTableMC = GetLuaFindTableMC();
PVOID pBits = nullptr;
size_t bitLen = 0;
GetModInfo(TEXT("Wow.exe"), pBits, bitLen);
if(!pBits || bitLen==0){
printf("Cant get Wow.exe modinfo lua cant be use\n");
return;
}
PBYTE baseAddr = (PBYTE)pBits;
SIZE_T size = (SIZE_T)bitLen;
int off1 = KMPSearch(baseAddr, size, openBaseMC);
if (off1 != -1) {
g_openBaseAddr = baseAddr + off1;
}
int off2 = KMPSearch(baseAddr, size, stateLMC);
if (off2 != -1) {
g_stateLAddr = baseAddr + off2;
}
int off3 = KMPSearch(baseAddr, size, luaFindTableMC);
PBYTE pLuaFindTable = nullptr;
if (off3 != -1) {
pLuaFindTable = (baseAddr + off3);
}
printf("openBaseAddr=%p,stateLAddr=%p\n", g_openBaseAddr, g_stateLAddr);
DWORD offset[] = { 0x8cb,0x8d7,0x8e6,0x8f3,0x900,0x916 };
DWORD offset2[] = { 0x96c,0x97E,0x98E,0x99B,0x9AD, 0x9D7,0x9E4,0x9F4,0xA01 ,0xA0E,0xA3A };
//{"baseAddr","findTable","luaGetField","lua_Type","lua_pop","lua_Error","lua_pushvalue","LuaSetField","LuaRemove","LuaInsert","lua_pushccloseure"}
PBYTE tmp = nullptr;
tmp = pLuaFindTable + (offset2[1]-offset2[0]);
luaFindTable = (fnFindTable)(*(DWORD*)(tmp + 1) + (DWORD64)tmp + 5 - 0x100000000);
tmp = pLuaFindTable + (offset2[2] - offset2[0]);
luaGetField = (fnLuaGetField)(*(DWORD*)(tmp + 1) + (DWORD64)tmp + 5 - 0x100000000);
tmp = pLuaFindTable + (offset2[3] - offset2[0]);
luaType = (fnLua_Type)(*(DWORD*)(tmp + 1) + (DWORD64)tmp + 5 - 0x100000000);
tmp = pLuaFindTable + (offset2[4] - offset2[0]);
luaPop = (fnLua_pop)(*(DWORD*)(tmp + 1) + (DWORD64)tmp + 5 - 0x100000000);
tmp = pLuaFindTable + (offset2[5] - offset2[0]);
luaError = (fnLuaError)(*(DWORD*)(tmp + 1) + (DWORD64)tmp + 5 - 0x100000000);
tmp = pLuaFindTable + (offset2[6] - offset2[0]);
luaPushValue = (fnLua_pushvalue)(*(DWORD*)(tmp + 1) + (DWORD64)tmp + 5 - 0x100000000);
tmp = pLuaFindTable + (offset2[7] - offset2[0]);
luaSetField = (fnLua_setfield)(*(DWORD*)(tmp + 1) + (DWORD64)tmp + 5 - 0x100000000);
tmp = pLuaFindTable + (offset2[8] - offset2[0]);
luaRemove = (fnLua_remove)(*(DWORD*)(tmp + 1) + (DWORD64)tmp + 5 - 0x100000000);
tmp = pLuaFindTable + (offset2[9] - offset2[0]);
luaInsert = (fnLua_insert)(*(DWORD*)(tmp + 1) + (DWORD64)tmp + 5 - 0x100000000);
tmp = pLuaFindTable + (offset2[10] - offset2[0]);
luaPushCClosure = (fnLua_pushcclosure)(*(DWORD*)(tmp + 1) + (DWORD64)tmp + 5 - 0x100000000);
g_oba_call1 = (g_openBaseAddr + (offset[1]-offset[0]));
g_oba_call2 = (g_openBaseAddr + (offset[2] - offset[0]));
g_oba_call3 = (g_openBaseAddr + (offset[3] - offset[0]));
g_oba_call4 = (g_openBaseAddr + (offset[4] - offset[0]));
g_oba_call5 = (g_openBaseAddr + (offset[5] - offset[0]));
g_oba_call1 = (PBYTE)(*(DWORD*)(g_oba_call1 + 1) + (DWORD64)g_oba_call1 + 5) - 0x100000000;
g_oba_call2 = (PBYTE)(*(DWORD*)(g_oba_call2 + 1) + (DWORD64)g_oba_call2 + 5) - 0x100000000;
g_oba_call3 = (PBYTE)(*(DWORD*)(g_oba_call3 + 1) + (DWORD64)g_oba_call3 + 5) - 0x100000000;
g_oba_call4 = (PBYTE)(*(DWORD*)(g_oba_call4 + 1) + (DWORD64)g_oba_call4 + 5) - 0x100000000;
g_oba_call5 = (PBYTE)(*(DWORD*)(g_oba_call5 + 1) + (DWORD64)g_oba_call5 + 5) - 0x100000000;
g_stateLAddr = (PBYTE)(*(DWORD*)(g_stateLAddr + 3) + (DWORD64)g_stateLAddr + 7);
PBYTE pp = baseAddr + 0x347a8be;
g_ret_addr = pp;
pp = (PBYTE)GetModuleHandle(NULL);
pp += 0x433e958;
gPLuaFun[0].pfn = (lua_CFunction)(*(DWORD64*)pp);
}
/*
48 89 5D 10 BA EE D8 FF FF 48 8B D9 E8 E4 E4 EC FC
00007FF7CB28A8C0 < | 40:55 | push rbp |
00007FF7CB28A8C2 | 48:83EC 20 | sub rsp,20 |
00007FF7CB28A8C6 | 48:8D6C24 20 | lea rbp,qword ptr ss:[rsp+20] |
00007FF7CB28A8CB | 48:895D 10 | mov qword ptr ss:[rbp+10],rbx |
00007FF7CB28A8CF | BA EED8FFFF | mov edx,FFFFD8EE |----OpenBaseStart
00007FF7CB28A8D4 | 48:8BD9 | mov rbx,rcx |
00007FF7CB28A8D7 | E8 E4E4ECFC | call wow.7FF7C8158DC0 |
00007FF7CB28A8DC | 48:8D15 F5A84900 | lea rdx,qword ptr ds:[7FF7CB7251D8] | 00007FF7CB7251D8:"_G"
00007FF7CB28A8E3 | 48:8BCB | mov rcx,rbx |
00007FF7CB28A8E6 | E8 E5E3ECFC | call wow.7FF7C8158CD0 |
00007FF7CB28A8EB | BA FEFFFFFF | mov edx,FFFFFFFE |
00007FF7CB28A8F0 | 48:8BCB | mov rcx,rbx |
00007FF7CB28A8F3 | E8 78DAECFC | call wow.7FF7C8158370 |
00007FF7CB28A8F8 | BA EED8FFFF | mov edx,FFFFD8EE |
00007FF7CB28A8FD | 48:8BCB | mov rcx,rbx |
00007FF7CB28A900 | E8 7BE7ECFC | call wow.7FF7C8159080 |
00007FF7CB28A905 | 4C:8D05 343FEC00 | lea r8,qword ptr ds:[7FF7CC14E840] | 00007FF7CC14E840:&"assert"
00007FF7CB28A90C | 48:8BCB | mov rcx,rbx |
00007FF7CB28A90F | 48:8D15 C2A84900 | lea rdx,qword ptr ds:[7FF7CB7251D8] | 00007FF7CB7251D8:"_G"
00007FF7CB28A916 | E8 15E0FFFF | call wow.7FF7CB288930 |
00007FF7C83EEF3D | 48:8B0D B475CB04 | mov rcx,qword ptr ds:[7FF7CD0A64F8] | StateL
00007FF7C83EEF44 | 881D 6F75CB04 | mov byte ptr ds:[7FF7CD0A64B9],bl |
00007FF7C83EEF4A | E8 91E90100 | call <wow.sub_7FF7C840D8E0> |
*/
/*
41 B9 01 00 00 00 4C 8D 05 07 5B EC 00 BA F0 D8 FF FF E8
00007FF7CB288930 < | 48:895C24 18 | mov qword ptr ss:[rsp+18],rbx | rbx:agsSetDisplayMode+1E42478
00007FF7CB288935 | 57 | push rdi |
00007FF7CB288936 | 48:83EC 20 | sub rsp,20 |
00007FF7CB28893A | 48:896C24 30 | mov qword ptr ss:[rsp+30],rbp |
00007FF7CB28893F | 48:8BEA | mov rbp,rdx |
00007FF7CB288942 | 49:8BD8 | mov rbx,r8 | rbx:agsSetDisplayMode+1E42478, r8:agsSetDisplayMode+2683E
00007FF7CB288945 | 48:8BF9 | mov rdi,rcx |
00007FF7CB288948 | 48:85D2 | test rdx,rdx |
00007FF7CB28894B | 0F84 C7000000 | je wow.7FF7CB288A18 |
00007FF7CB288951 < | 48:897424 38 | mov qword ptr ss:[rsp+38],rsi |
00007FF7CB288956 | 48:8BC3 | mov rax,rbx | rbx:agsSetDisplayMode+1E42478
00007FF7CB288959 | 33F6 | xor esi,esi |
00007FF7CB28895B | 49:3930 | cmp qword ptr ds:[r8],rsi | r8:agsSetDisplayMode+2683E
00007FF7CB28895E | 74 0C | je wow.7FF7CB28896C |
00007FF7CB288960 | FFC6 | inc esi |
00007FF7CB288962 | 48:8D40 10 | lea rax,qword ptr ds:[rax+10] |
00007FF7CB288966 | 48:8338 00 | cmp qword ptr ds:[rax],0 |
00007FF7CB28896A | 75 F4 | jne wow.7FF7CB288960 |
00007FF7CB28896C | 41:B9 01000000 | mov r9d,1 |
00007FF7CB288972 | 4C:8D05 075BEC00 | lea r8,qword ptr ds:[7FF7CC14E480] | r8:agsSetDisplayMode+2683E, 00007FF7CC14E480:"_LOADED"
00007FF7CB288979 | BA F0D8FFFF | mov edx,FFFFD8F0 |
00007FF7CB28897E | E8 DDF6FFFF | call <wow.findTable> | findtable address
00007FF7CB288983 | 4C:8BC5 | mov r8,rbp | r8:agsSetDisplayMode+2683E
00007FF7CB288986 | BA FFFFFFFF | mov edx,FFFFFFFF |
00007FF7CB28898B | 48:8BCF | mov rcx,rdi |
00007FF7CB28898E | E8 7DF6ECFC | call <wow.luaGetField> | getfiled
00007FF7CB288993 | BA FFFFFFFF | mov edx,FFFFFFFF |
00007FF7CB288998 | 48:8BCF | mov rcx,rdi |
00007FF7CB28899B | E8 1012EDFC | call <wow.lua_Type> | lua_istable == 5
00007FF7CB2889A0 | 83F8 05 | cmp eax,5 |
00007FF7CB2889A3 | 74 54 | je wow.7FF7CB2889F9 |
00007FF7CB2889A5 | BA FEFFFFFF | mov edx,FFFFFFFE |
00007FF7CB2889AA | 48:8BCF | mov rcx,rdi |
00007FF7CB2889AD | E8 8E0DEDFC | call <wow.lua_pop> |
00007FF7CB2889B2 | 44:8BCE | mov r9d,esi |
00007FF7CB2889B5 | 4C:8BC5 | mov r8,rbp | r8:agsSetDisplayMode+2683E
00007FF7CB2889B8 | BA EED8FFFF | mov edx,FFFFD8EE |
00007FF7CB2889BD | 48:8BCF | mov rcx,rdi |
00007FF7CB2889C0 | E8 9BF6FFFF | call <wow.findTable> |
00007FF7CB2889C5 | 48:85C0 | test rax,rax |
00007FF7CB2889C8 | 74 12 | je wow.7FF7CB2889DC |
00007FF7CB2889CA | 4C:8BC5 | mov r8,rbp | r8:agsSetDisplayMode+2683E
00007FF7CB2889CD | 48:8D15 B45AEC00 | lea rdx,qword ptr ds:[7FF7CC14E488] | 00007FF7CC14E488:"name conflict for module '%s'"
00007FF7CB2889D4 | 48:8BCF | mov rcx,rdi |
00007FF7CB2889D7 | E8 D4F5FFFF | call <wow.lua_Error> |
00007FF7CB2889DC | BA FFFFFFFF | mov edx,FFFFFFFF |
00007FF7CB2889E1 | 48:8BCF | mov rcx,rdi |
00007FF7CB2889E4 | E8 D703EDFC | call <wow.Lua_pushvalue> |
00007FF7CB2889E9 | 4C:8BC5 | mov r8,rbp | r8:agsSetDisplayMode+2683E
00007FF7CB2889EC | BA FDFFFFFF | mov edx,FFFFFFFD |
00007FF7CB2889F1 | 48:8BCF | mov rcx,rdi |
00007FF7CB2889F4 | E8 370BEDFC | call <wow.Lua_setfield> |
00007FF7CB2889F9 | BA FEFFFFFF | mov edx,FFFFFFFE |
00007FF7CB2889FE | 48:8BCF | mov rcx,rdi |
00007FF7CB288A01 | E8 1A08EDFC | call <wow.lua_remove> | remove_LOADED table
00007FF7CB288A06 | BA FFFFFFFF | mov edx,FFFFFFFF |
00007FF7CB288A0B | 48:8BCF | mov rcx,rdi |
00007FF7CB288A0E | E8 5DF9ECFC | call <wow.lua_insert> |
00007FF7CB288A13 | 48:8B7424 38 | mov rsi,qword ptr ss:[rsp+38] |
00007FF7CB288A18 | 48:833B 00 | cmp qword ptr ds:[rbx],0 | rbx:agsSetDisplayMode+1E42478
00007FF7CB288A1C | 48:8B6C24 30 | mov rbp,qword ptr ss:[rsp+30] |
00007FF7CB288A21 | 74 52 | je wow.7FF7CB288A75 |
00007FF7CB288A23 | 0F1F40 00 | nop dword ptr ds:[rax],eax |
00007FF7CB288A27 | 66:0F1F8400 00000000 | nop word ptr ds:[rax+rax],ax |
00007FF7CB288A30 | 48:8B53 08 | mov rdx,qword ptr ds:[rbx+8] | rbx+08:agsSetDisplayMode+1E42480
00007FF7CB288A34 | 45:33C0 | xor r8d,r8d |
00007FF7CB288A37 | 48:8BCF | mov rcx,rdi |
00007FF7CB288A3A | E8 A1FFECFC | call <wow.lua_pushccloseure> |
00007FF7CB288A3F | 90 | nop |
00007FF7CB288A40 | 90 | nop |
00007FF7CB288A41 | 7F 18 | jg <wow.sub_7FF7CB288A5B> |
00007FF7CB288A43 | C0FE 00 | sar dh,0 |
00007FF7CB288A46 | 7E 13 | jle <wow.sub_7FF7CB288A5B> |
00007FF7CB288A48 | 83C3 66 | add ebx,66 |
00007FF7CB288A4B | 57 | push rdi |
00007FF7CB288A4C | 0F87 6CC30000 | ja <wow.sub_7FF7CB294DBE> |
00007FF7CB288A5B < | 4C:8B03 | mov r8,qword ptr ds:[rbx] | r8:agsSetDisplayMode+2683E, rbx:agsSetDisplayMode+1E42478
00007FF7CB288A5E | BA FEFFFFFF | mov edx,FFFFFFFE |
00007FF7CB288A63 | 48:8BCF | mov rcx,rdi |
00007FF7CB288A66 | E8 C50AEDFC | call <wow.Lua_setfield> |
00007FF7CB288A6B | 48:83C3 10 | add rbx,10 | rbx:agsSetDisplayMode+1E42478
00007FF7CB288A6F | 48:833B 00 | cmp qword ptr ds:[rbx],0 | rbx:agsSetDisplayMode+1E42478
00007FF7CB288A73 | 75 BB | jne wow.7FF7CB288A30 |
00007FF7CB288A75 | BA FFFFFFFF | mov edx,FFFFFFFF |
00007FF7CB288A7A | 48:8BCF | mov rcx,rdi |
00007FF7CB288A7D | E8 BE0CEDFC | call <wow.lua_pop> |
00007FF7CB288A82 | 48:8B4C24 28 | mov rcx,qword ptr ss:[rsp+28] | [rsp+28]:CallWindowProcW+482
00007FF7CB288A87 | 48:8B5C24 40 | mov rbx,qword ptr ss:[rsp+40] | rbx:agsSetDisplayMode+1E42478
00007FF7CB288A8C | 48:83C4 20 | add rsp,20 |
00007FF7CB288A90 | 5F | pop rdi |
*/
const char* pLOADED = "_LOADED";
const char* pLIBName = "__MYEXT";
extern "C" {
/*
00007FF7C81589DF | 6648:895C24 08 | mov qword ptr ss:[rsp+8],rbx | [rsp+08]:&"testMe"
00007FF7C81589E5 | 48:896C24 10 | mov qword ptr ss:[rsp+10],rbp |
00007FF7C81589EA | 48:897424 18 | mov qword ptr ss:[rsp+18],rsi |
00007FF7C81589EF | 48:897C24 20 | mov qword ptr ss:[rsp+20],rdi |
00007FF7C81589F4 | 41:56 | push r14 |
00007FF7C81589F6 | 48:83EC 20 | sub rsp,20 |
00007FF7C81589FA | 48:8BD9 | mov rbx,rcx | rbx:&"testMe", rcx:CLuaHook::LuaHookInit+150
00007FF7C81589FD | 49:63F0 | movsxd rsi,r8d |
00007FF7C8158A00 | 48:8B49 38 | mov rcx,qword ptr ds:[rcx+38] | rcx:CLuaHook::LuaHookInit+150, rcx+38:std::_Xlen_string+8
00007FF7C8158A04 | 48:8BFA | mov rdi,rdx |
00007FF7C8158A07 | 48:8B41 70 | mov rax,qword ptr ds:[rcx+70] | rcx+70:ConsoleThread+20
00007FF7C8158A0B | 48:3941 78 | cmp qword ptr ds:[rcx+78],rax | rcx+78:ConsoleThread+28
00007FF7C8158A0F | 72 0E | jb wow.7FF7C8158A1F |
00007FF7C8158A11 | 807B 7E 00 | cmp byte ptr ds:[rbx+7E],0 | rbx+7E:GetHPAddr+1E
00007FF7C8158A15 | 75 08 | jne wow.7FF7C8158A1F |
00007FF7C8158A17 | 48:8BCB | mov rcx,rbx | rcx:CLuaHook::LuaHookInit+150, rbx:&"testMe"
00007FF7C8158A1A | E8 71B20000 | call wow.7FF7C8163C90 |
00007FF7C8158A1F | 48:8B43 40 | mov rax,qword ptr ds:[rbx+40] | [rbx+40]:MyLua
00007FF7C8158A23 | 48:3B43 68 | cmp rax,qword ptr ds:[rbx+68] | rbx+68:GetHPAddr+8
00007FF7C8158A27 | 75 09 | jne wow.7FF7C8158A32 |
00007FF7C8158A29 | 4C:8B83 90000000 | mov r8,qword ptr ds:[rbx+90] | r8:CLuaHook::LuaHookInit+150, rbx+90:GetHPAddr+30
00007FF7C8158A30 | EB 0B | jmp wow.7FF7C8158A3D |
00007FF7C8158A32 | 48:8B40 08 | mov rax,qword ptr ds:[rax+8] |
00007FF7C8158A36 | 48:8B08 | mov rcx,qword ptr ds:[rax] | rcx:CLuaHook::LuaHookInit+150
00007FF7C8158A39 | 4C:8B41 20 | mov r8,qword ptr ds:[rcx+20] | r8:CLuaHook::LuaHookInit+150, rcx+20:CLuaHook::LuaHookInit+170
00007FF7C8158A3D | 8BD6 | mov edx,esi |
00007FF7C8158A3F | 48:8BCB | mov rcx,rbx | rcx:CLuaHook::LuaHookInit+150, rbx:&"testMe"
00007FF7C8158A42 | E8 F9A20000 | call wow.7FF7C8162D40 |
00007FF7C8158A47 | 4C:8D3476 | lea r14,qword ptr ds:[rsi+rsi*2] |
00007FF7C8158A4B | 48:8BE8 | mov rbp,rax |
00007FF7C8158A4E | 49:C1E6 03 | shl r14,3 |
00007FF7C8158A52 | 48:8978 30 | mov qword ptr ds:[rax+30],rdi |
00007FF7C8158A56 | 4C:2973 28 | sub qword ptr ds:[rbx+28],r14 | [rbx+28]:g_LuaHookFun
00007FF7C8158A5A | 85F6 | test esi,esi |
00007FF7C8158A5C | 74 7D | je wow.7FF7C8158ADB |
00007FF7C8158A5E | 66:90 | nop |
00007FF7C8158A60 | 48:8B7B 28 | mov rdi,qword ptr ds:[rbx+28] | [rbx+28]:g_LuaHookFun
00007FF7C8158A64 | 49:83EE 18 | sub r14,18 |
00007FF7C8158A68 | 49:03FE | add rdi,r14 |
00007FF7C8158A6B | FFCE | dec esi |
00007FF7C8158A6D | 0F1007 | movups xmm0,xmmword ptr ds:[rdi] |
00007FF7C8158A70 | 41:0F11442E 38 | movups xmmword ptr ds:[r14+rbp+38],xmm0 |
00007FF7C8158A76 | F2:0F104F 10 | movsd xmm1,qword ptr ds:[rdi+10] |
00007FF7C8158A7B | F241:0F114C2E 48 | movsd qword ptr ds:[r14+rbp+48],xmm1 |
00007FF7C8158A82 | 48:8B57 10 | mov rdx,qword ptr ds:[rdi+10] |
00007FF7C8158A86 | 48:85D2 | test rdx,rdx |
00007FF7C8158A89 | 74 4C | je wow.7FF7C8158AD7 |
00007FF7C8158A8B | 833D 56D9EF04 00 | cmp dword ptr ds:[7FF7CD0563E8],0 |
00007FF7C8158A92 | 74 43 | je wow.7FF7C8158AD7 |
00007FF7C8158A94 | 833D 51D9EF04 00 | cmp dword ptr ds:[7FF7CD0563EC],0 |
00007FF7C8158A9B | 75 3A | jne wow.7FF7C8158AD7 |
00007FF7C8158A9D | 48:8BCB | mov rcx,rbx | rcx:CLuaHook::LuaHookInit+150, rbx:&"testMe"
00007FF7C8158AA0 | E8 8B950000 | call wow.7FF7C8162030 |
00007FF7C8158AA5 | 48:8B47 10 | mov rax,qword ptr ds:[rdi+10] |
00007FF7C8158AA9 | 48:8905 30D9EF04 | mov qword ptr ds:[7FF7CD0563E0],rax |
00007FF7C8158AB0 | 48:85C0 | test rax,rax |
00007FF7C8158AB3 | 74 22 | je wow.7FF7C8158AD7 |
00007FF7C8158AB5 | 48:833D 4BD9EF04 00 | cmp qword ptr ds:[7FF7CD056408],0 |
00007FF7C8158ABD | 75 18 | jne wow.7FF7C8158AD7 |
00007FF7C8158ABF | 833D 4AD9EF04 00 | cmp dword ptr ds:[7FF7CD056410],0 |
00007FF7C8158AC6 | 48:8905 3BD9EF04 | mov qword ptr ds:[7FF7CD056408],rax |
00007FF7C8158ACD | 74 08 | je wow.7FF7C8158AD7 |
00007FF7C8158ACF | 48:8BCB | mov rcx,rbx | rcx:CLuaHook::LuaHookInit+150, rbx:&"testMe"
00007FF7C8158AD2 | E8 F9E8FFFF | call wow.7FF7C81573D0 |
00007FF7C8158AD7 | 85F6 | test esi,esi |
00007FF7C8158AD9 | 75 85 | jne wow.7FF7C8158A60 |
00007FF7C8158ADB | 48:8B4B 28 | mov rcx,qword ptr ds:[rbx+28] | rcx:CLuaHook::LuaHookInit+150, [rbx+28]:g_LuaHookFun
00007FF7C8158ADF | 48:8B05 FAD8EF04 | mov rax,qword ptr ds:[7FF7CD0563E0] |
00007FF7C8158AE6 | 48:8941 10 | mov qword ptr ds:[rcx+10],rax | rcx+10:CLuaHook::LuaHookInit+160
00007FF7C8158AEA | 48:8929 | mov qword ptr ds:[rcx],rbp | rcx:CLuaHook::LuaHookInit+150
00007FF7C8158AED | C741 08 06000000 | mov dword ptr ds:[rcx+8],6 | rcx+08:CLuaHook::LuaHookInit+158
00007FF7C8158AF4 | 48:8343 28 18 | add qword ptr ds:[rbx+28],18 | [rbx+28]:g_LuaHookFun
00007FF7C8158AF9 | 48:8B4C24 28 | mov rcx,qword ptr ss:[rsp+28] | rcx:CLuaHook::LuaHookInit+150
00007FF7C8158AFE | 48:8B5C24 30 | mov rbx,qword ptr ss:[rsp+30] | [rsp+30]:ConsoleThread+C5
00007FF7C8158B03 | 48:8B6C24 38 | mov rbp,qword ptr ss:[rsp+38] |
00007FF7C8158B08 | 48:8B7424 40 | mov rsi,qword ptr ss:[rsp+40] |
00007FF7C8158B0D | 48:8B7C24 48 | mov rdi,qword ptr ss:[rsp+48] |
00007FF7C8158B12 | 48:83C4 20 | add rsp,20 |
00007FF7C8158B16 | 41:5E | pop r14 |
00007FF7C8158B18 | E9 C3E61203 | jmp <wow.sub_7FF7CB2871E0> |*/
void MyPushCCloure(PBYTE pStart, void* L, lua_CFunction fn, int def = 0) {
DWORD base = 0x9E0;
DWORD call1 = 0xA1A;
PBYTE tmp = nullptr;
tmp = pStart + (call1 - base);
tmp = PBYTE(*(DWORD*)(tmp + 1) + (DWORD64)tmp + 5) ;
PBYTE pL = (PBYTE)L;
PBYTE pRCX = (PBYTE)(*(DWORD64*)(pL + 0x38));
DWORD64 rax = *(DWORD64*)(pRCX + 0x70);
DWORD64 r8 = 0;
if (*(DWORD64*)(pRCX + 0x78) >= rax) {
if (*(PBYTE(pRCX + 0x7E)) == 0) {
typedef void (*fnCall1)(void*);
((fnCall1)(tmp))(L);
}
}
rax = *(DWORD64*)(pL + 0x40);
if (rax == *(DWORD64*)(pL + 0x68)) {
r8 = *(DWORD64*)(pL + 0x90);
}
else {
rax = *(DWORD64*)(PBYTE(rax) + 8);
rax = *(DWORD64*)(rax);
r8 = *(DWORD64*)(PBYTE(rax) + 0x20);
}
//call 2
call1 = 0xA42;
tmp = pStart + (call1 - base);
tmp = PBYTE(*(DWORD*)(tmp + 1) + (DWORD64)tmp + 5) ;
typedef void* (*fnCall2)(void*, int,void*);//Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e)
PBYTE pRet = (PBYTE)((fnCall2)(tmp))(L, 0, (PVOID)r8);
*(lua_CFunction*)(pRet + 0x30) = fn;
pRCX = (PBYTE)(*(DWORD64*)(pL + 0x28));
DWORD offset = 0xADF - base;
tmp = pStart + offset;
tmp = PBYTE(*(DWORD*)(tmp + 3) + (DWORD64)tmp + 7);
rax = *(DWORD64*)tmp;
*(DWORD64*)(pRCX + 0x10) = rax;
*(DWORD64*)(pRCX) = (DWORD64)L;
*(DWORD*)(pRCX + 8) = 6;
*(DWORD64*)(pL + 0x28) = *(DWORD64*)(pL + 0x28)+ 0x18;
}
int DoLuaInit2() {
if (!g_stateLAddr) {
printf("StateL is null\n");
return 0;
}
PVOID pStateL = (PVOID)(*((DWORD64*)g_stateLAddr));
if (!pStateL) {
printf("Lua not init!\n");
return 0;
}
luaPushValue(pStateL, -10002);
typedef void (*fnC2)(void*, const char*);
((fnC2)(g_oba_call2))(pStateL, pLIBName);
luaInsert(pStateL, -2);
typedef void(*fnC3)(void*, int);
((fnC3)(g_oba_call4))(pStateL, -10002);
int lsize = 0;
auto pfn = gPLuaFun;
for (; pfn->pname; pfn++) { lsize++; }
luaFindTable(pStateL, -10000, pLOADED, 1);
luaGetField(pStateL, -1, pLIBName);
if (!(luaType(pStateL, -1) == 5)) {
luaPop(pStateL, -2);
if (luaFindTable(pStateL, -10002, pLIBName, lsize)!=NULL)
luaError(pStateL, "Error replace lib '%s'", pLIBName);
luaPushValue(pStateL, -1);
luaSetField(pStateL, -3, pLIBName);;
}
luaRemove(pStateL, -2);
luaInsert(pStateL, -1);
pfn = gPLuaFun;
for (; pfn->pname; pfn++) {
//luaPushCClosure(pStateL, pfn->pfn, 0);
MyPushCCloure(PBYTE((DWORD64*)luaPushCClosure), pStateL, pfn->pfn, 0);
luaSetField(pStateL, -2, pfn->pname);
}
luaPop(pStateL, -1);
return 1;
}
}