From 1f17e92643dea4340719ed195f4425272a29301e Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Wed, 25 Mar 2020 17:36:20 +0100 Subject: Added checks for obviously fake files --- src/SBaseCommon.cpp | 1 - src/SFileFindFile.cpp | 4 ++++ src/SFileOpenFileEx.cpp | 34 ++++++++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp index a131380..61e7bdb 100644 --- a/src/SBaseCommon.cpp +++ b/src/SBaseCommon.cpp @@ -1376,7 +1376,6 @@ int WriteSectorOffsets(TMPQFile * hf) return ERROR_SUCCESS; } - int WriteSectorChecksums(TMPQFile * hf) { TMPQArchive * ha = hf->ha; diff --git a/src/SFileFindFile.cpp b/src/SFileFindFile.cpp index 9ff6ca1..30be19a 100644 --- a/src/SFileFindFile.cpp +++ b/src/SFileFindFile.cpp @@ -222,6 +222,10 @@ static bool DoMPQSearch_FileEntry( // Is it a file but not a patch file? if((pFileEntry->dwFlags & hs->dwFlagMask) == MPQ_FILE_EXISTS) { + // Ignore fake files which are not compressed but have size higher than the archive + if ((pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) == 0 && (pFileEntry->dwFileSize > ha->FileSize)) + return false; + // Now we have to check if this file was not enumerated before if(!FileWasFoundBefore(ha, hs, pFileEntry)) { diff --git a/src/SFileOpenFileEx.cpp b/src/SFileOpenFileEx.cpp index a139585..fc37f6a 100644 --- a/src/SFileOpenFileEx.cpp +++ b/src/SFileOpenFileEx.cpp @@ -296,27 +296,45 @@ bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearch // Check whether the file really exists in the MPQ if(nError == ERROR_SUCCESS) { - if(pFileEntry == NULL || (pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0) + // If we didn't find the file, try to open it using pseudo file name ("File + if (pFileEntry == NULL || (pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0) { - // Check the pseudo-file name - if((bOpenByIndex = IsPseudoFileName(szFileName, &dwFileIndex)) == true) + // Check the pseudo-file name ("File00000001.ext") + if ((bOpenByIndex = IsPseudoFileName(szFileName, &dwFileIndex)) == true) { // Get the file entry for the file - if(dwFileIndex < ha->dwFileTableSize) + if (dwFileIndex < ha->dwFileTableSize) { pFileEntry = ha->pFileTable + dwFileIndex; } } - if(pFileEntry == NULL) + // Still not found? + if (pFileEntry == NULL) { nError = ERROR_FILE_NOT_FOUND; } } - // Ignore unknown loading flags (example: MPQ_2016_v1_WME4_4.w3x) -// if(pFileEntry != NULL && pFileEntry->dwFlags & ~MPQ_FILE_VALID_FLAGS) -// nError = ERROR_NOT_SUPPORTED; + // Perform some checks of invalid files + if (pFileEntry != NULL) + { + // MPQ protectors use insanely amount of fake files, often with very high size. + // We won't open any files whose compressed size is bigger than archive size + // If the file is not compressed, its size cannot be bigger than archive size + if ((pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) == 0 && (pFileEntry->dwFileSize > ha->FileSize)) + { + nError = ERROR_FILE_CORRUPT; + pFileEntry = NULL; + } + + // Ignore unknown loading flags (example: MPQ_2016_v1_WME4_4.w3x) +// if(pFileEntry->dwFlags & ~MPQ_FILE_VALID_FLAGS) +// { +// nError = ERROR_NOT_SUPPORTED; +// pFileEntry = NULL; +// } + } } // Did the caller just wanted to know if the file exists? -- cgit v1.2.3