Back to Blog
Detecting DLL Side-Loading: Telemetry, Image Load Auditing, and Detection Logic
PublishedAugust 25, 20267 min readIntermediate

Detecting DLL Side-Loading: Telemetry, Image Load Auditing, and Detection Logic

Learn how threat actors exploit Windows DLL search order to execute malicious code through legitimate binaries, and how to build targeted detections without overwhelming your SIEM.

Cyber SecurityCybersecuritySecurity Operations
Written byAbdul Muqeet Tabraiz

DLL side-loading remains one of the most reliable techniques adversaries use to execute arbitrary code, evade endpoint detection and response (EDR) agents, and blend into normal administrative activity. By placing a malicious Dynamic Link Library (DLL) into a folder alongside a legitimate, trusted executable, an attacker tricks the operating system into loading their payload instead of the benign library.

Because the process running in memory is a digitally signed binary—such as a Microsoft tool, a vendor agent, or a widely used application—security tooling often grants it higher trust.

Detecting this activity requires understanding how Windows resolves library dependencies, which telemetry events capture module loads, and how to filter out legitimate administrative noise without blowing up your logging budget.


How DLL Side-Loading Works

When a Windows application starts up, it frequently relies on external libraries (DLLs) to execute specific functions. If an application imports a DLL without using an explicit, hardcoded file path—or without instructing the OS to load exclusively from secure system directories—the Windows Loader follows a defined search order to locate the required file.

By default, the standard DLL search order for desktop applications processes locations in the following sequence:

  1. The directory from which the application loaded.
  2. The system directory (e.g., C:\Windows\System32).
  3. The 16-bit system directory (e.g., C:\Windows\System).
  4. The Windows directory (e.g., C:\Windows).
  5. The current working directory.
  6. The directories listed in the system PATH environment variable.

Because the application’s originating directory is evaluated first, an attacker who has write access to a non-protected folder (such as C:\Users\Public\, C:\AppData\Local\Temp\, or custom application folders) can copy a legitimate binary into that folder along with a crafted DLL sharing the exact name of a dependency the application expects.

Attacker-Controlled Directory: C:\Users\Public\Downloads\
├── legitimate_signed_app.exe  (Valid Digital Signature)
└── targeted_dependency.dll     (Malicious Unsigned Payload)

When legitimate_signed_app.exe executes, the OS checks C:\Users\Public\Downloads\ first. It finds targeted_dependency.dll, loads it into the process memory space of the signed binary, and executes its exported functions—often inside DllMain upon process attachment.


Telemetry Sources and the Ingestion Problem

To detect DLL side-loading, you need visibility into process creation and module load events. However, full module load tracing across an entire enterprise is exceptionally noisy.

Essential Telemetry Sources

  1. Sysmon Event ID 7 (Image Loaded): Logs when a process loads a DLL module. It captures crucial fields such as Image (the executing process), ImageLoaded (the DLL path), Signed, SignatureStatus, and file hashes.
  2. Sysmon Event ID 1 / Windows Event ID 4688 (Process Creation): Captures the command line, execution path, parent process, and user context.
  3. EDR Module Load Events: Proprietary EDR telemetry equivalent to Sysmon Event ID 7 (e.g., Microsoft Defender for Endpoint’s DeviceImageLoadEvents).

Managing Telemetry Noise

If you enable Sysmon Event ID 7 globally with a default “include all” configuration, your log volume will spike drastically. A single execution of a web browser or developer tool can generate hundreds of module load events per minute.

To keep telemetry manageable and actionable, focus monitoring on high-risk indicators:

  • Unsigned DLLs loaded by signed binaries.
  • Legitimate binaries executing outside their standard installation paths (e.g., workstation.exe or calc.exe running from C:\Users\...\AppData\).
  • Known side-loadable binaries loading DLLs from user-writable directories (\AppData\, \Temp\, \Public\, \ProgramData\).

Auditing with Sysmon Configuration

Below is a focused Sysmon configuration snippet designed to capture potential side-loading attempts in user-writable folders while filtering out standard system locations.

<Sysmon schemaversion="4.90">
  <EventFiltering>
    <ImageLoad onmatch="include">
      <!-- Capture DLL loads from common user-writable directories -->
      <ImageLoaded condition="begin with">C:\Users\</ImageLoaded>
      <ImageLoaded condition="begin with">C:\ProgramData\</ImageLoaded>
      <ImageLoaded condition="begin with">C:\Windows\Temp\</ImageLoaded>
    </ImageLoad>
    <ImageLoad onmatch="exclude">
      <!-- Exclude validly signed DLLs loaded from standard locations to reduce noise -->
      <SignatureStatus condition="is">Valid</SignatureStatus>
    </ImageLoad>
  </EventFiltering>
</Sysmon>

