|
受看雪里所有svc hook思路启发
根据返回指针地址判断是否为劫持svc
仅支持aarch64
仿inlinehook框架结构
不依靠root
代码ai写的 自己优化
可以直接编译使用
seccomp bpf有意思的玩法:
后门
提前设置一个svc被劫持
,保存自己syscall的地址为instruction_pointer
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, instruction_pointer)),
当执行该syscall时seccomp进入自己的函数
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP)
或者触发
SECCOMP_RET_KILL
该kill只传递信号 不能被捕捉到svc 所以一切针对svc的hook无效- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/syscall.h>
- #include <pthread.h>
- #include <signal.h>
- #include <string.h>
- #include <stdatomic.h>
- // http://aospxref.com/android-13.0.0_r3/s?path=asm/sigcontext.h&project=bionic
- #include <asm/sigcontext.h>
- #include <setjmp.h>
- #if defined(__aarch64__)
- #include "syscalls_aarch64.h"
- const char *const *syscall_table = &kSyscalls_Aarch64[0];
- #elif defined(__x86_64__)
- #include "syscalls_x86_64.h"
- const char *const *syscall_table = &kSyscalls_x86_64[0];
- #endif
- __inline__ __attribute__((always_inline))__attribute__ ((visibility ("hidden"))) long my_syscall(long __number, ...);
- typedef long (*hook_function_t)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
- #define MAX_SYSCALL_NO 1024
- void sigsys_handler(int sig, siginfo_t *info, void *secret);
- typedef struct RemoteCaller {
- pthread_rwlock_t rwlock_;
- pthread_mutex_t caller_mutex_;
- pthread_cond_t caller_cond_;
- pthread_mutex_t callee_mutex_;
- pthread_cond_t callee_cond_;
- atomic_long call_result_;
- atomic_int syscall_no_;
- atomic_bool start_loop_;
- _Atomic(struct sigcontext *) call_args_; // 修改为原子指针类型
- atomic_bool signal_received_;
- atomic_bool signal_received_1;
- atomic_bool signal_received_2;
- hook_function_t before_hook_func_;
- hook_function_t after_hook_func_;
- hook_function_t patch_func_;
- pthread_barrier_t barrier_;
- } RemoteCaller;
- _Atomic(RemoteCaller *)* g_remote_caller[MAX_SYSCALL_NO] = {0};
- void trace_sys_call(int sysno) {
- printf("===== handle syscall no %d : %s\n", sysno, syscall_table[sysno]);
- }
- void RemoteCaller_handleSigsys();
- void RemoteCaller_start_remote_thread(_Atomic(RemoteCaller *) caller);
- /*void RemoteCaller_start_remote_thread(RemoteCaller *caller);*/
- long RemoteCaller_remote_syscall( _Atomic(RemoteCaller *) caller, struct sigcontext* sigctx);
- //l*long RemoteCaller_remote_syscall( RemoteCaller *caller, struct sigcontext* sigctx);*/
- RemoteCaller* RemoteCaller_create(int syscall_no, void *before_hook_func, void *after_hook_func, void *patch_func) {
- _Atomic(RemoteCaller *) caller = ATOMIC_VAR_INIT(malloc(sizeof(RemoteCaller)));
- if (caller == NULL) {
- }
- /* RemoteCaller *caller = (RemoteCaller *) malloc(sizeof(RemoteCaller));
-
- /* if (caller == NULL) {
- return NULL;
- }*/
- caller->caller_mutex_ = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
- caller->caller_cond_ = (pthread_cond_t) PTHREAD_COND_INITIALIZER;
-
- caller->callee_mutex_ = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
- caller->callee_cond_ = (pthread_cond_t) PTHREAD_COND_INITIALIZER;
- pthread_barrier_init(&caller->barrier_, NULL, 2);
- atomic_init(&caller->call_result_, 0);
- atomic_init(&caller->syscall_no_, syscall_no);
- caller->start_loop_ = false;
- // caller->start_loop_ = true;
- caller->before_hook_func_ = (hook_function_t) before_hook_func;
- caller->after_hook_func_ = (hook_function_t) after_hook_func;
- caller->patch_func_ = (hook_function_t) patch_func;
- RemoteCaller_handleSigsys();
- RemoteCaller_start_remote_thread(atomic_load(&caller));
- return atomic_load(&caller);
- }
- RemoteCaller* RemoteCaller_getInstance(int syscall_no) {
- if (syscall_no > MAX_SYSCALL_NO - 1 || syscall_no < 0) {
- printf("syscall_no %d error\n", syscall_no);
- abort();
- return NULL;
- }
- _Atomic(RemoteCaller *) *atomic_caller = &g_remote_caller[syscall_no];
- // 使用原子操作获取g_remote_caller[syscall_no]
- _Atomic(RemoteCaller *) *caller = atomic_load(atomic_caller);
- if (caller == NULL) {
- // 如果不存在,调用RemoteCaller_create创建一个
- caller = RemoteCaller_create(syscall_no, NULL, NULL, NULL);
- }
- return caller;
- }
- void RemoteCaller_registerSyscall(int syscall_no, void *before_hook_func, void *after_hook_func, void *patch_func) {
- if (syscall_no > MAX_SYSCALL_NO - 1 || syscall_no < 0) {
- printf("syscall_no %d error\n", syscall_no);
- return;
- }
- _Atomic(RemoteCaller *) *atomic_caller = &g_remote_caller[syscall_no];
- _Atomic(RemoteCaller *) * old_val = NULL;
- _Atomic(RemoteCaller *) new_val = RemoteCaller_create(syscall_no, before_hook_func, after_hook_func, patch_func);
- atomic_compare_exchange_strong(atomic_caller, &old_val, new_val);
- // If the atomic pointer to RemoteCaller was already set, free the new RemoteCaller object.
- if (old_val != NULL) {
- free(new_val);
- }
- }
- _Atomic(bool) RemoteCaller_handle_sigsys_ = false;
- //bool RemoteCaller_handle_sigsys_ = false;
- jmp_buf env;
- void sigsys_handler1(int sig, siginfo_t *info, void *secret) {
-
-
- ucontext_t *ctx = (ucontext_t *) secret;
- struct sigcontext *sigctx = (struct sigcontext *) &ctx->uc_mcontext;
- bool is_handle_syscall = false;
- #if defined(__aarch64__)
- is_handle_syscall = *(((uint32_t *) info->si_call_addr) - 1) == 0xd4000001; //01 00 00 d4 svc #0
- int sysno = sigctx->regs[8];
- unsigned long *presult = (unsigned long *) &sigctx->regs[0];
- #else
- printf("unsupport arch\n");
- // exit(0);
- #endif
- if (is_handle_syscall) {
- _Atomic(RemoteCaller *) caller = RemoteCaller_getInstance(sysno);
- if (caller == NULL) {
- printf("remote caller for syscall %d not found\n", sysno);
- }
- long ret = RemoteCaller_remote_syscall(caller, sigctx);
- *presult = ret;
- }
- }
- int is_address_valid(void* ptr) {
- setjmp(env);
- printf("The pointer is invalid.\n");
- }
- void RemoteCaller_handleSigsys1() {
- /* if (!atomic_load(&RemoteCaller_handle_sigsys_)) {*/
- printf("register SIGSYS start\n");
- struct sigaction act;
- struct sigaction old_act;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_SIGINFO;
- act.sa_sigaction = sigsys_handler;
- sigaction(SIGSYS, &act, &old_act);
- atomic_store(&RemoteCaller_handle_sigsys_, true);
- printf("register SIGSYS end\n");
- /* }*/
- }
- unsigned long *RemoteCaller_get_syscall_param(struct sigcontext *sigctx, int index) {
- if (index < 0 || index >= 6) return 0;
- unsigned long *regs = NULL;
- unsigned long *sp = NULL;
-
- #if defined(__aarch64__)
- regs = (ucontext_t *) &(sigctx->regs[0]);
- sp = (ucontext_t *) sigctx->sp;
- if (index <= 7) {
- // x0 - x7
- return regs[index];
- } else {
- // stack
- return sp[index - 3];
- }
- #else
- printf("unsupport arch");
- // exit(0);
- #endif
- }
- void* RemoteCaller_remote_call_thread_function(void *args_ptr) {
- //printf(">>>>> handle signal not caused by ebpf\n");
- // RemoteCaller *caller = (RemoteCaller *) args_ptr;
- _Atomic(RemoteCaller *) caller = atomic_load((_Atomic(RemoteCaller *) *) &args_ptr);
- // 发送信号
- atomic_store(&caller->signal_received_2, true);
- pthread_cond_signal(&caller->caller_cond_);
- pthread_mutex_lock(&caller->callee_mutex_);
- while (atomic_load(&caller->start_loop_)) {
- printf("## RemoteCaller wait call\n");
- while (!atomic_load(&caller->signal_received_1)) {
- pthread_cond_wait(&caller->callee_cond_, &caller->callee_mutex_);
- }
- // 重置信号标志
- atomic_store(&caller->signal_received_1, false);
- pthread_mutex_unlock(&caller->callee_mutex_);
- printf("## RemoteCaller wait call\n");
- atomic_store(&caller->call_result_, syscall(caller->syscall_no_,
- RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 0),
- RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 1),
- // 0,
- RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 2),
- RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 3),
- RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 4),
- RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 5),
- RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 6),
- RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 7)
- ));
-
-
- trace_sys_call(caller->syscall_no_);
- printf("## RemoteCaller wake call thread\n");
- // 发送信号
- atomic_store(&caller->signal_received_, true);
- pthread_cond_signal(&caller->caller_cond_);
- }
- return NULL;
- }
- // 使用barrier同步线程
- void RemoteCaller_start_remote_thread(_Atomic(RemoteCaller *) caller_atomic) {
- _Atomic(RemoteCaller *) caller = atomic_load(&caller_atomic);
- if (!atomic_load(&caller->start_loop_)) {
- atomic_store(&caller->start_loop_, true);
- printf("start remote thread for syscall no %d\n", caller->syscall_no_);
- pthread_t td;
- int rc = pthread_create(&td, NULL, RemoteCaller_remote_call_thread_function, caller);
- if (rc != 0) {
- printf("Failed to create remote call thread for syscall no %d\n", caller->syscall_no_);
- return;
- }
- pthread_detach(td);
- pthread_mutex_lock(&caller->caller_mutex_);
- while (!atomic_load(&caller->signal_received_2)) {
- pthread_cond_wait(&caller->caller_cond_, &caller->caller_mutex_);
- break;
- }
- // 重置信号标志
- atomic_store(&caller->signal_received_2, false);
- pthread_spin_unlock(&caller->caller_mutex_);
- printf("start remote thread for syscall no %d finished\n", caller->syscall_no_);
- }
- }
- /*void RemoteCaller_start_remote_thread(_Atomic(RemoteCaller *) caller) {
-
- if (!atomic_load(&caller->start_loop_)) {
- atomic_store(&caller->start_loop_, true);
- printf("start remote thread for syscall no %d\n", caller->syscall_no_);
-
- pthread_t td;
- int rc =
- pthread_create(&td, NULL, RemoteCaller_remote_call_thread_function, caller);
- if (rc != 0) {
- printf("Failed to create remote call thread for syscall no %d\n", caller->syscall_no_);
- return;
- }
- pthread_detach(td);
-
- while (!atomic_load(&caller->signal_received_2)) {
- pthread_cond_wait(&caller->caller_cond_, &caller->caller_mutex_);
- break;
- }
- // 重置信号标志
- atomic_store(&caller->signal_received_2, false);
- printf("start remote thread for syscall no %d finished\n", caller->syscall_no_);
- }
- }*/
- void RemoteCaller_stop_remote_thread(RemoteCaller *caller) {
- caller->start_loop_ = false;
- }
- long RemoteCaller_remote_syscall1(_Atomic(RemoteCaller *) caller_atomic, struct sigcontext *sigctx) {
- _Atomic(RemoteCaller *) caller = atomic_load(&caller_atomic);
- printf("locked exec remote_syscall\n");
- atomic_store(&caller->call_args_, sigctx);
- printf("wake up remote thread\n");
- // 发送信号
- atomic_store(&caller->signal_received_1, true);
- pthread_cond_signal(&caller->callee_cond_);
- printf("wait remote thread...\n");
- pthread_spin_lock(&caller->caller_mutex_);
- /* atomic_init(&caller->signal_received_, false);*/
- while (!atomic_load(&caller->signal_received_)) {
- pthread_cond_wait(&caller->caller_cond_, &caller->caller_mutex_);
- break;
- }
- // 重置信号标志
- atomic_store(&caller->signal_received_, false);
- pthread_spin_unlock(&caller->caller_mutex_);
- // 读取 call_result_
- unsigned long ret = atomic_load(&caller->call_result_);
- // 写入 call_result_
- atomic_store(&caller->call_result_, ret);
- printf("unlocked exec remote_syscall\n");
- return ret;
- }
- long RemoteCaller_remote_syscall(_Atomic(RemoteCaller *) caller_atomic, struct sigcontext *sigctx) {
- _Atomic(RemoteCaller *) caller = atomic_load(&caller_atomic);
- printf("locked exec remote_syscall\n");
- atomic_store(&caller->call_args_, sigctx);
- printf("wake up remote thread\n");
- // 发送信号
- atomic_store(&caller->signal_received_1, true);
- pthread_cond_signal(&caller->callee_cond_);
- printf("wait remote thread...\n");
- pthread_spin_lock(&caller->caller_mutex_);
- /* atomic_init(&caller->signal_received_, false);*/
- while (!atomic_load(&caller->signal_received_)) {
- pthread_cond_wait(&caller->caller_cond_, &caller->caller_mutex_);
- break;
- }
- // 重置信号标志
- atomic_store(&caller->signal_received_, false);
- pthread_spin_unlock(&caller->caller_mutex_);
- // 读取 call_result_
- unsigned long ret = atomic_load(&caller->call_result_);
- // 写入 call_result_
- atomic_store(&caller->call_result_, ret);
- printf("unlocked exec remote_syscall\n");
- return ret;
- }
- #define SECMAGIC 0xdeadbeef
- void sigsys_handler(int sig, siginfo_t *info, void *secret) {
-
-
- ucontext_t *ctx = (ucontext_t *) secret;
- struct sigcontext *sigctx = (struct sigcontext *) &ctx->uc_mcontext;
- bool is_handle_syscall = false;
- #if defined(__aarch64__)
- is_handle_syscall = *(((uint32_t *) info->si_call_addr) - 1) == 0xd4000001; //01 00 00 d4 svc #0
- int sysno = sigctx->regs[8];
- unsigned long *presult = (unsigned long *) &sigctx->regs[0];
- #else
- printf("unsupport arch\n");
- // exit(0);
- #endif
- if (is_handle_syscall) {
-
- long ret = my_syscall(sysno,
- RemoteCaller_get_syscall_param(sigctx, 0),
- RemoteCaller_get_syscall_param(sigctx, 1),
- RemoteCaller_get_syscall_param(sigctx, 2),
- RemoteCaller_get_syscall_param(sigctx, 3),
- RemoteCaller_get_syscall_param(sigctx, 4),
- RemoteCaller_get_syscall_param(sigctx, 5),
- RemoteCaller_get_syscall_param(sigctx, 6),
- RemoteCaller_get_syscall_param(sigctx, 7)
- );;
- *presult = ret;
- }
- }
- void RemoteCaller_handleSigsys() {
- printf("register SIGSYS start\n");
- struct sigaction act;
- struct sigaction old_act;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_SIGINFO;
- act.sa_sigaction = sigsys_handler;
- sigaction(SIGSYS, &act, &old_act);
- printf("register SIGSYS end\n");
- }
-
- int svc_register_hook1(int signo){
- struct sock_filter filter[] = {
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS,
- (offsetof(struct seccomp_data, nr))),
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, signo, 0, 1),
- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_TRAP),
- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW),
- };
- struct sock_fprog prog = {
- .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
- .filter = filter,
- };
- if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
- printf("prctl(NO_NEW_PRIVS)");
- goto failed;
- }
- if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
- printf("prctl(SECCOMP)");
- goto failed;
- }
- return 0;
- failed:
- if (errno == EINVAL)
- printf("SECCOMP_FILTER is not available. :(n\n");
- return -1;
- }
- int svc_register_hook(int signo){
- struct sock_filter filter[] = {
- BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
- BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, signo, 0, 2),
- /* BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, args[6])),
- BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECMAGIC, 0, 1),*/
- BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, instruction_pointer)),
- BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, (uint64_t)&my_syscall+0x20, 0, 1),
- BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
- BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP)
-
- };
- struct sock_fprog prog = {
- .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
- .filter = filter,
- };
- if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
- printf("prctl(NO_NEW_PRIVS)");
- goto failed;
- }
- if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
- printf("prctl(SECCOMP)");
- goto failed;
- }
- return 0;
- failed:
- if (errno == EINVAL)
- printf("SECCOMP_FILTER is not available. :(n\n");
- return -1;
- }
- int svc_hook(int sysno, void *before_hook_func, void *after_hook_func, void *patch_func){
- // svc_register_hook(sysno);
- /* RemoteCaller_registerSyscall(sysno, before_hook_func, after_hook_func, patch_func);*/
- RemoteCaller_handleSigsys();
- return svc_register_hook(sysno);
- }
复制代码
|
|