+ Added support for newest Spazzler protector

This commit is contained in:
Ladislav Zezula
2014-08-25 12:59:01 +02:00
parent 2b5b7e9771
commit d7044aecae
25 changed files with 4179 additions and 3840 deletions

View File

@@ -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