aboutsummaryrefslogtreecommitdiff
path: root/src/SBaseFileTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/SBaseFileTable.cpp')
-rw-r--r--src/SBaseFileTable.cpp31
1 files changed, 26 insertions, 5 deletions
diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp
index 564287c..ff73bdc 100644
--- a/src/SBaseFileTable.cpp
+++ b/src/SBaseFileTable.cpp
@@ -382,6 +382,7 @@ int ConvertMpqHeaderToFormat4(
ULONGLONG HashTablePos64 = 0;
ULONGLONG ByteOffset;
USHORT wFormatVersion = BSWAP_INT16_UNSIGNED(pHeader->wFormatVersion);
+ DWORD dwByteOffset32;
DWORD dwTableSize;
int nError = ERROR_SUCCESS;
@@ -430,6 +431,16 @@ int ConvertMpqHeaderToFormat4(
pHeader->ArchiveSize64 = DetermineArchiveSize_V1(ha, pHeader, MpqOffset, FileSize);
pHeader->dwArchiveSize = (DWORD)pHeader->ArchiveSize64;
+ // Handle case when the block table is placed before the MPQ header
+ // Used by BOBA protector
+ dwByteOffset32 = (DWORD)MpqOffset + pHeader->dwBlockTablePos;
+ if(dwByteOffset32 < MpqOffset)
+ {
+ pHeader->BlockTableSize64 = (DWORD)MpqOffset - dwByteOffset32;
+ pHeader->dwBlockTableSize = (DWORD)(pHeader->BlockTableSize64 / sizeof(TMPQBlock));
+ break;
+ }
+
// Handle case when either the MPQ is cut in the middle of the block table
// or the MPQ is malformed so that block table size is greater than should be
ByteOffset = MpqOffset + pHeader->dwBlockTablePos;
@@ -438,6 +449,7 @@ int ConvertMpqHeaderToFormat4(
{
pHeader->BlockTableSize64 = FileSize - ByteOffset;
pHeader->dwBlockTableSize = (DWORD)(pHeader->BlockTableSize64 / sizeof(TMPQBlock));
+ break;
}
}
break;
@@ -577,8 +589,15 @@ int ConvertMpqHeaderToFormat4(
default:
- // Last resort: Check if it's a War of the Immortal data file (SQP)
- nError = ConvertSqpHeaderToFormat4(ha, FileSize, dwFlags);
+ // Check if it's a War of the Immortal data file (SQP)
+ // If not, we treat it as malformed MPQ version 1.0
+ if(ConvertSqpHeaderToFormat4(ha, FileSize, dwFlags) != ERROR_SUCCESS)
+ {
+ pHeader->wFormatVersion = MPQ_FORMAT_VERSION_1;
+ pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1;
+ ha->dwFlags |= MPQ_FLAG_MALFORMED;
+ goto Label_ArchiveVersion1;
+ }
break;
}
@@ -2262,12 +2281,14 @@ TMPQBlock * LoadBlockTable(TMPQArchive * ha, bool bDontFixEntries)
{
case MPQ_SUBTYPE_MPQ:
- // Calculate sizes of both tables
+ // Calculate byte position of the block table
ByteOffset = ha->MpqPos + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
+ if((pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1) && (ha->dwFlags & MPQ_FLAG_MALFORMED))
+ ByteOffset = (DWORD)ha->MpqPos + pHeader->dwBlockTablePos;
+
+ // Calculate full and compressed size of the block table
dwTableSize = pHeader->dwBlockTableSize * sizeof(TMPQBlock);
dwCmpSize = (DWORD)pHeader->BlockTableSize64;
-
- // If the the block table size was invalid, it should be fixed by now
assert((ByteOffset + dwCmpSize) <= (ha->MpqPos + ha->pHeader->ArchiveSize64));
//