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
|
use bitflags::bitflags;
use windows_kernel_sys::{
base::{CLIENT_ID, HANDLE, KAPC_STATE, OBJECT_ATTRIBUTES, PEPROCESS},
ntoskrnl::{
KeStackAttachProcess,
KeUnstackDetachProcess,
ObDereferenceObject,
ObReferenceObject,
PsGetCurrentProcess,
PsLookupProcessByProcessId,
ZwClose,
ZwOpenProcess,
},
};
use crate::error::{Error, IntoResult};
pub type ProcessId = usize;
#[derive(Clone, Debug)]
pub struct Process {
pub process: PEPROCESS,
}
impl Process {
pub fn as_ptr(&self) -> PEPROCESS { self.process }
pub fn current() -> Self {
let process = unsafe { PsGetCurrentProcess() };
unsafe {
ObReferenceObject(process as _);
}
Self {
process,
}
}
pub fn by_id(process_id: ProcessId) -> Result<Self, Error> {
let mut process = core::ptr::null_mut();
unsafe { PsLookupProcessByProcessId(process_id as _, &mut process) }.into_result()?;
Ok(Self {
process,
})
}
pub fn id(&self) -> ProcessId {
let handle = unsafe { windows_kernel_sys::ntoskrnl::PsGetProcessId(self.process) };
handle as _
}
pub fn attach(&self) -> ProcessAttachment { unsafe { ProcessAttachment::attach(self.process) } }
}
impl Drop for Process {
fn drop(&mut self) {
unsafe {
ObDereferenceObject(self.process as _);
}
}
}
pub struct ProcessAttachment {
process: PEPROCESS,
state: KAPC_STATE,
}
impl ProcessAttachment {
/// # Safety
/// `unsafe`
pub unsafe fn attach(process: PEPROCESS) -> Self {
let mut state: KAPC_STATE = core::mem::zeroed();
ObReferenceObject(process as _);
KeStackAttachProcess(process, &mut state);
Self {
process,
state,
}
}
}
impl Drop for ProcessAttachment {
fn drop(&mut self) {
unsafe {
KeUnstackDetachProcess(&mut self.state);
ObDereferenceObject(self.process as _);
}
}
}
bitflags! {
pub struct ProcessAccess: u32 {
const ALL_ACCESS = windows_kernel_sys::base::PROCESS_ALL_ACCESS;
}
}
pub struct ZwProcess {
pub(crate) handle: HANDLE,
}
impl ZwProcess {
pub fn open(id: ProcessId, access: ProcessAccess) -> Result<Self, Error> {
let mut attrs: OBJECT_ATTRIBUTES = unsafe { core::mem::zeroed() };
attrs.Length = core::mem::size_of::<OBJECT_ATTRIBUTES>() as u32;
let mut client_id = CLIENT_ID {
UniqueProcess: id as _,
UniqueThread: core::ptr::null_mut(),
};
let mut handle = core::ptr::null_mut();
unsafe { ZwOpenProcess(&mut handle, access.bits(), &mut attrs, &mut client_id) }
.into_result()?;
Ok(Self {
handle,
})
}
}
impl Drop for ZwProcess {
fn drop(&mut self) {
unsafe {
ZwClose(self.handle);
}
}
}
|