Search code examples
winapirustffi

Segfault when calling GetBinaryTypeA


I tried to import the GetBinaryTypeA function:

use std::ffi::CString;

use ::std::os::raw::{c_char, c_ulong};
extern { fn GetBinaryTypeA(s: *const c_char, out: *mut c_ulong) -> i32; }

fn main() {
    let path = "absolute/path/to/bin.exe";

    let cpath = CString::new(path).unwrap();
    let mut out: c_ulong = 0;

    println!("{:?}", cpath);
    unsafe { GetBinaryTypeA(cpath.as_ptr(), out as *mut c_ulong); }
    println!("{:?}", cpath);
}

Output:

error: process didn't exit successfully: `target\debug\bin_deploy.exe` (exit code: 3221225477)
Process finished with exit code -1073741819 (0xC0000005)

If I set an invalid path then it executes successfully and GetLastError() returns 2 ("The system cannot find the file specified"), so it looks like the imported function works.

I received the same error using the kernel32-sys crate. Where else can the error be?


Solution

  • You are casting the value 0 to a pointer. On the vast majority of computers in use today, the pointer with the value 0 is known as NULL. Thus, you are trying to write to the NULL pointer, which causes a crash.

    You want to write to the address of the value:

    &mut out as *mut c_ulong
    

    Which doesn't even need the cast:

    unsafe {
        GetBinaryTypeA(cpath.as_ptr(), &mut out);
    }