summaryrefslogtreecommitdiff
path: root/crates/windows-kernel-rs/src/section.rs
diff options
context:
space:
mode:
authorFuwn <[email protected]>2022-01-03 03:20:12 -0800
committerFuwn <[email protected]>2022-01-03 03:20:12 -0800
commit85db2b507f3f69b32811c54a89d9ac7bbbc46121 (patch)
tree2efd66da452f8a6a2cc6c91584c925f237506ddf /crates/windows-kernel-rs/src/section.rs
downloaddriver-85db2b507f3f69b32811c54a89d9ac7bbbc46121.tar.xz
driver-85db2b507f3f69b32811c54a89d9ac7bbbc46121.zip
feat(driver): commit primer
Diffstat (limited to 'crates/windows-kernel-rs/src/section.rs')
-rw-r--r--crates/windows-kernel-rs/src/section.rs163
1 files changed, 163 insertions, 0 deletions
diff --git a/crates/windows-kernel-rs/src/section.rs b/crates/windows-kernel-rs/src/section.rs
new file mode 100644
index 0000000..f80b8b7
--- /dev/null
+++ b/crates/windows-kernel-rs/src/section.rs
@@ -0,0 +1,163 @@
+use bitflags::bitflags;
+use widestring::U16CString;
+use windows_kernel_sys::{
+ base::{HANDLE, LARGE_INTEGER, OBJECT_ATTRIBUTES},
+ ntoskrnl::{ZwClose, ZwMapViewOfSection, ZwOpenSection, ZwUnmapViewOfSection},
+};
+
+use crate::{
+ error::{Error, IntoResult},
+ process::ZwProcess,
+ string::create_unicode_string,
+};
+
+bitflags! {
+ pub struct AllocationFlags: u32 {
+ const RESERVE = windows_kernel_sys::base::MEM_RESERVE;
+ const LARGE_PAGES = windows_kernel_sys::base::MEM_LARGE_PAGES;
+ const TOP_DOWN = windows_kernel_sys::base::MEM_TOP_DOWN;
+ }
+}
+
+bitflags! {
+ pub struct ProtectFlags: u32 {
+ const READ_WRITE = windows_kernel_sys::base::PAGE_READWRITE;
+ }
+}
+
+bitflags! {
+ pub struct SectionAccess: u32 {
+ const EXTEND_SIZE = windows_kernel_sys::base::SECTION_EXTEND_SIZE;
+ const MAP_EXECUTE = windows_kernel_sys::base::SECTION_MAP_EXECUTE;
+ const MAP_READ = windows_kernel_sys::base::SECTION_MAP_READ;
+ const MAP_WRITE = windows_kernel_sys::base::SECTION_MAP_WRITE;
+ const QUERY = windows_kernel_sys::base::SECTION_QUERY;
+ const ALL_ACCESS = windows_kernel_sys::base::SECTION_ALL_ACCESS;
+ }
+}
+
+bitflags! {
+ pub struct ObjectFlags: u32 {
+ const CASE_INSENSITIVE = windows_kernel_sys::base::OBJ_CASE_INSENSITIVE;
+ const KERNEL_HANDLE = windows_kernel_sys::base::OBJ_KERNEL_HANDLE;
+ }
+}
+
+#[repr(i32)]
+pub enum SectionInherit {
+ ViewShare = windows_kernel_sys::base::_SECTION_INHERIT::ViewShare,
+ ViewUnmap = windows_kernel_sys::base::_SECTION_INHERIT::ViewUnmap,
+}
+
+pub enum BaseAddress {
+ Desired(*mut core::ffi::c_void),
+ ZeroBits(usize),
+}
+
+pub struct Section {
+ handle: HANDLE,
+}
+
+unsafe impl Send for Section {}
+unsafe impl Sync for Section {}
+
+impl Section {
+ pub fn open(path: &str, obj_flags: ObjectFlags, access: SectionAccess) -> Result<Self, Error> {
+ let name = U16CString::from_str(path).unwrap();
+ let mut name = create_unicode_string(name.as_slice());
+
+ let mut attrs = OBJECT_ATTRIBUTES {
+ Length: core::mem::size_of::<OBJECT_ATTRIBUTES>() as u32,
+ RootDirectory: core::ptr::null_mut(),
+ ObjectName: &mut name,
+ Attributes: obj_flags.bits(),
+ SecurityDescriptor: core::ptr::null_mut(),
+ SecurityQualityOfService: core::ptr::null_mut(),
+ };
+
+ let mut handle: HANDLE = core::ptr::null_mut();
+
+ unsafe { ZwOpenSection(&mut handle, access.bits(), &mut attrs) }.into_result()?;
+
+ Ok(Self {
+ handle,
+ })
+ }
+
+ pub fn map_view(
+ &mut self,
+ process: ZwProcess,
+ base_address: BaseAddress,
+ commit_size: usize,
+ offset: Option<u64>,
+ view_size: usize,
+ inherit: SectionInherit,
+ allocation: AllocationFlags,
+ protection: ProtectFlags,
+ ) -> Result<SectionView, Error> {
+ let (mut base_address, zero_bits) = match base_address {
+ BaseAddress::Desired(ptr) => (ptr, 0),
+ BaseAddress::ZeroBits(bits) => (core::ptr::null_mut(), bits),
+ };
+
+ let mut offset = offset.map(|value| {
+ let mut offset: LARGE_INTEGER = unsafe { core::mem::zeroed() };
+ offset.QuadPart = value as _;
+ offset
+ });
+
+ let mut size: u64 = view_size as _;
+
+ unsafe {
+ ZwMapViewOfSection(
+ self.handle,
+ process.handle,
+ &mut base_address,
+ zero_bits as _,
+ commit_size as _,
+ match offset {
+ Some(ref mut offset) => offset as _,
+ _ => core::ptr::null_mut(),
+ },
+ &mut size,
+ inherit as _,
+ allocation.bits(),
+ protection.bits(),
+ )
+ }
+ .into_result()?;
+
+ Ok(SectionView {
+ process,
+ address: base_address,
+ })
+ }
+}
+
+impl Drop for Section {
+ fn drop(&mut self) {
+ unsafe {
+ ZwClose(self.handle);
+ }
+ }
+}
+
+pub struct SectionView {
+ process: ZwProcess,
+ address: *mut core::ffi::c_void,
+}
+
+unsafe impl Send for SectionView {}
+unsafe impl Sync for SectionView {}
+
+impl SectionView {
+ pub fn address(&self) -> *mut core::ffi::c_void { self.address }
+}
+
+impl Drop for SectionView {
+ fn drop(&mut self) {
+ unsafe {
+ ZwUnmapViewOfSection(self.process.handle, self.address);
+ }
+ }
+}