mirror of
https://github.com/BeamMP/BeamMP-Launcher.git
synced 2026-04-11 02:06:07 +00:00
Lot of work and added MS Detours
This commit is contained in:
28
src/Memory/BeamNG.cpp
Normal file
28
src/Memory/BeamNG.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/21/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#include "Memory/Patterns.h"
|
||||
#include "Memory/BeamNG.h"
|
||||
#include "Memory/Memory.h"
|
||||
|
||||
std::string GetHex(uint64_t num) {
|
||||
char buffer[30];
|
||||
sprintf(buffer, "%llx", num);
|
||||
return std::string{buffer};
|
||||
}
|
||||
|
||||
void BeamNG::EntryPoint() {
|
||||
auto GameBaseAddr = Memory::GetModuleBase("BeamNG.drive.x64.exe");
|
||||
auto DllBaseAddr = Memory::GetModuleBase("libbeamng.x64.dll");
|
||||
Memory::Print("PID : " + std::to_string(Memory::GetPID()));
|
||||
|
||||
auto res = Memory::FindByPattern("BeamNG.drive.x64.exe", Patterns::GetTickCount[0], Patterns::GetTickCount[1]);
|
||||
auto res2 = Memory::FindByPattern("BeamNG.drive.x64.exe", Patterns::open_jit[0], Patterns::open_jit[1]);
|
||||
auto res3 = Memory::FindByPattern("BeamNG.drive.x64.exe", Patterns::get_field[0], Patterns::get_field[1]);
|
||||
auto res4 = Memory::FindByPattern("BeamNG.drive.x64.exe", Patterns::push_fstring[0], Patterns::push_fstring[1]);
|
||||
auto res5 = Memory::FindByPattern("BeamNG.drive.x64.exe", Patterns::p_call[0], Patterns::p_call[1]);
|
||||
|
||||
|
||||
}
|
||||
29
src/Memory/Detours.cpp
Normal file
29
src/Memory/Detours.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
///
|
||||
/// 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;
|
||||
}
|
||||
}
|
||||
131
src/Memory/Memory.cpp
Normal file
131
src/Memory/Memory.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
///
|
||||
/// Created by Anonymous275 on 1/21/22
|
||||
/// Copyright (c) 2021-present Anonymous275 read the LICENSE file for more info.
|
||||
///
|
||||
|
||||
#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"
|
||||
|
||||
uint32_t Memory::GetBeamNGPID() {
|
||||
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)break;
|
||||
}while(Process32Next(Snapshot, &pe32));
|
||||
}
|
||||
|
||||
if(Snapshot != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(Snapshot);
|
||||
}
|
||||
|
||||
if(GetLastError() != 0)return 0;
|
||||
return pe32.th32ProcessID;
|
||||
}
|
||||
|
||||
uint64_t Memory::GetModuleBase(const char* Name) {
|
||||
return (uint64_t)GetModuleHandleA(Name);
|
||||
}
|
||||
|
||||
uint32_t Memory::GetPID() {
|
||||
return GetCurrentProcessId();
|
||||
}
|
||||
|
||||
uint64_t Memory::FindByPattern(const char* module, const char* Pattern, const char* Mask) {
|
||||
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(Mask);
|
||||
|
||||
for(auto i = 0; i < size - len; i++) {
|
||||
bool found = true;
|
||||
for(auto j = 0; j < len && found; j++) {
|
||||
found &= Mask[j] == '?' || Pattern[j] == *(char*)(base+i+j);
|
||||
}
|
||||
if(found) {
|
||||
return base+i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void* operator new(size_t size) {
|
||||
return GlobalAlloc(GPTR, size);
|
||||
}
|
||||
|
||||
void* operator new[](size_t size) {
|
||||
return GlobalAlloc(GPTR, size);
|
||||
}
|
||||
|
||||
void operator delete(void* p) noexcept {
|
||||
GlobalFree(p);
|
||||
}
|
||||
|
||||
void operator delete[](void* p) noexcept {
|
||||
GlobalFree(p);
|
||||
}
|
||||
|
||||
typedef struct BASE_RELOCATION_ENTRY {
|
||||
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 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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Memory::EntryPoint() {
|
||||
AllocConsole();
|
||||
SetConsoleTitleA("BeamMP Console");
|
||||
BeamNG::EntryPoint();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user