diff options
author | unknown <E:\Ladik\Mail> | 2015-04-01 06:52:50 +0200 |
---|---|---|
committer | unknown <E:\Ladik\Mail> | 2015-04-01 06:52:50 +0200 |
commit | 93370897471cb7bff861f9e961ff36e6ce46a5e8 (patch) | |
tree | 2e650adc65630f70a76afe4f4e7647849c2ce5b2 /src | |
parent | e5b9f5132a9010a36db81788e10bb1be07ccf410 (diff) |
+ Better handling of MPQs corrupted by yet another silly MPQ protector
Diffstat (limited to 'src')
-rw-r--r-- | src/SBaseCommon.cpp | 24 | ||||
-rw-r--r-- | src/SFileReadFile.cpp | 10 | ||||
-rw-r--r-- | src/StormCommon.h | 14 |
3 files changed, 29 insertions, 19 deletions
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp index 23c9833..9509b6f 100644 --- a/src/SBaseCommon.cpp +++ b/src/SBaseCommon.cpp @@ -988,8 +988,13 @@ int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile) { ULONGLONG RawFilePos = hf->RawFilePos; + // Append the length of the patch info, if any if(hf->pPatchInfo != NULL) + { + if((RawFilePos + hf->pPatchInfo->dwLength) < RawFilePos) + return ERROR_FILE_CORRUPT; RawFilePos += hf->pPatchInfo->dwLength; + } // Load the sector offsets from the file if(!FileStream_Read(ha->pStream, &RawFilePos, hf->SectorOffsets, dwSectorOffsLen)) @@ -1043,12 +1048,13 @@ int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile) // The sector size must not be bigger than compressed file size // Edit: Yes, but apparently, in original Storm.dll, the compressed - // size is not checked anywhere -// if((dwSectorOffset1 - dwSectorOffset0) > pFileEntry->dwCmpSize) -// { -// bSectorOffsetTableCorrupt = true; -// break; -// } + // size is not checked anywhere. However, we need to do this check + // in order to sector offset table malformed by MPQ protectors + if((dwSectorOffset1 - dwSectorOffset0) > ha->dwSectorSize) + { + bSectorOffsetTableCorrupt = true; + break; + } } // If data corruption detected, free the sector offset table @@ -1070,9 +1076,13 @@ int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile) if(hf->SectorOffsets[0] > dwSectorOffsLen) { + // MPQ protectors put some ridiculous values there. We must limit the extra bytes + if(hf->SectorOffsets[0] > (dwSectorOffsLen + 0x400)) + return ERROR_FILE_CORRUPT; + + // Free the old sector offset table dwSectorOffsLen = hf->SectorOffsets[0]; STORM_FREE(hf->SectorOffsets); - hf->SectorOffsets = NULL; goto __LoadSectorOffsets; } } diff --git a/src/SFileReadFile.cpp b/src/SFileReadFile.cpp index 02def18..2451865 100644 --- a/src/SFileReadFile.cpp +++ b/src/SFileReadFile.cpp @@ -81,14 +81,14 @@ static int ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, DW // return nError; // } - // If the file is compressed, also allocate secondary buffer - pbInSector = pbRawSector = STORM_ALLOC(BYTE, dwBytesToRead); - if(pbRawSector == NULL) - return ERROR_NOT_ENOUGH_MEMORY; - // Assign the temporary buffer as target for read operation dwRawSectorOffset = hf->SectorOffsets[dwSectorIndex]; dwRawBytesToRead = hf->SectorOffsets[dwSectorIndex + dwSectorsToRead] - dwRawSectorOffset; + + // If the file is compressed, also allocate secondary buffer + pbInSector = pbRawSector = STORM_ALLOC(BYTE, dwRawBytesToRead); + if(pbRawSector == NULL) + return ERROR_NOT_ENOUGH_MEMORY; } // Calculate raw file offset where the sector(s) are stored. diff --git a/src/StormCommon.h b/src/StormCommon.h index 93193cf..00ea3d8 100644 --- a/src/StormCommon.h +++ b/src/StormCommon.h @@ -105,17 +105,17 @@ typedef struct _MPQ_SIGNATURE_INFO // - Memory freeing function doesn't have to test the pointer to NULL // -//#if defined(_MSC_VER) && defined(_DEBUG) -// -//#define STORM_ALLOC(type, nitems) (type *)HeapAlloc(GetProcessHeap(), 0, ((nitems) * sizeof(type))) -//#define STORM_FREE(ptr) HeapFree(GetProcessHeap(), 0, ptr) -// -//#else +#if defined(_MSC_VER) && defined(_DEBUG) + +#define STORM_ALLOC(type, nitems) (type *)HeapAlloc(GetProcessHeap(), 0, ((nitems) * sizeof(type))) +#define STORM_FREE(ptr) HeapFree(GetProcessHeap(), 0, ptr) + +#else #define STORM_ALLOC(type, nitems) (type *)malloc((nitems) * sizeof(type)) #define STORM_FREE(ptr) free(ptr) -//#endif +#endif //----------------------------------------------------------------------------- // StormLib internal global variables |