From b4caa2e593aac27d4dd8db6e687c122466c2b2db Mon Sep 17 00:00:00 2001 From: KiraCoding <38864051+KiraCoding@users.noreply.github.com> Date: Wed, 4 Sep 2024 21:36:25 +0200 Subject: [PATCH] wip --- src/base.rs | 13 +++++++++---- src/program.rs | 42 ++++++++++++++++++++++++++++++------------ src/section.rs | 4 ++-- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/base.rs b/src/base.rs index 3d0db2d..1b61623 100644 --- a/src/base.rs +++ b/src/base.rs @@ -14,13 +14,13 @@ impl Base { pub fn program() -> Self { let raw_base = unsafe { GetModuleHandleW(PCWSTR::null()).unwrap_unchecked().0.cast() }; - // SAFETY: todo!() + // SAFETY: `raw_base` is a valid and non-null. unsafe { Self::new_unchecked(raw_base) } } #[inline] - pub fn as_ptr(&self) -> *const u8 { - self.ptr.as_ptr() + pub fn as_ptr(&self) -> NonNull { + self.ptr } #[inline] @@ -28,8 +28,13 @@ impl Base { unsafe { self.ptr.add(count) } } + /// Creates a new `Base`. + /// + /// # Safety + /// + /// `ptr` must be non-null. pub(crate) unsafe fn new_unchecked(ptr: *mut u8) -> Self { - // SAFETY: todo!() + // SAFETY: Caller ensures that `ptr` is non-null. let ptr = unsafe { NonNull::new_unchecked(ptr) }; Self { ptr } diff --git a/src/program.rs b/src/program.rs index 51f7fc0..f4919c8 100644 --- a/src/program.rs +++ b/src/program.rs @@ -44,15 +44,15 @@ impl Program { #[inline] pub fn as_slice(&self) -> &[u8] { // SAFETY: todo!() - unsafe { from_raw_parts(self.base.as_ptr(), self.len) } + unsafe { from_raw_parts(self.base.as_ptr().as_ptr(), self.len) } } /// Returns `true` if the program contains the byte pattern. - /// + /// /// # Examples /// ``` /// use inka::program; - /// + /// /// let result = program().contains(&[0]); /// assert!(result); /// ``` @@ -71,15 +71,33 @@ impl Program { /// Returns the pointer of the first byte that matches the byte pattern. /// /// Returns [`None`] if the pattern doesn’t match. - /// + /// /// # Examples /// ``` /// use inka::program; - /// - /// program().find(&[0]); + /// + /// let data = &[ + /// 0x7c, 0x73, 0xe1, 0x3d, + /// 0x1a, 0x7d, 0xb3, 0x00, + /// 0xd2, 0x6c, 0x61, 0xf9, + /// 0x5f, 0x00, 0xf1, 0x10, + /// 0x80, 0x5e, 0x5f, 0xbf, + /// ]; + /// + /// let pattern = &[ + /// 0x7c, 0x73, 0xe1, 0x3d, + /// 0x1a, 0x7d, 0xb3, 0x00, + /// 0xd2, + /// ]; + /// + /// let ptr = program() + /// .find(pattern) + /// .unwrap(); + /// + /// assert_eq!(data.as_ptr(), ptr.as_ptr()); /// ``` pub fn find(&self, pattern: &[u8]) -> Option> { - debug_assert!(pattern.len() >= 1); + assert!(pattern.len() >= 1); self.as_slice() .par_windows(pattern.len()) @@ -88,17 +106,17 @@ impl Program { } /// Returns the pointer of the first byte of the last match of the pattern. - /// + /// /// Returns [`None`] if the pattern doesn’t match. - /// + /// /// # Examples /// ``` /// use inka::program; - /// + /// /// program().rfind(&[0]); /// ``` pub fn rfind(&self, pattern: &[u8]) -> Option> { - debug_assert!(pattern.len() >= 1); + assert!(pattern.len() >= 1); self.as_slice() .par_windows(pattern.len()) @@ -109,7 +127,7 @@ impl Program { fn init() -> Self { let base = Base::program(); - let dos_header = base.as_ptr() as *const IMAGE_DOS_HEADER; + let dos_header = base.as_ptr().as_ptr() as *const IMAGE_DOS_HEADER; let nt_headers64: &IMAGE_NT_HEADERS64 = unsafe { &*(base.add((*dos_header).e_lfanew as usize).as_ptr().cast()) }; diff --git a/src/section.rs b/src/section.rs index 0a544a1..894c64e 100644 --- a/src/section.rs +++ b/src/section.rs @@ -1,7 +1,7 @@ use crate::Base; +use core::ops::Index; use core::ptr::NonNull; use core::slice::{from_raw_parts, SliceIndex}; -use core::ops::Index; use rayon::iter::IndexedParallelIterator; use rayon::slice::ParallelSlice; @@ -34,7 +34,7 @@ impl Section { #[inline] pub fn as_slice(&self) -> &[u8] { - unsafe { from_raw_parts(self.base.as_ptr(), self.len) } + unsafe { from_raw_parts(self.base.as_ptr().as_ptr(), self.len) } } pub fn contains(&self, pattern: &[u8]) -> bool {