diff options
author | Ladislav Zezula <ladislav.zezula@avg.com> | 2014-08-25 12:59:01 +0200 |
---|---|---|
committer | Ladislav Zezula <ladislav.zezula@avg.com> | 2014-08-25 12:59:01 +0200 |
commit | d7044aecaeb2bbb33e0f5cc2080d5b2995bd79d5 (patch) | |
tree | e260ef9d1415bef05b0071af573512d90f93ae3b /src/SBaseCommon.cpp | |
parent | 2b5b7e977145c16f6ec23933c41678c382d22de3 (diff) |
+ Added support for newest Spazzler protector
Diffstat (limited to 'src/SBaseCommon.cpp')
-rw-r--r-- | src/SBaseCommon.cpp | 54 |
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 |