Repository navigation
Development Windows Hardening
What the application does about DLL search-path injection, what it defers, and what it does not address.
Platemaker is an unsigned desktop app that ships a large bundled DLL closure (Qt, platemaker.dll,
the whole libvips graph, the toolchain's runtime), all copied next to the executable
(cross-platform notes). Third-party global hooks do inject themselves
into the process (seen: LG OnScreen Control's ScreenSplitterHook64X.dll, RGB software) — benign, but a
reminder that the process has to take its own precautions. This page records the security posture and,
importantly, what is deliberately not done and why.
app/main.cpp calls SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32) as the first statement in main() — before QApplication, before
any post-main dynamic DLL load. This drops the current working directory and PATH from the default
LoadLibrary search, closing the classic DLL search-order hijack / planting vector (drop a
malicious zlib1/libpng on PATH or beside a data file and have our graph pick it up).
-
Why it's safe here: the entire dependency closure is co-located in the application directory, which
LOAD_LIBRARY_SEARCH_APPLICATION_DIRstill covers, and the exe's static imports are resolved beforemain()runs — so startup linkage is unaffected. Only post-maindynamic loads are narrowed (Qt plugins, loaded by absolute path with their deps in the app dir; libvips operation DLLs at render time). Verified by launching + running a full render under both the Qt Creator run environment (which injects the Qt bin viaPATH) and the installed build. -
Robustness: the API is resolved dynamically via
GetProcAddress, so it degrades to a no-op on any pre-Windows-8 host instead of failing to load, and sidesteps MinGW header/_WIN32_WINNTquirks. It logs a one-line startup notice (DLL hardening: …) so the code path is verifiable in DebugView / the Qt Creator Application Output. -
The one consequence: SVG icons. Qt's SVG plugins (
qsvgicon,qsvg) importQt6Svg.dll, which nothing in the executable referenced, so it would load lazily — after the search path no longer includesPATH, where a build-directory run finds the Qt bin. Every SVG then rendered blank.main()constructs a throwawayQSvgRenderer, which makesQt6Svg.dlla load-time import resolved before the hardening runs. Deployed builds carry it in the app directory anyway.
The natural companion is SetProcessMitigationPolicy(ProcessExtensionPointDisablePolicy, …), which would
block exactly the hook injection we observed, plus AppInit_DLLs and legacy IME DLLs. We deliberately
do not ship it. It also disables legacy IMM32 IMEs and some accessibility / assistive tools.
Broken IME would hurt non-Latin text entry for Korean / Japanese / Chinese authors — a core webcomic
audience — and we have no way to validate that without a CJK IME test rig (modern TSF IMEs are usually
unaffected; legacy ones are not). The benign, low real-world risk of hook injection (the attacker already
needs hook-registration privileges on the machine — not a remote vector) does not justify that
regression. It stays an idea, not a plan: it costs more than it buys, and it is not on the TODO list.
Neither mitigation affects SmartScreen / AV reputation — for an unsigned app that is per-file-hash and resets each release. Code signing is the real integrity/reputation fix; the search-path restriction is defence-in-depth layered under it, not a substitute.
Platemaker GUI 1.4.3 · GPL-3.0 · Application repository · libplatemaker · Report an issue
Development pages synced to code commit 1331e01 (2026-10-04).
Overview
Manual
- Manual overview
- Installation
- Quick start
- Concepts
- Main window
- Workspaces
- Projects
- Canvas profiles
- Templates
- Output profiles
- Rendering
- File statuses
- Menu reference
- Troubleshooting
Comic production
Development
- Overview
- Environment
- Building
- Architecture
- Main window
- Workflows
- Releasing
- Contributing
- Windows hardening
Strip editor