Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can Redhook (or other project) hook into Rust code? #6

Open
vi opened this issue Apr 9, 2016 · 2 comments
Open

Can Redhook (or other project) hook into Rust code? #6

vi opened this issue Apr 9, 2016 · 2 comments

Comments

@vi
Copy link

vi commented Apr 9, 2016

If something is compiled with -C prefer-dynamic, can, for example, <std::fs::File as std::io::Write>::write be instrumented by LD_PRELOAD to inject failures?

@geofft
Copy link
Owner

geofft commented Apr 9, 2016

Looks like the answer is yes, if you're willing to dig out the mangled name, and of course if the Rust compiler version is the same (since there's no stable ABI). If I cargo new --bin hello and cargo new p, edit p/Cargo.toml to make it a dylib and depend on libc, and then put the following in p/src/lib.rs:

#![allow(bad_style)]

extern crate libc;

use std::fmt::Arguments;
use std::mem::transmute;
use libc::{c_char, c_void};

#[link(name="dl")]
extern {
    fn dlsym(handle: *const c_void, symbol: *const c_char) -> *const c_void;
}

const RTLD_NEXT: *const c_void = -1isize as *const c_void;

#[no_mangle]
pub unsafe fn _ZN2io5stdio6_print20h47445faa595ef503E6gE(args: Arguments) {
    let ptr: unsafe extern fn(args: Arguments) =
        transmute(dlsym(RTLD_NEXT, b"_ZN2io5stdio6_print20h47445faa595ef503E6gE\0".as_ptr() as *const _));
    ptr(args);
    ptr(args);
}

then I can build both with -C prefer-dynamic as follows:

titan:~/src/rust/t/p geofft$ cargo rustc -- -C prefer-dynamic
   Compiling libc v0.2.9
   Compiling p v0.1.0 (file:///home/geofft/src/rust/t/p)
titan:~/src/rust/t/p geofft$ cd ../hello
titan:~/src/rust/t/hello geofft$ cargo rustc -- -C prefer-dynamic
   Compiling hello v0.1.0 (file:///home/geofft/src/rust/t/hello)
titan:~/src/rust/t/hello geofft$ LD_PRELOAD=../p/target/debug/libp.so target/debug/hello 
Hello, world!
Hello, world!

The difference with what redhook does already is that this is a pub unsafe fn, not a pub unsafe extern fn. I don't think there's a good way to programmatically derive the mangled name from the actual one, especially because the crate's name is not part of it and the crate's random ID is. If it's still useful for you with this restriction, I'm happy to add something to the syntax to let you drop the extern from redhook's generated code.

@vi
Copy link
Author

vi commented Apr 10, 2016

I was just curious.

When Rust's stable ABI land and there be libstd in distros like today's libc, will Redhook extend its scope to also cover hooking into Rust?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants