Overview#
DLL injection is a classic technique where you force a running process to load a DLL of your choosing. While often associated with malware, it’s also used legitimately by debuggers, profilers, and mod frameworks.
We’ll implement the CreateRemoteThread injection method in Rust.
The Win32 API Chain#
The injection follows this sequence:
OpenProcess — get a handle to the target processVirtualAllocEx — allocate memory in the targetWriteProcessMemory — write the DLL path stringCreateRemoteThread — spawn a thread that calls LoadLibraryA
Rust Implementation#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
| use windows::Win32::System::Memory::*;
use windows::Win32::System::Threading::*;
use windows::Win32::Foundation::*;
fn inject_dll(pid: u32, dll_path: &str) -> Result<(), String> {
let dll_path_wide: Vec<u8> = dll_path.bytes()
.chain(std::iter::once(0))
.collect();
// Step 1: Open target process
unsafe {
let process = OpenProcess(
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD,
None,
pid,
).map_err(|e| format!("OpenProcess failed: {e}"))?;
// Step 2: Allocate memory in target
let remote_buf = VirtualAllocEx(
process,
None,
dll_path_wide.len(),
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE,
);
if remote_buf.is_null() {
return Err("VirtualAllocEx failed".into());
}
// Step 3: Write DLL path
let mut written = 0usize;
WriteProcessMemory(
process,
remote_buf,
dll_path_wide.as_ptr() as *const _,
dll_path_wide.len(),
Some(&mut written),
).map_err(|e| format!("WriteProcessMemory failed: {e}"))?;
// Step 4: Create remote thread
let load_library = GetProcAddress(
GetModuleHandleA(s!("kernel32"))?,
s!("LoadLibraryA"),
);
CreateRemoteThread(
process,
None,
0,
Some(std::mem::transmute(load_library)),
remote_buf,
0,
None,
).map_err(|e| format!("CreateRemoteThread failed: {e}"))?;
}
Ok(())
}
|
Cargo.toml#
1
2
3
4
5
6
| [dependencies]
windows = { version = "0.58", features = [
"Win32_System_Memory",
"Win32_System_Threading",
"Win32_Foundation",
] }
|
Detection & Defense#
Modern EDR solutions detect this technique through:
- API hooking: Monitoring
CreateRemoteThread calls - Memory scanning: Detecting injected DLLs in process space
- Thread origin analysis: Threads started from outside the process module range
For red team work, consider more evasive alternatives like reflective DLL injection or process hollowing.
Legal Disclaimer#
This content is for educational purposes only. Only use these techniques on systems you own or have explicit authorization to test.