summaryrefslogtreecommitdiff
path: root/src/SBaseCommon.cpp
diff options
context:
space:
mode:
authorLadislav Zezula <ladislav.zezula@avg.com>2014-08-25 12:59:01 +0200
committerLadislav Zezula <ladislav.zezula@avg.com>2014-08-25 12:59:01 +0200
commitd7044aecaeb2bbb33e0f5cc2080d5b2995bd79d5 (patch)
treee260ef9d1415bef05b0071af573512d90f93ae3b /src/SBaseCommon.cpp
parent2b5b7e977145c16f6ec23933c41678c382d22de3 (diff)
+ Added support for newest Spazzler protector
Diffstat (limited to 'src/SBaseCommon.cpp')
-rw-r--r--src/SBaseCommon.cpp54
1 files changed, 33 insertions, 21 deletions
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp
index be7a74d..f363c28 100644
--- a/src/SBaseCommon.cpp
+++ b/src/SBaseCommon.cpp
@@ -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