From b8fb98fcc4aa2d1c6ab6ce57b6b2e10a25861a56 Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Fri, 30 Sep 2016 11:23:29 +0200 Subject: + Yet another protector --- src/SBaseCommon.cpp | 2 +- src/SBaseDumpData.cpp | 4 ++-- src/SBaseFileTable.cpp | 40 ++++++++++++++++++++++++++-------------- src/SBaseSubTypes.cpp | 4 ++-- src/StormLib.h | 7 ++++--- 5 files changed, 35 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp index 977664a..aa891df 100644 --- a/src/SBaseCommon.cpp +++ b/src/SBaseCommon.cpp @@ -721,7 +721,7 @@ TMPQHash * AllocateHashEntry( pHash->dwName1 = dwName1; pHash->dwName2 = dwName2; pHash->lcLocale = (USHORT)lcLocale; - pHash->wPlatform = 0; + pHash->Platform = 0; pHash->dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable); } diff --git a/src/SBaseDumpData.cpp b/src/SBaseDumpData.cpp index d156030..334561b 100644 --- a/src/SBaseDumpData.cpp +++ b/src/SBaseDumpData.cpp @@ -51,11 +51,11 @@ void DumpHashTable(TMPQHash * pHashTable, DWORD dwHashTableSize) printf("== Hash Table =================================\n"); for(i = 0; i < dwHashTableSize; i++) { - printf("[%08x] %08X %08X %04X %04X %08X\n", i, + printf("[%08x] %08X %08X %04X %02X %08X\n", i, pHashTable[i].dwName1, pHashTable[i].dwName2, pHashTable[i].lcLocale, - pHashTable[i].wPlatform, + pHashTable[i].Platform, pHashTable[i].dwBlockIndex); } printf("-----------------------------------------------\n\n"); diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp index fe5eb78..c7a26aa 100644 --- a/src/SBaseFileTable.cpp +++ b/src/SBaseFileTable.cpp @@ -612,32 +612,42 @@ static bool IsValidHashEntry1(TMPQArchive * ha, TMPQHash * pHash, TMPQBlock * pB } // Returns a hash table entry in the following order: -// 1) A hash table entry with the preferred locale -// 2) A hash table entry with the neutral locale +// 1) A hash table entry with the preferred locale and platform +// 2) A hash table entry with the neutral|matching locale and neutral|matching platform // 3) NULL -static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale) +// Storm_2016.dll: 15020940 +static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale, BYTE Platform) { - TMPQHash * pHashNeutral = NULL; TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName); + TMPQHash * pBestEntry = NULL; TMPQHash * pHash = pFirstHash; // Parse the found hashes while(pHash != NULL) { - // If the locales match, return it - if(lcLocale == pHash->lcLocale) + // Storm_2016.dll: 150209CB + // If the hash entry matches both locale and platform, return it immediately + // Note: We only succeed this check if the locale is non-neutral, because + // some Warcraft III maps have several items with neutral locale&platform, which leads + // to wrong item being returned + if((lcLocale || Platform) && pHash->lcLocale == lcLocale && pHash->Platform == Platform) return pHash; - - // If we found neutral hash, remember it - if(pHash->lcLocale == 0) - pHashNeutral = pHash; + + // Storm_2016.dll: 150209D9 + // If (locale matches or is neutral) OR (platform matches or is neutral) + // remember this as the best entry + if(pHash->lcLocale == 0 || pHash->lcLocale == lcLocale) + { + if(pHash->Platform == 0 || pHash->Platform == Platform) + pBestEntry = pHash; + } // Get the next hash entry for that file pHash = GetNextHashEntry(ha, pFirstHash, pHash); } // At the end, return neutral hash (if found), otherwise NULL - return pHashNeutral; + return pBestEntry; } // Returns a hash table entry in the following order: @@ -1803,7 +1813,7 @@ TFileEntry * GetFileEntryLocale2(TMPQArchive * ha, const char * szFileName, LCID // we will need the pointer to hash table entry if(ha->pHashTable != NULL) { - pHash = GetHashEntryLocale(ha, szFileName, lcLocale); + pHash = GetHashEntryLocale(ha, szFileName, lcLocale, 0); if(pHash != NULL && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize) { if(PtrHashIndex != NULL) @@ -1987,7 +1997,8 @@ int RenameFileEntry( pHashEntry->dwName1 = 0xFFFFFFFF; pHashEntry->dwName2 = 0xFFFFFFFF; pHashEntry->lcLocale = 0xFFFF; - pHashEntry->wPlatform = 0xFFFF; + pHashEntry->Platform = 0xFF; + pHashEntry->Reserved = 0xFF; pHashEntry->dwBlockIndex = HASH_ENTRY_DELETED; } @@ -2027,7 +2038,8 @@ int DeleteFileEntry(TMPQArchive * ha, TMPQFile * hf) pHashEntry->dwName1 = 0xFFFFFFFF; pHashEntry->dwName2 = 0xFFFFFFFF; pHashEntry->lcLocale = 0xFFFF; - pHashEntry->wPlatform = 0xFFFF; + pHashEntry->Platform = 0xFF; + pHashEntry->Reserved = 0xFF; pHashEntry->dwBlockIndex = HASH_ENTRY_DELETED; } diff --git a/src/SBaseSubTypes.cpp b/src/SBaseSubTypes.cpp index 333b881..47c205e 100644 --- a/src/SBaseSubTypes.cpp +++ b/src/SBaseSubTypes.cpp @@ -216,7 +216,7 @@ TMPQHash * LoadSqpHashTable(TMPQArchive * ha) // Store the rest. Note that this must be done last, // because block index corresponds to pMpqHash->dwName2 pMpqHash->dwBlockIndex = MPQ_BLOCK_INDEX(pSqpHash); - pMpqHash->wPlatform = 0; + pMpqHash->Platform = 0; pMpqHash->lcLocale = 0; } } @@ -544,7 +544,7 @@ TMPQHash * LoadMpkHashTable(TMPQArchive * ha) // Copy the MPK hash entry to the hash table pHash->dwBlockIndex = pMpkHash[i].dwBlockIndex; - pHash->wPlatform = 0; + pHash->Platform = 0; pHash->lcLocale = 0; pHash->dwName1 = pMpkHash[i].dwName2; pHash->dwName2 = pMpkHash[i].dwName3; diff --git a/src/StormLib.h b/src/StormLib.h index 3621096..b6df481 100644 --- a/src/StormLib.h +++ b/src/StormLib.h @@ -617,12 +617,13 @@ typedef struct _TMPQHash // The platform the file is used for. 0 indicates the default platform. // No other values have been observed. - // Note: wPlatform is actually just BYTE, but since it has never been used, we don't care. - USHORT wPlatform; + BYTE Platform; + BYTE Reserved; #else - USHORT wPlatform; + BYTE Platform; + BYTE Reserved; USHORT lcLocale; #endif -- cgit v1.2.3