diff options
author | Ladislav Zezula <zezula@volny.cz> | 2023-06-06 09:54:12 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-06 09:54:12 +0200 |
commit | 51ba11c5b78752852023fd6156cd8842c1c3e336 (patch) | |
tree | 161b1c1622d5d43e333bd73272173f83cc6e910e | |
parent | 1e436d61fe963d58235af5b898f0e70a18bbb550 (diff) | |
parent | afd304b180607a68edc1613074eeaca5e8805153 (diff) |
Merge pull request #294 from ladislav-zezula/LZ_MemoryCorruption
Fixed loading of corrupt MPQ version 2
-rw-r--r-- | StormLib.sln (renamed from StormLib_vs22.sln) | 6 | ||||
-rw-r--r-- | StormLib.vcxproj (renamed from StormLib_vs22.vcxproj) | 0 | ||||
-rw-r--r-- | StormLib.vcxproj.filters (renamed from StormLib_vs22.vcxproj.filters) | 0 | ||||
-rw-r--r-- | StormLib_dll.vcxproj (renamed from StormLib_vs22_dll.vcxproj) | 0 | ||||
-rw-r--r-- | StormLib_dll.vcxproj.filters (renamed from StormLib_vs22_dll.vcxproj.filters) | 0 | ||||
-rw-r--r-- | StormLib_test.vcxproj (renamed from StormLib_vs22_test.vcxproj) | 0 | ||||
-rw-r--r-- | StormLib_test.vcxproj.filters (renamed from StormLib_vs22_test.vcxproj.filters) | 0 | ||||
-rw-r--r-- | make-msvc.bat | 4 | ||||
-rw-r--r-- | src/SBaseFileTable.cpp | 58 | ||||
-rw-r--r-- | test/StormTest.cpp | 27 |
10 files changed, 57 insertions, 38 deletions
diff --git a/StormLib_vs22.sln b/StormLib.sln index 1d6f972..0ce51bc 100644 --- a/StormLib_vs22.sln +++ b/StormLib.sln @@ -2,11 +2,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.28010.2050 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib", "StormLib_vs22.vcxproj", "{78424708-1F6E-4D4B-920C-FB6D26847055}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib", "StormLib.vcxproj", "{78424708-1F6E-4D4B-920C-FB6D26847055}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_dll", "StormLib_vs22_dll.vcxproj", "{CB385198-50B1-4CF4-883B-11F042DED6AA}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_dll", "StormLib_dll.vcxproj", "{CB385198-50B1-4CF4-883B-11F042DED6AA}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_test", "StormLib_vs22_test.vcxproj", "{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib_test", "StormLib_test.vcxproj", "{AA561A7B-26EA-49AF-90E8-C53C1FA2965D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/StormLib_vs22.vcxproj b/StormLib.vcxproj index 26d8f70..26d8f70 100644 --- a/StormLib_vs22.vcxproj +++ b/StormLib.vcxproj diff --git a/StormLib_vs22.vcxproj.filters b/StormLib.vcxproj.filters index 22c9793..22c9793 100644 --- a/StormLib_vs22.vcxproj.filters +++ b/StormLib.vcxproj.filters diff --git a/StormLib_vs22_dll.vcxproj b/StormLib_dll.vcxproj index bda8dd9..bda8dd9 100644 --- a/StormLib_vs22_dll.vcxproj +++ b/StormLib_dll.vcxproj diff --git a/StormLib_vs22_dll.vcxproj.filters b/StormLib_dll.vcxproj.filters index 2eaf026..2eaf026 100644 --- a/StormLib_vs22_dll.vcxproj.filters +++ b/StormLib_dll.vcxproj.filters diff --git a/StormLib_vs22_test.vcxproj b/StormLib_test.vcxproj index 18cee5b..18cee5b 100644 --- a/StormLib_vs22_test.vcxproj +++ b/StormLib_test.vcxproj diff --git a/StormLib_vs22_test.vcxproj.filters b/StormLib_test.vcxproj.filters index d341b12..d341b12 100644 --- a/StormLib_vs22_test.vcxproj.filters +++ b/StormLib_test.vcxproj.filters diff --git a/make-msvc.bat b/make-msvc.bat index d2d06d3..3dbc675 100644 --- a/make-msvc.bat +++ b/make-msvc.bat @@ -27,8 +27,8 @@ if exist "%PROGRAM_FILES_X64%\Microsoft Visual Studio\2022\Enterprise\VC\Auxilia :: Build all libraries using Visual Studio 2008 and 2019 if not "x%VCVARS_2008%" == "x" call :BuildLibs "%VCVARS_2008%" x86 %LIB_NAME%_vs08.sln \vs2008 if not "x%VCVARS_2008%" == "x" call :BuildLibs "%VCVARS_2008%" x64 %LIB_NAME%_vs08.sln \vs2008 -if not "x%VCVARS_20xx%" == "x" call :BuildLibs "%VCVARS_20xx%" x86 %LIB_NAME%_vs22.sln -if not "x%VCVARS_20xx%" == "x" call :BuildLibs "%VCVARS_20xx%" x64 %LIB_NAME%_vs22.sln +if not "x%VCVARS_20xx%" == "x" call :BuildLibs "%VCVARS_20xx%" x86 %LIB_NAME%.sln +if not "x%VCVARS_20xx%" == "x" call :BuildLibs "%VCVARS_20xx%" x64 %LIB_NAME%.sln goto:eof ::----------------------------------------------------------------------------- diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp index 43202d0..20d7cc4 100644 --- a/src/SBaseFileTable.cpp +++ b/src/SBaseFileTable.cpp @@ -317,29 +317,54 @@ static ULONGLONG DetermineArchiveSize_V2( ULONGLONG MpqOffset,
ULONGLONG FileSize)
{
- ULONGLONG EndOfMpq = FileSize;
- DWORD dwArchiveSize32;
+ ULONGLONG TableOffset;
+ ULONGLONG TableSize;
+ ULONGLONG MaxOffset = 0;
// This could only be called for MPQs version 2.0
assert(pHeader->wFormatVersion == MPQ_FORMAT_VERSION_2);
- // Check if we can rely on the archive size in the header
- if((FileSize >> 0x20) == 0)
+ // Is the hash table end greater than max offset?
+ TableOffset = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos);
+ TableSize = (ULONGLONG)pHeader->dwHashTableSize * sizeof(TMPQHash);
+ if((TableOffset + TableSize) > MaxOffset)
+ MaxOffset = TableOffset + TableSize;
+
+ // Is the block table end greater than max offset?
+ TableOffset = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
+ TableSize = (ULONGLONG)pHeader->dwBlockTableSize * sizeof(TMPQBlock);
+ if((TableOffset + TableSize) > MaxOffset)
+ MaxOffset = TableOffset + TableSize;
+
+ // Is the hi-block table end greater than max offset?
+ if((TableOffset = pHeader->HiBlockTablePos64) != 0)
{
- if(pHeader->dwBlockTablePos < pHeader->dwArchiveSize)
- {
- if((pHeader->dwArchiveSize - pHeader->dwBlockTablePos) <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock)))
- return pHeader->dwArchiveSize;
+ TableSize = (ULONGLONG)pHeader->dwBlockTableSize * sizeof(USHORT);
+ if((TableOffset + TableSize) > MaxOffset)
+ MaxOffset = TableOffset + TableSize;
+ }
+
+ // Cut to the file size
+ if(MaxOffset > (FileSize - MpqOffset))
+ MaxOffset = FileSize - MpqOffset;
+ return MaxOffset;
+}
+
+static ULONGLONG DetermineBlockTableSize_V2(TMPQHeader * pHeader)
+{
+ ULONGLONG BlockTableOffset = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
+ ULONGLONG TableOffset;
+ ULONGLONG TableSize = (pHeader->ArchiveSize64 - BlockTableOffset);
- // If the archive size in the header is less than real file size
- dwArchiveSize32 = (DWORD)(FileSize - MpqOffset);
- if(pHeader->dwArchiveSize <= dwArchiveSize32)
- return pHeader->dwArchiveSize;
+ // Subtract the offset of the hi-block table
+ if((TableOffset = pHeader->HiBlockTablePos64) != 0)
+ {
+ if(TableOffset > BlockTableOffset)
+ {
+ TableSize = TableOffset - BlockTableOffset;
}
}
-
- // Return the calculated archive size
- return (EndOfMpq - MpqOffset);
+ return TableSize;
}
static ULONGLONG DetermineArchiveSize_V4(
@@ -564,9 +589,10 @@ DWORD ConvertMpqHeaderToFormat4( {
// Determine real archive size
pHeader->ArchiveSize64 = DetermineArchiveSize_V2(pHeader, ByteOffset, FileSize);
+ pHeader->dwArchiveSize = (DWORD)(pHeader->ArchiveSize64);
// Calculate size of the block table
- pHeader->BlockTableSize64 = pHeader->ArchiveSize64 - BlockTablePos64;
+ pHeader->BlockTableSize64 = DetermineBlockTableSize_V2(pHeader);
assert(pHeader->BlockTableSize64 <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock)));
}
}
diff --git a/test/StormTest.cpp b/test/StormTest.cpp index 2f45e96..82668cf 100644 --- a/test/StormTest.cpp +++ b/test/StormTest.cpp @@ -4183,30 +4183,23 @@ int _tmain(int argc, TCHAR * argv[]) // Initialize storage and mix the random number generator
printf("==== Test Suite for StormLib version %s ====\n", STORMLIB_VERSION_STRING);
dwErrCode = InitializeMpqDirectory(argv, argc);
-/*
+
// Check creation of the MPQ with LZMA compression
- LPCTSTR szArchiveName = _T("E:\\new-mpq.mpq");
+ LPCTSTR szArchiveName = _T("e:\\MemoryCorruption.SC2Replay");
HANDLE hFile = NULL;
HANDLE hMpq = NULL;
-
- DeleteFile(szArchiveName);
- if(SFileCreateArchive(szArchiveName, MPQ_CREATE_ARCHIVE_V2 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES, 0x1000, &hMpq))
+/*
+ if(SFileOpenArchive(szArchiveName, 0, 0, &hMpq))
{
- SFileAddFileEx(hMpq, _T("e:\\DlgSearchFile.cpp"), "DlgSearchFile.cpp", MPQ_FILE_SINGLE_UNIT | MPQ_FILE_COMPRESS, MPQ_COMPRESSION_LZMA, MPQ_COMPRESSION_NEXT_SAME);
- SFileCloseArchive(hMpq);
-
- if(SFileOpenArchive(szArchiveName, 0, 0, &hMpq))
+ if(SFileOpenFileEx(hMpq, "DlgSearchFile.cpp", 0, &hFile))
{
- if(SFileOpenFileEx(hMpq, "DlgSearchFile.cpp", 0, &hFile))
- {
- DWORD dwBytesRead = 0;
- BYTE Buffer[0x100];
+ DWORD dwBytesRead = 0;
+ BYTE Buffer[0x100];
- SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
- SFileCloseFile(hFile);
- }
- SFileCloseArchive(hMpq);
+ SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
+ SFileCloseFile(hFile);
}
+ SFileCloseArchive(hMpq);
}
*/
#ifdef TEST_COMMAND_LINE
|