svc-hook is a system call hook mechanism for ARM64. It is designed to be low performance overhead, independent of the target source code, without relying on kernel features. It utilizes binary rewriting, replacing every svc
instruction with a b
instruction in the loaded target binary code before the main function starts.
- 1,000 times faster than
ptrace
- No need for target source code
- Works without relying on kernel features
svc-hook supports ARM64 Linux, Android, FreeBSD, and NetBSD.
Note that NetBSD support is not upstreamed yet. See: PR#29.
svc-hook has no external dependencies.
To build libsvchook.so
, run the following command in the root directory on an
ARM64 system:
make
If you are building on x86_64 or another host architecture, provide an ARM64
cross compiler via the CC
variable:
make CC=aarch64-linux-gnu-gcc
# or with clang
make CC=aarch64-linux-gnu-clang
To build a simple hook application libsvchook_basic.so
, use:
make -C apps/basic
You need to set two environment variables:
LIBSVCHOOK
: Path to the hook application e.g.,apps/basic/libsvchook_basic.so
LD_PRELOAD
: Path tolibsvchook.so
LIBSVCHOOK=./apps/basic/libsvchook_basic.so LD_PRELOAD=./libsvchook.so [target]
Replace [target]
with the binary whose system calls you wish to hook.
LIBSVCHOOK=./apps/basic/libsvchook_basic.so LD_PRELOAD=./libsvchook.so /bin/ls
output from __hook_init: we can do some init work here
output from hook_function: syscall number 56
output from hook_function: syscall number 56
output from hook_function: syscall number 79
output from hook_function: syscall number 63
output from hook_function: syscall number 63
output from hook_function: syscall number 57
output from hook_function: syscall number 56
output from hook_function: syscall number 56
output from hook_function: syscall number 56
output from hook_function: syscall number 56
output from hook_function: syscall number 56
output from hook_function: syscall number 56
output from hook_function: syscall number 29
output from hook_function: syscall number 29
output from hook_function: syscall number 56
output from hook_function: syscall number 79
output from hook_function: syscall number 61
output from hook_function: syscall number 61
output from hook_function: syscall number 57
output from hook_function: syscall number 79
output from hook_function: syscall number 64
Documentation LICENSE Makefile README.md apps libsvchook.so main.c main.o
output from hook_function: syscall number 57
svc-hook has four stages during initialization:
- It records the addresses of
svc
instructions in the target code and computes the range ab
instruction can branch to (frompc - 0x8000000
topc + 0x7fffffc
). - It instantiates a custom trampoline code for each
svc
instruction. The recorded addresses are embedded in the custom trampoline code. - It rewrites every
svc
instruction to ab
instruction that branches to the trampoline. - It loads the hook application specified by the
LIBSVCHOOK
environment variable.
When the target process executes a system call, it branches to the trampoline, which saves the CPU context and calls the hook function defined in the hook application. After executing the hook function, it restores the CPU context and returns to the instruction following the original svc
instruction.
- My blog post (ja): An initial introduction to svc-hook.
- Supplemental Documentation: Supplemental documentation for svc-hook experimental results.
svc-hook is released under the Apache license version 2.0.