removed local-only 'utils' dependency
- switched to the ´widestring´ crate for u16string support - moved the error handling code from the utils crate to here.
This commit is contained in:
parent
c5f7a98382
commit
e9363700df
|
@ -7,8 +7,12 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
winapi = {version = "0.3.9" , features = ["libloaderapi", "dbghelp", "ntdef", "processthreadsapi"] }
|
winapi = {version = "0.3.9" , features = ["libloaderapi", "dbghelp", "ntdef", "processthreadsapi", "winerror", "errhandlingapi", "winuser"] }
|
||||||
utils = { path = "../utils", features = ["win32-error"]}
|
widestring = "1.0.2"
|
||||||
lazy_static = "1.0.0"
|
lazy_static = "1.0.0"
|
||||||
thiserror = "1.0.0"
|
thiserror = "1.0.0"
|
||||||
log = "0.4.0"
|
log = "0.4.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
test-log = "0.2"
|
||||||
|
env_logger = "*"
|
34
src/lib.rs
34
src/lib.rs
|
@ -11,7 +11,6 @@ use std::{
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use log::error;
|
use log::error;
|
||||||
use utils::{string::ToWide, win32::Win32Error};
|
|
||||||
use winapi::{
|
use winapi::{
|
||||||
shared::ntdef::{HANDLE, ULONG},
|
shared::ntdef::{HANDLE, ULONG},
|
||||||
um::{
|
um::{
|
||||||
|
@ -32,8 +31,8 @@ pub mod error {
|
||||||
ImageHelpError(#[from] ImageHelpError),
|
ImageHelpError(#[from] ImageHelpError),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
NullError(#[from] NulError),
|
NullError(#[from] NulError),
|
||||||
#[error(transparent)]
|
#[error("win32 Error Code {0}")]
|
||||||
Win32Error(#[from] utils::win32::error::Win32Error),
|
Win32Error(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
@ -41,6 +40,22 @@ pub mod error {
|
||||||
#[error("Module could not be found")]
|
#[error("Module could not be found")]
|
||||||
ModuleNotFound,
|
ModuleNotFound,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
pub(crate) fn last_error() -> Self {
|
||||||
|
Self::Win32Error(unsafe { winapi::um::errhandlingapi::GetLastError() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn true_or_last_error<F>(f: F) -> Result<(), Error>
|
||||||
|
where
|
||||||
|
F: FnOnce() -> bool,
|
||||||
|
{
|
||||||
|
match f() {
|
||||||
|
true => Ok(()),
|
||||||
|
false => Err(Error::last_error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ImageHelp {
|
pub struct ImageHelp {
|
||||||
|
@ -92,14 +107,14 @@ impl ImageHelp {
|
||||||
) -> Result<*const u8, error::Error> {
|
) -> Result<*const u8, error::Error> {
|
||||||
let process_handle = self.process_handle.read().unwrap();
|
let process_handle = self.process_handle.read().unwrap();
|
||||||
|
|
||||||
let module_name_w = module_name.to_wide_null();
|
let module_name_w = widestring::U16CString::from_str(module_name).expect("unexpected null");
|
||||||
|
|
||||||
let module_handle = unsafe {
|
let module_handle = unsafe {
|
||||||
let handle = LoadLibraryW(module_name_w.as_ptr());
|
let handle = LoadLibraryW(module_name_w.as_ptr());
|
||||||
|
|
||||||
if handle == std::ptr::null_mut() {
|
if handle == std::ptr::null_mut() {
|
||||||
error!("Module handle {} is NULL.", module_name);
|
error!("Module handle {} is NULL.", module_name);
|
||||||
Err(error::ImageHelpError::ModuleNotFound)
|
Err(error::Error::last_error())
|
||||||
} else {
|
} else {
|
||||||
Ok(handle)
|
Ok(handle)
|
||||||
}
|
}
|
||||||
|
@ -121,7 +136,7 @@ impl ImageHelp {
|
||||||
|
|
||||||
log::debug!("SymLoadModuleExW..");
|
log::debug!("SymLoadModuleExW..");
|
||||||
|
|
||||||
match utils::win32::error::true_or_last_error(|| unsafe {
|
match error::true_or_last_error(|| unsafe {
|
||||||
dbghelp::SymLoadModuleExW(
|
dbghelp::SymLoadModuleExW(
|
||||||
GetCurrentProcess(),
|
GetCurrentProcess(),
|
||||||
null_mut(),
|
null_mut(),
|
||||||
|
@ -134,7 +149,7 @@ impl ImageHelp {
|
||||||
) != 0
|
) != 0
|
||||||
}) {
|
}) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(Win32Error { error_code: 0 }) => {
|
Err(error::Error::Win32Error(0)) => {
|
||||||
log::debug!("Symbols already loaded.");
|
log::debug!("Symbols already loaded.");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -146,12 +161,13 @@ impl ImageHelp {
|
||||||
unsafe { std::mem::MaybeUninit::<dbghelp::SYMBOL_INFOW>::zeroed().assume_init() };
|
unsafe { std::mem::MaybeUninit::<dbghelp::SYMBOL_INFOW>::zeroed().assume_init() };
|
||||||
sym_info.SizeOfStruct = std::mem::size_of::<dbghelp::SYMBOL_INFOW>() as ULONG;
|
sym_info.SizeOfStruct = std::mem::size_of::<dbghelp::SYMBOL_INFOW>() as ULONG;
|
||||||
|
|
||||||
let symbol_name_utf16 = function_name.to_wide_null();
|
let symbol_name_utf16 =
|
||||||
|
widestring::U16CString::from_str(function_name).expect("unexpected null char");
|
||||||
sym_info.MaxNameLen = 255;
|
sym_info.MaxNameLen = 255;
|
||||||
|
|
||||||
log::debug!("SymFromNameW..");
|
log::debug!("SymFromNameW..");
|
||||||
|
|
||||||
utils::win32::error::true_or_last_error(|| unsafe {
|
error::true_or_last_error(|| unsafe {
|
||||||
dbghelp::SymFromNameW(*process_handle, symbol_name_utf16.as_ptr(), &mut sym_info)
|
dbghelp::SymFromNameW(*process_handle, symbol_name_utf16.as_ptr(), &mut sym_info)
|
||||||
!= 0
|
!= 0
|
||||||
})?;
|
})?;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test_log::test]
|
||||||
fn find_message_box_procaddress() {
|
fn find_message_box_procaddress() {
|
||||||
let messagebox = ImageHelp::get()
|
let messagebox = ImageHelp::get()
|
||||||
.find_function("User32.dll", "MessageBoxA")
|
.find_function("User32.dll", "MessageBoxA")
|
||||||
|
|
Loading…
Reference in a new issue