请选择 进入手机版 | 继续访问电脑版

玩转Android10源码开发定制(六)修改内核源码绕过反调试检测

[复制链接]
黎平 发表于 2020-12-31 20:24:59 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
一、Android反调试   
  反调试在代码掩护中饰演着非常重要的脚色,虽然不能完全阻止攻击者,但是能加大攻击者的分析时间成本。现在绝大多数Android app都加固了,为了防止App被调试分析,加固功能中添加了各种反调试功能,好比:自己ptrace自己、查抄函数执行时间、读取/proc/$pid/wchan大概/proc/$pid/task/$pid/wchan文件信息判定调试状态、读取/proc/$pid/stat大概/proc/$pid/task/$pid/stat文件信息判定调试状态、读取/proc/$pid/status大概/proc/$pid/task/$pid/status文件检测TracerPid、读取检测调试历程名、检测调试端口等等。网上关于Android 反调试的文章比较多,想相识更多Android反调试检测手段可以看看[https://bbs.pediy.com/thread-223324.htm]中总结的方法。本篇文章我们只讨论读取/proc/$pid/status 文件和/proc/$pid/wchan文件检测app是否处于被调试。
二、读取/proc/$pid检测原理分析
  1.读取/proc/$pid下的status文件检测被调试
   在Android 中调试状态下,linux内核会向/proc/$pid/status大概/proc/$pid/task/$pid/status 中写入历程状态信息。此中TracerPid 字段写入调试该历程的历程的的Pid。此中State字段中写入该历程当前处于的状态,取值如下之一:
  1. R (running)", "S (sleeping)", "D (disk sleep)", "T (stopped)", "t(tracing stop)", "Z (zombie)",  "X (dead)"
复制代码
当State为t (tracing stop)大概T (stopped)的时候,表现正被调试追踪。所以反调试的方法之一就是通过不断轮询读取/proc/$pid/status大概/proc/$pid/task/$pid/status文件检测查抄TracerPid的值大概State的值,如果TracerPid非0说明该历程被调试;如果state值为t (tracing stop)大概T (stopped),说明被调试追踪。如下图所示:
 

      
   2.读取/proc/$pid/stat、/proc/$pid/task/$pid/stat检测被调试
    历程被调试状态下内核会向/proc/$pid/stat、/proc/$pid/task/$pid/stat文件中的第三个字段写入t标识。
        3.读取/proc/$pid/wchan、/proc/$pid/task/$pid/wchan
          wchan文件内容表现显示当历程sleep时,kernel当前运行的函数。若历程被调试,内核会往/proc/$pid/wchan、/proc/$pid/task/$pid/wchan文件中写入ptrace_stop信息。
     三、修改内核
         内核源码中和"二"中相关的信息代码位于内核/fs/proc目次中,如下图所示:

       1.修改State标识值
        该标识写入相关信息位于内核文件/fs/proc/array.c中,如下所示。
原代码内容:
  1. static const char * const task_state_array[] = {  "R (running)",    /*   0 */  "S (sleeping)",    /*   1 */  "D (disk sleep)",  /*   2 */  "T (stopped)",    /*   4 */  "t (tracing stop)",  /*   8 */  "X (dead)",    /*  16 */  "Z (zombie)",    /*  32 */};
复制代码
我们需要把以上内容中的"t (tracing stop)"和"T (stopped)"替换为"S (sleeping)",不管App如何被调试,内核写入的都是正常状态来对抗反调试检测。修改之后的代码如下:
  1. static const char * const task_state_array[] = {  "R (running)",    /*   0 */  "S (sleeping)",    /*   1 */  "D (disk sleep)",  /*   2 */  ///ADD START  //"T (stopped)",    /*   4 */  "S (sleeping)",       /*   4 */  ///ADD END  /*  ///ADD START  //"t (tracing stop)",/*   8 */    */  "S (sleeping)",  /*   8 */  /*  ///ADD END  */  "X (dead)",    /*  16 */  "Z (zombie)",    /*  32 */};
复制代码
 
2.修改TracerPid相关
          该标识写入相关信息位于内核文件/fs/proc/array.c中的task_state函数中,如下所示。

此中tpid就表现当前正在调试的历程Pid,我们将tpid永远修改为0。就可以绕过检测TracerPid。修改之后如下:

3.修改wchan文件相关的信息
    文件/proc/$pid/wchan、/proc/$pid/task/$pid/wchan内核写入相关代码路径位于:\fs\proc\base.c中,如下所示:
  1. #ifdef CONFIG_KALLSYMS/* * Provides a wchan file via kallsyms in a proper one-value-per-file format. * Returns the resolved symbol.  If that fails, simply return the address. */static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,        struct pid *pid, struct task_struct *task){  unsigned long wchan;  char symname[KSYM_NAME_LEN];​  wchan = get_wchan(task);​  if (lookup_symbol_name(wchan, symname) < 0)    if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))      return 0;    else      return seq_printf(m, "%lu", wchan);  else    return seq_printf(m, "%s", symname);}#endif /* CONFIG_KALLSYMS */
复制代码
将以上写入符号名称的地方,修改成过滤符号名称包含trace关键字,然后写入sys_epoll_wait。修改后如下所示:
  1. #ifdef CONFIG_KALLSYMS/* * Provides a wchan file via kallsyms in a proper one-value-per-file format. * Returns the resolved symbol.  If that fails, simply return the address. */static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,        struct pid *pid, struct task_struct *task){  unsigned long wchan;  char symname[KSYM_NAME_LEN];​  wchan = get_wchan(task);​  if (lookup_symbol_name(wchan, symname) < 0)    if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))      return 0;    else      return seq_printf(m, "%lu", wchan);  else{    ///ADD START    if(strstr(symname,"trace")){          return seq_printf(m, "%s","sys_epoll_wait");    }    ///ADD END    return seq_printf(m, "%s", symname);  }}#endif /* CONFIG_KALLSYMS */
复制代码
四、编译刷机
      修改生存之后,在Android源码根目次执行如下下令编译刷机包然后刷机:
  1. source build/envsetup.shbrunch oneplus3-userdebug
复制代码
 
关注公众号,实时获取文章更新:


来源:https://blog.csdn.net/xiaomaNo01/article/details/111967193
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

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

本版积分规则


专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )