| Crates.io | interceptor-rs |
| lib.rs | interceptor-rs |
| version | 0.1.0 |
| created_at | 2023-03-28 15:18:19.506032+00 |
| updated_at | 2023-03-28 15:18:19.506032+00 |
| description | Interceptor is a lib based on `ptrace` that intercepts and modifies Linux system calls. |
| homepage | https://github.com/avalon1610/interceptor |
| repository | https://github.com/avalon1610/interceptor |
| max_upload_size | |
| id | 823165 |
| size | 50,127 |
Interceptor is a lib based on ptrace that intercepts and modifies Linux system calls.
It currently only supports x86_64 architecture.
Write a function whose signature is same as a syscall, and mark it as #[syscall],
and you are done.
#[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
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.
Some glibc released without libgcc_s.so.1, we removed this dependency using link
script "linker_without_libgcc.wrap".
This parameter is used in syscall like
execve'sconst 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:
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" |
memory is reallocated in interceptor instance, so address changed.
| ptr (*const c_char) | content |
|---|---|
| 0x87654321 | "aaaa\0bbbb\0cccc\0\0" |
you can use helper function [read_ptr_to_ptr] to read content from converted ptr.
and use [write_ptr_to_ptr] to write back.