Repository navigation
Releases: projectmerai/DLLHijackHunter
Release list
v2.5.0 — Canary Reliability Fixes + Runtime Proxy Synthesis
v2.5.0 — Canary Reliability Fixes + Runtime Proxy Synthesis
Three canary bugs that caused confirmed hijacks to be missed or mis-reported, plus a new compiler-free proxy generation pipeline. No breaking changes.
Bug Fixes
TriggerExecutor — Service canary masked by sc.exe exit-code oracle
When a service loads the canary DLL and then crashes (common for export-consuming services), DllMain fires and writes the confirmation file before the process exits. sc start returns non-zero on a crash, so the old code set triggered = false and reported CanaryResult.Failed even though the confirm file had already been written. Fixed: TriggerService now returns true unconditionally after dispatching sc start; the canary file poll is the correct oracle and is now the only arbiter.
CanaryDllBuilder — Proxy forwarder naming causes import-snap failure before DllMain
GetForwardModuleBase used .hhorig (dot separator) to name the sidecar, producing strings like "foo.hhorig.ExportName". The Windows PE loader splits forwarder strings at the first dot, so this was parsed as module = foo (the canary itself) and export = hhorig.ExportName — not found, import snap fails before DllMain runs, confirmation file is never written: CanaryResult.Timeout. Fixed: separator changed to underscore → foo_hhorig, producing the unambiguous single-dot forwarder "foo_hhorig.ExportName" that correctly resolves to the sidecar.
TriggerExecutor — Scheduled-task canary settlement delay too short
schtasks /run is asynchronous: it queues the task and returns almost immediately. The previous 3 s post-trigger delay was insufficient for the scheduler to launch the process and for DllMain to complete. The polling window was opening before the DLL was loaded, producing CanaryResult.Timeout. Fixed: post-trigger delay increased from 3 s to 8 s.
AutoElevateEnumerator + COMEnumerator — LocalServer32 path corruption
LocalServer32 registry values are full command lines (e.g. "C:\Program Files\Foo\bar.exe" /sta). The old code applied Trim('"') directly, which corrupts a quoted-path-with-arguments string and causes the wrong executable to be analyzed. Both enumerators now route through CommandLineParser.ExtractExecutablePath, which correctly extracts the executable from any quoted or unquoted command line.
KnownDllsFilter — incorrect .local bypass logic
The filter previously passed .local-redirect candidates for KnownDLLs as valid findings, on the assumption that .local files can bypass KnownDLLs. This was true on Windows XP/2003 but was removed in Vista. On all modern Windows, KnownDLLs are served from the kernel object store (\KnownDlls\) and are immune to .local redirection. These candidates are now correctly suppressed as false positives.
SearchOrderCalculator — overwrite attack detection
Previously the search-order walk stopped as soon as the legitimate DLL was found, skipping positions where the attacker could overwrite the existing file in a writable directory. The calculator now checks whether the directory at the legitimate DLL's position is writable by a standard user. If it is, the position is added as an overwrite-attack hijack candidate before the walk terminates.
FilterPipeline — EnvPath deduplication
EnvPath (writable %PATH% directory) candidates represent a (DLL, directory) attack slot, not a specific binary. Grouping by (binary, DLL, directory) was producing hundreds of identical findings — one per binary that loads the same DLL from the same PATH directory. Candidates of type EnvPath are now grouped by (DLL, directory), collapsing duplicates into a single finding and retaining the highest-priority trigger.
ETWDiscoveryEngine + StaticDiscoveryEngine — --target scoping
ETW event capture now filters to processes whose binary falls under the --target path, eliminating unrelated system noise from a targeted scan. StaticDiscoveryEngine suppresses system-wide PATH analysis when --target is set, since PATH weaponization is independent of any specific target binary.
Program.cs — --canary-settle CLI flag
New flag to override the canary settle window (seconds to wait for the canary DLL to fire after execution is triggered) directly from the command line, independent of the selected profile. Useful for services that load many DLLs at startup and need more headroom than the profile default.
New Features
RuntimeProxyBuilder — Compiler-free export-forwarding proxy generation
Export-forwarding proxy DLLs are now generated entirely at runtime via PE surgery. A synthesised .edata section is grafted onto the embedded precompiled canary binary in-process — no MSVC, no cl.exe, no vswhere/vcvarsall required. The Windows loader resolves the forwarder strings to a sidecar copy of the same canary, DllMain fires in both, and the host process survives the load. MSVC is fully retired as a runtime dependency; the complete canary pipeline now works from a single self-contained binary.
Documentation
README — Corrected all compiler/MSVC claims
Multiple sections incorrectly stated MSVC was required for export-forwarding proxy generation. All affected passages corrected: the functional-proxy blockquote now describes the PE surgery approach; the Mermaid sequence diagram, footnotes ¹ and �, the proxy section heading, and the triage recommendation have all been updated to reflect the no-compiler-required reality. The --target CLI description now notes that it also scopes ETW event capture and suppresses system-wide PATH analysis.
v2.4.0 — Verification & Analysis Fixes
v2.4.0 — Verification & Analysis Fixes
Seven bug fixes targeting false positives, analysis accuracy, and operational correctness. No breaking changes.
Bug Fixes
ReportGenerator — console crash on redirected stdout
AnsiConsole.Clear() threw IOException: The handle is invalid whenever --output was used or stdout was piped. Guarded with !Console.IsOutputRedirected.
CanaryDllBuilder — loadprobe.dll leaked after scan
CleanupAll() removed MSVC build artifacts but never deleted %ProgramData%\DLLHijackHunter\loadprobe.dll. The file now accumulates across scans until an explicit cleanup. Fixed — probe DLL is deleted in CleanupAll().
LoadLibraryExFlagsFilter — AnalysisConfidence mislabeled
All five confidence assignment sites were using incorrect labels, producing misleading filter output:
SetDefaultDllDirectories/AddDllDirectorydetections →Certain(wasIndirectCall)LoadLibraryExwith runtime-unknown flags →Unknown(wasIndirectCall)- Plain
LoadLibrary(standard search order confirmed) →CertainDirect(wasCertain) - Import-table-only loads (no LoadLibrary call) →
CertainDirect(wasCertain)
KnowledgeBaseEngine — false KB hits on generic binary names
Matching solely on binary basename caused setup.exe, update.exe, installer.exe, and similar high-collision names to spuriously set IsKnownVulnerability = true, bypassing the 79% static-only confidence cap. Matches for these names now require at least one parent-directory path hint from the HijackLibs dataset to appear in the binary's actual path.
LoadProbe — wrong search model for service candidates
All candidates were verified with LOAD_LIBRARY_SEARCH_USER_DIRS | SEARCH_SYSTEM32 | ... (opt-in modern ordering). Service binaries use the traditional unmodified search order (SetCurrentDirectory + LoadLibraryW). Service candidates are now probed with the correct model, eliminating both false wins and false losses for that trigger type.
StartupItemEnumerator — SilentProcessExit (T1546.012) not enumerated
IFEO\<image>\SilentProcessExit\MonitorProcess entries were not discovered at all. When a monitored image exits, Windows launches MonitorProcess — typically under the user or service account that triggered the exit. These are now surfaced as hijack candidates.
AutoElevateEnumerator — fragile manifest detection
IsAutoElevate() read up to 2 MB of each EXE as raw UTF-8 and searched for <autoElevate>true</autoElevate>, missing binaries with embedded RT_MANIFEST resources, whitespace variants in the XML, or external .manifest sidecar files. Replaced with PEAnalyzer.Analyze(), which already handles all three cases.
Full changelog: https://github.com/ghostvectoracademy/DLLHijackHunter/commits/main
Presented at Black Hat Arsenal @ SecTor 2026 · projectmerai.com
v2.3.0 - Codebase Audit Fixes
What's Changed
Logic Fixes
- Fix duplicate UseCases accumulation in reports
- Cache AllImportedDlls to avoid repeated allocations
- Warn on unknown profile names (catches typos like
--profile aggresive) - Guard WindowsIdentity.GetCurrent() in AttackChainCorrelator
- Validate
--min-confidencerange (0-100)
New Functionality
- ScanLogger wired into pipeline —
--log-fileand--verbosenow produce meaningful diagnostic output - Attack chains in JSON/HTML — no longer console-only
- FORCE_INTEGRITY filter — binaries with this DllCharacteristic are now correctly penalized
uac-bypassprofile added to--helptext
Code Quality
- PE analysis cache in WinSxSManifestFilter (avoids re-parsing same binary)
- MSVC artifact cleanup (.obj/.lib/.exp/.pdb) in CanaryDllBuilder
- Deduplicated KnownDlls registry loading
- Fixed env-var expansion order in ServiceEnumerator
- COMEnumerator now scans both InprocServer32 and LocalServer32
Full Changelog: v2.2.0...v2.3.0
v2.2.0 - Canary Improvements and Bug Fixes
Fixed
- README now matches the current canary implementation
- Improved canary cleanup and service restore flow
TriggerExecutornow drains stderr to avoid process hangs
Changed
- Updated Windows executable
- Clarified current canary behavior and limitations
Notes
- Canary confirmation is file-based
- Canary compilation currently requires MSVC
cl.exe - Proxy/export-forwarding canaries are experimental
v2.1.0 - LPE Only Addition
Now you have the best of both worlds.
When you want to find Guaranteed 0-Day Standard User -> SYSTEM Exploits, you open an Administrator PowerShell window and run this exact command:
.\DLLHijackHunter.exe --profile aggressive --lpe-only
What this does:
- --lpe-only strips away all the "boring" Admin-to-SYSTEM persistence bugs in System32 and Program Files. It forces the tool to only look at ProgramData, %PATH%, and other messy user-writable folders.
- Administrator Rights gives the tool the power to instantly restart the services (net stop / start) without you having to reboot the computer.
- --profile aggressive unleashes the Canary DLL to prove that Windows mitigations won't block the exploit.
v2.0.0: Attack Chain Discovery
🚀 What's New
Attack Chain Correlation
We've introduced a new correlation engine that analyzes isolated findings and stitches them together into realistic, actionable exploit paths. Instead of just seeing 50 vulnerable DLLs, you now see exactly how an attacker would use them to take over the machine.
The engine currently detects three distinct exploit chains:
-
The Direct Path (User → SYSTEM)
-
Identifies critical misconfigurations where a standard user can directly hijack a SYSTEM-level process (e.g., via a globally writable PATH directory or a vulnerable CWD load).
-
The Ladder (User → Admin → SYSTEM)
-
Models a realistic Red Team escalation path. It correlates a silent UAC Bypass vulnerability with a high-privilege payload. The engine is smart enough to ensure that the chosen SYSTEM payload actually requires the UAC bypass to exploit (e.g., writing to C:\Program Files).
The Long Con (User → Persistence) -
Identifies findings that survive a reboot (e.g., Run keys, Startup folder items) and links them to an initial foothold, demonstrating how an attacker would maintain stealthy access without triggering alarms.
Minor Fixes & Polish
Updated all internal reporting and console banners to reflect the v2.0.0 release.
Refined the WritabilityFilter integration to ensure Attack Chains only use targets that are guaranteed to be writable by the current user.
v1.3.0 - Threat Intelligence & Weaponized Exploits
Major New Features
- Offline Vulnerability Knowledge Base (HijackLibs): The scanner now features a built-in Threat Intelligence engine. It cross-references discovered DLL hijack opportunities against known vulnerabilities (e.g., Teams, OneDrive, Discord). Matches receive a massive
+15Confidence score boost, are flagged with[HIJACKLIBS MATCH], and include direct exploit URLs. - Automated PATH Exploitation Engine: Dynamically weaponizes writable directories in the
%PATH%. It actively hunts for highly vulnerable native Windows services (likeIKEEXT,SessionEnv,Spooler,WlanSvc,Schedule) that blindly poll the PATH for missing phantom DLLs, generating actionable attack paths. - Massive Phantom DLL Expansion: We completely overhauled the database, expanding from 101 to 497 unique, highly-targeted DLLs across 25 categories (including .NET/CLR, Third-Party Sideloading, COM/OLE, AMSI/Defender tools, and Virtualization).
Improvements & Fixes
- Integrated Knowledge Base intelligence directly into the AutoElevate Side-Loading Simulation and
.localRedirect checks. - Restructured TieredScorer to accurately clamp confidence bounds and properly rank Threat Intel findings at the
ConfirmedandHightiers.
v1.2.0 - UAC Bypass Module
What's New
UAC Bypass Discovery
- Manifest AutoElevate scanning — Finds EXEs with
<autoElevate>true</autoElevate>manifests - COM AutoElevation scanning — Discovers COM objects with
Elevation\Enabled=1(Fodhelper, CMSTPLUA, etc.) - Side-load simulation — Simulates copy-to-writable-folder attack for unprotected AutoElevate binaries
- New
uac-bypassscan profile — Focused UAC bypass scanning
Improvements
- Parallel System32 scanning with
Parallel.ForEach - XML-validated manifest detection (fewer false positives)
- +10 confidence bonus for UAC bypass candidates
- WritabilityFilter auto-passes simulated copy attacks
- 5 new tests for UAC bypass scoring
Bug Fixes
- Fixed missing
UACBypassin TriggerType enum - Fixed
ExecutionContext→DiscoveryContextnaming - Fixed
TriggerAutoElevatedefaulting to true
Other
- README rewritten with updated documentation
v1.1.0 - Code Quality & Developer Experience
What's Changed
Code Quality Improvements
- Cleaned up dev scaffold comments — Removed leftover
// ← ADD THIScomments fromScanProfile.csandProgram.cs - Extracted ASCII banner to shared constant —
BannerConstants.cseliminates duplication betweenProgram.csandReportGenerator.cs - Externalized phantom DLL database — Moved 75 phantom DLLs from hardcoded C# to
Resources/phantom_dlls.jsonembedded resource for easier community contributions - Consolidated data models — Merged
ProcessContextandExecutionContextinto unifiedDiscoveryContextclass
New Features
- Logging abstraction — New
ScanLoggerwith--log-fileCLI option to write diagnostic logs to file - Graceful cancellation — Press Ctrl+C during ETW collection or canary testing for clean shutdown via
CancellationToken
Testing
- Added xUnit test project with 26 tests:
- 14 tests for
TieredScorer(tiers, canary impacts, score formula, clamping, use cases) - 12 tests for
SearchOrderCalculator(3 cross-platform + 9 Windows-only)
- 14 tests for
v1.0.0 - Initial Release
DLLHijackHunter v1.0.0
Automated DLL Hijacking Detection with Zero False Positives
Highlights
- 50+ DLL hijacking vulnerabilities discovered across enterprise security software in first scan
- Canary confirmation — proves hijacks actually work before reporting
- 8-gate filter pipeline — eliminates false positives
- ETW real-time monitoring — catches runtime-loaded DLLs
- 5-tier scoring — Confirmed > High > Medium > Low > Info
Features
- 10 hijack types: Phantom, Search Order, Side-Loading, .local Redirect, ENV PATH, KnownDLL Bypass, CWD, AppInit, IFEO, AppCert
- 6 discovery sources: Services, Scheduled Tasks, Startup Items, COM Objects, Run Keys, ETW
- 4 scan profiles: Aggressive, Strict, Safe, Red Team
- 3 output formats: Console, JSON, HTML
- Target filtering: Scan specific binaries, directories, or filenames with
--target
Quick Start
.\DLLHijackHunter.exe --profile aggressiveRequirements
- Windows 10/11 or Windows Server 2016+
- Administrator privileges recommended (required for ETW, canary, service triggers)
- Self-contained binary — no .NET runtime needed
Assets
DLLHijackHunter.exe— Self-contained Windows x64 binary