aboutsummaryrefslogtreecommitdiff
path: root/src/SBaseFileTable.cpp
diff options
context:
space:
mode:
authorLadislav Zezula <zezula-at-volny-dot-cz>2016-06-18 20:32:15 +0200
committerLadislav Zezula <zezula-at-volny-dot-cz>2016-06-18 20:32:15 +0200
commit303631f9d7f753dacffb1e038dd273dc204e1ea9 (patch)
tree5397acd7c5b8efe6e1a721f0177b534e38d9acd6 /src/SBaseFileTable.cpp
parent47b6b6eb4addd82a89d6bcd8fa92f9c0a09a5781 (diff)
+ Updated for protectors fiddling with too big block table index
Diffstat (limited to 'src/SBaseFileTable.cpp')
-rw-r--r--src/SBaseFileTable.cpp46
1 files changed, 18 insertions, 28 deletions
diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp
index 9d37ff1..981328b 100644
--- a/src/SBaseFileTable.cpp
+++ b/src/SBaseFileTable.cpp
@@ -581,11 +581,9 @@ int ConvertMpqHeaderToFormat4(
// Hash entry verification when the file table does not exist yet
bool IsValidHashEntry(TMPQArchive * ha, TMPQHash * pHash)
{
- TFileEntry * pFileEntry = ha->pFileTable + MPQ_BLOCK_INDEX(pHash->dwBlockIndex);
- DWORD dwBlockIndex = MPQ_BLOCK_INDEX(pHash->dwBlockIndex);
+ TFileEntry * pFileEntry = ha->pFileTable + MPQ_BLOCK_INDEX(pHash);
- pFileEntry = ha->pFileTable + dwBlockIndex;
- return ((dwBlockIndex < ha->dwFileTableSize) && (pFileEntry->dwFlags & MPQ_FILE_EXISTS)) ? true : false;
+ return ((MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize) && (pFileEntry->dwFlags & MPQ_FILE_EXISTS)) ? true : false;
}
// Hash entry verification when the file table does not exist yet
@@ -593,20 +591,12 @@ static bool IsValidHashEntry1(TMPQArchive * ha, TMPQHash * pHash, TMPQBlock * pB
{
ULONGLONG ByteOffset;
TMPQBlock * pBlock;
- DWORD dwBlockIndex;
-
- // We need to mask out the upper 4 bits of the block table index.
- // This is because it gets shifted out when calculating block table offset
- // BlockTableOffset = pHash->dwBlockIndex * 0x10
- // Malformed MPQ maps may contain invalid entries
- // Note that Storm.dll does not perfom this check
- dwBlockIndex = MPQ_BLOCK_INDEX(pHash->dwBlockIndex);
// The block index is considered valid if it's less than block table size
- if(dwBlockIndex < ha->pHeader->dwBlockTableSize)
+ if(MPQ_BLOCK_INDEX(pHash) < ha->pHeader->dwBlockTableSize)
{
// Calculate the block table position
- pBlock = pBlockTable + dwBlockIndex;
+ pBlock = pBlockTable + MPQ_BLOCK_INDEX(pHash);
// Check whether this is an existing file
// Also we do not allow to be file size greater than 2GB
@@ -787,28 +777,28 @@ static int BuildFileTableFromBlockTable(
// - Multiple hash entries (different file name) point to the same block entry
//
// Ignore all hash table entries where:
- // - dwBlockIndex >= BlockTableSize
+ // - Block Index >= BlockTableSize
// - Flags of the appropriate block table entry
//
if(IsValidHashEntry1(ha, pHash, pBlockTable))
{
- DWORD dwBlockIndex = MPQ_BLOCK_INDEX(pHash->dwBlockIndex);
- DWORD dwNewIndex = MPQ_BLOCK_INDEX(pHash->dwBlockIndex);
+ DWORD dwOldIndex = MPQ_BLOCK_INDEX(pHash);
+ DWORD dwNewIndex = MPQ_BLOCK_INDEX(pHash);
// Determine the new block index
if(DefragmentTable != NULL)
{
// Need to handle case when multiple hash
// entries point to the same block entry
- if(DefragmentTable[dwBlockIndex] == HASH_ENTRY_FREE)
+ if(DefragmentTable[dwOldIndex] == HASH_ENTRY_FREE)
{
- DefragmentTable[dwBlockIndex] = dwItemCount;
+ DefragmentTable[dwOldIndex] = dwItemCount;
dwNewIndex = dwItemCount++;
}
else
{
- dwNewIndex = DefragmentTable[dwBlockIndex];
+ dwNewIndex = DefragmentTable[dwOldIndex];
}
// Fix the pointer in the hash entry
@@ -820,7 +810,7 @@ static int BuildFileTableFromBlockTable(
// Get the pointer to the file entry and the block entry
pFileEntry = ha->pFileTable + dwNewIndex;
- pBlock = pBlockTable + dwBlockIndex;
+ pBlock = pBlockTable + dwOldIndex;
// ByteOffset is only valid if file size is not zero
pFileEntry->ByteOffset = pBlock->dwFilePos;
@@ -1814,11 +1804,11 @@ TFileEntry * GetFileEntryLocale2(TMPQArchive * ha, const char * szFileName, LCID
if(ha->pHashTable != NULL)
{
pHash = GetHashEntryLocale(ha, szFileName, lcLocale);
- if(pHash != NULL && pHash->dwBlockIndex < ha->dwFileTableSize)
+ if(pHash != NULL && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize)
{
if(PtrHashIndex != NULL)
PtrHashIndex[0] = (DWORD)(pHash - ha->pHashTable);
- return ha->pFileTable + pHash->dwBlockIndex;
+ return ha->pFileTable + MPQ_BLOCK_INDEX(pHash);
}
}
@@ -1848,11 +1838,11 @@ TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID l
if(ha->pHashTable != NULL)
{
pHash = GetHashEntryExact(ha, szFileName, lcLocale);
- if(pHash != NULL && pHash->dwBlockIndex < ha->dwFileTableSize)
+ if(pHash != NULL && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize)
{
if(PtrHashIndex != NULL)
PtrHashIndex[0] = (DWORD)(pHash - ha->pHashTable);
- return ha->pFileTable + pHash->dwBlockIndex;
+ return ha->pFileTable + MPQ_BLOCK_INDEX(pHash);
}
}
@@ -2640,11 +2630,11 @@ int DefragmentFileTable(TMPQArchive * ha)
for(pHash = ha->pHashTable; pHash < pHashTableEnd; pHash++)
{
- if(pHash->dwBlockIndex < ha->dwFileTableSize)
+ if(MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize)
{
// If that block entry is there, set it to the hash entry
// If not, set it as DELETED
- dwNewBlockIndex = DefragmentTable[pHash->dwBlockIndex];
+ dwNewBlockIndex = DefragmentTable[MPQ_BLOCK_INDEX(pHash)];
pHash->dwBlockIndex = (dwNewBlockIndex != HASH_ENTRY_FREE) ? dwNewBlockIndex : HASH_ENTRY_DELETED;
}
}
@@ -2753,7 +2743,7 @@ int RebuildFileTable(TMPQArchive * ha, DWORD dwNewHashTableSize)
{
if(IsValidHashEntry(ha, pHash))
{
- pFileEntry = ha->pFileTable + pHash->dwBlockIndex;
+ pFileEntry = ha->pFileTable + MPQ_BLOCK_INDEX(pHash);
AllocateHashEntry(ha, pFileEntry, pHash->lcLocale);
}
}