mirror of
https://github.com/0xflux/Vectored-Exception-Handling-Squared
synced 2026-06-08 10:12:58 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1 @@
|
||||
/target
|
||||
Generated
+25
@@ -0,0 +1,25 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "veh"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
[package]
|
||||
name = "veh"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
windows-sys = {version = "0.61", features = [
|
||||
"Win32",
|
||||
"Win32_Foundation",
|
||||
"Win32_NetworkManagement_NetManagement",
|
||||
"Win32_Storage_FileSystem",
|
||||
"Win32_System_ProcessStatus",
|
||||
"Win32_System_SystemInformation",
|
||||
"Win32_System_Threading",
|
||||
"Win32_System_WindowsProgramming",
|
||||
"Win32_System_SystemServices",
|
||||
"Win32_Security",
|
||||
"Win32_UI_WindowsAndMessaging",
|
||||
"Win32_System_Diagnostics_Debug",
|
||||
"Win32_System_Services",
|
||||
"Win32_System_Diagnostics_ToolHelp",
|
||||
"Win32_System_Ole",
|
||||
"Win32_System_Variant",
|
||||
"Win32_System_ClrHosting",
|
||||
"Win32_System_Com",
|
||||
"Win32_System_Console",
|
||||
"Win32_System_IO",
|
||||
"Win32_System_Pipes",
|
||||
"Win32_Security_Authorization",
|
||||
"Win32_Globalization",
|
||||
"Win32_Networking_WinHttp",
|
||||
"Win32_System_Memory",
|
||||
"Win32_System_Kernel",
|
||||
]}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
use std::ffi::c_void;
|
||||
|
||||
use windows_sys::Win32::{Foundation::{EXCEPTION_BREAKPOINT, EXCEPTION_SINGLE_STEP, STATUS_SUCCESS}, System::Diagnostics::Debug::{
|
||||
AddVectoredExceptionHandler, CONTEXT_DEBUG_REGISTERS_AMD64, EXCEPTION_CONTINUE_EXECUTION, EXCEPTION_CONTINUE_SEARCH, EXCEPTION_POINTERS
|
||||
}};
|
||||
|
||||
fn main() {
|
||||
println!("Starting program..");
|
||||
let _h = unsafe { AddVectoredExceptionHandler(1, Some(veh)) };
|
||||
unsafe { core::arch::asm!("int3") };
|
||||
change_execution();
|
||||
println!("Finished!")
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn change_execution() {
|
||||
println!("If this worked I should not print!!!! :(");
|
||||
}
|
||||
|
||||
unsafe extern "system" fn veh(p_ep: *mut EXCEPTION_POINTERS) -> i32 {
|
||||
let exception_record = unsafe { *(*p_ep).ExceptionRecord };
|
||||
let ctx = unsafe { &mut *(*p_ep).ContextRecord };
|
||||
|
||||
if exception_record.ExceptionCode == EXCEPTION_BREAKPOINT {
|
||||
println!("Received initial break to set hardware breakpoint on a function");
|
||||
// Set the address we wish to monitor for a hardware breakpoint
|
||||
ctx.Dr0 = change_execution as *const c_void as u64;
|
||||
// Set the bit which says Dr0 is enabled locally
|
||||
ctx.Dr7 |= 1;
|
||||
// Increase the instruction pointer by 1, so we effectively move to the next instruction after int3
|
||||
ctx.Rip += 1;
|
||||
// Set flags
|
||||
ctx.ContextFlags |= CONTEXT_DEBUG_REGISTERS_AMD64;
|
||||
// clear dr6
|
||||
ctx.Dr6 = 0;
|
||||
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
} else if exception_record.ExceptionCode == EXCEPTION_SINGLE_STEP {
|
||||
|
||||
// Gate the exception to make sure it was our entry which triggered
|
||||
// to prevent false positives (will probably lead to UB in the process)
|
||||
if (ctx.Dr6 & 0x1) == 0 {
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
println!("Now in the 2nd VEH when change_execution was accessed");
|
||||
|
||||
// fake a return value as if we intercepted a syscall
|
||||
ctx.Rax = STATUS_SUCCESS as u64;
|
||||
|
||||
// get return addr from the stack
|
||||
let rsp = ctx.Rsp as *const u64;
|
||||
let return_address = unsafe { *rsp };
|
||||
// set it
|
||||
ctx.Rip = return_address;
|
||||
|
||||
// simulate popping the ret from the stack
|
||||
ctx.Rsp += 8;
|
||||
|
||||
// clear dr6
|
||||
ctx.Dr6 = 0;
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
EXCEPTION_CONTINUE_SEARCH
|
||||
}
|
||||
Reference in New Issue
Block a user