From 495608ed7cb3219d722fd7b1878a7aab738ad0db Mon Sep 17 00:00:00 2001 From: WerWolv Date: Tue, 9 Dec 2025 21:25:35 +0100 Subject: [PATCH] build: Force-remove all version information from libwinpthread --- cmake/build_helpers.cmake | 31 +++++--- main/CMakeLists.txt | 1 + main/version_stripper/CMakeLists.txt | 5 ++ main/version_stripper/source/main.cpp | 110 ++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 11 deletions(-) create mode 100644 main/version_stripper/CMakeLists.txt create mode 100644 main/version_stripper/source/main.cpp diff --git a/cmake/build_helpers.cmake b/cmake/build_helpers.cmake index 8c53074a1..ff421964e 100644 --- a/cmake/build_helpers.cmake +++ b/cmake/build_helpers.cmake @@ -330,21 +330,30 @@ macro(createPackage) FILES "${_file}" ) endforeach() + ]]) - # Download rcedit if not already present - set(RCEDIT_PATH "${CMAKE_BINARY_DIR}/rcedit.exe") - if(NOT EXISTS ${RCEDIT_PATH}) - file(DOWNLOAD - "https://github.com/electron/rcedit/releases/download/v2.0.0/rcedit-x64.exe" - ${RCEDIT_PATH} - ) + set(VERSIONLESS_LIBWINPTHREAD "${CMAKE_BINARY_DIR}/libwinpthread-1.dll") + find_file(LIBWINPTHREAD_PATH NAMES libwinpthread-1.dll) + if (NOT LIBWINPTHREAD_PATH) + message(FATAL_ERROR "Could not find libwinpthread-1.dll!") endif() - execute_process(COMMAND ${RCEDIT_PATH} - "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/libwinpthread-1.dll" - --set-file-version "0,0,0,0" + add_custom_command( + OUTPUT ${VERSIONLESS_LIBWINPTHREAD} + COMMAND $ ${LIBWINPTHREAD_PATH} ${VERSIONLESS_LIBWINPTHREAD} + DEPENDS version-stripper + COMMENT "Stripping version info from libwinpthread..." + VERBATIM + ) + + add_custom_target(versionless_libwinpthread ALL + DEPENDS ${VERSIONLESS_LIBWINPTHREAD} + ) + + # Install the generated file + install(FILES ${VERSIONLESS_LIBWINPTHREAD} + DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}" ) - ]]) downloadImHexPatternsFiles(".") elseif(UNIX AND NOT APPLE) diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 068970440..94131c0ac 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -7,6 +7,7 @@ endif () add_subdirectory(gui) if (WIN32) add_subdirectory(forwarder) + add_subdirectory(version_stripper) endif () if (NOT EMSCRIPTEN) diff --git a/main/version_stripper/CMakeLists.txt b/main/version_stripper/CMakeLists.txt new file mode 100644 index 000000000..a8c215add --- /dev/null +++ b/main/version_stripper/CMakeLists.txt @@ -0,0 +1,5 @@ +project(version-stripper) + +add_executable(version-stripper + source/main.cpp +) \ No newline at end of file diff --git a/main/version_stripper/source/main.cpp b/main/version_stripper/source/main.cpp new file mode 100644 index 000000000..82957a8cf --- /dev/null +++ b/main/version_stripper/source/main.cpp @@ -0,0 +1,110 @@ +/** + * A simple utility to strip version resources from Windows executables. + * + * Usage: version_stripper + * + * This program copies the input executable to the output path and removes + * its version resource information. + * + * Based on https://github.com/shewitt-au/nuke_version + */ + +#include +#include +#include +#include +#include +#include + +using LangIds = std::vector; + +BOOL CALLBACK EnumResLangProc( + HMODULE hModule, + LPCTSTR lpszType, + LPCTSTR lpszName, + WORD wIDLanguage, + LONG_PTR lParam +) { + auto& langs = *reinterpret_cast(lParam); + langs.push_back(wIDLanguage); + return true; +} + +LangIds getLangIDs(LPCTSTR pExe) { + LangIds langs; + + HMODULE hMod = LoadLibrary(pExe); + if (hMod == nullptr) + throw std::runtime_error("LoadLibrary failed!"); + + BOOL bOK = EnumResourceLanguages( + hMod, // HMODULE hModule + RT_VERSION, // LPCTSTR lpType + MAKEINTRESOURCE(1), // LPCTSTR lpName + EnumResLangProc, // ENUMRESLANGPROC lpEnumFunc + reinterpret_cast(&langs) // LONG_PTR lParam + ); + + FreeLibrary(hMod); + + if (!bOK) + throw std::runtime_error("EnumResourceLanguages failed!"); + + return langs; +} + +void nukeVersionResource(LPCTSTR pExe) { + LangIds langs = getLangIDs(pExe); + + HANDLE hResUpdate = BeginUpdateResource(pExe, FALSE); + if (hResUpdate == nullptr) + throw std::runtime_error("BeginUpdateResource failed!"); + + for (WORD langID : langs) { + BOOL bOK = UpdateResource( + hResUpdate, // HANDLE hUpdate + RT_VERSION, // LPCTSTR lpType + MAKEINTRESOURCE(1), // LPCTSTR lpName + langID, // WORD wLanguage + nullptr, // LPVOID lpData + 0 // DWORD cb + ); + + if (!bOK) { + EndUpdateResource( + hResUpdate, // HANDLE hUpdate + TRUE // BOOL fDiscard + ); + + throw std::runtime_error("UpdateResource failed! Nothing done!"); + } + + } + + EndUpdateResource( + hResUpdate, // HANDLE hUpdate + FALSE // BOOL fDiscard + ); +} + +int main(int argc, char* argv[]) { + if (argc != 3) { + printf("Usage: %s \n", argv[0]); + return 1; + } + + std::filesystem::path inputPath(argv[1]); + std::filesystem::path outputPath(argv[2]); + + std::filesystem::copy(inputPath, outputPath); + + try { + nukeVersionResource(outputPath.c_str()); + } catch (const std::exception& e) { + fprintf(stderr, "%s", e.what()); + std::filesystem::remove(outputPath); + return 1; + } + + return 0; +} \ No newline at end of file