In an operational environment, you will likely need to extend these exclusions to account for developer tools, portable software, and third-party software updaters that run out of %LOCALAPPDATA%.


Building Detection Logic

Once telemetry is flowing into your SIEM or log repository, you can construct queries to identify anomalies.

Approach 1: Signed Binaries in Non-Standard Paths

Adversaries often copy standard Microsoft utilities (like OneDriveStandaloneUpdater.exe, Dism.exe, or GfxDownloadWrapper.exe) to staging folders. Detecting legitimate system binaries running from non-standard locations is a reliable indicator of compromise.

Here is a Kusto Query Language (KQL) query designed for Microsoft Sentinel or Defender for Endpoint:

DeviceProcessEvents
| where FolderPath !startswith @"C:\Windows\System32\"
    and FolderPath !startswith @"C:\Windows\SysWOW64\"
    and FolderPath !startswith @"C:\Program Files"
    and FolderPath !startswith @"C:\Program Files (x86)"
| where FileName in~ (
    "calc.exe",
    "notepad.exe",
    "cmd.exe",
    "dism.exe",
    "control.exe",
    "certutil.exe"
)
| project Timestamp, DeviceName, AccountName, FileName, FolderPath, ProcessCommandLine, InitiatingProcessFileName

Approach 2: Unsigned DLL Loads via ImageLoad Events

This KQL query searches for processes executing from user-writable locations that load unsigned or invalidly signed DLL files.

DeviceImageLoadEvents
| where InitiatingProcessFolderPath has_any (@"C:\Users\", @"C:\ProgramData\", @"C:\Windows\Temp\")
| where IsSigned == false or SignatureStatus != "Valid"
| where FolderPath endswith ".dll"
| project Timestamp, 
          DeviceName, 
          ExecutingProcess = InitiatingProcessFileName, 
          ExecutingProcessPath = InitiatingProcessFolderPath, 
          LoadedDLL = FileName, 
          LoadedDLLPath = FolderPath, 
          SHA256, 
          SignatureStatus

Practical Investigation Workflow

When an alert triggers for a suspicious module load, follow this investigation flow:

[ Alert Generated ] 


[ Step 1: Binary Verification ]
  └─ Is the host process executing from its expected path?
  └─ Is the host process signed by a trusted vendor?


[ Step 2: Analyze Loaded DLL ]
  └─ Inspect signature, hash, creation timestamp, and file size.
  └─ Does the creation timestamp match the host execution timestamp?


[ Step 3: Contextual Telemetry ]
  └─ Inspect network connections initiated immediately after load.
  └─ Look for anomalous child processes spawned by the host binary.

1. Verify Process Location and Signature

Compare the binary’s running directory against its expected native directory. If whoami.exe or explorer.exe is running from C:\Users\Public\, treat the alert as high severity.

2. Inspect the Loaded DLL File Properties

Check the loaded DLL’s creation timestamp. A host binary that has resided on disk for months loading a DLL created seconds prior to the event is a strong indicator of recent drop-and-execute activity.

Check external threat intelligence platforms or submit the hash to your internal sandbox.

3. Analyze Network and Child Process Activity

Because side-loading is primarily an execution and persistence vector, the loaded DLL will typically perform post-exploitation actions. Look at process telemetry in the immediate timeframe following the image load:

  • Does the signed host binary open outbound network connections to unfamiliar IP addresses?
  • Does it spawn cmd.exe, powershell.exe, or wmic.exe?

If legitimate_app.exe loads untrusted.dll and immediately initiates an HTTP POST request to an external IP, you are likely dealing with active command-and-control (C2) beaconing.


Common Pitfalls and Limitations

  1. Noise from Portable Applications: Tools like VS Code extensions, web browsers, and administrative utilities often load unsigned DLLs from %APPDATA%. You will need to maintain a baseline of safe environment-specific behaviors to tune out false positives.
  2. DLL Redirection (.local files): Windows allows applications to prefer local DLLs if a .local file or directory exists in the application root. Be aware that adversaries may drop a empty <appname>.exe.local file to force Windows to bypass default SafeDLLSearchMode rules.
  3. Resource Constraints: Collecting module loads environment-wide without strict filtering can overwhelm endpoint agents and telemetry pipelines. Always test Sysmon or EDR deployment configurations on a small system subset first.

Defensive Recommendations

To mitigate DLL side-loading risks across your enterprise:

  • Enforce Directory Permissions: Ensure standard users cannot write to root application directories or critical administrative paths.
  • Implement Application Control: Use AppLocker or Windows Defender Application Control (WDAC) to restrict script execution and block binaries running from user-writable directories (%AppData%, %Temp%, C:\Users\Public\).
  • Developer Safeguards: For internal software development, specify explicit, fully qualified paths when calling LoadLibrary or use SetDefaultDllDirectories to force the Windows loader to search only %System32% for dependencies.