load a dynamic library crash
FlorentinoJink opened this issue · 1 comments
This my rust code
use libc::{size_t, wchar_t};
use widestring::WideString;
const UTILITIES: &str = "utilities.dll";
const MAX_PATH: usize = 260;
pub fn test() -> Result<size_t, Box<dyn std::error::Error>> {
let mut dll_path = std::env::current_dir().unwrap();
dll_path.push(UTILITIES);
unsafe {
let lib = libloading::Library::new(dll_path)?;
let return_value: libloading::Symbol<
extern "C" fn(*const wchar_t, size_t, *mut wchar_t, size_t) -> size_t,
> = lib.get(b"return_value")?;
let filename = WideString::from("hahah");
let file_size = filename.len();
let file_ptr = filename.as_ptr();
// let mut content: [u16; MAX_PATH] = [0; MAX_PATH];
// let company = &mut content as *mut _ as *mut wchar_t;
let mut company2 = WideString::with_capacity(MAX_PATH).as_mut_ptr();
let mut company = WideString::from("TotototototototototototototototototoT").as_mut_ptr();
let return_size = return_value(file_ptr, file_size, company, 30);
std::ptr::copy_nonoverlapping(company, company2, 30);
println!("company1: {:?}", WideString::from_ptr(company,30));
println!("company2: {:?}", WideString::from_ptr(company2,30));
Ok(1)
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
std::env::set_current_dir(std::env::current_exe()?.parent().unwrap())?;
// let binding = WideString::from("D:\\workspace\\rust_load\\filemaster.exe");
// let name = get_company_sign(binding)?;
// println!("name: {:?}, size: {}", name, name.len());
println!("running");
test()?;
println!("after call test");
Ok(())
}
this my toml
[package]
name = "rust_load"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
libloading = "0.8"
widestring = "1.0.2"
libc = "0.2.139"
and this my windows cpp dll
UTILITIES_API size_t return_value(const wchar_t* name, size_t name_size, wchar_t* company_name, size_t company_size)
{
return 11;
}
I just return a value. when I run it,
as long as I operate on the pointer created using WideString::with_capacity, the dynamic library unloads and crashes, but if I use an array, there is no such issue.
if I load the dynamic library, it crashes.
if not dynamic library, not crash
Why does memory operation crash after loading a dynamic library, and why doesn't it crash when switching to an array?
Try
let mut company2_ws = WideString::with_capacity(MAX_PATH);
let company2 = company2_ws.as_mut_ptr()
instead of
let mut company2 = WideString::with_capacity(MAX_PATH).as_mut_ptr();
and similarly for other instances of this. The way you're doing it right now the WideString
is allocated, the mutable pointer is obtained from it and then the WideString
is freed at the end of the statement, because it itself is not assigned to anything. Then the code goes on to use-after-free this now-dangling pointer.
As a general rule of thumb I would recommend converting to raw pointers at the very last moment (e.g. in a function call arguments), as this way you get most out of the static analyses that Rust provides -- raw pointers are not included into those!)
All that said, these issues are not libloading specifically. I would like to point you at users.rust-lang.org
or a similar forum for questions about use of Rust.
Thanks!