From cfdb37f55d2e682d8400ae1b216b9cd32ef8fd18 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Thu, 5 Nov 2026 03:03:21 +0000 Subject: [PATCH] Decompile 2 functions in Source/Archive/GPak.cpp Batch #11721 by dori: 0 byte-identical, 2 confirmed by peer review. - fn_04832 GPakEx::OFB_Base::ProcessData: logic confirmed by peer review - fn_04833 GPakEx::CipherModeBase::Process: logic confirmed by peer review Peer-reviewed-by: Yommy, Tanke, cremane Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Archive/GPak.cpp | 59 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/Source/Archive/GPak.cpp b/Source/Archive/GPak.cpp index 61bae560..dee9ae49 100644 --- a/Source/Archive/GPak.cpp +++ b/Source/Archive/GPak.cpp @@ -2715,6 +2715,54 @@ namespace GPakEx { } // OFFSET: 0x00643160 + // FUNCTION: fn_04833 + __declspec(noinline) std::size_t CipherModeBase::Process(std::span input, std::span output, bool final) { + const bool forward = this->IsForwardTransformation(); + const std::size_t blockSize = this->m_cipher->BlockSize(); + const std::size_t reserved = (!forward && final) ? blockSize : 0; + const std::uint8_t* in = input.data(); + std::size_t inLength = input.size(); + std::uint8_t* out = output.data(); + std::size_t outLength = output.size(); + + std::size_t done = 0; + if (inLength >= reserved + blockSize) { + done = (inLength - reserved) - (inLength - reserved) % blockSize; + if (outLength < done) { + return static_cast(-1); + } + this->ProcessData(in, out, done); + in += done; + out += done; + inLength -= done; + outLength -= done; + } + + if (!final) { + if (inLength == 0) { + return done; + } + } else if (!forward) { + if (inLength == blockSize) { + this->ProcessData(in, this->m_buffer.data(), blockSize); + const std::uint8_t pad = this->m_buffer[blockSize - 1]; + const std::size_t size = blockSize - pad; + if (pad != 0 && pad <= blockSize && size <= outLength) { + std::memcpy(out, this->m_buffer.data(), size); + return done + size; + } + } + } else { + std::memcpy(this->m_buffer.data(), in, inLength); + const std::uint8_t pad = static_cast(blockSize - inLength); + std::memset(this->m_buffer.data() + inLength, pad, pad); + if (blockSize <= outLength) { + this->ProcessData(this->m_buffer.data(), out, blockSize); + return done + blockSize; + } + } + return static_cast(-1); + } // OFFSET: 0x00643480 // FUNCTION: fn_04837 @@ -2795,6 +2843,17 @@ namespace GPakEx { }; // OFFSET: 0x006430F0 + // FUNCTION: fn_04832 + void OFB_Base::ProcessData(const std::uint8_t* input, std::uint8_t* output, std::size_t length) { + const std::size_t blockSize = this->m_cipher->BlockSize(); + while (length != 0) { + this->m_cipher->ProcessAndXorBlock(this->m_register.data(), nullptr, this->m_register.data()); + XorBuffers(output, input, this->m_register.data(), blockSize); + length -= blockSize; + input = input ? input + blockSize : nullptr; + output = output ? output + blockSize : nullptr; + } + } template class BlockCipherFinal : public Cipher {