diff --git a/ida/find_patterns.py b/ida/find_patterns.py index d96b2480..a57db88a 100644 --- a/ida/find_patterns.py +++ b/ida/find_patterns.py @@ -85,7 +85,7 @@ def find_ptr(pattern: str, expected: int = 1, index: int = 0, offset: int = 0) - version = idc.get_strlit_contents(addr) print(f'Finding {total} item(s)...') - with open('Addresses.hpp', 'w') as file: + with open('Addresses.h', 'w') as file: file.write('#pragma once\n') file.write('\n') file.write('/*\n') diff --git a/ida/patterns.py b/ida/patterns.py index bc1deb5e..ce3a187c 100644 --- a/ida/patterns.py +++ b/ida/patterns.py @@ -28,7 +28,10 @@ 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='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) + ], functions=[ + Item(name='Resize', pattern='44 88 4C 24 20 44 89 44 24 18 89 54 24 10 89 4C', expected=1) ]), Group(name='CRenderNode_Present', functions=[ Item(name='DoInternal', pattern='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) diff --git a/src/d3d12/D3D12.h b/src/d3d12/D3D12.h index ecf76bc5..01f99bdc 100644 --- a/src/d3d12/D3D12.h +++ b/src/d3d12/D3D12.h @@ -8,6 +8,7 @@ using TPresentD3D12Downlevel = HRESULT(ID3D12CommandQueueDownlevel*, ID3D12Graph using TCreateCommittedResource = HRESULT(ID3D12Device*, const D3D12_HEAP_PROPERTIES*, D3D12_HEAP_FLAGS, const D3D12_RESOURCE_DESC*, D3D12_RESOURCE_STATES, const D3D12_CLEAR_VALUE*, const IID*, void**); using TExecuteCommandLists = void(ID3D12CommandQueue*, UINT, ID3D12CommandList* const*); using TCRenderNode_Present_InternalPresent = void*(int32_t*, uint8_t ,UINT); +using TCRenderGlobal_Resize = void*(uint32_t a1, uint32_t a2, uint32_t a3, uint8_t a4, int* a5); struct D3D12 { @@ -51,6 +52,7 @@ struct D3D12 static HRESULT CreateCommittedResource(ID3D12Device* apDevice, const D3D12_HEAP_PROPERTIES* acpHeapProperties, D3D12_HEAP_FLAGS aHeapFlags, const D3D12_RESOURCE_DESC* acpDesc, D3D12_RESOURCE_STATES aInitialResourceState, const D3D12_CLEAR_VALUE* acpOptimizedClearValue, const IID* acpRIID, void** appvResource); static void ExecuteCommandLists(ID3D12CommandQueue* apCommandQueue, UINT aNumCommandLists, ID3D12CommandList* const* apcpCommandLists); static void* CRenderNode_Present_InternalPresent(int32_t* apSomeInt, uint8_t aSomeSync, UINT aSyncInterval); + static void* CRenderGlobal_Resize(uint32_t a1, uint32_t a2, uint32_t a3, uint8_t a4, int* a5); private: @@ -59,6 +61,7 @@ struct D3D12 TCreateCommittedResource* m_realCreateCommittedResource{ nullptr }; TExecuteCommandLists* m_realExecuteCommandLists{ nullptr }; TCRenderNode_Present_InternalPresent* m_realInternalPresent{ nullptr }; + TCRenderGlobal_Resize* m_realInternalResize{nullptr}; bool m_initialized{ false }; diff --git a/src/d3d12/D3D12_Hooks.cpp b/src/d3d12/D3D12_Hooks.cpp index dabfb18c..0d042af6 100644 --- a/src/d3d12/D3D12_Hooks.cpp +++ b/src/d3d12/D3D12_Hooks.cpp @@ -3,7 +3,7 @@ #include #include "D3D12.h" -#include "reverse/Addresses.hpp" +#include "reverse/Addresses.h" #include "reverse/RenderContext.h" #include @@ -135,16 +135,6 @@ void* D3D12::CRenderNode_Present_InternalPresent(int32_t* apSomeInt, uint8_t aSo if (pContext->unkED65C0 == nullptr) { auto* pDevice = pContext->devices[idx].pSwapChain; - - static std::once_flag s_init; - std::call_once(s_init, [&]() { - void** vtbl = *reinterpret_cast(pDevice); - d3d12.m_realResizeBuffersD3D12 = - static_cast(ApplyHook(vtbl, 13, &D3D12::ResizeBuffers)); - - Log::Info("D3D12: Applied ResizeBuffers vtable hook"); - }); - d3d12.m_pCommandQueue = pContext->pDirectQueue; if (d3d12.Initialize(pDevice)) @@ -155,6 +145,19 @@ void* D3D12::CRenderNode_Present_InternalPresent(int32_t* apSomeInt, uint8_t aSo return d3d12.m_realInternalPresent(apSomeInt, aSomeSync, aSyncInterval); } +void* D3D12::CRenderGlobal_Resize(uint32_t a1, uint32_t a2, uint32_t a3, uint8_t a4, int* a5) +{ + auto& d3d12 = CET::Get().GetD3D12(); + + if (d3d12.m_initialized) + { + Log::Info("CRenderGlobal::Resize() called with initialized D3D12, triggering D3D12::ResetState."); + d3d12.ResetState(); + } + + return d3d12.m_realInternalResize(a1, a2, a3, a4, a5); +} + void D3D12::Hook() { if (kiero::isDownLevelDevice()) @@ -211,7 +214,8 @@ void D3D12::Hook() void D3D12::HookGame() { - RED4ext::RelocPtr presentInternal(CyberEngineTweaks::Addresses::CRenderNode_Present_DoInternal); + const RED4ext::RelocPtr presentInternal(CyberEngineTweaks::Addresses::CRenderNode_Present_DoInternal); + const RED4ext::RelocPtr resizeInternal(CyberEngineTweaks::Addresses::CRenderGlobal_Resize); if (MH_CreateHook(presentInternal.GetAddr(), &CRenderNode_Present_InternalPresent, reinterpret_cast(&m_realInternalPresent)) != MH_OK || @@ -219,5 +223,12 @@ void D3D12::HookGame() Log::Error("Could not hook CRenderNode_Present_InternalPresent function!"); else Log::Info("CRenderNode_Present_InternalPresent function hook complete!"); + + if (MH_CreateHook(resizeInternal.GetAddr(), &CRenderGlobal_Resize, + reinterpret_cast(&m_realInternalResize)) != MH_OK || + MH_EnableHook(resizeInternal.GetAddr()) != MH_OK) + Log::Error("Could not hook CRenderGlobal_Resize function!"); + else + Log::Info("CRenderGlobal_Resize function hook complete!"); } diff --git a/src/reverse/Addresses.hpp b/src/reverse/Addresses.h similarity index 73% rename from src/reverse/Addresses.hpp rename to src/reverse/Addresses.h index 5bb0252c..cbd5faf2 100644 --- a/src/reverse/Addresses.hpp +++ b/src/reverse/Addresses.h @@ -15,6 +15,8 @@ constexpr uintptr_t ImageBase = 0x140000000; #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 #pragma endregion #pragma region CRenderNode_Present diff --git a/src/reverse/RenderContext.cpp b/src/reverse/RenderContext.cpp index 8a2c7b28..fdccf01b 100644 --- a/src/reverse/RenderContext.cpp +++ b/src/reverse/RenderContext.cpp @@ -1,7 +1,7 @@ #include #include "RenderContext.h" -#include "Addresses.hpp" +#include "Addresses.h" RenderContext* RenderContext::GetInstance() noexcept {