VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Setup/SelfExtract.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Setup/SelfExtract.c')
-rw-r--r--src/Setup/SelfExtract.c179
1 files changed, 134 insertions, 45 deletions
diff --git a/src/Setup/SelfExtract.c b/src/Setup/SelfExtract.c
index 8c155c64..c672c364 100644
--- a/src/Setup/SelfExtract.c
+++ b/src/Setup/SelfExtract.c
@@ -22,6 +22,7 @@
#include "Dir.h"
#include "Language.h"
#include "Resource.h"
+#include "LzmaLib.h"
#include <tchar.h>
#include <Strsafe.h>
@@ -30,17 +31,22 @@
#endif
#ifdef PORTABLE
-#define OutputPackageFile L"VeraCrypt Portable " _T(VERSION_STRING) L".exe"
+#define OutputPackageFile L"VeraCrypt Portable " _T(VERSION_STRING) _T(VERSION_STRING_SUFFIX)L".exe"
#else
-#define OutputPackageFile L"VeraCrypt Setup " _T(VERSION_STRING) L".exe"
+#ifdef VC_COMREG
+#define OutputPackageFile L"VeraCrypt COMReg.exe"
+#else
+#define OutputPackageFile L"VeraCrypt Setup " _T(VERSION_STRING) _T(VERSION_STRING_SUFFIX) L".exe"
+#endif
#endif
-#define MAG_START_MARKER "TCINSTRT"
-#define MAG_END_MARKER_OBFUSCATED "T/C/I/N/S/C/R/C"
+#define MAG_START_MARKER "VCINSTRT"
+#define MAG_END_MARKER_OBFUSCATED "V/C/I/N/S/C/R/C"
#define PIPE_BUFFER_LEN (4 * BYTES_PER_KB)
unsigned char MagEndMarker [sizeof (MAG_END_MARKER_OBFUSCATED)];
wchar_t DestExtractPath [TC_MAX_PATH];
DECOMPRESSED_FILE Decompressed_Files [NBR_COMPRESSED_FILES];
+int Decompressed_Files_Count = 0;
volatile char *PipeWriteBuf = NULL;
volatile HANDLE hChildStdinWrite = INVALID_HANDLE_VALUE;
@@ -57,7 +63,7 @@ void SelfExtractStartupInit (void)
// The end marker must be included in the self-extracting exe only once, not twice (used e.g.
// by IsSelfExtractingPackage()) and that's why MAG_END_MARKER_OBFUSCATED is obfuscated and
// needs to be deobfuscated using this function at startup.
-static void DeobfuscateMagEndMarker (void)
+void DeobfuscateMagEndMarker (void)
{
int i;
@@ -89,24 +95,43 @@ static void PkgInfo (wchar_t *msg)
// Returns 0 if decompression fails or, if successful, returns the size of the decompressed data
static int DecompressBuffer (unsigned char *out, int outSize, unsigned char *in, int len)
{
- uLongf outlen = (uLongf) outSize;
- int ret = uncompress (out, &outlen, in, (uLong) len);
- if (Z_OK == ret)
- return (int) outlen;
- else
- return 0;
+ int outlen = 0;
+ int status;
+ if (len > 5)
+ {
+ // the first 5 bytes of in contain props parameter
+ size_t srcLen = len - 5;
+ size_t outputLen = (size_t) outSize;
+ status = LzmaUncompress (out, &outputLen, in + 5, &srcLen, in, 5);
+ if (status == SZ_OK)
+ {
+ outlen = (int) outputLen;
+ }
+ }
+
+ return outlen;
}
// Returns 0 if compression fails or, if successful, the size of the compressed data
static int CompressBuffer (unsigned char *out, int outSize, unsigned char *in, int len)
{
- uLongf outlen = (uLongf) outSize;
- int ret = compress2 (out, &outlen, in, (uLong) len, Z_BEST_COMPRESSION);
- if (Z_OK == ret)
- return (int) outlen;
- else
- return 0;
+ unsigned char outProps[5];
+ size_t outPropsSize = 5;
+ int outlen = 0;
+ int status;
+ if (outSize > 5)
+ {
+ size_t outputLen = (size_t) (outSize - 5);
+ status = LzmaCompress (out + 5, &outputLen, in, len, outProps, &outPropsSize, 9, 0, -1, -1, -1, -1, -1);
+ if (status == SZ_OK)
+ {
+ memcpy (out, outProps, outPropsSize);
+ outlen = (int) (outputLen + 5);
+ }
+ }
+
+ return outlen;
}
@@ -119,7 +144,7 @@ static void WipeSignatureAreas (char *buffer)
}
-BOOL MakeSelfExtractingPackage (HWND hwndDlg, wchar_t *szDestDir)
+BOOL MakeSelfExtractingPackage (HWND hwndDlg, wchar_t *szDestDir, BOOL bSkipX64)
{
int i, x;
wchar_t inputFile [TC_MAX_PATH];
@@ -132,7 +157,7 @@ BOOL MakeSelfExtractingPackage (HWND hwndDlg, wchar_t *szDestDir)
wchar_t tmpStr [2048];
int bufLen = 0, compressedDataLen = 0, uncompressedDataLen = 0;
- x = wcslen (szDestDir);
+ x = (int) wcslen (szDestDir);
if (x < 2)
goto err;
@@ -163,6 +188,17 @@ BOOL MakeSelfExtractingPackage (HWND hwndDlg, wchar_t *szDestDir)
for (i = 0; i < sizeof (szCompressedFiles) / sizeof (szCompressedFiles[0]); i++)
{
+ if (bSkipX64 && wcsstr(szCompressedFiles[i], L"-x64"))
+ continue;
+
+#ifdef VC_COMREG
+ if ( wcsstr(szCompressedFiles[i], L".zip") || wcsstr(szCompressedFiles[i], L".inf")
+ || wcsstr(szCompressedFiles[i], L".cat") || wcsstr(szCompressedFiles[i], L".txt")
+ || wcsstr(szCompressedFiles[i], L"LICENSE") || wcsstr(szCompressedFiles[i], L"NOTICE")
+ )
+ continue;
+#endif
+
StringCbPrintfW (szTmpFilePath, sizeof(szTmpFilePath), L"%s%s", szDestDir, szCompressedFiles[i]);
if (!FileExists (szTmpFilePath))
@@ -179,7 +215,7 @@ BOOL MakeSelfExtractingPackage (HWND hwndDlg, wchar_t *szDestDir)
bufLen += (int) GetFileSize64 (szTmpFilePath);
bufLen += 2; // 16-bit filename length
- bufLen += (wcslen(szCompressedFiles[i]) * sizeof (wchar_t)); // Filename
+ bufLen += (int) (wcslen(szCompressedFiles[i]) * sizeof (wchar_t)); // Filename
bufLen += 4; // CRC-32
bufLen += 4; // 32-bit file length
}
@@ -197,7 +233,7 @@ BOOL MakeSelfExtractingPackage (HWND hwndDlg, wchar_t *szDestDir)
// Write the start marker
- if (!SaveBufferToFile (MAG_START_MARKER, outputFile, strlen (MAG_START_MARKER), TRUE, FALSE))
+ if (!SaveBufferToFile (MAG_START_MARKER, outputFile, (DWORD) strlen (MAG_START_MARKER), TRUE, FALSE))
{
if (_wremove (outputFile))
PkgError (L"Cannot write the start marker\nFailed also to delete package file");
@@ -215,6 +251,17 @@ BOOL MakeSelfExtractingPackage (HWND hwndDlg, wchar_t *szDestDir)
DWORD tmpFileSize;
unsigned char *tmpBuffer;
+ if (bSkipX64 && wcsstr(szCompressedFiles[i], L"-x64"))
+ continue;
+
+#ifdef VC_COMREG
+ if ( wcsstr(szCompressedFiles[i], L".zip") || wcsstr(szCompressedFiles[i], L".inf")
+ || wcsstr(szCompressedFiles[i], L".cat") || wcsstr(szCompressedFiles[i], L".txt")
+ || wcsstr(szCompressedFiles[i], L"LICENSE") || wcsstr(szCompressedFiles[i], L"NOTICE")
+ )
+ continue;
+#endif
+
StringCbPrintfW (szTmpFilePath, sizeof(szTmpFilePath), L"%s%s", szDestDir, szCompressedFiles[i]);
tmpBuffer = LoadFile (szTmpFilePath, &tmpFileSize);
@@ -324,7 +371,7 @@ BOOL MakeSelfExtractingPackage (HWND hwndDlg, wchar_t *szDestDir)
}
// Write the end marker
- if (!SaveBufferToFile (MagEndMarker, outputFile, strlen (MagEndMarker), TRUE, FALSE))
+ if (!SaveBufferToFile (MagEndMarker, outputFile, (DWORD) strlen (MagEndMarker), TRUE, FALSE))
{
if (_wremove (outputFile))
PkgError (L"Cannot write the end marker.\nFailed also to delete package file");
@@ -385,18 +432,30 @@ err:
// Verifies the CRC-32 of the whole self-extracting package (except the digital signature areas, if present)
-BOOL VerifyPackageIntegrity (void)
+BOOL VerifySelfPackageIntegrity ()
+{
+ wchar_t path [TC_MAX_PATH];
+
+ GetModuleFileName (NULL, path, ARRAYSIZE (path));
+ return VerifyPackageIntegrity (path);
+}
+
+BOOL VerifyPackageIntegrity (const wchar_t *path)
{
int fileDataEndPos = 0;
int fileDataStartPos = 0;
unsigned __int32 crc = 0;
unsigned char *tmpBuffer;
int tmpFileSize;
- wchar_t path [TC_MAX_PATH];
- GetModuleFileName (NULL, path, ARRAYSIZE (path));
+ // verify Authenticode digital signature of the exe file
+ if (!VerifyModuleSignature (path))
+ {
+ Error ("DIST_PACKAGE_CORRUPTED", NULL);
+ return FALSE;
+ }
- fileDataEndPos = (int) FindStringInFile (path, MagEndMarker, strlen (MagEndMarker));
+ fileDataEndPos = (int) FindStringInFile (path, MagEndMarker, (int) strlen (MagEndMarker));
if (fileDataEndPos < 0)
{
Error ("DIST_PACKAGE_CORRUPTED", NULL);
@@ -404,13 +463,13 @@ BOOL VerifyPackageIntegrity (void)
}
fileDataEndPos--;
- fileDataStartPos = (int) FindStringInFile (path, MAG_START_MARKER, strlen (MAG_START_MARKER));
+ fileDataStartPos = (int) FindStringInFile (path, MAG_START_MARKER, (int) strlen (MAG_START_MARKER));
if (fileDataStartPos < 0)
{
Error ("DIST_PACKAGE_CORRUPTED", NULL);
return FALSE;
}
- fileDataStartPos += strlen (MAG_START_MARKER);
+ fileDataStartPos += (int) strlen (MAG_START_MARKER);
if (!LoadInt32 (path, &crc, fileDataEndPos + strlen (MagEndMarker) + 1))
@@ -431,7 +490,7 @@ BOOL VerifyPackageIntegrity (void)
// Zero all bytes that change when an exe is digitally signed (except appended blocks).
WipeSignatureAreas (tmpBuffer);
- if (crc != GetCrc32 (tmpBuffer, fileDataEndPos + 1 + strlen (MagEndMarker)))
+ if (crc != GetCrc32 (tmpBuffer, fileDataEndPos + 1 + (int) strlen (MagEndMarker)))
{
free (tmpBuffer);
Error ("DIST_PACKAGE_CORRUPTED", NULL);
@@ -451,11 +510,11 @@ BOOL IsSelfExtractingPackage (void)
GetModuleFileName (NULL, path, ARRAYSIZE (path));
- return (FindStringInFile (path, MagEndMarker, strlen (MagEndMarker)) != -1);
+ return (FindStringInFile (path, MagEndMarker, (int) strlen (MagEndMarker)) != -1);
}
-static void FreeAllFileBuffers (void)
+void FreeAllFileBuffers (void)
{
int fileNo;
@@ -473,6 +532,8 @@ static void FreeAllFileBuffers (void)
Decompressed_Files[fileNo].fileLength = 0;
Decompressed_Files[fileNo].crc = 0;
}
+
+ Decompressed_Files_Count = 0;
}
@@ -480,7 +541,7 @@ static void FreeAllFileBuffers (void)
// Creates a table of pointers to buffers containing the following objects for each file:
// filename size, filename (not null-terminated!), file size, file CRC-32, uncompressed file contents.
// For details, see the definition of the DECOMPRESSED_FILE structure.
-BOOL SelfExtractInMemory (wchar_t *path)
+BOOL SelfExtractInMemory (wchar_t *path, BOOL bSkipCountCheck)
{
int filePos = 0, fileNo = 0;
int fileDataEndPos = 0;
@@ -493,7 +554,7 @@ BOOL SelfExtractInMemory (wchar_t *path)
FreeAllFileBuffers();
- fileDataEndPos = (int) FindStringInFile (path, MagEndMarker, strlen (MagEndMarker));
+ fileDataEndPos = (int) FindStringInFile (path, MagEndMarker, (int) strlen (MagEndMarker));
if (fileDataEndPos < 0)
{
Error ("CANNOT_READ_FROM_PACKAGE", NULL);
@@ -502,14 +563,14 @@ BOOL SelfExtractInMemory (wchar_t *path)
fileDataEndPos--;
- fileDataStartPos = (int) FindStringInFile (path, MAG_START_MARKER, strlen (MAG_START_MARKER));
+ fileDataStartPos = (int) FindStringInFile (path, MAG_START_MARKER, (int) strlen (MAG_START_MARKER));
if (fileDataStartPos < 0)
{
Error ("CANNOT_READ_FROM_PACKAGE", NULL);
return FALSE;
}
- fileDataStartPos += strlen (MAG_START_MARKER);
+ fileDataStartPos += (int) strlen (MAG_START_MARKER);
filePos = fileDataStartPos;
@@ -534,9 +595,17 @@ BOOL SelfExtractInMemory (wchar_t *path)
if (compressedLen != fileDataEndPos - fileDataStartPos - 8 + 1)
{
Error ("DIST_PACKAGE_CORRUPTED", NULL);
+ return FALSE;
+ }
+
+ // Test to make Coverity happy. It will always be false
+ if (uncompressedLen >= (INT_MAX - 524288))
+ {
+ Error ("DIST_PACKAGE_CORRUPTED", NULL);
+ return FALSE;
}
- decompressedDataLen = uncompressedLen + 524288; // + 512K reserve
+ decompressedDataLen = uncompressedLen;
DecompressedData = malloc (decompressedDataLen);
if (DecompressedData == NULL)
{
@@ -595,12 +664,14 @@ BOOL SelfExtractInMemory (wchar_t *path)
fileNo++;
}
- if (fileNo < NBR_COMPRESSED_FILES)
+ if (!bSkipCountCheck && (fileNo < NBR_COMPRESSED_FILES))
{
Error ("DIST_PACKAGE_CORRUPTED", NULL);
goto sem_end;
}
+ Decompressed_Files_Count = fileNo;
+
free (compressedData);
return TRUE;
@@ -610,7 +681,7 @@ sem_end:
return FALSE;
}
-
+#ifdef SETUP
void __cdecl ExtractAllFilesThread (void *hwndDlg)
{
int fileNo;
@@ -623,7 +694,7 @@ void __cdecl ExtractAllFilesThread (void *hwndDlg)
GetModuleFileName (NULL, packageFile, ARRAYSIZE (packageFile));
- if (!(bSuccess = SelfExtractInMemory (packageFile)))
+ if (!(bSuccess = SelfExtractInMemory (packageFile, FALSE)))
goto eaf_end;
if (mkfulldir (DestExtractPath, TRUE) != 0)
@@ -644,20 +715,38 @@ void __cdecl ExtractAllFilesThread (void *hwndDlg)
{
wchar_t fileName [TC_MAX_PATH] = {0};
wchar_t filePath [TC_MAX_PATH] = {0};
+ BOOL bResult = FALSE, zipFile = FALSE;
// Filename
StringCchCopyNW (fileName, ARRAYSIZE(fileName), Decompressed_Files[fileNo].fileName, Decompressed_Files[fileNo].fileNameLength);
StringCchCopyW (filePath, ARRAYSIZE(filePath), DestExtractPath);
StringCchCatW (filePath, ARRAYSIZE(filePath), fileName);
+ if ((wcslen (fileName) > 4) && (0 == wcscmp (L".zip", &fileName[wcslen(fileName) - 4])))
+ zipFile = TRUE;
+
StatusMessageParam (hwndDlg, "EXTRACTING_VERB", filePath);
+ if (zipFile)
+ {
+ bResult = DecompressZipToDir (
+ Decompressed_Files[fileNo].fileContent,
+ Decompressed_Files[fileNo].fileLength,
+ DestExtractPath,
+ CopyMessage,
+ hwndDlg);
+ }
+ else
+ {
+ bResult = SaveBufferToFile (
+ (char *) Decompressed_Files[fileNo].fileContent,
+ filePath,
+ Decompressed_Files[fileNo].fileLength,
+ FALSE, FALSE);
+ }
+
// Write the file
- if (!SaveBufferToFile (
- Decompressed_Files[fileNo].fileContent,
- filePath,
- Decompressed_Files[fileNo].fileLength,
- FALSE, FALSE))
+ if (!bResult)
{
wchar_t szTmp[512];
@@ -677,4 +766,4 @@ eaf_end:
else
PostMessage (MainDlg, TC_APPMSG_EXTRACTION_FAILURE, 0, 0);
}
-
+#endif