diff options
author | Ladislav Zezula <ladislav.zezula@avast.com> | 2021-12-21 10:37:24 +0100 |
---|---|---|
committer | Ladislav Zezula <ladislav.zezula@avast.com> | 2021-12-21 10:37:24 +0100 |
commit | 7da097c51323f15752f252e8c5ed0bd1a349ec75 (patch) | |
tree | 1666ca90759e7343dfc6b188304723171f6ccc3f /src | |
parent | 76887d4bb0836b09a04c7ab578b6df5f1262812e (diff) |
Regression tests
Diffstat (limited to 'src')
-rw-r--r-- | src/SBaseCommon.cpp | 72 | ||||
-rw-r--r-- | src/SFileReadFile.cpp | 55 |
2 files changed, 70 insertions, 57 deletions
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp index 98d541a..2defdab 100644 --- a/src/SBaseCommon.cpp +++ b/src/SBaseCommon.cpp @@ -552,46 +552,52 @@ void DecryptMpqBlock(void * pvDataBlock, DWORD dwLength, DWORD dwKey1) DWORD DetectFileKeyBySectorSize(LPDWORD EncryptedData, DWORD dwSectorSize, DWORD dwDecrypted0)
{
- DWORD dwDecrypted1Max = dwSectorSize + dwDecrypted0;
- DWORD dwKey1PlusKey2;
- DWORD DataBlock[2];
-
// We must have at least 2 DWORDs there to be able to decrypt something
- if(dwSectorSize < 0x08)
- return 0;
+ if(dwSectorSize >= 0x08)
+ {
+ // Also try subsequent three values. This is because the value of the sector offset[0]
+ // could be higher than the total size of the sector table.
+ // Example MPQ: MPQ_2021_v1_CantExtractCHK.scx
+ for(DWORD dwDecrypted4 = dwDecrypted0 + 4; dwDecrypted0 < dwDecrypted4; dwDecrypted0++)
+ {
+ DWORD dwDecrypted1Max = dwSectorSize + dwDecrypted0;
+ DWORD dwKey1PlusKey2;
+ DWORD DataBlock[2];
- // Get the value of the combined encryption key
- dwKey1PlusKey2 = (EncryptedData[0] ^ dwDecrypted0) - 0xEEEEEEEE;
+ // Get the value of the combined encryption key
+ dwKey1PlusKey2 = (EncryptedData[0] ^ dwDecrypted0) - 0xEEEEEEEE;
- // Try all 256 combinations of dwKey1
- for(DWORD i = 0; i < 0x100; i++)
- {
- DWORD dwSaveKey1;
- DWORD dwKey1 = dwKey1PlusKey2 - StormBuffer[MPQ_HASH_KEY2_MIX + i];
- DWORD dwKey2 = 0xEEEEEEEE;
+ // Try all 256 combinations of dwKey1
+ for(DWORD i = 0; i < 0x100; i++)
+ {
+ DWORD dwSaveKey1;
+ DWORD dwKey1 = dwKey1PlusKey2 - StormBuffer[MPQ_HASH_KEY2_MIX + i];
+ DWORD dwKey2 = 0xEEEEEEEE;
- // Modify the second key and decrypt the first DWORD
- dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
- DataBlock[0] = EncryptedData[0] ^ (dwKey1 + dwKey2);
+ // Modify the second key and decrypt the first DWORD
+ dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
+ DataBlock[0] = EncryptedData[0] ^ (dwKey1 + dwKey2);
- // Did we obtain the same value like dwDecrypted0?
- if(DataBlock[0] == dwDecrypted0)
- {
- // Save this key value. Increment by one because
- // we are decrypting sector offset table
- dwSaveKey1 = dwKey1 + 1;
+ // Did we obtain the same value like dwDecrypted0?
+ if(DataBlock[0] == dwDecrypted0)
+ {
+ // Save this key value. Increment by one because
+ // we are decrypting sector offset table
+ dwSaveKey1 = dwKey1 + 1;
- // Rotate both keys
- dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B);
- dwKey2 = DataBlock[0] + dwKey2 + (dwKey2 << 5) + 3;
+ // Rotate both keys
+ dwKey1 = ((~dwKey1 << 0x15) + 0x11111111) | (dwKey1 >> 0x0B);
+ dwKey2 = DataBlock[0] + dwKey2 + (dwKey2 << 5) + 3;
- // Modify the second key again and decrypt the second DWORD
- dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
- DataBlock[1] = EncryptedData[1] ^ (dwKey1 + dwKey2);
+ // Modify the second key again and decrypt the second DWORD
+ dwKey2 += StormBuffer[MPQ_HASH_KEY2_MIX + (dwKey1 & 0xFF)];
+ DataBlock[1] = EncryptedData[1] ^ (dwKey1 + dwKey2);
- // Now compare the results
- if(DataBlock[1] <= dwDecrypted1Max)
- return dwSaveKey1;
+ // Now compare the results
+ if(DataBlock[1] <= dwDecrypted1Max)
+ return dwSaveKey1;
+ }
+ }
}
}
@@ -1304,7 +1310,7 @@ DWORD AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile) DWORD dwSectorOffset0 = hf->SectorOffsets[i];
// Every following sector offset must be bigger than the previous one
- if(dwSectorOffset1 <= dwSectorOffset0)
+ if(dwSectorOffset1 < dwSectorOffset0)
{
bSectorOffsetTableCorrupt = true;
break;
diff --git a/src/SFileReadFile.cpp b/src/SFileReadFile.cpp index 1703748..6ec04f3 100644 --- a/src/SFileReadFile.cpp +++ b/src/SFileReadFile.cpp @@ -159,34 +159,41 @@ static DWORD ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, // by comparing uncompressed and compressed size !!! if(dwRawBytesInThisSector < dwBytesInThisSector) { - int cbOutSector = dwBytesInThisSector; - int cbInSector = dwRawBytesInThisSector; - int nResult = 0; - - // Is the file compressed by Blizzard's multiple compression ? - if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS) + if(dwRawBytesInThisSector != 0) { - // Remember the last used compression - hf->dwCompression0 = pbInSector[0]; - - // Decompress the data - if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) - nResult = SCompDecompress2(pbOutSector, &cbOutSector, pbInSector, cbInSector); - else - nResult = SCompDecompress(pbOutSector, &cbOutSector, pbInSector, cbInSector); - } + int cbOutSector = dwBytesInThisSector; + int cbInSector = dwRawBytesInThisSector; + int nResult = 0; - // Is the file compressed by PKWARE Data Compression Library ? - else if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE) - { - nResult = SCompExplode(pbOutSector, &cbOutSector, pbInSector, cbInSector); - } + // Is the file compressed by Blizzard's multiple compression ? + if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS) + { + // Remember the last used compression + hf->dwCompression0 = pbInSector[0]; + + // Decompress the data + if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) + nResult = SCompDecompress2(pbOutSector, &cbOutSector, pbInSector, cbInSector); + else + nResult = SCompDecompress(pbOutSector, &cbOutSector, pbInSector, cbInSector); + } + + // Is the file compressed by PKWARE Data Compression Library ? + else if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE) + { + nResult = SCompExplode(pbOutSector, &cbOutSector, pbInSector, cbInSector); + } - // Did the decompression fail ? - if(nResult == 0) + // Did the decompression fail ? + if(nResult == 0) + { + dwErrCode = ERROR_FILE_CORRUPT; + break; + } + } + else { - dwErrCode = ERROR_FILE_CORRUPT; - break; + memset(pbOutSector, 0, dwBytesInThisSector); } } else |