登录  | 立即注册

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

查看: 80|回复: 1

svc hook框架

[复制链接]

102

主题

10

回帖

607

积分

管理员

积分
607
发表于 6 天前 | 显示全部楼层 |阅读模式
受看雪里所有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无效
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/syscall.h>
  5. #include <pthread.h>
  6. #include <signal.h>
  7. #include <string.h>
  8. #include <stdatomic.h>
  9. // http://aospxref.com/android-13.0.0_r3/s?path=asm/sigcontext.h&project=bionic
  10. #include <asm/sigcontext.h>
  11. #include <setjmp.h>
  12. #if defined(__aarch64__)
  13. #include "syscalls_aarch64.h"
  14. const char *const *syscall_table = &kSyscalls_Aarch64[0];
  15. #elif defined(__x86_64__)
  16. #include "syscalls_x86_64.h"
  17. const char *const *syscall_table = &kSyscalls_x86_64[0];
  18. #endif
  19. __inline__ __attribute__((always_inline))__attribute__ ((visibility ("hidden")))  long my_syscall(long __number, ...);
  20. typedef long (*hook_function_t)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);

  21. #define MAX_SYSCALL_NO 1024

  22. void sigsys_handler(int sig, siginfo_t *info, void *secret);
  23. typedef struct RemoteCaller {
  24. pthread_rwlock_t rwlock_;
  25.     pthread_mutex_t caller_mutex_;
  26.     pthread_cond_t caller_cond_;
  27.     pthread_mutex_t callee_mutex_;
  28.     pthread_cond_t callee_cond_;
  29. atomic_long call_result_;
  30.     atomic_int syscall_no_;
  31.     atomic_bool start_loop_;
  32. _Atomic(struct sigcontext *) call_args_; // 修改为原子指针类型
  33.    atomic_bool signal_received_;
  34.    atomic_bool signal_received_1;
  35.    atomic_bool signal_received_2;
  36.     hook_function_t before_hook_func_;
  37.     hook_function_t after_hook_func_;
  38.     hook_function_t patch_func_;
  39. pthread_barrier_t barrier_;
  40. } RemoteCaller;

  41. _Atomic(RemoteCaller *)* g_remote_caller[MAX_SYSCALL_NO] = {0};

  42. void trace_sys_call(int sysno) {
  43.     printf("===== handle syscall no %d : %s\n", sysno, syscall_table[sysno]);
  44. }

  45. void RemoteCaller_handleSigsys();
  46. void RemoteCaller_start_remote_thread(_Atomic(RemoteCaller *) caller);
  47. /*void RemoteCaller_start_remote_thread(RemoteCaller *caller);*/
  48. long RemoteCaller_remote_syscall( _Atomic(RemoteCaller *) caller, struct sigcontext* sigctx);
  49. //l*long RemoteCaller_remote_syscall( RemoteCaller *caller, struct sigcontext* sigctx);*/
  50. RemoteCaller* RemoteCaller_create(int syscall_no, void *before_hook_func, void *after_hook_func, void *patch_func) {


  51. _Atomic(RemoteCaller *) caller = ATOMIC_VAR_INIT(malloc(sizeof(RemoteCaller)));
  52. if (caller == NULL) {
  53. }


  54.    /* RemoteCaller *caller = (RemoteCaller *) malloc(sizeof(RemoteCaller));
  55.    
  56.   /*  if (caller == NULL) {
  57.         return NULL;
  58.     }*/
  59.     caller->caller_mutex_ = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
  60.     caller->caller_cond_ = (pthread_cond_t) PTHREAD_COND_INITIALIZER;
  61.    
  62.     caller->callee_mutex_ = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
  63.     caller->callee_cond_ = (pthread_cond_t) PTHREAD_COND_INITIALIZER;
  64.     pthread_barrier_init(&caller->barrier_, NULL, 2);
  65.     atomic_init(&caller->call_result_, 0);
  66.     atomic_init(&caller->syscall_no_, syscall_no);
  67.    caller->start_loop_ = false;
  68.   //  caller->start_loop_ = true;
  69.     caller->before_hook_func_ = (hook_function_t) before_hook_func;
  70.     caller->after_hook_func_ = (hook_function_t) after_hook_func;
  71.     caller->patch_func_ = (hook_function_t) patch_func;
  72.     RemoteCaller_handleSigsys();
  73.     RemoteCaller_start_remote_thread(atomic_load(&caller));
  74.     return atomic_load(&caller);
  75. }




  76. RemoteCaller* RemoteCaller_getInstance(int syscall_no) {
  77.     if (syscall_no > MAX_SYSCALL_NO - 1 || syscall_no < 0) {
  78.         printf("syscall_no %d error\n", syscall_no);
  79.         abort();
  80.         return NULL;
  81.     }
  82.     _Atomic(RemoteCaller *) *atomic_caller = &g_remote_caller[syscall_no];
  83.     // 使用原子操作获取g_remote_caller[syscall_no]
  84.     _Atomic(RemoteCaller *) *caller = atomic_load(atomic_caller);
  85.     if (caller == NULL) {
  86.         // 如果不存在,调用RemoteCaller_create创建一个
  87.         caller = RemoteCaller_create(syscall_no, NULL, NULL, NULL);
  88.     }
  89.     return caller;
  90. }
  91. void RemoteCaller_registerSyscall(int syscall_no, void *before_hook_func, void *after_hook_func, void *patch_func) {
  92.     if (syscall_no > MAX_SYSCALL_NO - 1 || syscall_no < 0) {
  93.         printf("syscall_no %d error\n", syscall_no);
  94.         return;
  95.     }
  96. _Atomic(RemoteCaller *) *atomic_caller = &g_remote_caller[syscall_no];
  97.    _Atomic(RemoteCaller *) * old_val = NULL;
  98.     _Atomic(RemoteCaller *) new_val = RemoteCaller_create(syscall_no, before_hook_func, after_hook_func, patch_func);
  99.     atomic_compare_exchange_strong(atomic_caller, &old_val, new_val);

  100.     // If the atomic pointer to RemoteCaller was already set, free the new RemoteCaller object.
  101.     if (old_val != NULL) {
  102.         free(new_val);
  103.     }
  104. }


  105. _Atomic(bool) RemoteCaller_handle_sigsys_ = false;
  106. //bool RemoteCaller_handle_sigsys_ = false;

  107. jmp_buf env;
  108. void sigsys_handler1(int sig, siginfo_t *info, void *secret) {

  109.       


  110.     ucontext_t *ctx = (ucontext_t *) secret;
  111.     struct sigcontext *sigctx = (struct sigcontext *) &ctx->uc_mcontext;
  112.     bool is_handle_syscall = false;
  113. #if defined(__aarch64__)
  114.     is_handle_syscall = *(((uint32_t *) info->si_call_addr) - 1) == 0xd4000001; //01 00 00 d4  svc     #0
  115.     int sysno = sigctx->regs[8];
  116.     unsigned long *presult = (unsigned long *) &sigctx->regs[0];
  117. #else
  118.     printf("unsupport arch\n");
  119. //    exit(0);
  120. #endif
  121.     if (is_handle_syscall) {
  122. _Atomic(RemoteCaller *) caller = RemoteCaller_getInstance(sysno);
  123.         if (caller == NULL) {
  124.             printf("remote caller for syscall %d not found\n", sysno);
  125.         }
  126.         long ret = RemoteCaller_remote_syscall(caller, sigctx);
  127.         *presult = ret;
  128.     }
  129. }


  130. int is_address_valid(void* ptr) {
  131. setjmp(env);
  132. printf("The pointer is invalid.\n");
  133. }
  134. void RemoteCaller_handleSigsys1() {
  135. /*   if (!atomic_load(&RemoteCaller_handle_sigsys_)) {*/
  136.         printf("register SIGSYS start\n");
  137.         struct sigaction act;
  138.         struct sigaction old_act;
  139.         sigemptyset(&act.sa_mask);
  140.         act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_SIGINFO;
  141.         act.sa_sigaction = sigsys_handler;
  142.         sigaction(SIGSYS, &act, &old_act);
  143.         atomic_store(&RemoteCaller_handle_sigsys_, true);
  144.         printf("register SIGSYS end\n");
  145. /*   }*/
  146. }


  147. unsigned long *RemoteCaller_get_syscall_param(struct sigcontext *sigctx, int index) {
  148.     if (index < 0 || index >= 6) return 0;
  149.     unsigned long *regs = NULL;
  150.     unsigned long *sp = NULL;
  151.    
  152. #if defined(__aarch64__)
  153.     regs = (ucontext_t *) &(sigctx->regs[0]);
  154.     sp = (ucontext_t *) sigctx->sp;
  155.     if (index <= 7) {
  156.         // x0 - x7
  157.         return regs[index];
  158.     } else {
  159.         // stack
  160.         return sp[index - 3];
  161.     }
  162. #else
  163.     printf("unsupport arch");
  164. //    exit(0);
  165. #endif
  166. }

  167. void* RemoteCaller_remote_call_thread_function(void *args_ptr) {
  168. //printf(">>>>> handle signal not caused by ebpf\n");
  169. //    RemoteCaller *caller = (RemoteCaller *) args_ptr;
  170. _Atomic(RemoteCaller *) caller = atomic_load((_Atomic(RemoteCaller *) *) &args_ptr);

  171. // 发送信号
  172. atomic_store(&caller->signal_received_2, true);
  173. pthread_cond_signal(&caller->caller_cond_);
  174. pthread_mutex_lock(&caller->callee_mutex_);
  175.     while (atomic_load(&caller->start_loop_)) {
  176.         printf("## RemoteCaller wait call\n");
  177. while (!atomic_load(&caller->signal_received_1)) {
  178.     pthread_cond_wait(&caller->callee_cond_, &caller->callee_mutex_);
  179. }
  180. // 重置信号标志
  181. atomic_store(&caller->signal_received_1, false);
  182. pthread_mutex_unlock(&caller->callee_mutex_);
  183.         printf("## RemoteCaller wait call\n");
  184.     atomic_store(&caller->call_result_, syscall(caller->syscall_no_,
  185.                                RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 0),
  186.                                RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 1),
  187.                 //         0,
  188.                                RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 2),
  189.                                RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 3),
  190.                                RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 4),
  191.                                RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 5),
  192.                                RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 6),
  193.                                RemoteCaller_get_syscall_param(atomic_load(&caller->call_args_), 7)
  194.                                ));

  195.                                  
  196.                                        
  197.                                              trace_sys_call(caller->syscall_no_);
  198.         printf("## RemoteCaller wake call thread\n");
  199. // 发送信号
  200. atomic_store(&caller->signal_received_, true);

  201. pthread_cond_signal(&caller->caller_cond_);

  202.     }
  203.     return NULL;
  204. }



  205. // 使用barrier同步线程

  206. void RemoteCaller_start_remote_thread(_Atomic(RemoteCaller *) caller_atomic) {
  207.     _Atomic(RemoteCaller *) caller = atomic_load(&caller_atomic);
  208.     if (!atomic_load(&caller->start_loop_)) {
  209.         atomic_store(&caller->start_loop_, true);
  210.         printf("start remote thread for syscall no %d\n", caller->syscall_no_);

  211.         pthread_t td;
  212.         int rc = pthread_create(&td, NULL, RemoteCaller_remote_call_thread_function, caller);
  213.         if (rc != 0) {
  214.             printf("Failed to create remote call thread for syscall no %d\n", caller->syscall_no_);
  215.             return;
  216.         }
  217.         pthread_detach(td);
  218. pthread_mutex_lock(&caller->caller_mutex_);
  219.         while (!atomic_load(&caller->signal_received_2)) {
  220.             pthread_cond_wait(&caller->caller_cond_, &caller->caller_mutex_);
  221.             break;
  222.         }

  223.         // 重置信号标志
  224.         atomic_store(&caller->signal_received_2, false);
  225.         pthread_spin_unlock(&caller->caller_mutex_);
  226.         printf("start remote thread for syscall no %d finished\n", caller->syscall_no_);
  227.     }
  228. }

  229. /*void RemoteCaller_start_remote_thread(_Atomic(RemoteCaller *) caller) {

  230.         if (!atomic_load(&caller->start_loop_)) {
  231.         atomic_store(&caller->start_loop_, true);
  232.         printf("start remote thread for syscall no %d\n", caller->syscall_no_);
  233.         
  234.         pthread_t td;
  235.        int rc =
  236.      pthread_create(&td, NULL, RemoteCaller_remote_call_thread_function, caller);
  237.         if (rc != 0) {
  238.             printf("Failed to create remote call thread for syscall no %d\n", caller->syscall_no_);
  239.             return;
  240.         }
  241.         pthread_detach(td);

  242.      
  243.      while (!atomic_load(&caller->signal_received_2)) {
  244.     pthread_cond_wait(&caller->caller_cond_, &caller->caller_mutex_);
  245.     break;
  246. }

  247. // 重置信号标志
  248. atomic_store(&caller->signal_received_2, false);


  249.         printf("start remote thread for syscall no %d finished\n", caller->syscall_no_);
  250.     }
  251. }*/

  252. void RemoteCaller_stop_remote_thread(RemoteCaller *caller) {
  253.     caller->start_loop_ = false;
  254. }

  255. long RemoteCaller_remote_syscall1(_Atomic(RemoteCaller *) caller_atomic, struct sigcontext *sigctx) {
  256. _Atomic(RemoteCaller *) caller = atomic_load(&caller_atomic);
  257.     printf("locked exec remote_syscall\n");
  258.     atomic_store(&caller->call_args_, sigctx);
  259.     printf("wake up remote thread\n");

  260. // 发送信号

  261. atomic_store(&caller->signal_received_1, true);
  262. pthread_cond_signal(&caller->callee_cond_);


  263.     printf("wait remote thread...\n");

  264. pthread_spin_lock(&caller->caller_mutex_);
  265. /*  atomic_init(&caller->signal_received_, false);*/
  266. while (!atomic_load(&caller->signal_received_)) {
  267.     pthread_cond_wait(&caller->caller_cond_, &caller->caller_mutex_);
  268.     break;
  269. }

  270. // 重置信号标志
  271. atomic_store(&caller->signal_received_, false);
  272. pthread_spin_unlock(&caller->caller_mutex_);
  273. // 读取 call_result_
  274. unsigned long ret = atomic_load(&caller->call_result_);

  275. // 写入 call_result_
  276. atomic_store(&caller->call_result_, ret);
  277.     printf("unlocked exec remote_syscall\n");
  278.     return ret;
  279. }

  280. long RemoteCaller_remote_syscall(_Atomic(RemoteCaller *) caller_atomic, struct sigcontext *sigctx) {
  281. _Atomic(RemoteCaller *) caller = atomic_load(&caller_atomic);
  282.     printf("locked exec remote_syscall\n");
  283.     atomic_store(&caller->call_args_, sigctx);
  284.     printf("wake up remote thread\n");

  285. // 发送信号

  286. atomic_store(&caller->signal_received_1, true);
  287. pthread_cond_signal(&caller->callee_cond_);


  288.     printf("wait remote thread...\n");

  289. pthread_spin_lock(&caller->caller_mutex_);
  290. /*  atomic_init(&caller->signal_received_, false);*/
  291. while (!atomic_load(&caller->signal_received_)) {
  292.     pthread_cond_wait(&caller->caller_cond_, &caller->caller_mutex_);
  293.     break;
  294. }

  295. // 重置信号标志
  296. atomic_store(&caller->signal_received_, false);
  297. pthread_spin_unlock(&caller->caller_mutex_);
  298. // 读取 call_result_
  299. unsigned long ret = atomic_load(&caller->call_result_);

  300. // 写入 call_result_
  301. atomic_store(&caller->call_result_, ret);
  302.     printf("unlocked exec remote_syscall\n");
  303.     return ret;
  304. }

  305. #define SECMAGIC 0xdeadbeef

  306. void sigsys_handler(int sig, siginfo_t *info, void *secret) {

  307.       


  308.     ucontext_t *ctx = (ucontext_t *) secret;
  309.     struct sigcontext *sigctx = (struct sigcontext *) &ctx->uc_mcontext;
  310.     bool is_handle_syscall = false;
  311. #if defined(__aarch64__)
  312.     is_handle_syscall = *(((uint32_t *) info->si_call_addr) - 1) == 0xd4000001; //01 00 00 d4  svc     #0
  313.     int sysno = sigctx->regs[8];
  314.     unsigned long *presult = (unsigned long *) &sigctx->regs[0];
  315. #else
  316.     printf("unsupport arch\n");
  317. //    exit(0);
  318. #endif
  319.     if (is_handle_syscall) {
  320.    
  321.         long ret = my_syscall(sysno,
  322.                                        RemoteCaller_get_syscall_param(sigctx, 0),
  323.                                        RemoteCaller_get_syscall_param(sigctx, 1),
  324.                                        RemoteCaller_get_syscall_param(sigctx, 2),
  325.                                        RemoteCaller_get_syscall_param(sigctx, 3),
  326.                                        RemoteCaller_get_syscall_param(sigctx, 4),
  327.                                        RemoteCaller_get_syscall_param(sigctx, 5),
  328.                                        RemoteCaller_get_syscall_param(sigctx, 6),
  329.                                        RemoteCaller_get_syscall_param(sigctx, 7)
  330.                                        );;
  331.         *presult = ret;
  332.     }
  333. }
  334. void RemoteCaller_handleSigsys() {
  335.         printf("register SIGSYS start\n");
  336.         struct sigaction act;
  337.         struct sigaction old_act;
  338.         sigemptyset(&act.sa_mask);
  339.         act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_SIGINFO;
  340.         act.sa_sigaction = sigsys_handler;
  341.         sigaction(SIGSYS, &act, &old_act);
  342.         printf("register SIGSYS end\n");
  343. }



  344. int svc_register_hook1(int signo){
  345.     struct sock_filter filter[] = {
  346.         BPF_STMT(BPF_LD + BPF_W + BPF_ABS,
  347.                 (offsetof(struct seccomp_data, nr))),
  348.         BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, signo, 0, 1),
  349.         BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_TRAP),
  350.         BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW),
  351.     };
  352.     struct sock_fprog prog = {
  353.         .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
  354.         .filter = filter,
  355.     };

  356.     if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
  357.         printf("prctl(NO_NEW_PRIVS)");
  358.         goto failed;
  359.     }
  360.     if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
  361.         printf("prctl(SECCOMP)");
  362.         goto failed;
  363.     }
  364.     return 0;

  365. failed:
  366.     if (errno == EINVAL)
  367.         printf("SECCOMP_FILTER is not available. :(n\n");
  368.     return -1;
  369. }

  370. int svc_register_hook(int signo){
  371.     struct sock_filter filter[] = {
  372.         BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
  373.         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, signo, 0, 2),
  374.      /*   BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, args[6])),
  375.         BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECMAGIC, 0, 1),*/
  376.         BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, instruction_pointer)),
  377.     BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, (uint64_t)&my_syscall+0x20, 0, 1),
  378.         BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
  379.         BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP)
  380.    
  381.     };
  382.     struct sock_fprog prog = {
  383.         .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
  384.         .filter = filter,
  385.     };

  386.     if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
  387.         printf("prctl(NO_NEW_PRIVS)");
  388.         goto failed;
  389.     }
  390.     if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
  391.         printf("prctl(SECCOMP)");
  392.         goto failed;
  393.     }
  394.     return 0;

  395. failed:
  396.     if (errno == EINVAL)
  397.         printf("SECCOMP_FILTER is not available. :(n\n");
  398.     return -1;
  399. }
  400. int svc_hook(int sysno, void *before_hook_func, void *after_hook_func, void *patch_func){
  401. // svc_register_hook(sysno);
  402. /*    RemoteCaller_registerSyscall(sysno, before_hook_func, after_hook_func, patch_func);*/
  403.     RemoteCaller_handleSigsys();
  404.    return svc_register_hook(sysno);
  405. }
复制代码


0

主题

67

回帖

99

积分

注册会员

积分
99
发表于 5 天前 | 显示全部楼层
慢慢学习中!
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-2-22 16:42 , Processed in 0.116947 second(s), 26 queries .

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

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