lots of work, added atomic queue, changed githuyb workflows and added patterns with memory functions. Changed from MS Detours to MinHook.

now works with lua prototype
This commit is contained in:
Anonymous275
2022-02-22 16:19:53 +02:00
parent 6dfeba1e49
commit 19d7120b13
22 changed files with 189 additions and 164 deletions

View File

@@ -3,56 +3,39 @@
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
///
#include "atomic_queue/atomic_queue.h"
#include "Memory/BeamNG.h"
#include "Memory/Memory.h"
uint32_t BeamNG::GetTickCount_D() {
if(GELua::State != nullptr) {
IPCFromLauncher->try_receive();
if(!IPCFromLauncher->receive_timed_out()) {
if(IPCFromLauncher->msg()[0] == 'C') {
GELua::lua_get_field(GELua::State, -10002, "handleCoreMsg");
Memory::Print(std::string("Sending to handleCoreMsg -> ") + char(IPCFromLauncher->msg()[1]) + std::to_string(IPCFromLauncher->msg().size()) );
} else {
GELua::lua_get_field(GELua::State, -10002, "handleGameMsg");
Memory::Print(std::string("Sending to handleGameMsg -> ") + char(IPCFromLauncher->msg()[1]) + std::to_string(IPCFromLauncher->msg().size()) );
}
GELua::lua_push_fstring(GELua::State, "%s", &IPCFromLauncher->c_str()[1]);
GELua::lua_p_call(GELua::State, 1, 0, 0);
IPCFromLauncher->confirm_receive();
}
}
return Memory::GetTickCount();
}
atomic_queue::AtomicQueue2<std::string, 1000> AtomicQueue;
int BeamNG::lua_open_jit_D(lua_State* State) {
Memory::Print("Got lua State");
GELua::State = State;
RegisterGEFunctions();
OpenJITDetour->Detach();
int r = GELua::lua_open_jit(State);
OpenJITDetour->Attach();
return r;
return OpenJITDetour->Original(State);
}
void BeamNG::EntryPoint() {
auto status = MH_Initialize();
if(status != MH_OK)Memory::Print(std::string("MH Error -> ") + MH_StatusToString(status));
Memory::Print("PID : " + std::to_string(Memory::GetPID()));
GELua::FindAddresses();
/*GameBaseAddr = Memory::GetModuleBase(GameModule);
DllBaseAddr = Memory::GetModuleBase(DllModule);*/
TickCountDetour = std::make_unique<Detours>((void*)GELua::GetTickCount, (void*)GetTickCount_D);
TickCountDetour->Attach();
OpenJITDetour = std::make_unique<Detours>((void*)GELua::lua_open_jit, (void*)lua_open_jit_D);
OpenJITDetour->Attach();
OpenJITDetour = std::make_unique<Hook<def::lua_open_jit>>(GELua::lua_open_jit, lua_open_jit_D);
OpenJITDetour->Enable();
IPCToLauncher = std::make_unique<IPC>("BeamMP_IN", "BeamMP_Sem3", "BeamMP_Sem4", 0x1900000);
IPCFromLauncher = std::make_unique<IPC>("BeamMP_OUT", "BeamMP_Sem1", "BeamMP_Sem2", 0x1900000);
IPCListener();
}
int Core(lua_State* L) {
if(lua_gettop(L) == 1) {
size_t Size;
const char* Data = GELua::lua_tolstring(L, 1, &Size);
Memory::Print("Core -> " + std::string(Data) + " - " + std::to_string(Size));
//Memory::Print("Core -> " + std::string(Data) + " - " + std::to_string(Size));
std::string msg(Data, Size);
BeamNG::SendIPC("C" + msg);
}
@@ -63,18 +46,28 @@ int Game(lua_State* L) {
if(lua_gettop(L) == 1) {
size_t Size;
const char* Data = GELua::lua_tolstring(L, 1, &Size);
Memory::Print("Game -> " + std::string(Data) + " - " + std::to_string(Size));
//Memory::Print("Game -> " + std::string(Data) + " - " + std::to_string(Size));
std::string msg(Data, Size);
BeamNG::SendIPC("G" + msg);
}
return 0;
}
int LuaPop(lua_State* L) {
std::string MSG;
if (AtomicQueue.try_pop(MSG)) {
GELua::lua_push_fstring(L, "%s", MSG.c_str());
return 1;
}
return 0;
}
void BeamNG::RegisterGEFunctions() {
Memory::Print("Registering GE Functions");
GELuaTable::Begin(GELua::State);
GELuaTable::InsertFunction(GELua::State, "Core", Core);
GELuaTable::InsertFunction(GELua::State, "Game", Game);
GELuaTable::InsertFunction(GELua::State, "try_pop", LuaPop);
GELuaTable::End(GELua::State, "MP");
Memory::Print("Registered!");
}
@@ -83,9 +76,15 @@ void BeamNG::SendIPC(const std::string& Data) {
IPCToLauncher->send(Data);
}
std::unique_ptr<Detours> BeamNG::TickCountDetour;
std::unique_ptr<Detours> BeamNG::OpenJITDetour;
std::unique_ptr<IPC> BeamNG::IPCFromLauncher;
std::unique_ptr<IPC> BeamNG::IPCToLauncher;
uint64_t BeamNG::GameBaseAddr;
uint64_t BeamNG::DllBaseAddr;
void BeamNG::IPCListener() {
int TimeOuts = 0;
while(TimeOuts < 20) {
IPCFromLauncher->receive();
if (!IPCFromLauncher->receive_timed_out()) {
TimeOuts = 0;
AtomicQueue.push(IPCFromLauncher->msg());
IPCFromLauncher->confirm_receive();
} else TimeOuts++;
}
Memory::Print("IPC System shutting down");
}

View File

@@ -1,29 +0,0 @@
///
/// Created by Anonymous275 on 1/21/22
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
///
#define WIN32_LEAN_AND_MEAN
#include "Memory/Detours.h"
#include <windows.h>
#include "detours/detours.h"
void Detours::Attach() {
if(!Attached){
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&targetPtr,detourFunc);
DetourTransactionCommit();
Attached = true;
}
}
void Detours::Detach() {
if(Attached){
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&targetPtr,detourFunc);
DetourTransactionCommit();
Attached = false;
}
}

