diff --git a/other-licenses/7zstub/firefox/7zSD.sfx b/other-licenses/7zstub/firefox/7zSD.sfx index 0243a84c87..ecb03bad36 100644 Binary files a/other-licenses/7zstub/firefox/7zSD.sfx and b/other-licenses/7zstub/firefox/7zSD.sfx differ diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.cpp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.cpp index caec696a21..8a06ec1384 100644 --- a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.cpp +++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/ExtractCallback.cpp @@ -205,7 +205,7 @@ STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode) case NArchive::NExtract::NAskMode::kExtract: _extractMode = true; break; - }; + } return S_OK; } diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/Main.cpp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/Main.cpp index 4f739c886a..1de7d6893e 100644 --- a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/Main.cpp +++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/Main.cpp @@ -35,6 +35,101 @@ static LPCTSTR kTempDirPrefix = TEXT("7zS"); #define _SHELL_EXECUTE +/* BEGIN Mozilla customizations */ + +static char const * +FindStrInBuf(char const * buf, size_t bufLen, char const * str) +{ + size_t index = 0; + while (index < bufLen) { + char const * result = strstr(buf + index, str); + if (result) { + return result; + } + while ((buf[index] != '\0') && (index < bufLen)) { + index++; + } + index++; + } + return NULL; +} + +static bool +ReadPostSigningDataFromView(char const * view, DWORD size, AString& data) +{ + // Find the offset and length of the certificate table, + // so we know the valid range to look for the token. + if (size < (0x3c + sizeof(UInt32))) { + return false; + } + UInt32 PEHeaderOffset = *(UInt32*)(view + 0x3c); + UInt32 optionalHeaderOffset = PEHeaderOffset + 24; + UInt32 certDirEntryOffset = 0; + if (size < (optionalHeaderOffset + sizeof(UInt16))) { + return false; + } + UInt16 magic = *(UInt16*)(view + optionalHeaderOffset); + if (magic == 0x010b) { + // 32-bit executable + certDirEntryOffset = optionalHeaderOffset + 128; + } else if (magic == 0x020b) { + // 64-bit executable; certain header fields are wider + certDirEntryOffset = optionalHeaderOffset + 144; + } else { + // Unknown executable + return false; + } + if (size < certDirEntryOffset + 8) { + return false; + } + UInt32 certTableOffset = *(UInt32*)(view + certDirEntryOffset); + UInt32 certTableLen = *(UInt32*)(view + certDirEntryOffset + sizeof(UInt32)); + if (certTableOffset == 0 || certTableLen == 0 || + size < (certTableOffset + certTableLen)) { + return false; + } + + char const token[] = "__MOZCUSTOM__:"; + // We're searching for a string inside a binary blob, + // so a normal strstr that bails on the first NUL won't work. + char const * tokenPos = FindStrInBuf(view + certTableOffset, + certTableLen, token); + if (tokenPos) { + size_t tokenLen = (sizeof(token) / sizeof(token[0])) - 1; + data = AString(tokenPos + tokenLen); + return true; + } + return false; +} + +static bool +ReadPostSigningData(UString exePath, AString& data) +{ + bool retval = false; + HANDLE exeFile = CreateFileW(exePath, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (exeFile != INVALID_HANDLE_VALUE) { + HANDLE mapping = CreateFileMapping(exeFile, NULL, PAGE_READONLY, 0, 0, NULL); + if (mapping != INVALID_HANDLE_VALUE) { + // MSDN claims the return value on failure is NULL, + // but I've also seen it returned on success, so double-check. + if (mapping || GetLastError() == ERROR_SUCCESS) { + char * view = (char*)MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); + if (view) { + DWORD fileSize = GetFileSize(exeFile, NULL); + retval = ReadPostSigningDataFromView(view, fileSize, data); + } + CloseHandle(mapping); + } + } + CloseHandle(exeFile); + } + return retval; +} + +/* END Mozilla customizations */ + + static bool ReadDataString(LPCWSTR fileName, LPCSTR startID, LPCSTR endID, AString &stringResult) { @@ -141,6 +236,20 @@ struct AutoLoadSystemDependencies { AutoLoadSystemDependencies() { + HMODULE module = ::GetModuleHandleW(L"kernel32.dll"); + if (module) { + // SetDefaultDllDirectories is always available on Windows 8 and above. It + // is also available on Windows Vista, Windows Server 2008, and + // Windows 7 when MS KB2533623 has been applied. + typedef BOOL (WINAPI *SetDefaultDllDirectoriesType)(DWORD); + SetDefaultDllDirectoriesType setDefaultDllDirectories = + (SetDefaultDllDirectoriesType) GetProcAddress(module, "SetDefaultDllDirectories"); + if (setDefaultDllDirectories) { + setDefaultDllDirectories(0x0800 /* LOAD_LIBRARY_SEARCH_SYSTEM32 */ ); + return; + } + } + static LPCWSTR delayDLLs[] = { L"dwmapi.dll", L"cryptbase.dll", L"SHCore.dll", L"uxtheme.dll", L"oleacc.dll", L"apphelp.dll" }; @@ -331,7 +440,22 @@ int APIENTRY WinMain( } /* BEGIN Mozilla customizations */ - // The code immediately above handles the error case for extraction. + // Retrieve and store any data added to this file after signing. + { + AString postSigningData; + if (ReadPostSigningData(fullPath, postSigningData)) { + NFile::NName::CParsedPath postSigningDataFilePath; + postSigningDataFilePath.ParsePath(tempDirPath); + postSigningDataFilePath.PathParts.Add(L"postSigningData"); + + NFile::NIO::COutFile postSigningDataFile; + postSigningDataFile.Create(postSigningDataFilePath.MergePath(), true); + + UInt32 written = 0; + postSigningDataFile.Write(postSigningData, postSigningData.Length(), written); + } + } + if (extractOnly) { return 0; } diff --git a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsp b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsp index ffa6286560..e9ff6ad48b 100644 --- a/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsp +++ b/other-licenses/7zstub/src/7zip/Bundles/SFXSetup-moz/SFXSetup-moz.dsp @@ -54,7 +54,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zS.sfx" /opt:NOWIN98 +# ADD LINK32 comctl32.lib kernel32.lib user32.lib shell32.lib oleaut32.lib delayimp.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Util\7zS.sfx" /delayload:comctl32.dll /delayload:user32.dll /delayload:shell32.dll /delayload:oleaut32.dll /opt:NOWIN98 # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "SFXSetup-moz - Win32 Debug" @@ -81,7 +81,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zSfxS.exe" /pdbtype:sept +# ADD LINK32 comctl32.lib kernel32.lib user32.lib shell32.lib oleaut32.lib delayimp.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zSfxS.exe" /pdbtype:sept /delayload:comctl32.dll /delayload:user32.dll /delayload:shell32.dll /delayload:oleaut32.dll !ELSEIF "$(CFG)" == "SFXSetup-moz - Win32 ReleaseD" @@ -109,7 +109,7 @@ BSC32=bscmake.exe LINK32=link.exe # ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zWinSR.exe" # SUBTRACT BASE LINK32 /debug /nodefaultlib -# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"ReleaseD\7zSD.sfx" /opt:NOWIN98 +# ADD LINK32 comctl32.lib kernel32.lib user32.lib shell32.lib oleaut32.lib delayimp.lib /nologo /subsystem:windows /machine:I386 /out:"ReleaseD\7zSD.sfx" /delayload:comctl32.dll /delayload:user32.dll /delayload:shell32.dll /delayload:oleaut32.dll /opt:NOWIN98 # SUBTRACT LINK32 /pdb:none !ENDIF