diff --git a/r5dev/include/opcptc.h b/r5dev/include/opcptc.h index 0567a4ea..dea12757 100644 --- a/r5dev/include/opcptc.h +++ b/r5dev/include/opcptc.h @@ -1,41 +1,49 @@ #pragma once #include +#include + #include "utility.h" void InstallOpcodes(); +void InstallGlobals(); inline HANDLE GameProcess = GetCurrentProcess(); namespace { /* -------------- ORIGIN ------------------------------------------------------------------------------------------------------------------------------------------------ */ - DWORD64 dst000 = /*0x14032C910*/ 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 = /*0x14023C440*/ 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*/ 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"); /* -------------- ENGINE ------------------------------------------------------------------------------------------------------------------------------------------------ */ - DWORD64 dst002 = /*0x140438DE0*/ 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 = /*0x1403604E0*/ FindPattern("r5apex.exe", (const unsigned char*)"\x40\x53\x41\x56\x41\x57\x48\x83\xEC\x20\x48\x8B\xD9\x48\x89\x74", "xxxxxxxxxxxxxxxx"); + 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"); /* -------------- NETCHAN ----------------------------------------------------------------------------------------------------------------------------------------------- */ - DWORD64 dst004 = /*0x14030BEF0*/ 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*/ FindPattern("r5apex.exe", (const unsigned char*)"\x40\x55\x57\x41\x55\x41\x57\x48\x8D\xAC\x24\x28\xFF\xFF\xFF\x48", "xxxxxxxxxxxxxxxx"); /* -------------- FAIRFIGHT --------------------------------------------------------------------------------------------------------------------------------------------- */ - DWORD64 dst005 = /*0x140302D90*/ 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*/ FindPattern("r5apex.exe", (const unsigned char*)"\x40\x53\x48\x83\xEC\x20\x8B\x81\xB0\x03\x00\x00\x48\x8B\xD9\xC6", "xxxxxxxxxxxxxxxx"); - /* -------------- OTHER ------------------------------------------------------------------------------------------------------------------------------------------------- */ - /**/ /* -------------- ------- ----------------------------------------------------------------------------------------------------------------------------------------------- */ + /* -------------- GLOBALS ----------------------------------------------------------------------------------------------------------------------------------------------- */ + DWORD64 ofs000 = 0x000000016073B7BC; + void PrintOAddress() // Test the sigscan results { std::cout << "+--------------------------------------------------------+" << std::endl; - std::cout << "| dst000 : " << std::hex << dst000 << std::endl; - std::cout << "| dst001 : " << std::hex << dst001 << 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 << "+--------------------------------------------------------+" << std::endl; - std::cout << "| dst002 : " << std::hex << dst002 << std::endl; - std::cout << "| dst003 : " << std::hex << dst003 << 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 << "+--------------------------------------------------------+" << std::endl; - std::cout << "| dst004 : " << std::hex << dst004 << std::endl; - std::cout << "| dst005 : " << std::hex << dst005 << 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 << "+--------------------------------------------------------+" << std::endl; // TODO implement error handling when sigscan fails or result is 0 diff --git a/r5dev/include/patterns.h b/r5dev/include/patterns.h index efaa2207..f2da1744 100644 --- a/r5dev/include/patterns.h +++ b/r5dev/include/patterns.h @@ -1,5 +1,7 @@ #pragma once #include +#include + #include "utility.h" // Define the signatures or offsets to be searched and hooked @@ -42,16 +44,16 @@ namespace void PrintHAddress() // Test the sigscan results { std::cout << "+--------------------------------------------------------+" << std::endl; - std::cout << "| p_CommandExecute : " << std::hex << p_CommandExecute << std::endl; - std::cout << "| p_ConVar_IsFlagSet : " << std::hex << p_ConVar_IsFlagSet << std::endl; - std::cout << "| p_ConCommand_IsFlagSet : " << std::hex << p_ConCommand_IsFlagSet << std::endl; + std::cout << "| p_CommandExecute : " << std::hex << p_CommandExecute << std::setw(20) << " |" << std::endl; + std::cout << "| p_ConVar_IsFlagSet : " << std::hex << p_ConVar_IsFlagSet << std::setw(20) << " |" << std::endl; + std::cout << "| p_ConCommand_IsFlagSet : " << std::hex << p_ConCommand_IsFlagSet << std::setw(20) << " |" << std::endl; std::cout << "+--------------------------------------------------------+" << std::endl; - std::cout << "| p_SQVM_Print : " << std::hex << p_SQVM_Print << std::endl; - std::cout << "| p_SQVM_LoadScript : " << std::hex << p_SQVM_LoadScript << std::endl; - std::cout << "| p_SQVM_LoadRson : " << std::hex << p_SQVM_LoadRson << std::endl; + std::cout << "| p_SQVM_Print : " << std::hex << p_SQVM_Print << std::setw(20) << " |" << std::endl; + std::cout << "| p_SQVM_LoadScript : " << std::hex << p_SQVM_LoadScript << std::setw(20) << " |" << std::endl; + std::cout << "| p_SQVM_LoadRson : " << std::hex << p_SQVM_LoadRson << std::setw(20) << " |" << std::endl; std::cout << "+--------------------------------------------------------+" << std::endl; - std::cout << "| p_NET_ReceiveDatagram : " << std::hex << p_NET_ReceiveDatagram << std::endl; - std::cout << "| p_NET_SendDatagram : " << std::hex << p_NET_SendDatagram << std::endl; + std::cout << "| p_NET_ReceiveDatagram : " << std::hex << p_NET_ReceiveDatagram << std::setw(20) << " |" << std::endl; + std::cout << "| p_NET_SendDatagram : " << std::hex << p_NET_SendDatagram << std::setw(20) << " |" << std::endl; std::cout << "+--------------------------------------------------------+" << std::endl; // TODO implement error handling when sigscan fails or result is 0 diff --git a/r5dev/src/hooks.cpp b/r5dev/src/hooks.cpp index 43d3d405..31a76e3d 100644 --- a/r5dev/src/hooks.cpp +++ b/r5dev/src/hooks.cpp @@ -61,12 +61,39 @@ void* HSQVM_Print(void* sqvm, char* fmt, ...) __int64 HSQVM_LoadRson(const char* rson_name) { - printf("\n"); - printf("##################################################\n"); - printf("] '%s'\n", rson_name); - printf("##################################################\n"); - printf("\n"); - return SQVM_LoadRson(rson_name); + char filepath[MAX_PATH] = { 0 }; + sprintf_s(filepath, MAX_PATH, "platform\\%s", rson_name); + + /////////////////////////////////////////////////////////////////////////////// + // Flip forward slashes in filepath to windows-style backslash + for (int i = 0; i < strlen(filepath); i++) + { + if (filepath[i] == '/') + { + filepath[i] = '\\'; + } + } + + /////////////////////////////////////////////////////////////////////////////// + // Returns the new path if the rson exists on the disk + if (FileExists(filepath) && SQVM_LoadRson(rson_name)) + { + printf("\n"); + printf("##################################################\n"); + printf("] '%s'\n", filepath); + printf("##################################################\n"); + printf("\n"); + return SQVM_LoadRson(filepath); + } + else + { + printf("\n"); + printf("##################################################\n"); + printf("] '%s'\n", rson_name); + printf("##################################################\n"); + printf("\n"); + return SQVM_LoadRson(rson_name); + } } bool HSQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag) diff --git a/r5dev/src/opcptc.cpp b/r5dev/src/opcptc.cpp index a0d85bab..230fc6fb 100644 --- a/r5dev/src/opcptc.cpp +++ b/r5dev/src/opcptc.cpp @@ -7,24 +7,33 @@ void InstallOpcodes() /* .TEXT */ { - /////////////////////////////////////////////////////////////////////////// + //------------------------------------------------------------------------- // JNZ --> JMP | Prevent OriginSDK from initializing on the client //WriteProcessMemory(GameProcess, LPVOID(dst000 + 0x0B), "\xE9\x63\x02\x00\x00\x00", 6, NULL); //WriteProcessMemory(GameProcess, LPVOID(dst001 + 0x0E), "\xE9\xCB\x03\x00\x00", 5, NULL); - - /////////////////////////////////////////////////////////////////////////// + //------------------------------------------------------------------------- // JNE --> JMP | Allow games to be loaded without the optional texture streaming file WriteProcessMemory(GameProcess, LPVOID(dst002 + 0x8E5), "\xEB\x19", 2, NULL); - - /////////////////////////////////////////////////////////////////////////// + //------------------------------------------------------------------------- // MOV --> NOP | Prevent PDATA global being initialized as NULL WriteProcessMemory(GameProcess, LPVOID(dst003 + 0x174), "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90", 14, NULL); - - /////////////////////////////////////////////////////////////////////////// + //------------------------------------------------------------------------- + // JNE --> JMP | Prevent connect command from crashing by invalid call to UI function + WriteProcessMemory(GameProcess, LPVOID(dst004 + 0x1D6), "\xEB\x27", 2, NULL); + //------------------------------------------------------------------------- + // JNE --> JMP | Prevent connect localhost from being executed after listen server init + WriteProcessMemory(GameProcess, LPVOID(dst005 + 0x637), "\xE9\xC1\x00\x00\x00", 5, NULL); + //------------------------------------------------------------------------- // JA --> JMP | Disable server-side verification for duplicate accounts on the server - WriteProcessMemory(GameProcess, LPVOID(dst004 + 0x284), "\x90\x90", 2, NULL); // TODO: Verify for N1094 - - /////////////////////////////////////////////////////////////////////////// + WriteProcessMemory(GameProcess, LPVOID(dst006 + 0x284), "\x90\x90", 2, NULL); + //------------------------------------------------------------------------- // JA --> JMP | Prevent FairFight anti-cheat from initializing on the server - WriteProcessMemory(GameProcess, LPVOID(dst005 + 0x61), "\xE9\xED\x00\x00\x00\x00", 6, NULL); + WriteProcessMemory(GameProcess, LPVOID(dst007 + 0x61), "\xE9\xED\x00\x00\x00\x00", 6, NULL); +} + +void InstallGlobals() /* .DATA */ +{ + //------------------------------------------------------------------------- + // 00 --> 05 | Set PDATA global to enable clientcommand codecallback on the server + WriteProcessMemory(GameProcess, LPVOID(ofs000), "\x05", 1, NULL); }