mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Merge pull request #4 from PixieCore/master
Updated PatternScan and added more gameclasses.
This commit is contained in:
commit
4a4af50039
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "patterns.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Enums
|
||||
@ -223,22 +224,22 @@ enum ButtonCode_t
|
||||
class CInputSystem
|
||||
{
|
||||
public:
|
||||
void EnableInput(bool bEnabled)
|
||||
void EnableInput(bool bEnabled)// @0x14039F100 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void(__thiscall*)(CInputSystem*, bool);
|
||||
(*reinterpret_cast<OriginalFn**>(this))[10](this, bEnabled); // EnableInput is virtual function index 10 in the CInputSystem virtual table.
|
||||
(*reinterpret_cast<OriginalFn**>(this))[10](this, bEnabled);
|
||||
}
|
||||
|
||||
void EnableMessagePump(bool bEnabled)
|
||||
void EnableMessagePump(bool bEnabled) // @0x14039F110 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void(__thiscall*)(CInputSystem*, bool);
|
||||
(*reinterpret_cast<OriginalFn**>(this))[11](this, bEnabled); // EnableMessagePump is virtual function index 11 in the CInputSystem virtual table.
|
||||
(*reinterpret_cast<OriginalFn**>(this))[11](this, bEnabled);
|
||||
}
|
||||
|
||||
bool IsButtonDown(ButtonCode_t Button)
|
||||
bool IsButtonDown(ButtonCode_t Button) // @0x1403A0140 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = bool(__thiscall*)(CInputSystem*, ButtonCode_t);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[13](this, Button); // IsButtonDown is virtual function index 13 in the CInputSystem virtual table.
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[13](this, Button);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -247,3 +248,205 @@ public:
|
||||
bool m_bEnabled; //0x0010 IsInputEnabled variable.
|
||||
bool m_bPumpEnabled; //0x0011 EnabledMessagePump variable.
|
||||
};
|
||||
|
||||
typedef int HKeySymbol;
|
||||
|
||||
class CKeyValuesSystem // VTABLE @ 0x1413AA1E8 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
public:
|
||||
|
||||
void RegisterSizeofKeyValues(__int64 size) //@0x1413AA1F0 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void(__thiscall*)(CKeyValuesSystem*, __int64);
|
||||
(*reinterpret_cast<OriginalFn**>(this))[0](this, size);
|
||||
}
|
||||
|
||||
void* AllocKeyValuesMemory(__int64 size) // @0x1413AA1F8 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void*(__thiscall*)(CKeyValuesSystem*, __int64);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[1](this, size);
|
||||
}
|
||||
|
||||
void FreeKeyValuesMemory(void* pMem) // @0x1413AA200 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void(__thiscall*)(CKeyValuesSystem*, void*);
|
||||
(*reinterpret_cast<OriginalFn**>(this))[2](this, pMem);
|
||||
}
|
||||
|
||||
HKeySymbol GetSymbolForString(const char* name, bool bCreate) // @0x1413AA208 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = HKeySymbol(__thiscall*)(CKeyValuesSystem*, const char*, bool);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[3](this, name, bCreate);
|
||||
}
|
||||
|
||||
const char* GetStringForSymbol(HKeySymbol symbol) // @0x1413AA210 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = const char*(__thiscall*)(CKeyValuesSystem*, HKeySymbol);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[4](this, symbol);
|
||||
}
|
||||
|
||||
// void __fastcall CKeyValuesSystem::FreeKeyValuesMemory(CKeyValuesSystem* this_arg, void* ptr_mem_arg)
|
||||
// {
|
||||
// __int64* v2; // rax
|
||||
// __int64 v4; // rax
|
||||
// __int64* v5; // rax
|
||||
//
|
||||
// v2 = qword_14D40B538;
|
||||
// if (!qword_14D40B538)
|
||||
// {
|
||||
// v2 = sub_140462930();
|
||||
// qword_14D40B538 = v2;
|
||||
// }
|
||||
// v4 = (*(*v2 + 48))(v2, ptr_mem_arg);
|
||||
// if (v4 > 0)
|
||||
// CKeyValuesSystem::m_pMemPool -= v4;
|
||||
// v5 = qword_14D40B538;
|
||||
// if (!qword_14D40B538)
|
||||
// {
|
||||
// v5 = sub_140462930();
|
||||
// qword_14D40B538 = v5;
|
||||
// }
|
||||
// (*(*v5 + 40))(v5, ptr_mem_arg);
|
||||
// }
|
||||
|
||||
// GetMemPool return a global variable called m_pMemPool it gets modified by AllocKeyValuesMemory and FreeKeyValuesMemory above you can see where the find it in FreeKeyValuesMemory.
|
||||
void* GetMemPool() // @0x1413AA228 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
return reinterpret_cast<void*>(0x14D412768); // May need to dereference is once more not sure right now.
|
||||
}
|
||||
|
||||
void SetKeyValuesExpressionSymbol(const char* name, bool bValue) // @0x1413AA230 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = void(__thiscall*)(CKeyValuesSystem*, const char*, bool);
|
||||
(*reinterpret_cast<OriginalFn**>(this))[8](this, name, bValue);
|
||||
}
|
||||
|
||||
bool GetKeyValuesExpressionSymbol(const char* name) // @0x1413AA238 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = bool(__thiscall*)(CKeyValuesSystem*, const char*);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[9](this, name);
|
||||
}
|
||||
|
||||
HKeySymbol GetSymbolForStringCaseSensitive(HKeySymbol& hCaseInsensitiveSymbol, const char* name, bool bCreate) // @0x1413AA240 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
|
||||
{
|
||||
using OriginalFn = HKeySymbol(__thiscall*)(CKeyValuesSystem*, HKeySymbol&, const char*, bool);
|
||||
return (*reinterpret_cast<OriginalFn**>(this))[10](this, hCaseInsensitiveSymbol, name, bCreate);
|
||||
}
|
||||
|
||||
// Datatypes aren't accurate. But full fill the actual byte distance.
|
||||
public:
|
||||
void* vtable;
|
||||
__int64 m_iMaxKeyValuesSize;
|
||||
private:
|
||||
char gap10[240];
|
||||
public:
|
||||
int m_KvConditionalSymbolTable;
|
||||
private:
|
||||
char gap104[4];
|
||||
public:
|
||||
__int64 field_108;
|
||||
private:
|
||||
char gap110[32];
|
||||
public:
|
||||
int m_mutex;
|
||||
};
|
||||
|
||||
enum KeyValuesTypes
|
||||
{
|
||||
TYPE_NONE = 0x0,
|
||||
TYPE_STRING = 0x1,
|
||||
TYPE_INT = 0x2,
|
||||
TYPE_FLOAT = 0x3,
|
||||
TYPE_PTR = 0x4,
|
||||
TYPE_WSTRING = 0x5,
|
||||
TYPE_COLOR = 0x6,
|
||||
TYPE_UINT64 = 0x7,
|
||||
TYPE_COMPILED_INT_BYTE = 0x8,
|
||||
TYPE_COMPILED_INT_0 = 0x9,
|
||||
TYPE_COMPILED_INT_1 = 0xA,
|
||||
TYPE_NUMTYPES = 0xB,
|
||||
};
|
||||
|
||||
class KeyValues
|
||||
{
|
||||
public:
|
||||
|
||||
KeyValues* FindKey(const char* keyName, bool bCreate)
|
||||
{
|
||||
// static auto func = reinterpret_cast<KeyValues*(__thiscall*)(KeyValues*, const char*, bool)>(p_KeyValues_FindKey);
|
||||
// return func(this, keyName, bCreate);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int GetInt(const char* keyName, int defaultValue)
|
||||
{
|
||||
KeyValues* dat = FindKey(keyName, false);
|
||||
|
||||
if (!dat)
|
||||
return defaultValue;
|
||||
|
||||
switch (dat->m_iDataType)
|
||||
{
|
||||
case TYPE_STRING:
|
||||
return atoi(dat->m_sValue);
|
||||
case TYPE_FLOAT:
|
||||
return static_cast<int>(m_flValue());
|
||||
case TYPE_WSTRING:
|
||||
return _wtoi(dat->m_wsValue);
|
||||
case TYPE_UINT64:
|
||||
return 0;
|
||||
default:
|
||||
return dat->m_iValue();
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
void SetInt(const char* keyName, int iValue)
|
||||
{
|
||||
KeyValues* dat = FindKey(keyName, true);
|
||||
if (dat)
|
||||
{
|
||||
dat->m_iValue() = iValue;
|
||||
dat->m_iDataType = TYPE_INT;
|
||||
}
|
||||
}
|
||||
|
||||
void SetFloat(const char* keyName, float flValue)
|
||||
{
|
||||
KeyValues* dat = FindKey(keyName, true);
|
||||
if (dat)
|
||||
{
|
||||
dat->m_flValue() = flValue;
|
||||
dat->m_iDataType = TYPE_FLOAT;
|
||||
}
|
||||
}
|
||||
|
||||
// Compiler makes it so m_Value shares the offset spot with m_flValue that why we cast it like this.
|
||||
float& m_flValue()
|
||||
{
|
||||
static __int32 offset = 0x18;
|
||||
return *(float*)((std::uintptr_t)this + offset);
|
||||
}
|
||||
|
||||
int& m_iValue()
|
||||
{
|
||||
static __int32 offset = 0x18;
|
||||
return *(int*)((std::uintptr_t)this + offset);
|
||||
}
|
||||
|
||||
public:
|
||||
unsigned __int32 m_iKeyName : 24;
|
||||
unsigned __int32 m_iKeyNameCaseSensitive : 8;
|
||||
char* m_sValue;
|
||||
wchar_t* m_wsValue;
|
||||
int m_Value;
|
||||
private:
|
||||
char gap1C[12];
|
||||
public:
|
||||
char m_iDataType;
|
||||
unsigned __int16 m_iKeyNameCaseSensitive2;
|
||||
KeyValues* m_pPeer;
|
||||
KeyValues* m_pSub;
|
||||
KeyValues* m_pChain;
|
||||
};
|
@ -11,20 +11,20 @@ inline HANDLE GameProcess = GetCurrentProcess();
|
||||
namespace
|
||||
{
|
||||
/* -------------- ORIGIN ------------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||
DWORD64 dst000 = /*0x14032EEA0*/ FindPattern("r5apex.exe", (const unsigned char*)"\x48\x83\xEC\x28\x80\x3D\x00\x00\x00\x23\x00\x0F\x85\x00\x02\x00", "xxxxxx???xxxx?xx");
|
||||
DWORD64 dst001 = /*0x140330290*/ FindPattern("r5apex.exe", (const unsigned char*)"\x48\x81\xEC\x58\x04\x00\x00\x80\x3D\x00\x00\x00\x00\x00\x0F\x84", "xxxxxxxxx????xxx");
|
||||
DWORD64 dst000 /*0x14032EEA0*/ = reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "48 83 EC 28 80 3D ? ? ? 23 ? 0F 85 ? 02 ?"));
|
||||
DWORD64 dst001 /*0x140330290*/ = reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "48 81 EC 58 04 ? ? 80 3D ? ? ? ? ? 0F 84"));
|
||||
|
||||
/* -------------- ENGINE ------------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||
DWORD64 dst002 = /*0x14043FB90*/ FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x4C\x24\x08\x56\x41\x55\x48\x81\xEC\x68\x03\x00\x00\x4C", "xxxx?xxxxxxxxxxx");
|
||||
DWORD64 dst003 = /*0x140302FF0*/ FindPattern("r5apex.exe", (const unsigned char*)"\x40\x53\x41\x56\x41\x57\x48\x83\xEC\x20\x48\x8B\xD9\x48\x89\x74", "xxxxxxxxxxxxxxxx");
|
||||
DWORD64 dst004 = /*0x14022A4A0*/ FindPattern("r5apex.exe", (const unsigned char*)"\x48\x83\xEC\x38\x0F\x29\x74\x24\x20\x48\x89\x5C\x24\x40\x48\x8B", "xxxxxxxxxxxxxxxx");
|
||||
DWORD64 dst005 = /*0x140238DA0*/ FindPattern("r5apex.exe", (const unsigned char*)"\x48\x8B\xC4\x00\x41\x54\x41\x00\x48\x81\xEC\x00\x00\x00\x00\xF2", "xxx?xxx?xxx??xxx");
|
||||
DWORD64 dst002 /*0x14043FB90*/ = reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "48 89 4C 24 08 56 41 55 48 81 EC 68 03 ? ? 4C"));
|
||||
DWORD64 dst003 /*0x140302FF0*/ = reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "40 53 41 56 41 57 48 83 EC 20 48 8B D9 48 89 74"));
|
||||
DWORD64 dst004 /*0x14022A4A0*/ = reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "48 83 EC 38 0F 29 74 24 20 48 89 5C 24 40 48 8B"));
|
||||
DWORD64 dst005 /*0x140238DA0*/ = reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "48 8B C4 ? 41 54 41 ? 48 81 EC ? ? ? ? F2"));
|
||||
|
||||
/* -------------- NETCHAN ----------------------------------------------------------------------------------------------------------------------------------------------- */
|
||||
DWORD64 dst006 = /*0x14030D000*/ FindPattern("r5apex.exe", (const unsigned char*)"\x40\x55\x57\x41\x55\x41\x57\x48\x8D\xAC\x24\x28\xFF\xFF\xFF\x48", "xxxxxxxxxxxxxxxx");
|
||||
DWORD64 dst006 /*0x14030D000*/ = reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "40 55 57 41 55 41 57 48 8D AC 24 ? ? ? ?"));
|
||||
|
||||
/* -------------- FAIRFIGHT --------------------------------------------------------------------------------------------------------------------------------------------- */
|
||||
DWORD64 dst007 = /*0x140303AE0*/ FindPattern("r5apex.exe", (const unsigned char*)"\x40\x53\x48\x83\xEC\x20\x8B\x81\xB0\x03\x00\x00\x48\x8B\xD9\xC6", "xxxxxxxxxxxxxxxx");
|
||||
DWORD64 dst007 /*0x140303AE0*/ = reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "40 53 48 83 EC 20 8B 81 B0 03 ? ? 48 8B D9 C6"));
|
||||
|
||||
/* -------------- ------- ----------------------------------------------------------------------------------------------------------------------------------------------- */
|
||||
|
||||
@ -34,16 +34,16 @@ namespace
|
||||
void PrintOAddress() // Test the sigscan results
|
||||
{
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
std::cout << "| dst000 : " << std::hex << dst000 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst001 : " << std::hex << dst001 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst000 : " << std::hex << std::uppercase << dst000 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst001 : " << std::hex << std::uppercase << dst001 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
std::cout << "| dst002 : " << std::hex << dst002 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst003 : " << std::hex << dst003 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst004 : " << std::hex << dst004 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst005 : " << std::hex << dst005 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst002 : " << std::hex << std::uppercase << dst002 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst003 : " << std::hex << std::uppercase << dst003 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst004 : " << std::hex << std::uppercase << dst004 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst005 : " << std::hex << std::uppercase << dst005 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
std::cout << "| dst006 : " << std::hex << dst006 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst007 : " << std::hex << dst007 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst006 : " << std::hex << std::uppercase << dst006 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| dst007 : " << std::hex << std::uppercase << dst007 << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
|
||||
// TODO implement error handling when sigscan fails or result is 0
|
||||
|
@ -9,39 +9,44 @@ namespace
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/* ==== CONSOLE ========================================================================================================================================================= */
|
||||
DWORD64 p_CommandExecute = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8D\x0D\x27\x61\xa5\x1E\x41\x8B\xD8", "xxxx?xxxxxxxx????xxx");
|
||||
void (*CommandExecute)(void* self, const char* cmd) = (void (*)(void*, const char*))p_CommandExecute; /*48 89 5C 24 ?? 57 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 41 8B D8*/
|
||||
DWORD64 p_CommandExecute = /*0x140202090*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "48 89 5C 24 ? 57 48 83 EC 20 48 8D 0D ? ? ? ? 41 8B D8"));
|
||||
void (*CommandExecute)(void* self, const char* cmd) = (void (*)(void*, const char*))p_CommandExecute;
|
||||
|
||||
DWORD64 p_ConVar_IsFlagSet = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x8B\x41\x48\x85\x50\x38", "xxxxxxx");
|
||||
bool (*ConVar_IsFlagSet)(int** cvar, int flag) = (bool (*)(int**, int))p_ConVar_IsFlagSet; /*48 8B 41 48 85 50 38*/
|
||||
DWORD64 p_ConVar_IsFlagSet = /*0x14046FE90*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "48 8B 41 48 85 50 38"));
|
||||
bool (*ConVar_IsFlagSet)(int** cvar, int flag) = (bool (*)(int**, int))p_ConVar_IsFlagSet;
|
||||
|
||||
LONGLONG p_ConCommand_IsFlagSet = FindPattern("r5apex.exe", (const unsigned char*)"\x85\x51\x38\x0F\x95\xC0\xC3", "xxxxxxx");
|
||||
bool (*ConCommand_IsFlagSet)(int* cmd, int flag) = (bool (*)(int*, int))p_ConCommand_IsFlagSet; /*85 51 38 0F 95 C0 C3*/
|
||||
DWORD64 p_ConCommand_IsFlagSet = /*0x14046F490*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "85 51 38 0F 95 C0 C3"));
|
||||
bool (*ConCommand_IsFlagSet)(int* cmd, int flag) = (bool (*)(int*, int))p_ConCommand_IsFlagSet;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/* ==== SQUIRREL ======================================================================================================================================================== */
|
||||
DWORD64 p_SQVM_Print = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x8B\xC4\x48\x89\x50\x10\x4C\x89\x40\x18\x4C\x89\x48\x20\x53\x56\x57\x48\x81\xEC\x30\x08\x00\x00\x48\x8B\xDA\x48\x8D\x70\x18\x48\x8B\xF9\xE8\x00\x00\x00\xFF\x48\x89\x74\x24\x28\x48\x8D\x54\x24\x30\x33", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx???xxxxxxxxxxxx");
|
||||
void* SQVM_Print = (void*)p_SQVM_Print; /*48 8B C4 48 89 50 10 4C 89 40 18 4C 89 48 20 53 56 57 48 81 EC 30 08 00 00 48 8B DA 48 8D 70 18 48 8B F9 E8 ?? ?? ?? FF 48 89 74 24 28 48 8D 54 24 30 33*/
|
||||
DWORD64 p_SQVM_Print = /*0x141057FD0*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe","48 8B C4 48 89 50 10 4C 89 40 18 4C 89 48 20 53 56 57 48 81 EC 30 08 00 00 48 8B DA 48 8D 70 18 48 8B F9 E8 ?? ?? ?? FF 48 89 74 24 28 48 8D 54 24 30 33"));
|
||||
void* SQVM_Print = (void*)p_SQVM_Print;
|
||||
|
||||
//DWORD64 p_SQVM_LoadScript = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x48\x89\x4C\x24\x08\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\x6C", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // For S0 and S1
|
||||
DWORD64 p_SQVM_LoadScript = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x8B\xC4\x48\x89\x48\x08\x55\x41\x56\x48\x8D\x68", "xxxxxxxxxxxxx"); // For anything S2 and above (current S8)
|
||||
DWORD64 p_SQVM_LoadScript = /*0x141055630*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "48 8B C4 48 89 48 08 55 41 56 48 8D 68")); // For anything S2 and above (current S8)
|
||||
bool (*SQVM_LoadScript)(void* sqvm, const char* script_path, const char* script_name, int flag) = (bool (*)(void*, const char*, const char*, int))p_SQVM_LoadScript; /*E8 ?? ?? ?? ?? 84 C0 74 1C 41 B9 ?? ?? ?? ??*/
|
||||
|
||||
DWORD64 p_SQVM_LoadRson = FindPattern("r5apex.exe", (const unsigned char*)"\x4C\x8B\xDC\x49\x89\x5B\x08\x57\x48\x81\xEC\xA0\x00\x00\x00\x33", "xxxxxxxxxxxxxxxx");
|
||||
int (*SQVM_LoadRson)(const char* rson_name) = (int (*)(const char*))p_SQVM_LoadRson; /*4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33*/
|
||||
DWORD64 p_SQVM_LoadRson = /*0x140C957E0*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "4C 8B DC 49 89 5B 08 57 48 81 EC A0 00 00 00 33"));
|
||||
int (*SQVM_LoadRson)(const char* rson_name) = (int (*)(const char*))p_SQVM_LoadRson;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/* ==== NETCHAN ========================================================================================================================================================= */
|
||||
DWORD64 p_NET_ReceiveDatagram = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x50\xEB", "xxxxxxxxxxxxxxxxxxxxxxxxx");
|
||||
DWORD64 p_NET_ReceiveDatagram = /*0x1402655F0*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 50 EB"));
|
||||
bool (*NET_ReceiveDatagram)(int, void*, bool) = (bool (*)(int, void*, bool))p_NET_ReceiveDatagram; /*E8 ?? ?? ?? ?? 84 C0 75 35 48 8B D3*/
|
||||
|
||||
DWORD64 p_NET_SendDatagram = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x56\x41\x57\x48\x81\xEC\x00\x05\x00\x00", "xxxxxxxxxxxxxxxxxxxxxxx?xxx");
|
||||
int (*NET_SendDatagram)(SOCKET s, const char* buf, int len, int flags) = (int (*)(SOCKET, const char*, int, int))p_NET_SendDatagram; /*48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ?? 05 00 00*/
|
||||
DWORD64 p_NET_SendDatagram = /*0x1402662D0*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 56 41 57 48 81 EC ? 05 ? ?"));
|
||||
int (*NET_SendDatagram)(SOCKET s, const char* buf, int len, int flags) = (int (*)(SOCKET, const char*, int, int))p_NET_SendDatagram;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/* ==== UTILITY ========================================================================================================================================================= */
|
||||
DWORD64 p_MSG_EngineError = FindPattern("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x81\xEC\x30\x08\x00\x00\x48\x8B\xDA\x48\x8B\xF9\xE8\x00\x00\x00\xFF\x33\xF6\x48", "xxxxxxxxxxxxxxxxxxxxxxxxx???xxxx");
|
||||
int (*MSG_EngineError)(char* fmt, va_list args) = (int (*)(char*, va_list))p_MSG_EngineError; /*48 89 5C 24 08 48 89 74 24 10 57 48 81 EC 30 08 00 00 48 8B DA 48 8B F9 E8 ?? ?? ?? FF 33 F6 48*/
|
||||
DWORD64 p_MSG_EngineError = /*0x140295600*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "48 89 5C 24 08 48 89 74 24 10 57 48 81 EC 30 08 00 00 48 8B DA 48 8B F9 E8 ?? ?? ?? FF 33 F6 48"));
|
||||
int (*MSG_EngineError)(char* fmt, va_list args) = (int (*)(char*, va_list))p_MSG_EngineError;
|
||||
|
||||
// Un-used atm.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/* ==== KEYVALUES ======================================================================================================================================================= */
|
||||
// DWORD64 p_KeyValues_FindKey = /*1404744E0*/ reinterpret_cast<DWORD64>(PatternScan("r5apex.exe", "40 56 57 41 57 48 81 EC ?? ?? ?? ?? 45"));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/* ==== ------- ========================================================================================================================================================= */
|
||||
@ -49,18 +54,18 @@ namespace
|
||||
void PrintHAddress() // Test the sigscan results
|
||||
{
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
std::cout << "| CommandExecute : " << std::hex << p_CommandExecute << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| ConVar_IsFlagSet : " << std::hex << p_ConVar_IsFlagSet << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| ConCommand_IsFlagSet : " << std::hex << p_ConCommand_IsFlagSet << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| CommandExecute : " << std::hex << std::uppercase << p_CommandExecute << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| ConVar_IsFlagSet : " << std::hex << std::uppercase << p_ConVar_IsFlagSet << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| ConCommand_IsFlagSet : " << std::hex << std::uppercase << p_ConCommand_IsFlagSet << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
std::cout << "| SQVM_Print : " << std::hex << p_SQVM_Print << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| SQVM_LoadScript : " << std::hex << p_SQVM_LoadScript << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| SQVM_LoadRson : " << std::hex << p_SQVM_LoadRson << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| SQVM_Print : " << std::hex << std::uppercase << p_SQVM_Print << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| SQVM_LoadScript : " << std::hex << std::uppercase << p_SQVM_LoadScript << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| SQVM_LoadRson : " << std::hex << std::uppercase << p_SQVM_LoadRson << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
std::cout << "| NET_ReceiveDatagram : " << std::hex << p_NET_ReceiveDatagram << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| NET_SendDatagram : " << std::hex << p_NET_SendDatagram << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| NET_ReceiveDatagram : " << std::hex << std::uppercase << p_NET_ReceiveDatagram << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| NET_SendDatagram : " << std::hex << std::uppercase << p_NET_SendDatagram << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
std::cout << "| MSG_EngineError : " << std::hex << p_NET_SendDatagram << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "| MSG_EngineError : " << std::hex << std::uppercase << p_MSG_EngineError << std::setw(20) << " |" << std::endl;
|
||||
std::cout << "+--------------------------------------------------------+" << std::endl;
|
||||
|
||||
// TODO implement error handling when sigscan fails or result is 0
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Internals
|
||||
BOOL FileExists(LPCTSTR szPath);
|
||||
MODULEINFO GetModuleInfo(const char* szModule);
|
||||
DWORD64 FindPattern(const char* szModule, const unsigned char* szPattern, const char* szMask);
|
||||
std::uint8_t* PatternScan(const char* module, const char* signature);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Utility
|
||||
|
@ -67,7 +67,7 @@ LRESULT CALLBACK HwndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (uMsg == WM_KEYDOWN)
|
||||
{
|
||||
if (wParam == VK_OEM_3)
|
||||
if (wParam == VK_OEM_3 || wParam == VK_INSERT) // For everyone without a US keyboard layout.
|
||||
{
|
||||
g_bShowMenu = !g_bShowMenu;
|
||||
}
|
||||
|
@ -36,32 +36,68 @@ MODULEINFO GetModuleInfo(const char* szModule)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// For finding a byte pattern in memory of the game process
|
||||
BOOL Compare(const unsigned char* pData, const unsigned char* szPattern, const char* szMask)
|
||||
{
|
||||
for (; *szMask; ++szMask, ++pData, ++szPattern)
|
||||
{
|
||||
if (*szMask == 'x' && *pData != *szPattern)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return (*szMask) == NULL;
|
||||
}
|
||||
DWORD64 FindPattern(const char* szModule, const unsigned char* szPattern, const char* szMask)
|
||||
{
|
||||
MODULEINFO mInfo = GetModuleInfo(szModule);
|
||||
DWORD64 dwAddress = (DWORD64)mInfo.lpBaseOfDll;
|
||||
DWORD64 dwLen = (DWORD64)mInfo.SizeOfImage;
|
||||
|
||||
size_t maskLen = strlen(szMask);
|
||||
for (int i = 0; i < dwLen - maskLen; i++)
|
||||
std::uint8_t* PatternScan(const char* module, const char* signature)
|
||||
{
|
||||
static auto PatternToBytes = [](const char* pattern)
|
||||
{
|
||||
if (Compare((unsigned char*)(dwAddress + i), szPattern, szMask))
|
||||
char* PatternStart = const_cast<char*>(pattern); // Cast const away and get start of pattern.
|
||||
char* PatternEnd = PatternStart + std::strlen(pattern); // Get end of pattern.
|
||||
|
||||
std::vector<std::int32_t> Bytes = std::vector<std::int32_t>{ }; // Initialize byte vector.
|
||||
|
||||
for (char* CurrentByte = PatternStart; CurrentByte < PatternEnd; ++CurrentByte)
|
||||
{
|
||||
return (DWORD64)(dwAddress + i);
|
||||
if (*CurrentByte == '?') // Is current char(byte) a wildcard?
|
||||
{
|
||||
++CurrentByte; // Skip 1 character.
|
||||
|
||||
if (*CurrentByte == '?') // Is it a double wildcard pattern?
|
||||
++CurrentByte; // If so skip the next space that will come up so we can reach the next byte.
|
||||
|
||||
Bytes.push_back(-1); // Push the byte back as invalid.
|
||||
}
|
||||
else
|
||||
{
|
||||
// https://stackoverflow.com/a/43860875/12541255
|
||||
// Here we convert our string to a unsigned long integer. We pass our string then we use 16 as the base because we want it as hexadecimal.
|
||||
// Afterwards we push the byte into our bytes vector.
|
||||
Bytes.push_back(std::strtoul(CurrentByte, &CurrentByte, 16));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return Bytes;
|
||||
};
|
||||
|
||||
const MODULEINFO mInfo = GetModuleInfo(module); // Get module info.
|
||||
const DWORD64 SizeOfModule = (DWORD64)mInfo.SizeOfImage; // Grab the module size.
|
||||
std::uint8_t* ScanBytes = reinterpret_cast<std::uint8_t*>(mInfo.lpBaseOfDll); // Get the base of the module.
|
||||
|
||||
const std::vector<int> PatternBytes = PatternToBytes(signature); // Convert our pattern to a byte array.
|
||||
const std::pair BytesInfo = std::make_pair(PatternBytes.size(), PatternBytes.data()); // Get the size and data of our bytes.
|
||||
|
||||
for (DWORD i = 0ul; i < SizeOfModule - BytesInfo.first; ++i)
|
||||
{
|
||||
bool FoundAddress = true;
|
||||
|
||||
for (DWORD j = 0ul; j < BytesInfo.first; ++j)
|
||||
{
|
||||
// If either the current byte equals to the byte in our pattern or our current byte in the pattern is a wildcard
|
||||
// our if clause will be false.
|
||||
if (ScanBytes[i + j] != BytesInfo.second[j] && BytesInfo.second[j] != -1)
|
||||
{
|
||||
FoundAddress = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FoundAddress)
|
||||
{
|
||||
return &ScanBytes[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
x
Reference in New Issue
Block a user