登录  | 立即注册

游客您好!登录后享受更多精彩

查看: 211|回复: 1

svc hook框架

[复制链接]

171

主题

21

回帖

1106

积分

管理员

积分
1106
发表于 2025-2-16 22:45:34 | 显示全部楼层 |阅读模式
受看雪里所有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);
}

0

主题

203

回帖

170

积分

注册会员

积分
170
发表于 2025-2-17 10:53:52 | 显示全部楼层
慢慢学习中!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|断点社区 |网站地图

GMT+8, 2025-4-11 18:11 , Processed in 0.133647 second(s), 21 queries , Yac On.

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

快速回复 返回顶部 返回列表