Skip to content

Instantly share code, notes, and snippets.

@retep998
Last active May 31, 2017 09:58
Show Gist options
  • Save retep998/da9586ce0c4ded14b33d3fe535c683ec to your computer and use it in GitHub Desktop.
Save retep998/da9586ce0c4ded14b33d3fe535c683ec to your computer and use it in GitHub Desktop.
winapi-rs invalid handle in union
[package]
name = "handletest"
version = "0.1.0"
authors = ["Peter Atashian <[email protected]>"]
[dependencies.winapi]
git = "https://github.com/retep998/winapi-rs"
branch = "dev"
features = ["minwinbase", "minwindef", "processthreadsapi", "winbase", "winnt"]
extern crate winapi;
use std::mem::zeroed;
use std::ptr::null_mut;
use winapi::shared::minwindef::{BOOL, DWORD, LPVOID};
use winapi::um::minwinbase::{DEBUG_EVENT, EXIT_PROCESS_DEBUG_EVENT, LPDEBUG_EVENT, LPSECURITY_ATTRIBUTES, LOAD_DLL_DEBUG_EVENT};
use winapi::um::processthreadsapi::{LPPROCESS_INFORMATION, LPSTARTUPINFOW, PROCESS_INFORMATION, STARTUPINFOW};
use winapi::um::winbase::{CREATE_NEW_CONSOLE, DEBUG_PROCESS, INFINITE};
use winapi::um::winnt::{DBG_CONTINUE, LPCWSTR, LPWSTR};
use wide::ToWide;
extern "system" {
pub fn CreateProcessW(
lpApplicationName: LPCWSTR, lpCommandLine: LPWSTR,
lpProcessAttributes: LPSECURITY_ATTRIBUTES, lpThreadAttributes: LPSECURITY_ATTRIBUTES,
bInheritHandles: BOOL, dwCreationFlags: DWORD, lpEnvironment: LPVOID,
lpCurrentDirectory: LPCWSTR, lpStartupInfo: LPSTARTUPINFOW,
lpProcessInformation: LPPROCESS_INFORMATION,
) -> BOOL;
pub fn WaitForDebugEvent(lpDebugEvent: LPDEBUG_EVENT, dwMilliseconds: DWORD) -> BOOL;
pub fn ContinueDebugEvent(
dwProcessId: DWORD, dwThreadId: DWORD, dwContinueStatus: DWORD,
) -> BOOL;
}
unsafe fn foo() {
let mut si: STARTUPINFOW = zeroed();
let mut pi: PROCESS_INFORMATION = zeroed();
let err = CreateProcessW(r"C:\windows\system32\cmd.exe".to_wide_null().as_ptr(), null_mut(), null_mut(), null_mut(), 0, DEBUG_PROCESS | CREATE_NEW_CONSOLE, null_mut(), null_mut(), &mut si, &mut pi);
assert!(err != 0);
loop {
let mut de: DEBUG_EVENT = zeroed();
let err = WaitForDebugEvent(&mut de, INFINITE);
assert!(err != 0);
match de.dwDebugEventCode {
EXIT_PROCESS_DEBUG_EVENT => {
if de.dwProcessId == pi.dwProcessId {
break;
}
},
LOAD_DLL_DEBUG_EVENT => {
let handle = de.u.LoadDll().hFile;
println!("{:08X}", handle as usize);
},
_ => {},
}
let err = ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
assert!(err != 0);
}
}
fn main() {
unsafe { foo() }
}
mod wide {
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
pub trait ToWide {
fn to_wide(&self) -> Vec<u16>;
fn to_wide_null(&self) -> Vec<u16>;
}
impl<T> ToWide for T where T: AsRef<OsStr> {
fn to_wide(&self) -> Vec<u16> {
self.as_ref().encode_wide().collect()
}
fn to_wide_null(&self) -> Vec<u16> {
self.as_ref().encode_wide().chain(Some(0)).collect()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment