From ba5b14df0a4dfdfb0338564d1bcc0239afa87960 Mon Sep 17 00:00:00 2001 From: ergo720 <45463469+ergo720@users.noreply.github.com> Date: Sat, 28 Dec 2024 00:07:56 +0100 Subject: [PATCH] XeUnloadSection --- nboxkrnl/ke/thunk.cpp | 2 +- nboxkrnl/xe/xe.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++ nboxkrnl/xe/xe.hpp | 5 +++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/nboxkrnl/ke/thunk.cpp b/nboxkrnl/ke/thunk.cpp index 83a1e10..43242fb 100644 --- a/nboxkrnl/ke/thunk.cpp +++ b/nboxkrnl/ke/thunk.cpp @@ -348,7 +348,7 @@ ULONG KernelThunkTable[379] = (ULONG)FUNC(nullptr), //(ULONG)VARIABLE(&XboxSignatureKey), // 0x0145 (325) (ULONG)VARIABLE(&XeImageFileName), // 0x0146 (326) (ULONG)FUNC(&XeLoadSection), // 0x0147 (327) - (ULONG)FUNC(nullptr), //(ULONG)FUNC(&XeUnloadSection), // 0x0148 (328) + (ULONG)FUNC(&XeUnloadSection), // 0x0148 (328) (ULONG)FUNC(nullptr), //(ULONG)FUNC(&READ_PORT_BUFFER_UCHAR), // 0x0149 (329) (ULONG)FUNC(nullptr), //(ULONG)FUNC(&READ_PORT_BUFFER_USHORT), // 0x014A (330) (ULONG)FUNC(nullptr), //(ULONG)FUNC(&READ_PORT_BUFFER_ULONG), // 0x014B (331) diff --git a/nboxkrnl/xe/xe.cpp b/nboxkrnl/xe/xe.cpp index d75c770..4418943 100644 --- a/nboxkrnl/xe/xe.cpp +++ b/nboxkrnl/xe/xe.cpp @@ -285,3 +285,52 @@ EXPORTNUM(327) NTSTATUS XBOXAPI XeLoadSection return STATUS_SUCCESS; } + +// Source: Cxbx-Reloaded +EXPORTNUM(328) NTSTATUS XBOXAPI XeUnloadSection +( + PXBE_SECTION Section +) +{ + NTSTATUS Status = STATUS_INVALID_PARAMETER; + RtlEnterCriticalSectionAndRegion(&XepXbeLoaderLock); + + // If the section was loaded, process it + if (Section->SectionReferenceCount > 0) { + // Decrement the reference count + Section->SectionReferenceCount -= 1; + + // Free the section and the physical memory in use if necessary + if (Section->SectionReferenceCount == 0) { + // REMARK: the following can be tested with Broken Sword - The Sleeping Dragon, RalliSport Challenge, ... + // Test-case: Apex/Racing Evoluzione requires the memory NOT to be zeroed + + ULONG BaseAddress = (ULONG)Section->VirtualAddress; + ULONG EndingAddress = (ULONG)Section->VirtualAddress + Section->VirtualSize; + + // Decrement the head/tail page reference counters + (*Section->HeadReferenceCount)--; + (*Section->TailReferenceCount)--; + + if ((*Section->TailReferenceCount) != 0) { + EndingAddress = ROUND_DOWN_4K(EndingAddress); + } + + if ((*Section->HeadReferenceCount) != 0) { + BaseAddress = ROUND_UP_4K(BaseAddress); + } + + if (EndingAddress > BaseAddress) { + PVOID BaseAddress2 = (PVOID)BaseAddress; + ULONG RegionSize = EndingAddress - BaseAddress; + NtFreeVirtualMemory(&BaseAddress2, &RegionSize, MEM_DECOMMIT); + } + } + + Status = STATUS_SUCCESS; + } + + RtlLeaveCriticalSectionAndRegion(&XepXbeLoaderLock); + + return Status; +} diff --git a/nboxkrnl/xe/xe.hpp b/nboxkrnl/xe/xe.hpp index 465157e..2615bc1 100644 --- a/nboxkrnl/xe/xe.hpp +++ b/nboxkrnl/xe/xe.hpp @@ -36,6 +36,11 @@ EXPORTNUM(327) DLLEXPORT NTSTATUS XBOXAPI XeLoadSection PXBE_SECTION Section ); +EXPORTNUM(328) DLLEXPORT NTSTATUS XBOXAPI XeUnloadSection +( + PXBE_SECTION Section +); + #ifdef __cplusplus } #endif