From c3bd85c1db2a64d88fa1ed85c6b070a42d046bf1 Mon Sep 17 00:00:00 2001 From: dragon-zhang Date: Sun, 27 Oct 2024 16:24:38 +0800 Subject: [PATCH] add hook --- README.md | 4 -- core/src/common/constants.rs | 5 ++ core/src/syscall/unix/link.rs | 29 +++++++++ core/src/syscall/unix/lseek.rs | 32 ++++++++++ core/src/syscall/unix/mkdir.rs | 30 +++++++++ core/src/syscall/unix/mod.rs | 106 ++++++++++++++------------------ core/src/syscall/unix/rmdir.rs | 27 ++++++++ core/src/syscall/unix/unlink.rs | 27 ++++++++ hook/src/syscall/unix.rs | 24 +++++--- 9 files changed, 211 insertions(+), 73 deletions(-) create mode 100644 core/src/syscall/unix/link.rs create mode 100644 core/src/syscall/unix/lseek.rs create mode 100644 core/src/syscall/unix/mkdir.rs create mode 100644 core/src/syscall/unix/rmdir.rs create mode 100644 core/src/syscall/unix/unlink.rs diff --git a/README.md b/README.md index 3afb5f09..c96f1bcb 100644 --- a/README.md +++ b/README.md @@ -168,10 +168,6 @@ nanosleep hooked - [ ] open - [ ] chdir - [ ] chroot - - [ ] mkdir - - [ ] rmdir - - [ ] link - - [ ] unlink - [ ] readlink - [ ] stat - [ ] dup diff --git a/core/src/common/constants.rs b/core/src/common/constants.rs index 9ceb89d1..b8b5d12e 100644 --- a/core/src/common/constants.rs +++ b/core/src/common/constants.rs @@ -107,8 +107,13 @@ pub enum Syscall { renameat, #[cfg(target_os = "linux")] renameat2, + mkdir, mkdirat, + rmdir, + lseek, openat, + link, + unlink, pthread_cond_timedwait, pthread_mutex_trylock, pthread_mutex_lock, diff --git a/core/src/syscall/unix/link.rs b/core/src/syscall/unix/link.rs new file mode 100644 index 00000000..12fea515 --- /dev/null +++ b/core/src/syscall/unix/link.rs @@ -0,0 +1,29 @@ +use std::ffi::{c_char, c_int}; +use once_cell::sync::Lazy; + +#[must_use] +pub extern "C" fn link( + fn_ptr: Option<&extern "C" fn(*const c_char, *const c_char) -> c_int>, + src: *const c_char, + dst: *const c_char +) -> c_int{ + static CHAIN: Lazy> = Lazy::new(Default::default); + CHAIN.link(fn_ptr, src, dst) +} + +trait LinkSyscall { + extern "C" fn link( + &self, + fn_ptr: Option<&extern "C" fn(*const c_char, *const c_char) -> c_int>, + src: *const c_char, + dst: *const c_char + ) -> c_int; +} + +impl_facade!(LinkSyscallFacade, LinkSyscall, + link(src: *const c_char, dst: *const c_char) -> c_int +); + +impl_raw!(RawLinkSyscall, LinkSyscall, + link(src: *const c_char, dst: *const c_char) -> c_int +); diff --git a/core/src/syscall/unix/lseek.rs b/core/src/syscall/unix/lseek.rs new file mode 100644 index 00000000..1f7374fe --- /dev/null +++ b/core/src/syscall/unix/lseek.rs @@ -0,0 +1,32 @@ +use libc::off_t; +use std::ffi::c_int; +use once_cell::sync::Lazy; + +#[must_use] +pub extern "C" fn lseek( + fn_ptr: Option<&extern "C" fn(c_int, off_t, c_int) -> off_t>, + fd: c_int, + offset: off_t, + whence: c_int, +) -> off_t{ + static CHAIN: Lazy> = Lazy::new(Default::default); + CHAIN.lseek(fn_ptr, fd, offset,whence) +} + +trait LseekSyscall { + extern "C" fn lseek( + &self, + fn_ptr: Option<&extern "C" fn(c_int, off_t, c_int) -> off_t>, + fd: c_int, + offset: off_t, + whence: c_int, + ) -> off_t; +} + +impl_facade!(LseekSyscallFacade, LseekSyscall, + lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t +); + +impl_raw!(RawLseekSyscall, LseekSyscall, + lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t +); diff --git a/core/src/syscall/unix/mkdir.rs b/core/src/syscall/unix/mkdir.rs new file mode 100644 index 00000000..89968b70 --- /dev/null +++ b/core/src/syscall/unix/mkdir.rs @@ -0,0 +1,30 @@ +use libc::mode_t; +use once_cell::sync::Lazy; +use std::ffi::{c_char, c_int}; + +#[must_use] +pub extern "C" fn mkdir( + fn_ptr: Option<&extern "C" fn(*const c_char, mode_t) -> c_int>, + path: *const c_char, + mode: mode_t, +) -> c_int { + static CHAIN: Lazy> = Lazy::new(Default::default); + CHAIN.mkdir(fn_ptr, path, mode) +} + +trait MkdirSyscall { + extern "C" fn mkdir( + &self, + fn_ptr: Option<&extern "C" fn(*const c_char, mode_t) -> c_int>, + path: *const c_char, + mode: mode_t, + ) -> c_int; +} + +impl_facade!(MkdirSyscallFacade, MkdirSyscall, + mkdir(path: *const c_char, mode: mode_t) -> c_int +); + +impl_raw!(RawMkdirSyscall, MkdirSyscall, + mkdir(path: *const c_char, mode: mode_t) -> c_int +); diff --git a/core/src/syscall/unix/mod.rs b/core/src/syscall/unix/mod.rs index b8b21827..261fd129 100644 --- a/core/src/syscall/unix/mod.rs +++ b/core/src/syscall/unix/mod.rs @@ -1,36 +1,13 @@ use std::ffi::c_int; -pub use accept::accept; -#[cfg(target_os = "linux")] -pub use accept4::accept4; -pub use close::close; -pub use connect::connect; -pub use listen::listen; -pub use nanosleep::nanosleep; -pub use poll::poll; -pub use pread::pread; -pub use preadv::preadv; -pub use pthread_cond_timedwait::pthread_cond_timedwait; -pub use pthread_mutex_lock::pthread_mutex_lock; -pub use pthread_mutex_trylock::pthread_mutex_trylock; -pub use pthread_mutex_unlock::pthread_mutex_unlock; -pub use pwrite::pwrite; -pub use pwritev::pwritev; -pub use read::read; -pub use readv::readv; -pub use recv::recv; -pub use recvfrom::recvfrom; -pub use recvmsg::recvmsg; -pub use select::select; -pub use send::send; -pub use sendmsg::sendmsg; -pub use sendto::sendto; -pub use shutdown::shutdown; -pub use sleep::sleep; -pub use socket::socket; -pub use usleep::usleep; -pub use write::write; -pub use writev::writev; +macro_rules! syscall_mod { + ($($mod_name: ident);*) => { + $( + pub use $mod_name::$mod_name; + mod $mod_name; + )* + } +} macro_rules! impl_facade { ( $struct_name:ident, $trait_name: ident, $syscall: ident($($arg: ident : $arg_type: ty),*) -> $result: ty ) => { @@ -543,37 +520,44 @@ macro_rules! impl_raw { } } -mod accept; #[cfg(target_os = "linux")] -mod accept4; -mod close; -mod connect; -mod listen; -mod nanosleep; -mod poll; -mod pread; -mod preadv; -mod pthread_cond_timedwait; -mod pthread_mutex_lock; -mod pthread_mutex_trylock; -mod pthread_mutex_unlock; -mod pwrite; -mod pwritev; -mod read; -mod readv; -mod recv; -mod recvfrom; -mod recvmsg; -mod select; -mod send; -mod sendmsg; -mod sendto; -mod shutdown; -mod sleep; -mod socket; -mod usleep; -mod write; -mod writev; +syscall_mod!(accept4); +syscall_mod!( + accept; + close; + connect; + listen; + nanosleep; + poll; + pread; + preadv; + pthread_cond_timedwait; + pthread_mutex_lock; + pthread_mutex_trylock; + pthread_mutex_unlock; + pwrite; + pwritev; + read; + readv; + recv; + recvfrom; + recvmsg; + select; + send; + sendmsg; + sendto; + shutdown; + sleep; + socket; + usleep; + write; + writev; + mkdir; + rmdir; + lseek; + link; + unlink +); extern "C" { #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks")))] diff --git a/core/src/syscall/unix/rmdir.rs b/core/src/syscall/unix/rmdir.rs new file mode 100644 index 00000000..602a7123 --- /dev/null +++ b/core/src/syscall/unix/rmdir.rs @@ -0,0 +1,27 @@ +use once_cell::sync::Lazy; +use std::ffi::{c_char, c_int}; + +#[must_use] +pub extern "C" fn rmdir( + fn_ptr: Option<&extern "C" fn(*const c_char) -> c_int>, + path: *const c_char, +) -> c_int { + static CHAIN: Lazy> = Lazy::new(Default::default); + CHAIN.rmdir(fn_ptr, path) +} + +trait RmdirSyscall { + extern "C" fn rmdir( + &self, + fn_ptr: Option<&extern "C" fn(*const c_char) -> c_int>, + path: *const c_char, + ) -> c_int; +} + +impl_facade!(RmdirSyscallFacade, RmdirSyscall, + rmdir(path: *const c_char) -> c_int +); + +impl_raw!(RawRmdirSyscall, RmdirSyscall, + rmdir(path: *const c_char) -> c_int +); diff --git a/core/src/syscall/unix/unlink.rs b/core/src/syscall/unix/unlink.rs new file mode 100644 index 00000000..ac96c7ac --- /dev/null +++ b/core/src/syscall/unix/unlink.rs @@ -0,0 +1,27 @@ +use std::ffi::{c_char, c_int}; +use once_cell::sync::Lazy; + +#[must_use] +pub extern "C" fn unlink( + fn_ptr: Option<&extern "C" fn(*const c_char) -> c_int>, + src: *const c_char, +) -> c_int{ + static CHAIN: Lazy> = Lazy::new(Default::default); + CHAIN.unlink(fn_ptr, src) +} + +trait LinkSyscall { + extern "C" fn unlink( + &self, + fn_ptr: Option<&extern "C" fn(*const c_char) -> c_int>, + src: *const c_char + ) -> c_int; +} + +impl_facade!(UnlinkSyscallFacade, LinkSyscall, + unlink(src: *const c_char) -> c_int +); + +impl_raw!(RawUnlinkSyscall, LinkSyscall, + unlink(src: *const c_char) -> c_int +); diff --git a/hook/src/syscall/unix.rs b/hook/src/syscall/unix.rs index ee263d3f..d3f432ab 100644 --- a/hook/src/syscall/unix.rs +++ b/hook/src/syscall/unix.rs @@ -1,8 +1,8 @@ use libc::{ - fd_set, iovec, msghdr, off_t, pthread_cond_t, pthread_mutex_t, size_t, sockaddr, socklen_t, - ssize_t, timespec, timeval, + fd_set, iovec, mode_t, msghdr, off_t, pthread_cond_t, pthread_mutex_t, size_t, sockaddr, + socklen_t, ssize_t, timespec, timeval, }; -use std::ffi::{c_int, c_uint, c_void}; +use std::ffi::{c_char, c_int, c_uint, c_void}; // check https://www.rustwiki.org.cn/en/reference/introduction.html for help information #[allow(unused_macros)] @@ -34,8 +34,6 @@ macro_rules! impl_hook { impl_hook!(SLEEP, sleep(secs: c_uint) -> c_uint); impl_hook!(USLEEP, usleep(microseconds: c_uint) -> c_int); impl_hook!(NANOSLEEP, nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int); -// NOTE: unhook poll due to mio's poller -// impl_hook!(POLL, poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) -> c_int); impl_hook!(SELECT, select(nfds: c_int, readfds: *mut fd_set, writefds: *mut fd_set, errorfds: *mut fd_set, timeout: *mut timeval) -> c_int); impl_hook!(SOCKET, socket(domain: c_int, type_: c_int, protocol: c_int) -> c_int); impl_hook!(CONNECT, connect(fd: c_int, address: *const sockaddr, len: socklen_t) -> c_int); @@ -51,6 +49,7 @@ impl_hook!(ACCEPT4, accept4(fd: c_int, addr: *mut sockaddr, len: *mut socklen_t, impl_hook!(SHUTDOWN, shutdown(fd: c_int, how: c_int) -> c_int); impl_hook!(RECV, recv(fd: c_int, buf: *mut c_void, len: size_t, flags: c_int) -> ssize_t); impl_hook!(RECVFROM, recvfrom(fd: c_int, buf: *mut c_void, len: size_t, flags: c_int, addr: *mut sockaddr, addrlen: *mut socklen_t) -> ssize_t); +impl_hook!(READ, read(fd: c_int, buf: *mut c_void, count: size_t) -> ssize_t); impl_hook!(PREAD, pread(fd: c_int, buf: *mut c_void, count: size_t, offset: off_t) -> ssize_t); impl_hook!(READV, readv(fd: c_int, iov: *const iovec, iovcnt: c_int) -> ssize_t); impl_hook!(PREADV, preadv(fd: c_int, iov: *const iovec, iovcnt: c_int, offset: off_t) -> ssize_t); @@ -62,8 +61,17 @@ impl_hook!(WRITEV, writev(fd: c_int, iov: *const iovec, iovcnt: c_int) -> ssize_ impl_hook!(PWRITEV, pwritev(fd: c_int, iov: *const iovec, iovcnt: c_int, offset: off_t) -> ssize_t); impl_hook!(SENDMSG, sendmsg(fd: c_int, msg: *const msghdr, flags: c_int) -> ssize_t); impl_hook!(PTHREAD_COND_TIMEDWAIT, pthread_cond_timedwait(cond: *mut pthread_cond_t, lock: *mut pthread_mutex_t, abstime: *const timespec) -> c_int); -// NOTE: unhook pthread_mutex_lock due to stack overflow -// impl_hook!(PTHREAD_MUTEX_LOCK, pthread_mutex_lock(lock: *mut pthread_mutex_t) -> c_int); impl_hook!(PTHREAD_MUTEX_TRYLOCK, pthread_mutex_trylock(lock: *mut pthread_mutex_t) -> c_int); -// NOTE: unhook pthread_mutex_unlock due to stack overflow +impl_hook!(MKDIR, mkdir(path: *const c_char, mode: mode_t) -> c_int); +impl_hook!(RMDIR, rmdir(path: *const c_char) -> c_int); +impl_hook!(LSEEK, lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t); +impl_hook!(LINK, link(src: *const c_char, dst: *const c_char) -> c_int); +impl_hook!(UNLINK, unlink(src: *const c_char) -> c_int); + +// NOTE: unhook poll due to mio's poller +// impl_hook!(POLL, poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) -> c_int); + +// NOTE: unhook write/pthread_mutex_lock/pthread_mutex_unlock due to stack overflow or bug +// impl_hook!(WRITE, write(fd: c_int, buf: *const c_void, count: size_t) -> ssize_t); +// impl_hook!(PTHREAD_MUTEX_LOCK, pthread_mutex_lock(lock: *mut pthread_mutex_t) -> c_int); // impl_hook!(PTHREAD_MUTEX_UNLOCK, pthread_mutex_unlock(lock: *mut pthread_mutex_t) -> c_int);