diff options
author | KittenPopo <Pokeberry123@gmail.com> | 2022-06-19 14:46:03 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-19 23:46:03 +0200 |
commit | c7dd9ff6d4c80a91bfe66e08669c79d5c9532a2e (patch) | |
tree | 29f92222cdea53f494da4c1a1e50fafae5faa24c | |
parent | 0ffee77ca1e9ffdd4590e52d6e200fa2beace344 (diff) | |
download | NorthstarLauncher-c7dd9ff6d4c80a91bfe66e08669c79d5c9532a2e.tar.gz NorthstarLauncher-c7dd9ff6d4c80a91bfe66e08669c79d5c9532a2e.zip |
Move LZSS exploit segfault fix hook to ExploitFixes.cpp (#195)
* Move LZSS exploit fix hook to ExploitFixes.cpp
* Formatting changes for clang-format
-rw-r--r-- | NorthstarDedicatedTest/ExploitFixes.cpp | 77 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dllmain.cpp | 1 | ||||
-rw-r--r-- | NorthstarDedicatedTest/miscserverfixes.cpp | 108 | ||||
-rw-r--r-- | NorthstarDedicatedTest/miscserverfixes.h | 3 |
4 files changed, 79 insertions, 110 deletions
diff --git a/NorthstarDedicatedTest/ExploitFixes.cpp b/NorthstarDedicatedTest/ExploitFixes.cpp index af7d48ac..84ccc997 100644 --- a/NorthstarDedicatedTest/ExploitFixes.cpp +++ b/NorthstarDedicatedTest/ExploitFixes.cpp @@ -365,6 +365,83 @@ static void* GetEntByIndexHook(int idx) return GetEntByIndex(idx); } +// RELOCATED FROM https://github.com/R2Northstar/NorthstarLauncher/commit/25dbf729cfc75107a0fcf0186924b58ecc05214b +// Rewrite of CLZSS::SafeUncompress to fix a vulnerability where malicious compressed payloads could cause the decompressor to try to read +// out of the bounds of the output buffer. +KHOOK( + LZSS_SafeUncompress, + ("engine.dll", "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 33 ED 41 8B F9"), + uint32_t, + __fastcall, + (void* self, const unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize)) +{ + static constexpr int LZSS_LOOKSHIFT = 4; + + uint32_t totalBytes = 0; + int getCmdByte = 0, cmdByte = 0; + + struct lzss_header_t + { + uint32_t id, actualSize; + }; + + lzss_header_t header = *(lzss_header_t*)pInput; + + if (pInput == NULL || header.id != 'SSZL' || header.actualSize == 0 || header.actualSize > unBufSize) + return 0; + + pInput += sizeof(lzss_header_t); + + for (;;) + { + if (!getCmdByte) + cmdByte = *pInput++; + + getCmdByte = (getCmdByte + 1) & 0x07; + + if (cmdByte & 0x01) + { + int position = *pInput++ << LZSS_LOOKSHIFT; + position |= (*pInput >> LZSS_LOOKSHIFT); + position += 1; + + int count = (*pInput++ & 0x0F) + 1; + if (count == 1) + break; + + // Ensure reference chunk exists entirely within our buffer + if (position > totalBytes) + return 0; + + totalBytes += count; + if (totalBytes > unBufSize) + return 0; + + unsigned char* pSource = pOutput - position; + for (int i = 0; i < count; i++) + *pOutput++ = *pSource++; + } + else + { + totalBytes++; + if (totalBytes > unBufSize) + return 0; + + *pOutput++ = *pInput++; + } + cmdByte = cmdByte >> 1; + } + + if (totalBytes == header.actualSize) + { + return totalBytes; + } + else + { + return 0; + } +} + ////////////////////////////////////////////////// void DoBytePatches() diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp index b6b68811..fc403e95 100644 --- a/NorthstarDedicatedTest/dllmain.cpp +++ b/NorthstarDedicatedTest/dllmain.cpp @@ -266,7 +266,6 @@ bool InitialiseNorthstar() AddDllLoadCallback("engine.dll", InitialiseSharedMasterServer); AddDllLoadCallback("server.dll", InitialiseMiscServerScriptCommand); AddDllLoadCallback("server.dll", InitialiseMiscServerFixes); - AddDllLoadCallback("engine.dll", InitialiseMiscEngineServerFixes); AddDllLoadCallback("server.dll", InitialiseBuildAINFileHooks); AddDllLoadCallback("engine.dll", InitialisePlaylistHooks); diff --git a/NorthstarDedicatedTest/miscserverfixes.cpp b/NorthstarDedicatedTest/miscserverfixes.cpp index ddbfcfbb..e85950c4 100644 --- a/NorthstarDedicatedTest/miscserverfixes.cpp +++ b/NorthstarDedicatedTest/miscserverfixes.cpp @@ -23,110 +23,4 @@ void InitialiseMiscServerFixes(HMODULE baseAddress) { NSMem::BytePatch(ba + 0x153920, "C3"); } -} - -typedef unsigned int(__fastcall* CLZSS__SafeUncompressType)( - void* self, const unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize); -CLZSS__SafeUncompressType CLZSS__SafeUncompress; - -struct lzss_header_t -{ - unsigned int id; - unsigned int actualSize; -}; - -static constexpr int LZSS_LOOKSHIFT = 4; - -// Rewrite of CLZSS::SafeUncompress to fix a vulnerability where malicious compressed payloads could cause the decompressor to try to read -// out of the bounds of the output buffer. -static unsigned int CLZSS__SafeUncompressHook(void* self, const unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize) -{ - unsigned int totalBytes = 0; - int getCmdByte = 0; - int cmdByte = 0; - - lzss_header_t header = *(lzss_header_t*)pInput; - - if (pInput == NULL) - { - return 0; - } - if (header.id != 0x53535a4c) - { - return 0; - } - if (header.actualSize == 0) - { - return 0; - } - if (header.actualSize > unBufSize) - { - return 0; - } - - pInput += sizeof(lzss_header_t); - - for (;;) - { - if (!getCmdByte) - { - cmdByte = *pInput++; - } - getCmdByte = (getCmdByte + 1) & 0x07; - - if (cmdByte & 0x01) - { - int position = *pInput++ << LZSS_LOOKSHIFT; - position |= (*pInput >> LZSS_LOOKSHIFT); - position += 1; - int count = (*pInput++ & 0x0F) + 1; - if (count == 1) - { - break; - } - - // Ensure reference chunk exists entirely within our buffer - if (position > totalBytes) - { - return 0; - } - - totalBytes += count; - if (totalBytes > unBufSize) - { - return 0; - } - - unsigned char* pSource = pOutput - position; - for (int i = 0; i < count; i++) - { - *pOutput++ = *pSource++; - } - } - else - { - totalBytes++; - if (totalBytes > unBufSize) - { - return 0; - } - *pOutput++ = *pInput++; - } - cmdByte = cmdByte >> 1; - } - - if (totalBytes != header.actualSize) - { - return 0; - } - - return totalBytes; - - return 0; -} - -void InitialiseMiscEngineServerFixes(HMODULE baseAddress) -{ - HookEnabler hook; - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x432a10, &CLZSS__SafeUncompressHook, reinterpret_cast<LPVOID*>(&CLZSS__SafeUncompress)); -} +}
\ No newline at end of file diff --git a/NorthstarDedicatedTest/miscserverfixes.h b/NorthstarDedicatedTest/miscserverfixes.h index 3fdf56a8..d1c05a6b 100644 --- a/NorthstarDedicatedTest/miscserverfixes.h +++ b/NorthstarDedicatedTest/miscserverfixes.h @@ -1,2 +1 @@ -void InitialiseMiscServerFixes(HMODULE baseAddress); -void InitialiseMiscEngineServerFixes(HMODULE baseAddress);
\ No newline at end of file +void InitialiseMiscServerFixes(HMODULE baseAddress);
\ No newline at end of file |