mirror of
https://github.com/ladislav-zezula/StormLib.git
synced 2026-01-18 05:58:19 +01:00
+ Added support for newest Spazzler protector
This commit is contained in:
@@ -708,6 +708,8 @@ TMPQFile * CreateFileHandle(TMPQArchive * ha, TFileEntry * pFileEntry)
|
||||
{
|
||||
// Set the raw position and MPQ position
|
||||
hf->RawFilePos = ha->MpqPos + pFileEntry->ByteOffset;
|
||||
if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
|
||||
hf->RawFilePos = (DWORD)ha->MpqPos + (DWORD)pFileEntry->ByteOffset;
|
||||
hf->MpqFilePos = pFileEntry->ByteOffset;
|
||||
|
||||
// Set the data size
|
||||
@@ -732,7 +734,6 @@ void * LoadMpqTable(
|
||||
LPBYTE pbMpqTable;
|
||||
LPBYTE pbToRead;
|
||||
DWORD dwBytesToRead = dwCompressedSize;
|
||||
DWORD dwValidLength = dwTableSize;
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// Allocate the MPQ table
|
||||
@@ -751,6 +752,22 @@ void * LoadMpqTable(
|
||||
}
|
||||
}
|
||||
|
||||
// On archives v 1.0, Storm.dll does not actually check
|
||||
// if the hash table was read entirely. Abused by Spazzler map protector
|
||||
// which sets hash table size to 0x00100000
|
||||
if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1 && (ha->dwFlags & MPQ_FLAG_MALFORMED))
|
||||
{
|
||||
ULONGLONG FileSize = 0;
|
||||
|
||||
// Cut the table size
|
||||
FileStream_GetSize(ha->pStream, &FileSize);
|
||||
if((ByteOffset + dwBytesToRead) > FileSize)
|
||||
{
|
||||
dwBytesToRead = (DWORD)(FileSize - ByteOffset);
|
||||
memset(pbMpqTable + dwBytesToRead, 0, (dwTableSize - dwBytesToRead));
|
||||
}
|
||||
}
|
||||
|
||||
// If everything succeeded, read the raw table form the MPQ
|
||||
if(FileStream_Read(ha->pStream, &ByteOffset, pbToRead, dwBytesToRead))
|
||||
{
|
||||
@@ -774,10 +791,6 @@ void * LoadMpqTable(
|
||||
|
||||
// Make sure that the table is properly byte-swapped
|
||||
BSWAP_ARRAY32_UNSIGNED(pbMpqTable, dwTableSize);
|
||||
|
||||
// If the table was not fully readed, fill the rest with zeros
|
||||
if(dwValidLength < dwTableSize)
|
||||
memset(pbMpqTable + dwValidLength, 0, (dwTableSize - dwValidLength));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -805,25 +818,22 @@ void CalculateRawSectorOffset(
|
||||
TMPQFile * hf,
|
||||
DWORD dwSectorOffset)
|
||||
{
|
||||
// Must be used for files within a MPQ
|
||||
assert(hf->ha != NULL);
|
||||
assert(hf->ha->pHeader != NULL);
|
||||
|
||||
//
|
||||
// Some MPQ protectors place the sector offset table after the actual file data.
|
||||
// Sector offsets in the sector offset table are negative. When added
|
||||
// to MPQ file offset from the block table entry, the result is a correct
|
||||
// position of the file data in the MPQ.
|
||||
//
|
||||
// The position of sector table must be always within the MPQ, however.
|
||||
// When a negative sector offset is found, we make sure that we make the addition
|
||||
// just in 32-bits, and then add the MPQ offset.
|
||||
// For MPQs version 1.0, the offset is purely 32-bit
|
||||
//
|
||||
|
||||
if(dwSectorOffset & 0x80000000)
|
||||
{
|
||||
RawFilePos = hf->ha->MpqPos + ((DWORD)hf->pFileEntry->ByteOffset + dwSectorOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
RawFilePos = hf->RawFilePos + dwSectorOffset;
|
||||
}
|
||||
RawFilePos = hf->RawFilePos + dwSectorOffset;
|
||||
if(hf->ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
|
||||
RawFilePos = (DWORD)hf->ha->MpqPos + (DWORD)hf->pFileEntry->ByteOffset + dwSectorOffset;
|
||||
|
||||
// We also have to add patch header size, if patch header is present
|
||||
if(hf->pPatchInfo != NULL)
|
||||
@@ -1044,11 +1054,13 @@ int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile)
|
||||
}
|
||||
|
||||
// The sector size must not be bigger than compressed file size
|
||||
if((dwSectorOffset1 - dwSectorOffset0) > pFileEntry->dwCmpSize)
|
||||
{
|
||||
bSectorOffsetTableCorrupt = true;
|
||||
break;
|
||||
}
|
||||
// Edit: Yes, but apparently, in original Storm.dll, the compressed
|
||||
// size is not checked anywhere
|
||||
// if((dwSectorOffset1 - dwSectorOffset0) > pFileEntry->dwCmpSize)
|
||||
// {
|
||||
// bSectorOffsetTableCorrupt = true;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
// If data corruption detected, free the sector offset table
|
||||
|
||||
Reference in New Issue
Block a user