Skip to content

Instantly share code, notes, and snippets.

@vallahor
Created August 6, 2023 20:54
Show Gist options
  • Save vallahor/c43ef6fcf34db9e81179a0a52e23246c to your computer and use it in GitHub Desktop.
Save vallahor/c43ef6fcf34db9e81179a0a52e23246c to your computer and use it in GitHub Desktop.
Simple dll injector using CreateRemoteThread in rust
use std::ffi::CStr;
use windows_sys::{
core::*, Win32::Foundation::*, Win32::System::Diagnostics::Debug::*,
Win32::System::Diagnostics::ToolHelp::*, Win32::System::LibraryLoader::*,
Win32::System::Memory::*, Win32::System::StationsAndDesktops::*, Win32::System::Threading::*,
Win32::UI::WindowsAndMessaging::*,
};
fn get_pid(process: &str) -> Result<u32, &'static str> {
unsafe {
let snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
let mut process_struct: PROCESSENTRY32 = std::mem::zeroed();
process_struct.dwSize = std::mem::size_of::<PROCESSENTRY32>() as u32;
if Process32First(snapshot, &mut process_struct) == 1 {
while Process32Next(snapshot, &mut process_struct) == 1 {
let process_name = CStr::from_ptr(process_struct.szExeFile.as_ptr().cast())
.to_str()
.unwrap();
if process == process_name {
let process_id = process_struct.th32ProcessID;
return Ok(process_id);
}
}
}
}
Err("Process not found")
}
fn inject_dll(process: &str, dll_path: &str) -> Result<(), &'static str> {
let pid = get_pid(process)?;
let process = unsafe { OpenProcess(PROCESS_ALL_ACCESS, 0, pid) };
if process != INVALID_HANDLE_VALUE {
unsafe {
let name_len = dll_path.len() + 1;
let dll_str_alloc = VirtualAllocEx(
process,
std::ptr::null(),
name_len,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE,
);
let mut num_bytes = 0;
if WriteProcessMemory(
process,
dll_str_alloc,
dll_path.as_ptr().cast(),
name_len,
&mut num_bytes,
) != 0
{
let k32 = GetModuleHandleA(s!("kernel32.dll"));
if k32 != 0 {
let loadlibrary = GetProcAddress(k32, s!("LoadLibraryA")).unwrap();
let mut tid = 0;
let lib: LPTHREAD_START_ROUTINE = std::mem::transmute(loadlibrary);
let thread = CreateRemoteThread(
process,
std::ptr::null(),
0,
lib,
dll_str_alloc,
0,
&mut tid,
);
WaitForSingleObject(thread, INFINITE);
CloseHandle(process);
CloseHandle(thread);
return Ok(());
}
}
};
}
Err("Unable to inject")
}
fn main() {
let dll_path = "";
let process = "";
if let Err(err) = inject_dll(process, dll_path) {
println!("{}", err);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment