interceptor

Interceptor is a lib based on ptrace that intercepts and modifies Linux system calls. It currently only supports x86_64 architecture.

Usage

Write a function whose signature is same as a syscall, and mark it as #[syscall], and you are done.

```rust

[syscall]

fn openat(dfd: i32, mut filename: *const c_char, flags: i32, mode: i32) -> i32 { // do something before syscall, logging, changing arguments, etc.

let ret = real!(dfd, filename, flags, mode);

// do something after syscall, modifing return value..

} ``` See more detail in examples

Extra Info

Memory in target

We use "LD_PRELOAD" trick to insert a so into target process to malloc extra memory needed when modified a pointer argument which has larger length.

Remove dependency libgcc_s.so.1

Some glibc released without libgcc_s.so.1, we removed this dependency using link script "linkerwithoutlibgcc.wrap".

special handling of parameter "*const *const c_char"

This parameter is used in syscall like execve's const char *const argv[].

We treat *const *const c_char as *const c_char for convenience. That's say, original pointer to pointer has been converted to pointer's content after content. For example:

original

this ptr's address is inside target process, can not be used directly.

| ptr (const *const c_char) | ptr to ptr (const c_char) | content | | --- | --- | --- | | 0x12345678 | 0x11111111 | "aaaa\0" | | | 0x22222222 | "bbbb\0" | | | 0x33333333 | "cccc\0" | | | 0x44444444 | "\0" |

after converted

memory is reallocated in interceptor instance, so address changed.

| ptr (*const c_char) | content | | --- | --- | | 0x87654321 | "aaaa\0bbbb\0cccc\0\0" |

usage

you can use helper function [read_ptr_to_ptr] to read content from converted ptr. and use [write_ptr_to_ptr] to write back.