mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-07-23 13:33:56 +00:00
Added handling of normal compression for patching xex files (#126)
* Added handling of normal compression for patching xex files * Added normal compression handling to XenonAnalyse * Swap calloc for unique_ptr, tidied up code layout
This commit is contained in:
@@ -403,7 +403,63 @@ XexPatcher::Result XexPatcher::apply(const uint8_t* xexBytes, size_t xexBytesSiz
|
||||
memmove(outDataCursor, srcDataCursor, blocks[i].dataSize);
|
||||
}
|
||||
}
|
||||
else if (fileFormatInfo->compressionType == XEX_COMPRESSION_NORMAL || fileFormatInfo->compressionType == XEX_COMPRESSION_DELTA)
|
||||
else if (fileFormatInfo->compressionType == XEX_COMPRESSION_NORMAL)
|
||||
{
|
||||
const Xex2CompressedBlockInfo* blocks = &((const Xex2FileNormalCompressionInfo*)(fileFormatInfo + 1))->firstBlock;
|
||||
const uint32_t exeLength = xexBytesSize - xexHeader->headerSize.get();
|
||||
const uint8_t* exeBuffer = &outBytes[headerTargetSize];
|
||||
|
||||
auto compressBuffer = std::make_unique<uint8_t[]>(exeLength);
|
||||
const uint8_t* p = NULL;
|
||||
uint8_t* d = NULL;
|
||||
sha1::SHA1 s;
|
||||
|
||||
p = exeBuffer;
|
||||
d = compressBuffer.get();
|
||||
|
||||
uint8_t blockCalcedDigest[0x14];
|
||||
while (blocks->blockSize)
|
||||
{
|
||||
const uint8_t* pNext = p + blocks->blockSize;
|
||||
const auto* nextBlock = (const Xex2CompressedBlockInfo*)p;
|
||||
|
||||
s.reset();
|
||||
s.processBytes(p, blocks->blockSize);
|
||||
s.finalize(blockCalcedDigest);
|
||||
|
||||
if (memcmp(blockCalcedDigest, blocks->blockHash, 0x14) != 0)
|
||||
return Result::PatchFailed;
|
||||
|
||||
p += 4;
|
||||
p += 20;
|
||||
|
||||
while (true)
|
||||
{
|
||||
const size_t chunkSize = (p[0] << 8) | p[1];
|
||||
p += 2;
|
||||
|
||||
if (!chunkSize)
|
||||
break;
|
||||
|
||||
memcpy(d, p, chunkSize);
|
||||
p += chunkSize;
|
||||
d += chunkSize;
|
||||
}
|
||||
|
||||
p = pNext;
|
||||
blocks = nextBlock;
|
||||
}
|
||||
|
||||
int resultCode = 0;
|
||||
uint32_t uncompressedSize = originalSecurityInfo->imageSize;
|
||||
uint8_t* buffer = outBytes.data() + newXexHeaderSize;
|
||||
|
||||
resultCode = lzxDecompress(compressBuffer.get(), d - compressBuffer.get(), buffer, uncompressedSize, ((const Xex2FileNormalCompressionInfo*)(fileFormatInfo + 1))->windowSize, nullptr, 0);
|
||||
|
||||
if (resultCode)
|
||||
return Result::PatchFailed;
|
||||
}
|
||||
else if (fileFormatInfo->compressionType == XEX_COMPRESSION_DELTA)
|
||||
{
|
||||
return Result::XexFileUnsupported;
|
||||
}
|
||||
|
Reference in New Issue
Block a user