clang format

This commit is contained in:
Anonymous275
2022-07-26 11:43:45 +03:00
parent b26fb43746
commit 3c96bb3959
34 changed files with 1912 additions and 1832 deletions
+61 -59
View File
@@ -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");
}
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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();
}