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 /NorthstarDedicatedTest/ExploitFixes.cpp | |
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
Diffstat (limited to 'NorthstarDedicatedTest/ExploitFixes.cpp')
-rw-r--r-- | NorthstarDedicatedTest/ExploitFixes.cpp | 77 |
1 files changed, 77 insertions, 0 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() |