From db6d99b5c225f30e2dcf42c8bc3d0dae3c1dd4db Mon Sep 17 00:00:00 2001 From: ssrlive <30760636+ssrlive@users.noreply.github.com> Date: Wed, 2 Oct 2024 21:36:33 +0800 Subject: [PATCH] dynamic load function pointer with libloading crate --- src/fn_holder.rs | 51 ++++++++---------------------------------------- 1 file changed, 8 insertions(+), 43 deletions(-) diff --git a/src/fn_holder.rs b/src/fn_holder.rs index 1f038ae..bf7654f 100644 --- a/src/fn_holder.rs +++ b/src/fn_holder.rs @@ -1,50 +1,19 @@ -use std::ffi::CString; -use windows_sys::{ - core::PCSTR, - Win32::{ - Foundation::{FreeLibrary, FARPROC, HMODULE}, - System::LibraryLoader::{GetProcAddress, LoadLibraryA}, - }, -}; - -pub trait FnCast: Sized { - unsafe fn from_untyped(f: unsafe extern "system" fn() -> isize) -> Self; -} +pub trait FnCast: Sized + Copy {} pub struct FnHolder { - lib: HMODULE, + _lib: ::libloading::Library, pub func: F, } unsafe impl Send for FnHolder {} unsafe impl Sync for FnHolder {} -impl Drop for FnHolder { - fn drop(&mut self) { - if !self.lib.is_null() { - unsafe { FreeLibrary(self.lib) }; - } - } -} - pub fn load_function(module_name: &str, function_name: &str) -> Option> { unsafe { - let module_name_cstr = CString::new(module_name).ok()?; - let function_name_cstr = CString::new(function_name).ok()?; - - let lib = LoadLibraryA(module_name_cstr.as_ptr() as PCSTR); - if lib.is_null() { - return None; - } - - let func_opt: FARPROC = GetProcAddress(lib, function_name_cstr.as_ptr() as PCSTR); - let Some(func0) = func_opt else { - FreeLibrary(lib); - return None; - }; - let func = F::from_untyped(func0); - - Some(FnHolder { lib, func }) + let function_name_cstr = std::ffi::CString::new(function_name).ok()?; + let _lib = ::libloading::Library::new(module_name).ok()?; + let func: F = _lib.get(function_name_cstr.to_bytes()).map(|sym| *sym).ok()?; + Some(FnHolder { _lib, func }) } } @@ -53,11 +22,7 @@ macro_rules! define_fn_dynamic_load { ($fn_type:ident, $fn_signature:ty, $static_var:ident, $load_fn:ident, $module_name:expr, $fn_name:expr) => { pub type $fn_type = $fn_signature; - impl $crate::fn_holder::FnCast for $fn_type { - unsafe fn from_untyped(f: unsafe extern "system" fn() -> isize) -> Self { - std::mem::transmute(f) - } - } + impl $crate::fn_holder::FnCast for $fn_type {} #[allow(non_upper_case_globals)] static $static_var: std::sync::OnceLock>> = @@ -83,5 +48,5 @@ define_fn_dynamic_load!( "bcryptprimitives.dll", "ProcessPrng" ); -let func = get_fn_process_prng().ok_or("Failed to load function SetInterfaceDnsSettings")?; +let func = get_fn_process_prng().ok_or("Failed to load function ProcessPrng")?; */