View File

@@ -10,29 +10,37 @@
const char* GameModule = "BeamNG.drive.x64.exe";
const char* DllModule = "libbeamng.x64.dll";
void GELua::FindAddresses() {
GELua::State = nullptr;
GetTickCount = reinterpret_cast<def::GetTickCount>(Memory::FindPattern(GameModule, Patterns::GetTickCount));
lua_open_jit = reinterpret_cast<def::lua_open_jit>(Memory::FindPattern(GameModule, Patterns::open_jit));
lua_push_fstring = reinterpret_cast<def::lua_push_fstring>(Memory::FindPattern(GameModule, Patterns::push_fstring));
lua_get_field = reinterpret_cast<def::lua_get_field>(Memory::FindPattern(GameModule, Patterns::get_field));
lua_p_call = reinterpret_cast<def::lua_p_call>(Memory::FindPattern(GameModule, Patterns::p_call));
lua_createtable = reinterpret_cast<def::lua_createtable>(Memory::FindPattern(GameModule, Patterns::lua_createtable));
lua_pushcclosure = reinterpret_cast<def::lua_pushcclosure>(Memory::FindPattern(GameModule, Patterns::lua_pushcclosure));
lua_setfield = reinterpret_cast<def::lua_setfield>(Memory::FindPattern(GameModule, Patterns::lua_setfield));
lua_settable = reinterpret_cast<def::lua_settable>(Memory::FindPattern(GameModule, Patterns::lua_settable));
lua_tolstring = reinterpret_cast<def::lua_tolstring>(Memory::FindPattern(GameModule, Patterns::lua_tolstring));
std::string GetHex(uint64_t num) {
char buffer[30];
sprintf(buffer, "%llx", num);
return std::string{buffer};
}
def::GetTickCount GELua::GetTickCount;
def::lua_open_jit GELua::lua_open_jit;
def::lua_push_fstring GELua::lua_push_fstring;
def::lua_get_field GELua::lua_get_field;
def::lua_p_call GELua::lua_p_call;
def::lua_createtable GELua::lua_createtable;
def::lua_pushcclosure GELua::lua_pushcclosure;
def::lua_setfield GELua::lua_setfield;
def::lua_settable GELua::lua_settable;
def::lua_tolstring GELua::lua_tolstring;
lua_State* GELua::State;
void GELua::FindAddresses() {
GELua::State = nullptr;
auto Base = Memory::GetModuleBase(GameModule);
GetTickCount = reinterpret_cast<def::GetTickCount>(Memory::FindPattern(GameModule, Patterns::GetTickCount));
Memory::Print("GetTickCount -> " + GetHex(reinterpret_cast<uint64_t>(GetTickCount) - Base));
lua_open_jit = reinterpret_cast<def::lua_open_jit>(Memory::FindPattern(GameModule, Patterns::open_jit));
Memory::Print("lua_open_jit -> " + GetHex(reinterpret_cast<uint64_t>(lua_open_jit) - Base));
lua_push_fstring = reinterpret_cast<def::lua_push_fstring>(Memory::FindPattern(GameModule, Patterns::push_fstring));
Memory::Print("lua_push_fstring -> " + GetHex(reinterpret_cast<uint64_t>(lua_push_fstring) - Base));
lua_get_field = reinterpret_cast<def::lua_get_field>(Memory::FindPattern(GameModule, Patterns::get_field));
Memory::Print("lua_get_field -> " + GetHex(reinterpret_cast<uint64_t>(lua_get_field) - Base));
lua_p_call = reinterpret_cast<def::lua_p_call>(Memory::FindPattern(GameModule, Patterns::p_call));
Memory::Print("lua_p_call -> " + GetHex(reinterpret_cast<uint64_t>(lua_p_call) - Base));
lua_createtable = reinterpret_cast<def::lua_createtable>(Memory::FindPattern(GameModule, Patterns::lua_createtable));
Memory::Print("lua_createtable -> " + GetHex(reinterpret_cast<uint64_t>(lua_createtable) - Base));
lua_pushcclosure = reinterpret_cast<def::lua_pushcclosure>(Memory::FindPattern(GameModule, Patterns::lua_pushcclosure));
Memory::Print("lua_pushcclosure -> " + GetHex(reinterpret_cast<uint64_t>(lua_pushcclosure) - Base));
lua_setfield = reinterpret_cast<def::lua_setfield>(Memory::FindPattern(GameModule, Patterns::lua_setfield));
Memory::Print("lua_setfield -> " + GetHex(reinterpret_cast<uint64_t>(lua_setfield) - Base));
lua_settable = reinterpret_cast<def::lua_settable>(Memory::FindPattern(GameModule, Patterns::lua_settable));
Memory::Print("lua_settable -> " + GetHex(reinterpret_cast<uint64_t>(lua_settable) - Base));
lua_tolstring = reinterpret_cast<def::lua_tolstring>(Memory::FindPattern(GameModule, Patterns::lua_tolstring));
Memory::Print("lua_tolstring -> " + GetHex(reinterpret_cast<uint64_t>(lua_tolstring) - Base));
GEUpdate = reinterpret_cast<def::GEUpdate>(Memory::FindPattern(GameModule, Patterns::GEUpdate));
Memory::Print("GEUpdate -> " + GetHex(reinterpret_cast<uint64_t>(GEUpdate) - Base));
lua_settop = reinterpret_cast<def::lua_settop>(Memory::FindPattern(GameModule, Patterns::lua_settop));
Memory::Print("lua_settop -> " + GetHex(reinterpret_cast<uint64_t>(lua_settop) - Base));
}

View File

@@ -10,11 +10,11 @@
IPC::IPC(const char* MemID, const char* SemID, const char* SemID2, size_t Size) noexcept : Size_(Size) {
SemHandle_ = OpenSemaphoreA(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, FALSE, SemID);
if(SemHandle_ == nullptr) {
SemHandle_ = CreateSemaphoreA(nullptr, 0, 2, SemID);
SemHandle_ = CreateSemaphoreA(nullptr, 0, 1, SemID);
}
SemConfHandle_ = OpenSemaphoreA(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, FALSE, SemID2);
if(SemConfHandle_ == nullptr) {
SemConfHandle_ = CreateSemaphoreA(nullptr, 0, 2, SemID2);
SemConfHandle_ = CreateSemaphoreA(nullptr, 0, 1, SemID2);
}
MemoryHandle_ = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, MemID);
if(MemoryHandle_ == nullptr) {

View File

@@ -5,12 +5,12 @@
#define WIN32_LEAN_AND_MEAN
#undef UNICODE
#include <string>
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#include "Memory/Memory.h"
#include "Memory/BeamNG.h"
#include <string>
#include <tlhelp32.h>
#include <psapi.h>
uint32_t Memory::GetBeamNGPID() {
SetLastError(0);
@@ -46,7 +46,6 @@ uint64_t Memory::FindPattern(const char* module, const char* Pattern[]) {
auto base = uint64_t(mInfo.lpBaseOfDll);
auto size = uint32_t(mInfo.SizeOfImage);
auto len = strlen(Pattern[1]);
for(auto i = 0; i < size - len; i++) {
bool found = true;
for(auto j = 0; j < len && found; j++) {
@@ -56,7 +55,6 @@ uint64_t Memory::FindPattern(const char* module, const char* Pattern[]) {
return base+i;
}
}
return 0;
}