Android for arm上的so注入(inject)和挂钩(hook)

Posted Mark_YPQ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android for arm上的so注入(inject)和挂钩(hook)相关的知识,希望对你有一定的参考价值。

对于Android for arm上的so注入(inject)和挂钩(hook),网上已有牛人给出了代码-libinject(http://bbs.pediy.com/showthread.php?t=141355)。由于实现中的ptrace函数是依赖于平台的,所以不经改动只能用于arm平台。本文将之扩展了一下,使它能够通用于android的x86和arm平台。Arm平台部分基本重用了libinject中的代码,其中因为汇编不好移植且容易出错,所以把shellcode.s用ptrace_call替换掉了,另外保留了mmap,用来传字符串参数,当然也可以通过栈来传,但栈里和其它东西混一起,一弄不好就会隔儿了,所以还是保险点好。最后注意设备要root。

首先创建目录及文件:

jni
    inject.c
    Android.mk
    Application.mk

inject.c:

[cpp]  view plain  copy  print ?
  1. #include <stdio.h>    
  2. #include <stdlib.h>    
  3. #include <asm/user.h>    
  4. #include <asm/ptrace.h>    
  5. #include <sys/ptrace.h>    
  6. #include <sys/wait.h>    
  7. #include <sys/mman.h>    
  8. #include <dlfcn.h>    
  9. #include <dirent.h>    
  10. #include <unistd.h>    
  11. #include <string.h>    
  12. #include <elf.h>    
  13. #include <android/log.h>    
  14.     
  15. #if defined(__i386__)    
  16. #define pt_regs         user_regs_struct    
  17. #endif    
  18.     
  19. #define ENABLE_DEBUG 1    
  20.     
  21. #if ENABLE_DEBUG    
  22. #define  LOG_TAG "INJECT"    
  23. #define  LOGD(fmt, args...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, fmt, ##args)    
  24. #define DEBUG_PRINT(format,args...) \\    
  25.     LOGD(format, ##args)    
  26. #else    
  27. #define DEBUG_PRINT(format,args...)    
  28. #endif    
  29.     
  30. #define CPSR_T_MASK     ( 1u << 5 )    
  31.     
  32. const char *libc_path = "/system/lib/libc.so";    
  33. const char *linker_path = "/system/bin/linker";    
  34.     
  35. int ptrace_readdata(pid_t pid,  uint8_t *src, uint8_t *buf, size_t size)    
  36.     
  37.     uint32_t i, j, remain;    
  38.     uint8_t *laddr;    
  39.     
  40.     union u     
  41.         long val;    
  42.         char chars[sizeof(long)];    
  43.      d;    
  44.     
  45.     j = size / 4;    
  46.     remain = size % 4;    
  47.     
  48.     laddr = buf;    
  49.     
  50.     for (i = 0; i < j; i ++)     
  51.         d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0);    
  52.         memcpy(laddr, d.chars, 4);    
  53.         src += 4;    
  54.         laddr += 4;    
  55.         
  56.     
  57.     if (remain > 0)     
  58.         d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0);    
  59.         memcpy(laddr, d.chars, remain);    
  60.         
  61.     
  62.     return 0;    
  63.     
  64.     
  65. int ptrace_writedata(pid_t pid, uint8_t *dest, uint8_t *data, size_t size)    
  66.     
  67.     uint32_t i, j, remain;    
  68.     uint8_t *laddr;    
  69.     
  70.     union u     
  71.         long val;    
  72.         char chars[sizeof(long)];    
  73.      d;    
  74.     
  75.     j = size / 4;    
  76.     remain = size % 4;    
  77.     
  78.     laddr = data;    
  79.     
  80.     for (i = 0; i < j; i ++)     
  81.         memcpy(d.chars, laddr, 4);    
  82.         ptrace(PTRACE_POKETEXT, pid, dest, d.val);    
  83.     
  84.         dest  += 4;    
  85.         laddr += 4;    
  86.         
  87.     
  88.     if (remain > 0)     
  89.         d.val = ptrace(PTRACE_PEEKTEXT, pid, dest, 0);    
  90.         for (i = 0; i < remain; i ++)     
  91.             d.chars[i] = *laddr ++;    
  92.             
  93.     
  94.         ptrace(PTRACE_POKETEXT, pid, dest, d.val);    
  95.         
  96.     
  97.     return 0;    
  98.     
  99.     
  100. #if defined(__arm__)    
  101. int ptrace_call(pid_t pid, uint32_t addr, long *params, uint32_t num_params, struct pt_regs* regs)    
  102.     
  103.     uint32_t i;    
  104.     for (i = 0; i < num_params && i < 4; i ++)     
  105.         regs->uregs[i] = params[i];    
  106.         
  107.     
  108.     //    
  109.     // push remained params onto stack    
  110.     //    
  111.     if (i < num_params)     
  112.         regs->ARM_sp -= (num_params - i) * sizeof(long) ;    
  113.         ptrace_writedata(pid, (void *)regs->ARM_sp, (uint8_t *)&params[i], (num_params - i) * sizeof(long));    
  114.         
  115.     
  116.     regs->ARM_pc = addr;    
  117.     if (regs->ARM_pc & 1)     
  118.         /* thumb */    
  119.         regs->ARM_pc &= (~1u);    
  120.         regs->ARM_cpsr |= CPSR_T_MASK;    
  121.      else     
  122.         /* arm */    
  123.         regs->ARM_cpsr &= ~CPSR_T_MASK;    
  124.         
  125.     
  126.     regs->ARM_lr = 0;        
  127.     
  128.     if (ptrace_setregs(pid, regs) == -1     
  129.             || ptrace_continue(pid) == -1)     
  130.         printf("error\\n");    
  131.         return -1;    
  132.         
  133.     
  134.     int stat = 0;  
  135.     waitpid(pid, &stat, WUNTRACED);  
  136.     while (stat != 0xb7f)   
  137.         if (ptrace_continue(pid) == -1)   
  138.             printf("error\\n");  
  139.             return -1;  
  140.           
  141.         waitpid(pid, &stat, WUNTRACED);  
  142.       
  143.     
  144.     return 0;    
  145.     
  146.     
  147. #elif defined(__i386__)    
  148. long ptrace_call(pid_t pid, uint32_t addr, long *params, uint32_t num_params, struct user_regs_struct * regs)    
  149.     
  150.     regs->esp -= (num_params) * sizeof(long) ;    
  151.     ptrace_writedata(pid, (void *)regs->esp, (uint8_t *)params, (num_params) * sizeof(long));    
  152.     
  153. Android进程注入

    在 Qt Creator 中启动应用程序之前,如何将我在 Qt for Android 中的 .so 文件复制到 android-build/libs/arm64-v8a 中

    Android 逆向Android 进程注入工具开发 ( Visual Studio 开发 Android NDK 应用 | VS 自带的 Android 平台应用创建与配置 )

    android注入so怎么使用

    x86的库和arm的.o文件能链接吗

    Android 逆向Android 进程注入工具开发 ( SO 进程注入环境及 root 权限获取 | 进程注入时序分析 )