diff options
author | Ladislav Zezula <zezula@volny.cz> | 2020-08-09 11:24:16 +0200 |
---|---|---|
committer | Ladislav Zezula <zezula@volny.cz> | 2020-08-09 11:24:16 +0200 |
commit | ac0dfb94b0a2482f06c2dbff11104448857640a1 (patch) | |
tree | fd351cbe15de7badbaf70d8984fd59562db490f3 /src | |
parent | efa7e50ef7d25bcbb15007deed9453b3002aa8aa (diff) |
Loading of MPQs v 4.0 with fake MPQ headers
Diffstat (limited to 'src')
-rw-r--r-- | src/SBaseFileTable.cpp | 9 | ||||
-rw-r--r-- | src/SFileOpenArchive.cpp | 7 | ||||
-rw-r--r-- | src/StormLib.h | 1 |
3 files changed, 12 insertions, 5 deletions
diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp index a54f152..7f67533 100644 --- a/src/SBaseFileTable.cpp +++ b/src/SBaseFileTable.cpp @@ -553,8 +553,11 @@ int ConvertMpqHeaderToFormat4( // Verify header MD5. Header MD5 is calculated from the MPQ header since the 'MPQ\x1A'
// signature until the position of header MD5 at offset 0xC0
BSWAP_TMPQHEADER(pHeader, MPQ_FORMAT_VERSION_4);
+
+ // Apparently, Starcraft II only accepts MPQ headers where the MPQ header hash matches
+ // If MD5 doesn't match, we ignore this offset
if(!VerifyDataBlockHash(pHeader, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE, pHeader->MD5_MpqHeader))
- nError = ERROR_FILE_CORRUPT;
+ return ERROR_FAKE_MPQ_HEADER;
// Calculate the block table position
BlockTablePos64 = MpqOffset + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
@@ -2214,7 +2217,7 @@ static TMPQHash * LoadHashTable(TMPQArchive * ha) break;
}
- // Remember the size of the hash table
+ // Return the loaded hash table
return pHashTable;
}
@@ -2337,7 +2340,7 @@ int LoadAnyHashTable(TMPQArchive * ha) ha->pHetTable = LoadHetTable(ha);
// Try to load classic hash table
- if(pHeader->dwHashTableSize)
+ if(pHeader->dwHashTableSize && ha->pHetTable == NULL)
ha->pHashTable = LoadHashTable(ha);
// At least one of the tables must be present
diff --git a/src/SFileOpenArchive.cpp b/src/SFileOpenArchive.cpp index 9e6f5d6..7755eaf 100644 --- a/src/SFileOpenArchive.cpp +++ b/src/SFileOpenArchive.cpp @@ -317,8 +317,11 @@ bool WINAPI SFileOpenArchive( { // Now convert the header to version 4 nError = ConvertMpqHeaderToFormat4(ha, SearchOffset, FileSize, dwFlags, bIsWarcraft3Map); - bSearchComplete = true; - break; + if(nError != ERROR_FAKE_MPQ_HEADER) + { + bSearchComplete = true; + break; + } } // Check for MPK archives (Longwu Online - MPQ fork) diff --git a/src/StormLib.h b/src/StormLib.h index bd8ea94..81f8c59 100644 --- a/src/StormLib.h +++ b/src/StormLib.h @@ -158,6 +158,7 @@ extern "C" { #define ERROR_FILE_INCOMPLETE 10006 // The required file part is missing #define ERROR_UNKNOWN_FILE_NAMES 10007 // A name of at least one file is unknown #define ERROR_CANT_FIND_PATCH_PREFIX 10008 // StormLib was unable to find patch prefix for the patches +#define ERROR_FAKE_MPQ_HEADER 10009 // The header at this position is fake header // Values for SFileCreateArchive #define HASH_TABLE_SIZE_MIN 0x00000004 // Verified: If there is 1 file, hash table size is 4 |