
New releaseSep 1, 2026
Automated DLL Hijacking Discovery, Validation, and Confirmation. Turning local misconfigurations into weaponized, confirmed attack paths.
Automated DLL Hijacking Discovery, Validation, and Confirmation
Turning local misconfigurations into weaponized, confirmed attack paths.
DLLHijackHunter is an automated Windows DLL hijacking detection tool that goes beyond static analysis. It discovers, validates, and confirms DLL hijacking opportunities using a multi-phase pipeline:
Most DLL hijacking tools stop at “this DLL might be hijackable.” DLLHijackHunter attempts to validate it, cross-reference it against known exploit intelligence, and confirm real execution paths where possible.
flowchart TB
subgraph Phase1["Phase 1: Discovery"]
SE["Static Engine<br/>Services, Tasks, Startup,<br/>COM, Run Keys"]
AE["AutoElevate Engine<br/>Manifest + COM UAC Bypass"]
PE["PE Analyzer<br/>Import Tables, Delay Loads,<br/>Manifests, Exports"]
ETW["ETW Engine<br/>Real-time DLL Load<br/>Monitoring"]
SO["Search Order<br/>Calculator"]
end
subgraph Phase2["Phase 2: Filter Pipeline"]
direction LR
HG["Hard Gates<br/>(Binary Kill)"]
SG["Soft Gates<br/>(Confidence Adj.)"]
end
subgraph Phase3["Phase 3: Load Verification (--verify-load)"]
LP["LoadProbe<br/>Child-process loader test<br/>Probe DLL placed & removed"]
end
subgraph Phase4["Phase 4: Canary"]
CB["Canary DLL Builder"]
TE["Trigger Executor"]
VF["Verification"]
end
subgraph Phase5["Phase 5: Output"]
SC["Tiered Scorer"]
RC["Console Report"]
RJ["JSON Report"]
RH["HTML Report"]
end
SE --> PE --> SO
AE --> PE
ETW --> SO
SO --> Phase2
HG --> SG
Phase2 --> Phase3
Phase3 --> Phase4
CB --> TE --> VF
Phase4 --> Phase5
| Type | Description | Stealth | Status |
|---|---|---|---|
| Phantom | DLL doesn't exist anywhere on disk | High | Implemented |
| Search Order | Place DLL earlier in the Windows search order | High | Implemented |
| Side-Loading | Abuse legitimate app loading DLLs from its directory | High | Implemented (AutoElevate copy-to-temp path) |
| .local Redirect | Hijack via .local directory redirection | High | Implemented |
| ENV PATH | Weaponization of writable directories in system PATH | High | Implemented (curated service/DLL map) |
| AppInit DLLs | AppInit_DLLs registry abuse | Low | Implemented |
| AppCert DLLs | AppCertDLLs registry abuse (loads into every CreateProcess/WinExec caller) | Low | Implemented |
| CWD | Current Working Directory hijack | Low | Planned — not currently produced by any discovery path |
IFEO Debugger entries are enumerated and the referenced binary is analyzed for DLL imports, but there is no dedicated IFEO/KnownDLL-bypass hijack type — those are not advertised as standalone detections.
DLLHijackHunter includes dedicated UAC bypass discovery:
System32 and SysWOW64 for EXEs with <autoElevate>true</autoElevate> in embedded manifestsHKLM\SOFTWARE\Classes\CLSID for COM objects with Elevation\Enabled=1SetDllDirectory or SetDefaultDllDirectories, simulates the “copy EXE to writable folder + drop DLL” attack pathResources/hijacklibs.json. A match boosts confidence and links the finding to its HijackLibs reference page; the absence of a match means nothing. The dataset is data-driven — refresh it by re-downloading https://hijacklibs.net/api/hijacklibs.json over that resource (no code changes required). Dataset © the HijackLibs project and contributors.PATH folders and generates hijack candidates for a curated map of native Windows services known to search PATH for missing DLLsThe pipeline reduces false positives through two stages:
Hard Gates
api-ms-*, ext-ms-*)Users / Authenticated Users / Everyone, plus leak-proof sub-admin service accounts like LOCAL SERVICE/NETWORK SERVICE) has effective write rights. Crucially, this is computed independently of the token the tool runs under, so running elevated does not make System32/Program Files look writable. This is what makes elevated runs meaningful for LPE triage.Soft Gates
LoadLibraryEx mitigation checksInstead of guessing, DLLHijackHunter attempts to prove hijacks work:
sequenceDiagram
participant H as DLLHijackHunter
participant B as Canary DLL Builder
participant T as Trigger Executor
participant V as Victim Binary
H->>B: Build canary DLL
B->>B: Extract precompiled canary<br/>(or compile a proxy with MSVC)
B-->>H: canary.dll + confirmation file path
H->>H: Place DLL at hijack path
H->>T: Trigger binary execution
T->>V: Start service / run task / COM activate
V->>V: Loads canary DLL
V-->>H: Writes confirmation file<br/>PID, privilege, integrity level
H->>H: Record: CONFIRMED
H->>H: Cleanup canary DLL
The canary DLL:
%ProgramData%\DLLHijackHunter\canary_<hash>.confirm), so one binary serves every candidate. The scanner computes the same hash from the deploy path and polls for that file.The bundled binaries are built from the auditable source at src/DLLHijackHunter/Resources/canary_src.c and can be regenerated with Resources/build_canary.bat (requires the MSVC C++ toolchain; the scanner does not).
Functional-proxy exception: When a search-order hijack targets a DLL that exists and exposes exports, keeping the host alive after confirmation requires an export-forwarding proxy, which is compiled per-DLL with MSVC (
cl.exe, located viavswhere/vcvarsall). If no toolchain is present, the precompiled canary is used instead — it still confirms the load (DllMain fires) but does not forward exports, so the host process may crash after the confirmation is recorded. Phantom-DLL and other no-export candidates need no compiler at all.
Signing: The embedded canaries are unsigned. Code-signing them (so they load under stricter policies and are attributable) requires a signing certificate and is left as a release-time step for the maintainer.
Proxy/export-forwarding canaries are experimental and best-effort. Some targets may fail to load correctly or may behave unexpectedly depending on:
That means a failed proxy canary does not always mean the underlying hijack path is impossible.
--verify-load)An opt-in, standard-user verification that sits between the filter pipeline and canary phase. For each applicable candidate it briefly writes a benign probe DLL to the writable hijack position, then asks the real Windows loader — in a short-lived child process — to resolve the DLL by name. Where the loader resolves determines the verdict:
.local/search-order "finding" for ntdll.dll that KnownDLLs makes unexploitable).Design and safety notes:
LOAD_LIBRARY_SEARCH ordering, so it is only applied to Phantom / Search-Order / Side-Load candidates. .local, PATH, and AppInit/AppCert candidates use different mechanics and are reported as Skipped.# Standard-user triage with loader-verified search order (no canary, no ETW)
.\DLLHijackHunter.exe --lpe-only --no-canary --no-etw --verify-load
| Feature | DLLHijackHunter | Robber | DLLSpy | WinPEAS | Procmon |
|---|---|---|---|---|---|
| Automated discovery | ✅ | ✅ | ✅ | ✅ | ❌ |
| Phantom DLL detection | ✅ | ❌ | ✅ | ❌ | ✅ |
| Search order analysis | ✅ | ❌ | ❌ | ❌ | ❌ |
| ACL-based writability check | ✅ | Partial | ❌ | Basic | ❌ |
| ETW real-time monitoring | ✅ | ❌ | ❌ | ❌ | ✅ |
| Canary confirmation | ✅¹ | ❌ | ❌ | ❌ | ❌ |
| Privilege escalation check | ✅ | ❌ | ❌ | ❌ | ❌ |
| UAC bypass discovery | ✅ | ❌ | ❌ | ❌ | ❌ |
| False positive reduction | ✅² | None | Basic | None | None |
| Reboot persistence check | ✅³ | ❌ | ❌ | ❌ | ❌ |
| Proxy DLL generation | ✅⁴ | ❌ | ❌ | ❌ | ❌ |
| Confidence scoring | ✅ | ❌ | ❌ | ❌ | ❌ |
| Auto trigger (svc/task/COM) | ✅⁵ | ❌ | ❌ | ❌ | ❌ |
| HTML/JSON reporting | ✅ | ❌ | ❌ | TXT | ❌ |
| Threat intel correlation | ✅⁶ | ❌ | ❌ | ❌ | ❌ |
| Automated PATH exploits | ✅ | ❌ | ❌ | ❌ | ❌ |
| Target-specific scanning | ✅ | ❌ | ❌ | ❌ | ✅ |
| Self-contained binary | ✅ | ❌ | ❌ | ✅ | ❌ |
¹ Precompiled dual-arch canaries are embedded — **no compiler needed** to confirm a load. Only the optional export-forwarding *proxy* (to keep an export-consuming host alive) needs MSVC.
² Via attacker-relative ACL writability (see Filter Pipeline). It reduces — it does not eliminate — false positives; soft-gate heuristics (manifest/SxS/LoadLibraryEx) still carry uncertainty. Unverified static findings are now capped below the **High** tier.
³ Derived from auto-start status, not a verified reboot test.
⁴ Export-forwarding proxy is experimental/best-effort (see note above).
⁵ Service/Task/COM triggers only; UAC-bypass findings are not canary-triggered.
⁶ Backed by a bundled snapshot of the HijackLibs dataset (~590 entries); refreshable from hijacklibs.net.
git clone https://github.com/ghostvectoracademy/DLLHijackHunter.git
cd DLLHijackHunter
# Build (self-contained single file)
dotnet publish src/DLLHijackHunter/DLLHijackHunter.csproj `
-c Release -r win-x64 --self-contained `
-p:PublishSingleFile=true -o ./publish
# Or use the build script
.\build.ps1
# Full aggressive scan (recommended, requires admin)
.\DLLHijackHunter.exe --profile aggressive
# Safe scan (no file drops, no triggers)
.\DLLHijackHunter.exe --profile safe
# UAC bypass focused scan
.\DLLHijackHunter.exe --profile uac-bypass
# Target a specific binary
.\DLLHijackHunter.exe --target "C:\Program Files\MyApp\app.exe"
# Target by filename (partial match)
.\DLLHijackHunter.exe --target notepad.exe
# Confirmed findings only
.\DLLHijackHunter.exe --profile redteam --format json -o report.json
DLLHijackHunter — Automated DLL Hijacking Detection
Options:
-p, --profile <profile> Scan profile [default: aggressive]
aggressive | strict | safe | redteam | uac-bypass
-o, --output <path> Output file path (auto-detects format)
-f, --format <format> Output format [default: console]
console | json | html
-t, --target <target> Target specific binary, directory, or filename
--min-confidence <value> Minimum confidence threshold 0-100. When omitted, each
profile's own threshold applies; passing this overrides it.
--no-canary Disable canary confirmation
--no-etw Disable ETW runtime discovery
--verify-load Verify search order with the real loader (see below).
Standard-user; transiently writes a benign probe.
--confirmed-only Only show canary-confirmed findings
--lpe-only Strict LPE hunting: ignore System32/Program Files, show
only standard-user-writable vulnerabilities
--log-file <path> Write a diagnostic scan log to file
-v, --verbose Verbose output
Note:
--min-confidenceis only treated as an override when you explicitly pass it. Otherwise the selected profile's threshold is used (e.g.safe= 50%,strict= 80%).
| Profile | Use Case | Canary | ETW | UAC Bypass | Min Confidence | Triggers |
|---|---|---|---|---|---|---|
| aggressive | Full audit, lab environments | ✅ | ✅ | ✅ | 15% | Services, Tasks, COM |
| strict | High-confidence findings only | ✅ | ✅ | ❌ | 80% | Services, Tasks |
| safe | Production systems, read-only | ❌ | ❌ | ❌ | 50% | None |
| redteam | Confirmed exploitable only | ✅ | ✅ | ❌ | 50% | Services, Tasks, COM |
| uac-bypass | UAC bypass vectors only | ❌ | ❌ | ✅ | 20% | AutoElevate only |
Each finding receives confidence and impact signals that are combined into a final prioritization tier.
Typical impact considerations include:
Confirmed canary execution should be treated as the strongest validation signal.
Tier gating: the High and Confirmed tiers are reserved for findings backed by a proof signal — a fired canary, an ETW runtime load observation, or a documented knowledge-base match. A purely static search-order match, however clean, is capped at the top of the Medium tier and annotated as Static-only so unverified heuristics never present as high-confidence.
Because writability is evaluated attacker-relative, both elevated and standard-user runs are meaningful:
--lpe-only (and --no-canary if a compiler isn't available) — every surviving finding is genuinely writable by an unprivileged principal.DLLHijackHunter is designed for defensive security research, lab validation, auditing, and red-team simulation in authorized environments.
Use it only on systems and networks you own or are explicitly authorized to assess.
DLLHijackHunter supports:
Recommended workflow:
MIT
Built by ProjectMerai.