memflow_win32_ffi/win32/
kernel.rs1use memflow_ffi::mem::phys_mem::CloneablePhysicalMemoryObj;
2use memflow_ffi::util::*;
3use memflow_win32::kernel::Win32Version;
4use memflow_win32::win32::{kernel, Win32ProcessInfo, Win32VirtualTranslate};
5
6use memflow::mem::{
7 cache::{CachedMemoryAccess, CachedVirtualTranslate, TimedCacheValidator},
8 CloneablePhysicalMemory, DirectTranslate, VirtualDMA,
9};
10
11use memflow::iter::FnExtend;
12use memflow::process::PID;
13use memflow::types::{size, Address, PageType};
14
15use super::process::Win32Process;
16use crate::kernel::start_block::StartBlock;
17
18use std::ffi::CStr;
19use std::os::raw::c_char;
20use std::time::Duration;
21
22pub(crate) type FFIMemory =
23 CachedMemoryAccess<'static, Box<dyn CloneablePhysicalMemory>, TimedCacheValidator>;
24pub(crate) type FFIVirtualTranslate = CachedVirtualTranslate<DirectTranslate, TimedCacheValidator>;
25
26pub(crate) type FFIVirtualMemory =
27 VirtualDMA<FFIMemory, FFIVirtualTranslate, Win32VirtualTranslate>;
28
29pub type Kernel = kernel::Kernel<FFIMemory, FFIVirtualTranslate>;
30
31#[no_mangle]
40pub unsafe extern "C" fn kernel_build(
41 mem: &'static mut CloneablePhysicalMemoryObj,
42) -> Option<&'static mut Kernel> {
43 let mem: Box<dyn CloneablePhysicalMemory> = Box::from_raw(*Box::from_raw(mem));
44 kernel::Kernel::builder(mem)
45 .build_default_caches()
46 .build()
47 .map_err(inspect_err)
48 .ok()
49 .map(to_heap)
50}
51
52#[no_mangle]
63pub unsafe extern "C" fn kernel_build_custom(
64 mem: &'static mut CloneablePhysicalMemoryObj,
65 page_cache_time_ms: u64,
66 page_cache_flags: PageType,
67 page_cache_size_kb: usize,
68 vat_cache_time_ms: u64,
69 vat_cache_entries: usize,
70) -> Option<&'static mut Kernel> {
71 let mem: Box<dyn CloneablePhysicalMemory> = Box::from_raw(*Box::from_raw(mem));
72 kernel::Kernel::builder(mem)
73 .build_page_cache(move |connector, arch| {
74 CachedMemoryAccess::builder(connector)
75 .arch(arch)
76 .validator(TimedCacheValidator::new(
77 Duration::from_millis(page_cache_time_ms).into(),
78 ))
79 .page_type_mask(page_cache_flags)
80 .cache_size(size::kb(page_cache_size_kb))
81 .build()
82 .unwrap()
83 })
84 .build_vat_cache(move |vat, arch| {
85 CachedVirtualTranslate::builder(vat)
86 .arch(arch)
87 .validator(TimedCacheValidator::new(
88 Duration::from_millis(vat_cache_time_ms).into(),
89 ))
90 .entries(vat_cache_entries)
91 .build()
92 .unwrap()
93 })
94 .build()
95 .map_err(inspect_err)
96 .ok()
97 .map(to_heap)
98}
99
100#[no_mangle]
101pub extern "C" fn kernel_clone(kernel: &Kernel) -> &'static mut Kernel {
102 Box::leak(Box::new((*kernel).clone()))
103}
104
105#[no_mangle]
113pub unsafe extern "C" fn kernel_free(kernel: &'static mut Kernel) {
114 let _ = Box::from_raw(kernel);
115}
116
117#[no_mangle]
126pub unsafe extern "C" fn kernel_destroy(
127 kernel: &'static mut Kernel,
128) -> &'static mut CloneablePhysicalMemoryObj {
129 let kernel = Box::from_raw(kernel);
130 Box::leak(Box::new(Box::leak(kernel.destroy().destroy())))
131}
132
133#[no_mangle]
134pub extern "C" fn kernel_start_block(kernel: &Kernel) -> StartBlock {
135 kernel.kernel_info.start_block.into()
136}
137
138#[no_mangle]
139pub extern "C" fn kernel_winver(kernel: &Kernel) -> Win32Version {
140 kernel.kernel_info.kernel_winver.mask_build_number()
141}
142
143#[no_mangle]
144pub extern "C" fn kernel_winver_unmasked(kernel: &Kernel) -> Win32Version {
145 kernel.kernel_info.kernel_winver
146}
147
148#[no_mangle]
154pub unsafe extern "C" fn kernel_eprocess_list(
155 kernel: &'static mut Kernel,
156 buffer: *mut Address,
157 max_size: usize,
158) -> usize {
159 let mut ret = 0;
160
161 let buffer = std::slice::from_raw_parts_mut(buffer, max_size);
162
163 let mut extend_fn = FnExtend::new(|addr| {
164 if ret < max_size {
165 buffer[ret] = addr;
166 ret += 1;
167 }
168 });
169
170 kernel
171 .eprocess_list_extend(&mut extend_fn)
172 .map_err(inspect_err)
173 .ok()
174 .map(|_| ret)
175 .unwrap_or_default()
176}
177
178#[no_mangle]
187pub unsafe extern "C" fn kernel_process_info_list(
188 kernel: &'static mut Kernel,
189 buffer: *mut &'static mut Win32ProcessInfo,
190 max_size: usize,
191) -> usize {
192 let mut ret = 0;
193
194 let buffer = std::slice::from_raw_parts_mut(buffer, max_size);
195
196 let mut extend_fn = FnExtend::new(|info| {
197 if ret < max_size {
198 buffer[ret] = Box::leak(Box::new(info));
199 ret += 1;
200 }
201 });
202
203 kernel
204 .process_info_list_extend(&mut extend_fn)
205 .map_err(inspect_err)
206 .ok()
207 .map(|_| ret)
208 .unwrap_or_default()
209}
210
211#[no_mangle]
214pub extern "C" fn kernel_kernel_process_info(
215 kernel: &'static mut Kernel,
216) -> Option<&'static mut Win32ProcessInfo> {
217 kernel
218 .kernel_process_info()
219 .map_err(inspect_err)
220 .ok()
221 .map(to_heap)
222}
223
224#[no_mangle]
225pub extern "C" fn kernel_process_info_from_eprocess(
226 kernel: &'static mut Kernel,
227 eprocess: Address,
228) -> Option<&'static mut Win32ProcessInfo> {
229 kernel
230 .process_info_from_eprocess(eprocess)
231 .map_err(inspect_err)
232 .ok()
233 .map(to_heap)
234}
235
236#[no_mangle]
242pub unsafe extern "C" fn kernel_process_info(
243 kernel: &'static mut Kernel,
244 name: *const c_char,
245) -> Option<&'static mut Win32ProcessInfo> {
246 let name = CStr::from_ptr(name).to_string_lossy();
247 kernel
248 .process_info(&name)
249 .map_err(inspect_err)
250 .ok()
251 .map(to_heap)
252}
253
254#[no_mangle]
255pub extern "C" fn kernel_process_info_pid(
256 kernel: &'static mut Kernel,
257 pid: PID,
258) -> Option<&'static mut Win32ProcessInfo> {
259 kernel
260 .process_info_pid(pid)
261 .map_err(inspect_err)
262 .ok()
263 .map(to_heap)
264}
265
266#[no_mangle]
279pub unsafe extern "C" fn kernel_into_process(
280 kernel: &'static mut Kernel,
281 name: *const c_char,
282) -> Option<&'static mut Win32Process> {
283 let kernel = Box::from_raw(kernel);
284 let name = CStr::from_ptr(name).to_string_lossy();
285 kernel
286 .into_process(&name)
287 .map_err(inspect_err)
288 .ok()
289 .map(to_heap)
290}
291
292#[no_mangle]
301pub unsafe extern "C" fn kernel_into_process_pid(
302 kernel: &'static mut Kernel,
303 pid: PID,
304) -> Option<&'static mut Win32Process> {
305 let kernel = Box::from_raw(kernel);
306 kernel
307 .into_process_pid(pid)
308 .map_err(inspect_err)
309 .ok()
310 .map(to_heap)
311}
312
313#[no_mangle]
322pub unsafe extern "C" fn kernel_into_kernel_process(
323 kernel: &'static mut Kernel,
324) -> Option<&'static mut Win32Process> {
325 let kernel = Box::from_raw(kernel);
326 kernel
327 .into_kernel_process()
328 .map_err(inspect_err)
329 .ok()
330 .map(to_heap)
331}