Crate rhook[][src]

Hook libc functions with an easy API

Usage

1- Import the trait RunHook

2- Create an Command with Command::new and add hooks to it via add_hook and add_hooks methods

3- Confirm the hooks with set_hooks method this step is necessary

3.1- Hooks are closures that takes no input and return an option of the libc function as output.

If the closure return None that is equivalent to returning Some(original_function(args)) in other words it will run and use the original function output

Inside the closure you have access to the libc function input + some imports from std (see src/scaffold.rs)

4- Now you can carry on with the usual Command methods (output, spawn,status,..)

Tricks:

The closure used for hooks have acess to many things: (imported by https://github.com/sigmaSd/Rhook/blob/master/src/scaffold.rs)

  • closure input (which is the libc function input)

  • closure output (which is the libc function output)

  • The original function with the following name original_$libcfn this is useful in particular to avoid recursion

  • Some varaibles to make coding easier: transmute ManuallyDrop CString and a static mut COUNTER

  • You can find the input/output of a function by looking it up here libc

Example

Say you want to limit the bandwidth of a program

Usually downloading calls libc::recv function

So our goal is to throttle it with a simple sleep

To do that with this crate: (taking speedtest program as an example)

1- Look up its doc’s here recv to see what the function’s input/output is

2- use this crate

use rhook::{RunHook, Hook};

std::process::Command::new("speedtest").add_hook(Hook::recv(stringify!(||{
  std::thread::sleep(std::time::Duration::from_millis(10));
  // since we're not doing any modification to the output you can just return None here
  Some(original_recv(socket, buf, len, flags))
}))).set_hooks().unwrap().spawn();

Thats it! Note that you have acess inside the closure to the original function denoted by the prefix original_ + the function name

Couple of points:

  • If you take ownership of an input value inside of the closure, be sure to use ManuallyDrop so you don’t free it

Check out the examples for more info

Enums

Hook

libc hooks enum

Traits

RunHook

Specify libc hooks for a Command