diff --git a/ida/find_patterns.py b/ida/find_patterns.py index a57db88a..dd402c85 100644 --- a/ida/find_patterns.py +++ b/ida/find_patterns.py @@ -62,8 +62,23 @@ def find_pattern(pattern: str, expected: int = 1, index: int = 0) -> int: return addrs[index] -def find_function(pattern: str, expected: int = 1, index: int = 0) -> int: - return find_pattern(pattern, expected, index) +def find_function(pattern: str, expected: int = 1, index: int = 0, offset: int = 0) -> int: + addr = find_pattern(pattern, expected, index) + if addr == ida_idaapi.BADADDR: + return addr + + if offset != 0: + disp = ida_bytes.get_dword(addr + offset) + + if disp >= 1 << 31: + disp = 0xFFFFFFFF - disp + disp = disp + 1 + disp = -disp + + # Real address is: pattern_addr + offset + displacement + size_of_displacement. + return addr + offset + disp + 4 + + return addr def find_ptr(pattern: str, expected: int = 1, index: int = 0, offset: int = 0) -> int: addr = find_pattern(pattern, expected, index) @@ -81,7 +96,7 @@ def find_ptr(pattern: str, expected: int = 1, index: int = 0, offset: int = 0) - groups.sort(key=lambda g: g.name.lower()) - addr = find_ptr(pattern='4C 8D 05 ? ? ? ? 49 89 AE 80 01 00 00 8D 55 11', offset=3) + addr = find_ptr(pattern='4C 8D 05 ? ? ? ? 45 89 BE 20 02 00 00', offset=3) version = idc.get_strlit_contents(addr) print(f'Finding {total} item(s)...') @@ -92,7 +107,7 @@ def find_ptr(pattern: str, expected: int = 1, index: int = 0, offset: int = 0) - file.write(' * This file is generated. DO NOT modify it!\n') file.write(' *\n') file.write(' * Add new patterns in "patterns.py" file located in "project_root/scripts" and run "find_patterns.py".\n') - file.write(' * The new file should be located in "idb_path/Addresses.hpp".\n') + file.write(' * The new file should be located in "idb_path/Addresses.h".\n') file.write(' */\n') file.write('#include \n') file.write('\n') @@ -128,7 +143,7 @@ def find_ptr(pattern: str, expected: int = 1, index: int = 0, offset: int = 0) - file.write(f'// {ptr.pattern}, expected: {ptr.expected}, index: {ptr.index}, offset: {ptr.offset}\n') for func in group.functions: - addr = find_function(pattern=func.pattern, expected=func.expected, index=func.index) + addr = find_function(pattern=func.pattern, expected=func.expected, index=func.index, offset=func.offset) if addr == ida_idaapi.BADADDR: file.write(f'#error Could not find pattern "{func.pattern}", expected: {func.expected}, index: {func.index}\n') continue @@ -157,4 +172,4 @@ def find_ptr(pattern: str, expected: int = 1, index: int = 0, offset: int = 0) - print('Done!') ida_kernwin.beep() except: - traceback.print_exc() + traceback.print_exc() \ No newline at end of file diff --git a/ida/patterns.py b/ida/patterns.py index 99b385b2..91d09e6d 100644 --- a/ida/patterns.py +++ b/ida/patterns.py @@ -28,8 +28,8 @@ def get_groups() -> List[Group]: # Add new patterns here, please try to keep the groups ordering alphabetized. return [ Group(name='CRenderGlobal', pointers=[ - Item(name='InstanceOffset', pattern='48 8B 05 ? ? ? ? 8B D1 48 8B 88 18 8A 5A 01', expected=1, offset=3), - Item(name='_DoNotUse_RenderQueueOffset', pattern='4D 8B 0E 49 39 31 0F 84 85 00 00 00 41 39 71 24 74 ? 49 8B 95', expected=1) + Item(name='InstanceOffset', pattern='48 8B 05 ? ? ? ? 48 8B 88 18 8E 5A 01 8B 41 08 C3', expected=1, offset=3), + Item(name='_DoNotUse_RenderQueueOffset', pattern='49 39 29 0F 84 ? ? ? ? 41 39 69 24 0F 84 ? ? ? ? 49 8B 95', expected=1) ], functions=[ Item(name='Resize', pattern='44 88 4C 24 20 44 89 44 24 18 89 54 24 10 89 4C', expected=1) ]), @@ -38,12 +38,13 @@ def get_groups() -> List[Group]: ]), Group(name='CScript', functions=[ Item(name='RunPureScript', pattern='40 55 48 81 EC D0 00 00 00 48 8D 6C 24 40 8B', expected=1), - Item(name='CreateFunction', pattern='48 89 5C 24 08 57 48 83 EC 40 8B F9 48 8D 54 24 30 48 8B 0D ? ? ? ? 41 B8 B8 00 00 00', expected=1), + Item(name='AllocateFunction', pattern='BA B8 00 00 00 48 8D 4D D7 E8', expected=3, index=0, offset=10), Item(name='Log', pattern='40 53 48 83 EC ? 48 8D 4C 24 20 48 8B DA E8 ? ? ? ? 33 D2 48 8D 4C 24 40 E8', expected=1), - Item(name='LogChannel', pattern='40 53 48 83 EC ? 48 8D 4C 24 20 48 8B DA E8 ? ? ? ? 33 D2 48 8D 4C 24 40 E8', expected=1), + Item(name='LogChannel', pattern='4C 8B DC 49 89 5B 08 49 89 73 18 57 48 83 EC 70 48 8B 02 ? ? ? ? ? ? ? FE 42 62 4D 8D 43 10 33 FF 45 33 C9 49 89 7B 10 48 8B DA 48 89 7A', expected=1), Item(name='TDBIDConstructorDerive', pattern='40 53 48 83 EC 30 33 C0 4C 89 44 24 20 48 8B DA', expected=1), Item(name='ProcessRunningState', pattern='40 53 48 83 EC 20 48 8B 0D ? ? ? ? 48 8B DA E8 ? ? ? ? 84 C0', expected=1), - Item(name='TweakDBLoad', pattern='48 89 5C 24 10 48 89 7C 24 18 4C 89 74 24 20 55 48 8B EC 48 83 EC 70 48', expected=1) + Item(name='TweakDBLoad', pattern='48 89 5C 24 18 55 57 41 56 48 8B EC 48 83 EC 70 48 8B D9 45 33 F6 48 8D', expected=1), + Item(name='RegisterMemberFunction', pattern='48 89 5C 24 08 57 48 83 EC 20 49 8B C1 4D 8B D0 44 8B 4C 24 58 48 8B DA 41 83 C9 03', expected=1) ]), Group(name='CWinapi', functions=[ Item(name='ClipToCenter', pattern='48 89 5C 24 08 57 48 83 EC 30 48 8B 99 ? 01 00 00 48 8B F9 FF', expected=1) @@ -52,26 +53,25 @@ def get_groups() -> List[Group]: Item(name='Constructor', pattern='48 8B D9 E8 ? ? ? ? 48 8D 05 ? ? ? ? 48 C7 43 40 00 00 00 00', expected=2, index=0), Item(name='Initialize', pattern='48 89 5C 24 18 48 89 6C 24 20 57 48 83 EC 30 48 8B 42 78', expected=1), Item(name='UnInitialize', pattern='40 53 48 83 EC 20 48 8B D9 E8 ? ? ? ? 33 C0 48 89 43 50 48 89 43 48', expected=1), - Item(name='Spawn', pattern='FF 90 A8 01 00 00 48 8B 00 4C 8D 85 80 00 00 00', expected=1), - Item(name='Despawn', pattern='40 55 53 56 57 41 55 41 56 41 57 48 8B EC 48 83 EC 50', expected=1), - Item(name='SpawnCallback', pattern='41 57 48 83 EC 70 48 8B E9 4C 8B FA', expected=1) + Item(name='Spawn', pattern='48 89 5C 24 18 55 56 41 54 41 56 41 57 48 8D 6C 24 90 48 81 EC 70 01 00 00 48 83 79 50 00 49 8B', expected=1), + Item(name='Despawn', pattern='48 89 5C 24 10 48 89 6C 24 18 56 57 41 54 41 56 41 57 48 83 EC 50 4C 8B F9 0F 57 C0 48 83 C1 41', expected=1), + Item(name='SpawnCallback', pattern='48 89 5C 24 18 48 89 6C 24 20 56 57 41 56 48 83 EC 70 48 8B F1 48 8B EA 48 83 C1 48 E8', expected=1) ]), Group(name='CPhotoMode', functions=[ - Item(name='SetRecordID', pattern='48 89 5C 24 08 48 89 74 24 18 55 57 41 56 48 8D 6C 24 B9 48 81 EC 90 00 00 00 48 8B F9', expected=1) + Item(name='SetRecordID', pattern='48 8B C4 55 57 48 8D 68 A1 48 81 EC 98 00 00 00 48 89 58 08 48 8B D9 48 89 70 18 48 8D 4D 27 48', expected=1) ]), Group(name='CPatches', functions=[ - Item(name='BoundaryTeleport', pattern='48 8B C4 55 53 41 54 48 8D A8 78', expected=1), + Item(name='BoundaryTeleport', pattern='48 8B C4 55 53 41 54 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 48 89 70 10 48 8D 59 48', expected=1), Item(name='IntroMovie', pattern='48 89 5C 24 08 57 48 83 EC 20 48 8B 44 24 50 48 8B D9 48 89 41 08', expected=1), Item(name='Vignette', pattern='48 8B 41 30 48 83 78 68 00 74', expected=1), - Item(name='IsFinal', pattern='48 BB 87 C9 B1 63 33 01 15 75', expected=1), - Item(name='CanDebugTeleport', pattern='48 BB C3 63 E3 32 7C A2 3C C1', expected=1), Item(name='MinimapFlicker', pattern='83 79 2C 00 48 8B F2 4C', expected=1), - Item(name='OptionsInit', pattern='48 89 5C 24 08 48 89 74 24 10 57 48 83 EC 40 48 8B F1 48 8D 4C 24 20 E8', expected=1), - Item(name='RemovePedestrians', pattern='3B D8 0F 4E C3 8B D8 85 DB 0F 8E', expected=1), - Item(name='SkipStartScreen', pattern='48 BB E6 F8 A5 A3 36 56 4E A7 C6 85 B0 ? ? ? 01', expected=1), + Item(name='OptionsInit', pattern='40 53 48 83 EC 40 48 8B D9 48 8D 4C 24 20 E8 ? ? ? ? E8 ? ? ? ? 4C 8B 43 08', expected=1), + #Item(name='RemovePedestrians', pattern='44 3B E0 41 0F 4E C4 44 8B E0 89 45 67 45 85 E4 0F 8E', expected=1), # not needed anymore? + Item(name='SkipStartScreen', pattern='80 3D ? ? ? ? 00 48 BB E6 F8 A5 A3 36 56 4E A7 C6 85 A0 00 00 00 01', expected=1), Item(name='AmdSMT', pattern='75 2D 33 C9 B8 01 00 00 00 0F A2 8B C8 C1 F9 08', expected=1) ]), Group(name='CGame', functions=[ - Item(name='Main', pattern='40 55 57 41 57 48 81 EC', expected=1) + Item(name='Main', pattern='40 57 48 83 EC 70 48 8B F9 0F 29 7C 24 50 48 8D 4C 24 38', expected=1) ]), ] + diff --git a/src/Image.cpp b/src/Image.cpp index e0692501..3ad2e4a8 100644 --- a/src/Image.cpp +++ b/src/Image.cpp @@ -31,6 +31,7 @@ void Image::Initialize() {{0x2E, 0x36, 0x66, 0x8E, 0x25, 0x0E, 0xE6, 0x43, 0xBD, 0xEF, 0x47, 0xA1, 0x3E, 0xF7, 0x7F, 0xA6}, MakeVersion(1, 23)}, {{0xE7, 0x28, 0xD7, 0x5D, 0xB8, 0xF9, 0x79, 0x4D, 0x89, 0x76, 0x16, 0x64, 0xAB, 0x1E, 0xA0, 0x47}, MakeVersion(1, 30)}, {{0x8E, 0x08, 0xA2, 0x5B, 0xC7, 0xDD, 0xD5, 0x48, 0xB4, 0xE9, 0x90, 0x38, 0x15, 0xB8, 0xBB, 0xEB}, MakeVersion(1, 31)}, + {{0x5B, 0x6C, 0xAD, 0x70, 0x67, 0x2b, 0x54, 0x40, 0xBC, 0x45, 0x06, 0x60, 0x44, 0xA9, 0x12, 0x61}, MakeVersion(1, 50)} }; mem::module mainModule = mem::module::main(); diff --git a/src/Image.h b/src/Image.h index cb83d329..a4b78655 100644 --- a/src/Image.h +++ b/src/Image.h @@ -6,7 +6,7 @@ struct Image static std::tuple GetSupportedVersion() noexcept { - return std::make_tuple(1, 31); + return std::make_tuple(1, 50); } static uint64_t MakeVersion(uint32_t aMajor, uint16_t aMinor) noexcept diff --git a/src/d3d12/D3D12_Hooks.cpp b/src/d3d12/D3D12_Hooks.cpp index 0d042af6..506c1510 100644 --- a/src/d3d12/D3D12_Hooks.cpp +++ b/src/d3d12/D3D12_Hooks.cpp @@ -132,7 +132,7 @@ void* D3D12::CRenderNode_Present_InternalPresent(int32_t* apSomeInt, uint8_t aSo const auto idx = *apSomeInt - 1; const auto* pContext = RenderContext::GetInstance(); - if (pContext->unkED65C0 == nullptr) + if (pContext->unkED69C0 == nullptr) { auto* pDevice = pContext->devices[idx].pSwapChain; d3d12.m_pCommandQueue = pContext->pDirectQueue; diff --git a/src/patches/EnableDebug.cpp b/src/patches/EnableDebug.cpp index f2ff4bd7..f03dd5c0 100644 --- a/src/patches/EnableDebug.cpp +++ b/src/patches/EnableDebug.cpp @@ -59,63 +59,15 @@ void HookRegisterScriptMemberFunction(void* a, void* parentClass, uint64_t hash, void EnableDebugPatch(const Image* apImage) { - uint8_t* pChecksumLocations[] = { 0, 0 }; - - RED4ext::RelocPtr isFinal(CyberEngineTweaks::Addresses::CPatches_IsFinal); - RED4ext::RelocPtr canDebugTeleport(CyberEngineTweaks::Addresses::CPatches_CanDebugTeleport); - - pChecksumLocations[0] = isFinal.GetAddr(); // "IsFinal", helps us find RegisterScriptFunction - pChecksumLocations[1] = canDebugTeleport.GetAddr(); // "CanDebugTeleport", to find RegisterScriptMemberFunction - - for (int i = 0; i < 2; i++) - { - const char* patchType = (i == 0 ? "Unlock menu patch" : "Unlock debug functions"); - - uint8_t* pCallLocation = nullptr; - if (pChecksumLocations[i]) - { - mem::region reg(pChecksumLocations[i], 0x1000); - - if (i == 0) - { - const mem::pattern cPattern("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8D 0D"); - const mem::default_scanner cScanner(cPattern); - pCallLocation = cScanner(reg).as(); - } - else - { - const mem::pattern cPattern("48 8D 0D ?? ?? ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8D 0D"); - const mem::default_scanner cScanner(cPattern); - pCallLocation = cScanner(reg).as(); - } - - if (pCallLocation) - pCallLocation += (i == 0 ? 8 : 11); - } - - if (pCallLocation) - { - DWORD oldProtect = 0; - VirtualProtect(pCallLocation, 32, PAGE_EXECUTE_WRITECOPY, &oldProtect); - int32_t offset = *(int32_t*)(pCallLocation)+4; - VirtualProtect(pCallLocation, 32, oldProtect, nullptr); - - if (i == 0) - { - RealRegisterScriptFunction = reinterpret_cast(pCallLocation + offset); - MH_CreateHook(RealRegisterScriptFunction, &HookRegisterScriptFunction, reinterpret_cast(&RealRegisterScriptFunction)); - } - else - { - RealRegisterScriptMemberFunction = reinterpret_cast(pCallLocation + offset); - MH_CreateHook(RealRegisterScriptMemberFunction, &HookRegisterScriptMemberFunction, reinterpret_cast(&RealRegisterScriptMemberFunction)); - } - - Log::Info("{}: success", patchType); - } - else - { - Log::Warn("{}: failed, unknown version", patchType); - } - } + RED4ext::RelocPtr registerFunction(RED4ext::Addresses::CBaseFunction_Register); + RED4ext::RelocPtr registerMemberFunction(CyberEngineTweaks::Addresses::CScript_RegisterMemberFunction); + + RealRegisterScriptFunction = reinterpret_cast(registerFunction.GetAddr()); + MH_CreateHook(RealRegisterScriptFunction, &HookRegisterScriptFunction, + reinterpret_cast(&RealRegisterScriptFunction)); + + RealRegisterScriptMemberFunction = reinterpret_cast(registerMemberFunction.GetAddr()); + MH_CreateHook(RealRegisterScriptMemberFunction, &HookRegisterScriptMemberFunction, + reinterpret_cast(&RealRegisterScriptMemberFunction)); + } diff --git a/src/patches/RemovePeds.cpp b/src/patches/RemovePeds.cpp index 96fad0e2..26f2a673 100644 --- a/src/patches/RemovePeds.cpp +++ b/src/patches/RemovePeds.cpp @@ -4,7 +4,7 @@ void RemovePedsPatch(const Image* apImage) { - RED4ext::RelocPtr func(CyberEngineTweaks::Addresses::CPatches_RemovePedestrians); + /* RED4ext::RelocPtr func(CyberEngineTweaks::Addresses::CPatches_); uint8_t* pLocation = func.GetAddr(); if(pLocation == nullptr) @@ -15,9 +15,9 @@ void RemovePedsPatch(const Image* apImage) DWORD oldProtect = 0; VirtualProtect(pLocation, 32, PAGE_EXECUTE_WRITECOPY, &oldProtect); - pLocation[9] = 0x90; - pLocation[10] = 0xE9; - VirtualProtect(pLocation, 32, oldProtect, nullptr); + pLocation[16] = 0x90; + pLocation[17] = 0xE9; + VirtualProtect(pLocation, 32, oldProtect, nullptr);*/ - Log::Info("Remove peds patch: success"); + Log::Info("Remove peds patch: disabled for now"); } diff --git a/src/reverse/Addresses.h b/src/reverse/Addresses.h index 30078d94..11517669 100644 --- a/src/reverse/Addresses.h +++ b/src/reverse/Addresses.h @@ -4,66 +4,64 @@ * This file is generated. DO NOT modify it! * * Add new patterns in "patterns.py" file located in "project_root/scripts" and run "find_patterns.py". - * The new file should be located in "idb_path/Addresses.hpp". + * The new file should be located in "idb_path/Addresses.h". */ #include -// Addresses for Cyberpunk 2077, version 1.31. +// Addresses for Cyberpunk 2077, version 1.5. namespace CyberEngineTweaks::Addresses { constexpr uintptr_t ImageBase = 0x140000000; #pragma region CGame -constexpr uintptr_t CGame_Main = 0x140AD86C0 - ImageBase; // 40 55 57 41 57 48 81 EC, expected: 1, index: 0 +constexpr uintptr_t CGame_Main = 0x140A6ACD0 - ImageBase; // 40 57 48 83 EC 70 48 8B F9 0F 29 7C 24 50 48 8D 4C 24 38, expected: 1, index: 0 #pragma endregion #pragma region CPatches -constexpr uintptr_t CPatches_BoundaryTeleport = 0x141BBDED0 - ImageBase; // 48 8B C4 55 53 41 54 48 8D A8 78, expected: 1, index: 0 -constexpr uintptr_t CPatches_IntroMovie = 0x140222200 - ImageBase; // 48 89 5C 24 08 57 48 83 EC 20 48 8B 44 24 50 48 8B D9 48 89 41 08, expected: 1, index: 0 -constexpr uintptr_t CPatches_Vignette = 0x1412233C0 - ImageBase; // 48 8B 41 30 48 83 78 68 00 74, expected: 1, index: 0 -constexpr uintptr_t CPatches_IsFinal = 0x14020DDFD - ImageBase; // 48 BB 87 C9 B1 63 33 01 15 75, expected: 1, index: 0 -constexpr uintptr_t CPatches_CanDebugTeleport = 0x1426C0756 - ImageBase; // 48 BB C3 63 E3 32 7C A2 3C C1, expected: 1, index: 0 -constexpr uintptr_t CPatches_MinimapFlicker = 0x14260AD98 - ImageBase; // 83 79 2C 00 48 8B F2 4C, expected: 1, index: 0 -constexpr uintptr_t CPatches_OptionsInit = 0x142C64300 - ImageBase; // 48 89 5C 24 08 48 89 74 24 10 57 48 83 EC 40 48 8B F1 48 8D 4C 24 20 E8, expected: 1, index: 0 -constexpr uintptr_t CPatches_RemovePedestrians = 0x141E98965 - ImageBase; // 3B D8 0F 4E C3 8B D8 85 DB 0F 8E, expected: 1, index: 0 -constexpr uintptr_t CPatches_SkipStartScreen = 0x142A50634 - ImageBase; // 48 BB E6 F8 A5 A3 36 56 4E A7 C6 85 B0 ? ? ? 01, expected: 1, index: 0 -constexpr uintptr_t CPatches_AmdSMT = 0x142C1077B - ImageBase; // 75 2D 33 C9 B8 01 00 00 00 0F A2 8B C8 C1 F9 08, expected: 1, index: 0 +constexpr uintptr_t CPatches_BoundaryTeleport = 0x141AFFCB0 - ImageBase; // 48 8B C4 55 53 41 54 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 48 89 70 10 48 8D 59 48, expected: 1, index: 0 +constexpr uintptr_t CPatches_IntroMovie = 0x1401FA530 - ImageBase; // 48 89 5C 24 08 57 48 83 EC 20 48 8B 44 24 50 48 8B D9 48 89 41 08, expected: 1, index: 0 +constexpr uintptr_t CPatches_Vignette = 0x1411664F0 - ImageBase; // 48 8B 41 30 48 83 78 68 00 74, expected: 1, index: 0 +constexpr uintptr_t CPatches_MinimapFlicker = 0x14256793D - ImageBase; // 83 79 2C 00 48 8B F2 4C, expected: 1, index: 0 +constexpr uintptr_t CPatches_OptionsInit = 0x142B95870 - ImageBase; // 40 53 48 83 EC 40 48 8B D9 48 8D 4C 24 20 E8 ? ? ? ? E8 ? ? ? ? 4C 8B 43 08, expected: 1, index: 0 +constexpr uintptr_t CPatches_SkipStartScreen = 0x1429C8252 - ImageBase; // 80 3D ? ? ? ? 00 48 BB E6 F8 A5 A3 36 56 4E A7 C6 85 A0 00 00 00 01, expected: 1, index: 0 +constexpr uintptr_t CPatches_AmdSMT = 0x142B3E4FB - ImageBase; // 75 2D 33 C9 B8 01 00 00 00 0F A2 8B C8 C1 F9 08, expected: 1, index: 0 #pragma endregion #pragma region CPhotoMode -constexpr uintptr_t CPhotoMode_SetRecordID = 0x142E287C0 - ImageBase; // 48 89 5C 24 08 48 89 74 24 18 55 57 41 56 48 8D 6C 24 B9 48 81 EC 90 00 00 00 48 8B F9, expected: 1, index: 0 +constexpr uintptr_t CPhotoMode_SetRecordID = 0x142D60290 - ImageBase; // 48 8B C4 55 57 48 8D 68 A1 48 81 EC 98 00 00 00 48 89 58 08 48 8B D9 48 89 70 18 48 8D 4D 27 48, expected: 1, index: 0 #pragma endregion #pragma region CRenderGlobal -constexpr uintptr_t CRenderGlobal_InstanceOffset = 0x144C91230 - ImageBase; // 48 8B 05 ? ? ? ? 8B D1 48 8B 88 18 8A 5A 01, expected: 1, index: 0, offset: 3 -constexpr uintptr_t CRenderGlobal__DoNotUse_RenderQueueOffset = 0x18BE22C76 - ImageBase; // 4D 8B 0E 49 39 31 0F 84 85 00 00 00 41 39 71 24 74 ? 49 8B 95, expected: 1, index: 0, offset: 0 -constexpr uintptr_t CRenderGlobal_Resize = 0x142D41700 - ImageBase; // 44 88 4C 24 20 44 89 44 24 18 89 54 24 10 89 4C, expected: 1, index: 0 +constexpr uintptr_t CRenderGlobal_InstanceOffset = 0x144CB6BC0 - ImageBase; // 48 8B 05 ? ? ? ? 48 8B 88 18 8E 5A 01 8B 41 08 C3, expected: 1, index: 0, offset: 3 +constexpr uintptr_t CRenderGlobal__DoNotUse_RenderQueueOffset = 0x151F0F229 - ImageBase; // 49 39 29 0F 84 ? ? ? ? 41 39 69 24 0F 84 ? ? ? ? 49 8B 95, expected: 1, index: 0, offset: 0 +constexpr uintptr_t CRenderGlobal_Resize = 0x142C839C0 - ImageBase; // 44 88 4C 24 20 44 89 44 24 18 89 54 24 10 89 4C, expected: 1, index: 0 #pragma endregion #pragma region CRenderNode_Present -constexpr uintptr_t CRenderNode_Present_DoInternal = 0x142D439E0 - ImageBase; // 48 89 5C 24 08 48 89 6C 24 18 48 89 74 24 20 57 41 56 41 57 48 83 EC 30 8B 01 41 8B F8 4C 8B 35, expected: 1, index: 0 +constexpr uintptr_t CRenderNode_Present_DoInternal = 0x142C860B0 - ImageBase; // 48 89 5C 24 08 48 89 6C 24 18 48 89 74 24 20 57 41 56 41 57 48 83 EC 30 8B 01 41 8B F8 4C 8B 35, expected: 1, index: 0 #pragma endregion #pragma region CScript -constexpr uintptr_t CScript_RunPureScript = 0x14022E980 - ImageBase; // 40 55 48 81 EC D0 00 00 00 48 8D 6C 24 40 8B, expected: 1, index: 0 -constexpr uintptr_t CScript_CreateFunction = 0x14029CDD0 - ImageBase; // 48 89 5C 24 08 57 48 83 EC 40 8B F9 48 8D 54 24 30 48 8B 0D ? ? ? ? 41 B8 B8 00 00 00, expected: 1, index: 0 -constexpr uintptr_t CScript_Log = 0x140210470 - ImageBase; // 40 53 48 83 EC ? 48 8D 4C 24 20 48 8B DA E8 ? ? ? ? 33 D2 48 8D 4C 24 40 E8, expected: 1, index: 0 -constexpr uintptr_t CScript_LogChannel = 0x140210470 - ImageBase; // 40 53 48 83 EC ? 48 8D 4C 24 20 48 8B DA E8 ? ? ? ? 33 D2 48 8D 4C 24 40 E8, expected: 1, index: 0 -constexpr uintptr_t CScript_TDBIDConstructorDerive = 0x142C5D2B0 - ImageBase; // 40 53 48 83 EC 30 33 C0 4C 89 44 24 20 48 8B DA, expected: 1, index: 0 -constexpr uintptr_t CScript_ProcessRunningState = 0x140AD62A0 - ImageBase; // 40 53 48 83 EC 20 48 8B 0D ? ? ? ? 48 8B DA E8 ? ? ? ? 84 C0, expected: 1, index: 0 -constexpr uintptr_t CScript_TweakDBLoad = 0x140C43060 - ImageBase; // 48 89 5C 24 10 48 89 7C 24 18 4C 89 74 24 20 55 48 8B EC 48 83 EC 70 48, expected: 1, index: 0 +constexpr uintptr_t CScript_RunPureScript = 0x140206E70 - ImageBase; // 40 55 48 81 EC D0 00 00 00 48 8D 6C 24 40 8B, expected: 1, index: 0 +constexpr uintptr_t CScript_AllocateFunction = 0x1401A7720 - ImageBase; // BA B8 00 00 00 48 8D 4D D7 E8, expected: 3, index: 0 +constexpr uintptr_t CScript_Log = 0x1401E90F0 - ImageBase; // 40 53 48 83 EC ? 48 8D 4C 24 20 48 8B DA E8 ? ? ? ? 33 D2 48 8D 4C 24 40 E8, expected: 1, index: 0 +constexpr uintptr_t CScript_LogChannel = 0x1401E9190 - ImageBase; // 4C 8B DC 49 89 5B 08 49 89 73 18 57 48 83 EC 70 48 8B 02 ? ? ? ? ? ? ? FE 42 62 4D 8D 43 10 33 FF 45 33 C9 49 89 7B 10 48 8B DA 48 89 7A, expected: 1, index: 0 +constexpr uintptr_t CScript_TDBIDConstructorDerive = 0x142B8E8E0 - ImageBase; // 40 53 48 83 EC 30 33 C0 4C 89 44 24 20 48 8B DA, expected: 1, index: 0 +constexpr uintptr_t CScript_ProcessRunningState = 0x140A68BD0 - ImageBase; // 40 53 48 83 EC 20 48 8B 0D ? ? ? ? 48 8B DA E8 ? ? ? ? 84 C0, expected: 1, index: 0 +constexpr uintptr_t CScript_TweakDBLoad = 0x140BC8A90 - ImageBase; // 48 89 5C 24 18 55 57 41 56 48 8B EC 48 83 EC 70 48 8B D9 45 33 F6 48 8D, expected: 1, index: 0 +constexpr uintptr_t CScript_RegisterMemberFunction = 0x140206160 - ImageBase; // 48 89 5C 24 08 57 48 83 EC 20 49 8B C1 4D 8B D0 44 8B 4C 24 58 48 8B DA 41 83 C9 03, expected: 1, index: 0 #pragma endregion #pragma region CWinapi -constexpr uintptr_t CWinapi_ClipToCenter = 0x1407E7DA0 - ImageBase; // 48 89 5C 24 08 57 48 83 EC 30 48 8B 99 ? 01 00 00 48 8B F9 FF, expected: 1, index: 0 +constexpr uintptr_t CWinapi_ClipToCenter = 0x1407843A0 - ImageBase; // 48 89 5C 24 08 57 48 83 EC 30 48 8B 99 ? 01 00 00 48 8B F9 FF, expected: 1, index: 0 #pragma endregion #pragma region gameIGameSystem -constexpr uintptr_t gameIGameSystem_Constructor = 0x140B4E636 - ImageBase; // 48 8B D9 E8 ? ? ? ? 48 8D 05 ? ? ? ? 48 C7 43 40 00 00 00 00, expected: 2, index: 0 -constexpr uintptr_t gameIGameSystem_Initialize = 0x142E2A0F0 - ImageBase; // 48 89 5C 24 18 48 89 6C 24 20 57 48 83 EC 30 48 8B 42 78, expected: 1, index: 0 -constexpr uintptr_t gameIGameSystem_UnInitialize = 0x142E28DE0 - ImageBase; // 40 53 48 83 EC 20 48 8B D9 E8 ? ? ? ? 33 C0 48 89 43 50 48 89 43 48, expected: 1, index: 0 -constexpr uintptr_t gameIGameSystem_Spawn = 0x142E2B225 - ImageBase; // FF 90 A8 01 00 00 48 8B 00 4C 8D 85 80 00 00 00, expected: 1, index: 0 -constexpr uintptr_t gameIGameSystem_Despawn = 0x142E28E80 - ImageBase; // 40 55 53 56 57 41 55 41 56 41 57 48 8B EC 48 83 EC 50, expected: 1, index: 0 -constexpr uintptr_t gameIGameSystem_SpawnCallback = 0x14119D70E - ImageBase; // 41 57 48 83 EC 70 48 8B E9 4C 8B FA, expected: 1, index: 0 +constexpr uintptr_t gameIGameSystem_Constructor = 0x140AEBD36 - ImageBase; // 48 8B D9 E8 ? ? ? ? 48 8D 05 ? ? ? ? 48 C7 43 40 00 00 00 00, expected: 2, index: 0 +constexpr uintptr_t gameIGameSystem_Initialize = 0x142D61C70 - ImageBase; // 48 89 5C 24 18 48 89 6C 24 20 57 48 83 EC 30 48 8B 42 78, expected: 1, index: 0 +constexpr uintptr_t gameIGameSystem_UnInitialize = 0x142D60920 - ImageBase; // 40 53 48 83 EC 20 48 8B D9 E8 ? ? ? ? 33 C0 48 89 43 50 48 89 43 48, expected: 1, index: 0 +constexpr uintptr_t gameIGameSystem_Spawn = 0x142D634E0 - ImageBase; // 48 89 5C 24 18 55 56 41 54 41 56 41 57 48 8D 6C 24 90 48 81 EC 70 01 00 00 48 83 79 50 00 49 8B, expected: 1, index: 0 +constexpr uintptr_t gameIGameSystem_Despawn = 0x142D60950 - ImageBase; // 48 89 5C 24 10 48 89 6C 24 18 56 57 41 54 41 56 41 57 48 83 EC 50 4C 8B F9 0F 57 C0 48 83 C1 41, expected: 1, index: 0 +constexpr uintptr_t gameIGameSystem_SpawnCallback = 0x1410DBE40 - ImageBase; // 48 89 5C 24 18 48 89 6C 24 20 56 57 41 56 48 83 EC 70 48 8B F1 48 8B EA 48 83 C1 48 E8, expected: 1, index: 0 #pragma endregion } // namespace CyberEngineTweaks::Addresses diff --git a/src/reverse/RTTIExtender.cpp b/src/reverse/RTTIExtender.cpp index aeb769bd..3569ce57 100644 --- a/src/reverse/RTTIExtender.cpp +++ b/src/reverse/RTTIExtender.cpp @@ -281,7 +281,7 @@ struct TEMP_Spawner { // REDSmartPtr TEMP_Spawner::func(this, TEMP_SpawnSettings&, RED4ext::CName&) using TFunc = void (*)(TEMP_Spawner*, REDSmartPtr*, TEMP_SpawnSettings&, const RED4ext::CName&); - static GameCall func(CyberEngineTweaks::Addresses::gameIGameSystem_Spawn, -0x55); + static GameCall func(CyberEngineTweaks::Addresses::gameIGameSystem_Spawn); REDSmartPtr pendingEntity; func(this, &pendingEntity, aSettings, acEntityPath); @@ -516,7 +516,7 @@ struct exEntitySpawnerSystem : gameIGameSystem static void SpawnCallback(TEMP_PendingEntity::Unk00& aUnk) { using TFunc = void(*)(RED4ext::IScriptable*, RED4ext::ent::Entity*); - static GameCall func(CyberEngineTweaks::Addresses::gameIGameSystem_SpawnCallback, -0xE); + static GameCall func(CyberEngineTweaks::Addresses::gameIGameSystem_SpawnCallback); struct GameInstance_78_Unk { diff --git a/src/reverse/RenderContext.h b/src/reverse/RenderContext.h index 9736a4fa..dc91cc1a 100644 --- a/src/reverse/RenderContext.h +++ b/src/reverse/RenderContext.h @@ -15,13 +15,13 @@ struct RenderContext uint8_t pad0[0xC97F38]; Device devices[0x30]; // Count unknown, it is at least 0x20 - uint8_t pad[0xED65C0 - 0xC9A1B8]; - void* unkED65C0; // Some pointer, might be related to d3d12on7, I have never seen it being anything other than null - uint8_t padED65C8[0x10]; - ID3D12CommandQueue* pDirectQueue; + uint8_t pad[0xED69C0 - 0xC9A1B8]; + void* unkED69C0; // Some pointer, might be related to d3d12on7, I have never seen it being anything other than null + uint8_t padED69C8[0x10]; + ID3D12CommandQueue* pDirectQueue; // 0ED69D8 }; static_assert(sizeof(RenderContext::Device) == 0xB8); static_assert(offsetof(RenderContext, devices) == 0xC97F38); -static_assert(offsetof(RenderContext, unkED65C0) == 0xED65C0); -static_assert(offsetof(RenderContext, pDirectQueue) == 0xED65D8); +static_assert(offsetof(RenderContext, unkED69C0) == 0xED69C0); +static_assert(offsetof(RenderContext, pDirectQueue) == 0xED69D8); diff --git a/src/scripting/FunctionOverride.cpp b/src/scripting/FunctionOverride.cpp index 1d534e7e..b717e39a 100644 --- a/src/scripting/FunctionOverride.cpp +++ b/src/scripting/FunctionOverride.cpp @@ -11,10 +11,12 @@ static FunctionOverride* s_pOverride = nullptr; using TRunPureScriptFunction = bool (*)(RED4ext::CBaseFunction* apFunction, RED4ext::CScriptStack*, void*); +using TCreateFunction = void* (*)(void* apMemoryPool, size_t aSize); using TCallScriptFunction = bool (*)(RED4ext::IFunction* apFunction, RED4ext::IScriptable* apContext, RED4ext::CStackFrame* apFrame, void* apOut, void* a4); static TRunPureScriptFunction RealRunPureScriptFunction = nullptr; +static TCreateFunction RealCreateFunction = nullptr; static RED4ext::REDfunc CallScriptFunction(RED4ext::Addresses::CBaseFunction_InternalExecute); static constexpr size_t s_cMaxFunctionSize = @@ -157,6 +159,16 @@ bool FunctionOverride::HookRunPureScriptFunction(RED4ext::CClassFunction* apFunc return RealRunPureScriptFunction(apFunction, apStack, a3); } +void* FunctionOverride::HookCreateFunction(void* apMemoryPool, size_t aSize) +{ + enum + { + kOverrideAllocationSize = std::max(s_cMaxFunctionSize, sizeof(RED4ext::CScriptedFunction)) + }; + + return RealCreateFunction(apMemoryPool, kOverrideAllocationSize); +} + void FunctionOverride::HandleOverridenFunction(RED4ext::IScriptable* apContext, RED4ext::CStackFrame* apFrame, void* apOut, void* a4, RED4ext::CClassFunction* apFunction) { if (!s_pOverride) @@ -474,27 +486,20 @@ void FunctionOverride::Hook(Options& aOptions) const } } - { - RED4ext::RelocPtr func(CyberEngineTweaks::Addresses::CScript_CreateFunction); - uint8_t* pLocation = func.GetAddr(); - - if (pLocation) + { + RED4ext::RelocPtr func(CyberEngineTweaks::Addresses::CScript_AllocateFunction); + RealCreateFunction = static_cast(func.GetAddr()); + if (!RealCreateFunction) + Log::Error("Could not find create function!"); + else { - auto* pFirstLocation = pLocation + 0x1A; - auto* pSecondLocation = pLocation + 0x3A; - - if (*pFirstLocation == sizeof(RED4ext::CScriptedFunction) && - *pSecondLocation == sizeof(RED4ext::CScriptedFunction)) - { - DWORD oldProtect; - VirtualProtect(pLocation, 0x40, PAGE_READWRITE, &oldProtect); - *pFirstLocation = *pSecondLocation = std::max(s_cMaxFunctionSize, sizeof(RED4ext::CScriptedFunction)); - VirtualProtect(pLocation, 0x40, oldProtect, &oldProtect); - - Log::Info("Override function allocator patched!"); - } - else - Log::Error("Could not fix allocator for override functions!"); + auto* pLocation = RealCreateFunction; + if (MH_CreateHook(pLocation, &FunctionOverride::HookCreateFunction, + reinterpret_cast(&RealCreateFunction)) != MH_OK || + MH_EnableHook(pLocation) != MH_OK) + Log::Error("Could not hook RealCreateFunction function!"); + else + Log::Info("RealCreateFunction function hook complete!"); } } } diff --git a/src/scripting/FunctionOverride.h b/src/scripting/FunctionOverride.h index 1cb20247..cfbbf740 100644 --- a/src/scripting/FunctionOverride.h +++ b/src/scripting/FunctionOverride.h @@ -36,6 +36,7 @@ struct FunctionOverride static void HandleOverridenFunction(RED4ext::IScriptable* aContext, RED4ext::CStackFrame* aFrame, void* aOut, void* a4, RED4ext::CClassFunction* apFunction); static bool HookRunPureScriptFunction(RED4ext::CClassFunction* apFunction, RED4ext::CScriptStack* apContext, RED4ext::CStackFrame* a3); + static void* HookCreateFunction(void* apMemoryPool, size_t aSize); static bool ExecuteChain(const CallChain& aChain, std::shared_lock& aLock, RED4ext::IScriptable* apContext, TiltedPhoques::Vector* apArgs, RED4ext::CStackType* apResult, TiltedPhoques::Vector* apOutArgs, diff --git a/vendor/RED4ext.SDK b/vendor/RED4ext.SDK index 8e95e838..80838f39 160000 --- a/vendor/RED4ext.SDK +++ b/vendor/RED4ext.SDK @@ -1 +1 @@ -Subproject commit 8e95e83847157ac3e99975620a8870f9faba8845 +Subproject commit 80838f3958cdfe7605e23c0e37958caf4d91cf39