mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2026-06-22 08:31:07 +00:00
clang format
This commit is contained in:
+61
-59
@@ -10,84 +10,86 @@
|
||||
std::unique_ptr<atomic_queue<std::string, 1000>> Queue;
|
||||
|
||||
int BeamNG::lua_open_jit_D(lua_State* State) {
|
||||
Memory::Print("Got lua State");
|
||||
GELua::State = State;
|
||||
RegisterGEFunctions();
|
||||
return OpenJITDetour->Original(State);
|
||||
Memory::Print("Got lua State");
|
||||
GELua::State = State;
|
||||
RegisterGEFunctions();
|
||||
return OpenJITDetour->Original(State);
|
||||
}
|
||||
|
||||
void BeamNG::EntryPoint() {
|
||||
Queue = std::make_unique<atomic_queue<std::string, 1000>>();
|
||||
uint32_t PID = Memory::GetPID();
|
||||
auto status = MH_Initialize();
|
||||
if (status != MH_OK)
|
||||
Memory::Print(std::string("MH Error -> ") + MH_StatusToString(status));
|
||||
Memory::Print("PID : " + std::to_string(PID));
|
||||
GELua::FindAddresses();
|
||||
/*GameBaseAddr = Memory::GetModuleBase(GameModule);
|
||||
DllBaseAddr = Memory::GetModuleBase(DllModule);*/
|
||||
OpenJITDetour = std::make_unique<Hook<def::lua_open_jit>>(GELua::lua_open_jit, lua_open_jit_D);
|
||||
OpenJITDetour->Enable();
|
||||
IPCFromLauncher = std::make_unique<IPC>(PID, 0x1900000);
|
||||
IPCToLauncher = std::make_unique<IPC>(PID + 1, 0x1900000);
|
||||
IPCListener();
|
||||
Queue = std::make_unique<atomic_queue<std::string, 1000>>();
|
||||
uint32_t PID = Memory::GetPID();
|
||||
auto status = MH_Initialize();
|
||||
if (status != MH_OK)
|
||||
Memory::Print(std::string("MH Error -> ") + MH_StatusToString(status));
|
||||
Memory::Print("PID : " + std::to_string(PID));
|
||||
GELua::FindAddresses();
|
||||
/*GameBaseAddr = Memory::GetModuleBase(GameModule);
|
||||
DllBaseAddr = Memory::GetModuleBase(DllModule);*/
|
||||
OpenJITDetour = std::make_unique<Hook<def::lua_open_jit>>(
|
||||
GELua::lua_open_jit, lua_open_jit_D);
|
||||
OpenJITDetour->Enable();
|
||||
IPCFromLauncher = std::make_unique<IPC>(PID, 0x1900000);
|
||||
IPCToLauncher = std::make_unique<IPC>(PID + 1, 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));
|
||||
std::string msg(Data, Size);
|
||||
BeamNG::SendIPC("C" + msg);
|
||||
}
|
||||
return 0;
|
||||
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));
|
||||
std::string msg(Data, Size);
|
||||
BeamNG::SendIPC("C" + msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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));
|
||||
std::string msg(Data, Size);
|
||||
BeamNG::SendIPC("G" + msg);
|
||||
}
|
||||
return 0;
|
||||
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));
|
||||
std::string msg(Data, Size);
|
||||
BeamNG::SendIPC("G" + msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaPop(lua_State* L) {
|
||||
std::string MSG;
|
||||
if (Queue->try_pop(MSG)) {
|
||||
GELua::lua_push_fstring(L, "%s", MSG.c_str());
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
std::string MSG;
|
||||
if (Queue->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!");
|
||||
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!");
|
||||
}
|
||||
|
||||
void BeamNG::SendIPC(const std::string& Data) {
|
||||
IPCToLauncher->send(Data);
|
||||
IPCToLauncher->send(Data);
|
||||
}
|
||||
|
||||
void BeamNG::IPCListener() {
|
||||
int TimeOuts = 0;
|
||||
while (TimeOuts < 20) {
|
||||
IPCFromLauncher->receive();
|
||||
if (!IPCFromLauncher->receive_timed_out()) {
|
||||
TimeOuts = 0;
|
||||
Queue->push(IPCFromLauncher->msg());
|
||||
IPCFromLauncher->confirm_receive();
|
||||
} else
|
||||
TimeOuts++;
|
||||
}
|
||||
Memory::Print("IPC System shutting down");
|
||||
int TimeOuts = 0;
|
||||
while (TimeOuts < 20) {
|
||||
IPCFromLauncher->receive();
|
||||
if (!IPCFromLauncher->receive_timed_out()) {
|
||||
TimeOuts = 0;
|
||||
Queue->push(IPCFromLauncher->msg());
|
||||
IPCFromLauncher->confirm_receive();
|
||||
} else TimeOuts++;
|
||||
}
|
||||
Memory::Print("IPC System shutting down");
|
||||
}
|
||||
|
||||
@@ -12,5 +12,5 @@
|
||||
#include "lua/lj_strscan.h"
|
||||
|
||||
LUA_API int lua_gettop(lua_State* L) {
|
||||
return (int)(L->top - L->base);
|
||||
return (int)(L->top - L->base);
|
||||
}
|
||||
|
||||
+54
-30
@@ -8,39 +8,63 @@
|
||||
#include "Memory/Patterns.h"
|
||||
|
||||
const char* GameModule = "BeamNG.drive.x64.exe";
|
||||
const char* DllModule = "libbeamng.x64.dll";
|
||||
const char* DllModule = "libbeamng.x64.dll";
|
||||
|
||||
std::string GetHex(uint64_t num) {
|
||||
char buffer[30];
|
||||
sprintf(buffer, "%llx", num);
|
||||
return std::string { buffer };
|
||||
char buffer[30];
|
||||
sprintf(buffer, "%llx", num);
|
||||
return std::string{buffer};
|
||||
}
|
||||
|
||||
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));
|
||||
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));
|
||||
}
|
||||
|
||||
+46
-44
@@ -7,85 +7,87 @@
|
||||
#include "Memory/IPC.h"
|
||||
#include <windows.h>
|
||||
|
||||
IPC::IPC(uint32_t ID, size_t Size) noexcept
|
||||
: Size_(Size) {
|
||||
std::string Sem { "MP_S" + std::to_string(ID) },
|
||||
SemConf { "MP_SC" + std::to_string(ID) },
|
||||
Mem { "MP_IO" + std::to_string(ID) };
|
||||
IPC::IPC(uint32_t ID, size_t Size) noexcept : Size_(Size) {
|
||||
std::string Sem{"MP_S" + std::to_string(ID)},
|
||||
SemConf{"MP_SC" + std::to_string(ID)}, Mem{"MP_IO" + std::to_string(ID)};
|
||||
|
||||
SemHandle_ = OpenSemaphoreA(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, FALSE, Sem.c_str());
|
||||
if (SemHandle_ == nullptr) {
|
||||
SemHandle_ = CreateSemaphoreA(nullptr, 0, 1, Sem.c_str());
|
||||
}
|
||||
SemConfHandle_ = OpenSemaphoreA(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, FALSE, SemConf.c_str());
|
||||
if (SemConfHandle_ == nullptr) {
|
||||
SemConfHandle_ = CreateSemaphoreA(nullptr, 0, 1, SemConf.c_str());
|
||||
}
|
||||
MemoryHandle_ = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, Mem.c_str());
|
||||
if (MemoryHandle_ == nullptr) {
|
||||
MemoryHandle_ = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, DWORD(Size), Mem.c_str());
|
||||
}
|
||||
Data_ = (char*)MapViewOfFile(MemoryHandle_, FILE_MAP_ALL_ACCESS, 0, 0, Size);
|
||||
SemHandle_ =
|
||||
OpenSemaphoreA(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, FALSE, Sem.c_str());
|
||||
if (SemHandle_ == nullptr) {
|
||||
SemHandle_ = CreateSemaphoreA(nullptr, 0, 1, Sem.c_str());
|
||||
}
|
||||
SemConfHandle_ = OpenSemaphoreA(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, FALSE,
|
||||
SemConf.c_str());
|
||||
if (SemConfHandle_ == nullptr) {
|
||||
SemConfHandle_ = CreateSemaphoreA(nullptr, 0, 1, SemConf.c_str());
|
||||
}
|
||||
MemoryHandle_ = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, Mem.c_str());
|
||||
if (MemoryHandle_ == nullptr) {
|
||||
MemoryHandle_ =
|
||||
CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0,
|
||||
DWORD(Size), Mem.c_str());
|
||||
}
|
||||
Data_ = (char*)MapViewOfFile(MemoryHandle_, FILE_MAP_ALL_ACCESS, 0, 0, Size);
|
||||
}
|
||||
|
||||
void IPC::confirm_receive() noexcept {
|
||||
ReleaseSemaphore(SemConfHandle_, 1, nullptr);
|
||||
ReleaseSemaphore(SemConfHandle_, 1, nullptr);
|
||||
}
|
||||
|
||||
void IPC::send(const std::string& msg) noexcept {
|
||||
size_t Size = msg.size();
|
||||
memcpy(Data_, &Size, sizeof(size_t));
|
||||
memcpy(Data_ + sizeof(size_t), msg.c_str(), Size);
|
||||
memset(Data_ + sizeof(size_t) + Size, 0, 3);
|
||||
ReleaseSemaphore(SemHandle_, 1, nullptr);
|
||||
SendTimeout = WaitForSingleObject(SemConfHandle_, 5000) == WAIT_TIMEOUT;
|
||||
size_t Size = msg.size();
|
||||
memcpy(Data_, &Size, sizeof(size_t));
|
||||
memcpy(Data_ + sizeof(size_t), msg.c_str(), Size);
|
||||
memset(Data_ + sizeof(size_t) + Size, 0, 3);
|
||||
ReleaseSemaphore(SemHandle_, 1, nullptr);
|
||||
SendTimeout = WaitForSingleObject(SemConfHandle_, 5000) == WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
void IPC::receive() noexcept {
|
||||
RcvTimeout = WaitForSingleObject(SemHandle_, 5000) == WAIT_TIMEOUT;
|
||||
RcvTimeout = WaitForSingleObject(SemHandle_, 5000) == WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
void IPC::try_receive() noexcept {
|
||||
RcvTimeout = WaitForSingleObject(SemHandle_, 0) == WAIT_TIMEOUT;
|
||||
RcvTimeout = WaitForSingleObject(SemHandle_, 0) == WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
size_t IPC::size() const noexcept {
|
||||
return Size_;
|
||||
return Size_;
|
||||
}
|
||||
|
||||
char* IPC::c_str() const noexcept {
|
||||
return Data_ + sizeof(size_t);
|
||||
return Data_ + sizeof(size_t);
|
||||
}
|
||||
|
||||
void* IPC::raw() const noexcept {
|
||||
return Data_ + sizeof(size_t);
|
||||
return Data_ + sizeof(size_t);
|
||||
}
|
||||
|
||||
const std::string& IPC::msg() noexcept {
|
||||
size_t Size;
|
||||
memcpy(&Size, Data_, sizeof(size_t));
|
||||
Msg_ = std::string(c_str(), Size);
|
||||
return Msg_;
|
||||
size_t Size;
|
||||
memcpy(&Size, Data_, sizeof(size_t));
|
||||
Msg_ = std::string(c_str(), Size);
|
||||
return Msg_;
|
||||
}
|
||||
|
||||
bool IPC::receive_timed_out() const noexcept {
|
||||
return RcvTimeout;
|
||||
return RcvTimeout;
|
||||
}
|
||||
|
||||
bool IPC::send_timed_out() const noexcept {
|
||||
return SendTimeout;
|
||||
return SendTimeout;
|
||||
}
|
||||
|
||||
IPC::~IPC() noexcept {
|
||||
UnmapViewOfFile(Data_);
|
||||
CloseHandle(SemHandle_);
|
||||
CloseHandle(MemoryHandle_);
|
||||
UnmapViewOfFile(Data_);
|
||||
CloseHandle(SemHandle_);
|
||||
CloseHandle(MemoryHandle_);
|
||||
}
|
||||
|
||||
bool IPC::mem_used(uint32_t MemID) noexcept {
|
||||
std::string Mem { "MP_IO" + std::to_string(MemID) };
|
||||
HANDLE MEM = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, Mem.c_str());
|
||||
bool used = MEM != nullptr;
|
||||
UnmapViewOfFile(MEM);
|
||||
return used;
|
||||
std::string Mem{"MP_IO" + std::to_string(MemID)};
|
||||
HANDLE MEM = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, Mem.c_str());
|
||||
bool used = MEM != nullptr;
|
||||
UnmapViewOfFile(MEM);
|
||||
return used;
|
||||
}
|
||||
|
||||
+100
-80
@@ -6,131 +6,151 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#undef UNICODE
|
||||
#include "Memory/Memory.h"
|
||||
#include "Memory/BeamNG.h"
|
||||
#include <psapi.h>
|
||||
#include <string>
|
||||
#include <tlhelp32.h>
|
||||
#include <string>
|
||||
#include "Memory/BeamNG.h"
|
||||
|
||||
uint32_t Memory::GetBeamNGPID(const std::set<uint32_t>& BL) {
|
||||
SetLastError(0);
|
||||
PROCESSENTRY32 pe32;
|
||||
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||||
HANDLE Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
SetLastError(0);
|
||||
PROCESSENTRY32 pe32;
|
||||
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||||
HANDLE Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
|
||||
if (Process32First(Snapshot, &pe32)) {
|
||||
do {
|
||||
if (std::string("BeamNG.drive.x64.exe") == pe32.szExeFile
|
||||
&& BL.find(pe32.th32ProcessID) == BL.end()
|
||||
&& BL.find(pe32.th32ParentProcessID) == BL.end()) {
|
||||
break;
|
||||
}
|
||||
} while (Process32Next(Snapshot, &pe32));
|
||||
}
|
||||
if (Process32First(Snapshot, &pe32)) {
|
||||
do {
|
||||
if (std::string("BeamNG.drive.x64.exe") == pe32.szExeFile &&
|
||||
BL.find(pe32.th32ProcessID) == BL.end() &&
|
||||
BL.find(pe32.th32ParentProcessID) == BL.end()) {
|
||||
break;
|
||||
}
|
||||
} while (Process32Next(Snapshot, &pe32));
|
||||
}
|
||||
|
||||
if (Snapshot != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(Snapshot);
|
||||
}
|
||||
if (Snapshot != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(Snapshot);
|
||||
}
|
||||
|
||||
if (GetLastError() != 0)
|
||||
return 0;
|
||||
return pe32.th32ProcessID;
|
||||
if (GetLastError() != 0) return 0;
|
||||
return pe32.th32ProcessID;
|
||||
}
|
||||
|
||||
uint64_t Memory::GetModuleBase(const char* Name) {
|
||||
return (uint64_t)GetModuleHandleA(Name);
|
||||
return (uint64_t)GetModuleHandleA(Name);
|
||||
}
|
||||
|
||||
uint32_t Memory::GetPID() {
|
||||
return GetCurrentProcessId();
|
||||
return GetCurrentProcessId();
|
||||
}
|
||||
|
||||
uint64_t Memory::FindPattern(const char* module, const char* Pattern[]) {
|
||||
MODULEINFO mInfo { nullptr };
|
||||
GetModuleInformation(GetCurrentProcess(), GetModuleHandleA(module), &mInfo, sizeof(MODULEINFO));
|
||||
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++) {
|
||||
found &= Pattern[1][j] == '?' || Pattern[0][j] == *(char*)(base + i + j);
|
||||
}
|
||||
if (found) {
|
||||
return base + i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
MODULEINFO mInfo{nullptr};
|
||||
GetModuleInformation(GetCurrentProcess(), GetModuleHandleA(module), &mInfo,
|
||||
sizeof(MODULEINFO));
|
||||
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++) {
|
||||
found &=
|
||||
Pattern[1][j] == '?' || Pattern[0][j] == *(char*)(base + i + j);
|
||||
}
|
||||
if (found) {
|
||||
return base + i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* operator new(size_t size) {
|
||||
return GlobalAlloc(GPTR, size);
|
||||
return GlobalAlloc(GPTR, size);
|
||||
}
|
||||
|
||||
void* operator new[](size_t size) {
|
||||
return GlobalAlloc(GPTR, size);
|
||||
return GlobalAlloc(GPTR, size);
|
||||
}
|
||||
|
||||
void operator delete(void* p) noexcept {
|
||||
GlobalFree(p);
|
||||
GlobalFree(p);
|
||||
}
|
||||
|
||||
void operator delete[](void* p) noexcept {
|
||||
GlobalFree(p);
|
||||
GlobalFree(p);
|
||||
}
|
||||
|
||||
typedef struct BASE_RELOCATION_ENTRY {
|
||||
USHORT Offset : 12;
|
||||
USHORT Type : 4;
|
||||
USHORT Offset : 12;
|
||||
USHORT Type : 4;
|
||||
} BASE_RELOCATION_ENTRY, *PBASE_RELOCATION_ENTRY;
|
||||
|
||||
void Memory::Inject(uint32_t PID) {
|
||||
PVOID imageBase = GetModuleHandle(nullptr);
|
||||
auto dosHeader = (PIMAGE_DOS_HEADER)imageBase;
|
||||
auto ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeader->e_lfanew);
|
||||
PVOID imageBase = GetModuleHandle(nullptr);
|
||||
auto dosHeader = (PIMAGE_DOS_HEADER)imageBase;
|
||||
auto ntHeader =
|
||||
(PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeader->e_lfanew);
|
||||
|
||||
PVOID localImage = VirtualAlloc(nullptr, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_READWRITE);
|
||||
memcpy(localImage, imageBase, ntHeader->OptionalHeader.SizeOfImage);
|
||||
PVOID localImage =
|
||||
VirtualAlloc(nullptr, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
memcpy(localImage, imageBase, ntHeader->OptionalHeader.SizeOfImage);
|
||||
|
||||
HANDLE targetProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, PID);
|
||||
PVOID targetImage = VirtualAllocEx(targetProcess, nullptr, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
HANDLE targetProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, PID);
|
||||
PVOID targetImage = VirtualAllocEx(targetProcess, nullptr,
|
||||
ntHeader->OptionalHeader.SizeOfImage,
|
||||
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
|
||||
DWORD_PTR deltaImageBase = DWORD_PTR(targetImage) - DWORD_PTR(imageBase);
|
||||
DWORD_PTR deltaImageBase = DWORD_PTR(targetImage) - DWORD_PTR(imageBase);
|
||||
|
||||
auto relocationTable = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)localImage + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
|
||||
PDWORD_PTR patchedAddress;
|
||||
while (relocationTable->SizeOfBlock > 0) {
|
||||
DWORD relocationEntriesCount = (relocationTable->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
|
||||
auto relocationRVA = (PBASE_RELOCATION_ENTRY)(relocationTable + 1);
|
||||
for (uint32_t i = 0; i < relocationEntriesCount; i++) {
|
||||
if (relocationRVA[i].Offset) {
|
||||
patchedAddress = PDWORD_PTR(DWORD_PTR(localImage) + relocationTable->VirtualAddress + relocationRVA[i].Offset);
|
||||
*patchedAddress += deltaImageBase;
|
||||
}
|
||||
}
|
||||
relocationTable = PIMAGE_BASE_RELOCATION(DWORD_PTR(relocationTable) + relocationTable->SizeOfBlock);
|
||||
}
|
||||
WriteProcessMemory(targetProcess, targetImage, localImage, ntHeader->OptionalHeader.SizeOfImage, nullptr);
|
||||
CreateRemoteThread(targetProcess, nullptr, 0, (LPTHREAD_START_ROUTINE)((DWORD_PTR)EntryPoint + deltaImageBase), nullptr, 0, nullptr);
|
||||
CloseHandle(targetProcess);
|
||||
auto relocationTable =
|
||||
(PIMAGE_BASE_RELOCATION)((DWORD_PTR)localImage +
|
||||
ntHeader->OptionalHeader
|
||||
.DataDirectory
|
||||
[IMAGE_DIRECTORY_ENTRY_BASERELOC]
|
||||
.VirtualAddress);
|
||||
PDWORD_PTR patchedAddress;
|
||||
while (relocationTable->SizeOfBlock > 0) {
|
||||
DWORD relocationEntriesCount =
|
||||
(relocationTable->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) /
|
||||
sizeof(USHORT);
|
||||
auto relocationRVA = (PBASE_RELOCATION_ENTRY)(relocationTable + 1);
|
||||
for (uint32_t i = 0; i < relocationEntriesCount; i++) {
|
||||
if (relocationRVA[i].Offset) {
|
||||
patchedAddress = PDWORD_PTR(DWORD_PTR(localImage) +
|
||||
relocationTable->VirtualAddress +
|
||||
relocationRVA[i].Offset);
|
||||
*patchedAddress += deltaImageBase;
|
||||
}
|
||||
}
|
||||
relocationTable = PIMAGE_BASE_RELOCATION(DWORD_PTR(relocationTable) +
|
||||
relocationTable->SizeOfBlock);
|
||||
}
|
||||
WriteProcessMemory(targetProcess, targetImage, localImage,
|
||||
ntHeader->OptionalHeader.SizeOfImage, nullptr);
|
||||
CreateRemoteThread(
|
||||
targetProcess, nullptr, 0,
|
||||
(LPTHREAD_START_ROUTINE)((DWORD_PTR)EntryPoint + deltaImageBase),
|
||||
nullptr, 0, nullptr);
|
||||
CloseHandle(targetProcess);
|
||||
}
|
||||
|
||||
void Memory::Print(const std::string& msg) {
|
||||
HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (stdOut != nullptr && stdOut != INVALID_HANDLE_VALUE) {
|
||||
DWORD written = 0;
|
||||
WriteConsoleA(stdOut, "[BeamMP] ", 9, &written, nullptr);
|
||||
WriteConsoleA(stdOut, msg.c_str(), DWORD(msg.size()), &written, nullptr);
|
||||
WriteConsoleA(stdOut, "\n", 1, &written, nullptr);
|
||||
}
|
||||
HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (stdOut != nullptr && stdOut != INVALID_HANDLE_VALUE) {
|
||||
DWORD written = 0;
|
||||
WriteConsoleA(stdOut, "[BeamMP] ", 9, &written, nullptr);
|
||||
WriteConsoleA(stdOut, msg.c_str(), DWORD(msg.size()), &written, nullptr);
|
||||
WriteConsoleA(stdOut, "\n", 1, &written, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Memory::EntryPoint() {
|
||||
AllocConsole();
|
||||
SetConsoleTitleA("BeamMP Console");
|
||||
BeamNG::EntryPoint();
|
||||
return 0;
|
||||
AllocConsole();
|
||||
SetConsoleTitleA("BeamMP Console");
|
||||
BeamNG::EntryPoint();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Memory::GetTickCount() {
|
||||
return ::GetTickCount();
|
||||
return ::GetTickCount();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user