Skip to content
λmaldev wiki/
pagesClassic DLL Injection
T1055.001Windowsx64 / x86C / C++

Classic DLL Injection

updated 2026-06-025 min readthehackersbrain
Authorized use only. This material is published for detection engineering, malware analysis and authorized red-team engagements. Running these techniques against systems you do not own or have written permission to test is illegal.

Overview

The oldest injection primitive on Windows: write a DLL path into a remote process and start a thread at LoadLibraryA with that path as its argument. The Windows loader maps the image, resolves its imports and calls DllMain — all the hard work is done for you by a legitimate code path.

That reliance on the loader is also the technique’s undoing. The injected DLL appears in the target’s PEB_LDR_DATA module list, is backed by a file on disk, and had to be written to disk first. Every later injection technique in this category exists to remove one of those three artifacts.

The call chain

  1. 1
    OpenProcess(PROCESS_ALL_ACCESS)
    Acquire a handle to the target with allocate, write and thread-create rights.
  2. 2
    VirtualAllocEx
    Reserve a small RW page in the target to hold the DLL path string.
  3. 3
    WriteProcessMemory
    Copy the fully qualified path of the DLL into that page.
  4. 4
    CreateRemoteThread(LoadLibraryA)
    Start a thread at LoadLibraryA with the path as its argument; the loader does the rest.

Reference implementation

inject.cC
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);

// the loader needs a path it can open, so the DLL must exist on disk
SIZE_T len = strlen(dllPath) + 1;
PVOID remote = VirtualAllocEx(hProc, NULL, len, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, remote, dllPath, len, NULL);

// LoadLibraryA sits at the same address in every process on the box
FARPROC loadLib = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)loadLib, remote, 0, NULL);

Detection

SYSMON EID 8
CreateRemoteThread where the start address resolves to LoadLibraryA/W in kernel32.
SYSMON EID 7
Image load of a DLL from a user-writable path into a process that never loads plugins.
SYSMON EID 10
ProcessAccess with GrantedAccess 0x1F3FFF from an unusual source image.
BEHAVIOURAL
The injected module is in the target's module list — this technique hides nothing from an inventory sweep.

Treat this one as a calibration technique. If your pipeline cannot see classic DLL injection in the lab, nothing further down this category will fire either.

Was this page useful?edit this page ↗