一、前言
在前一篇文章中详细介绍了 Android现阶段可以采用的几种反调试方案策略,我们在破解逆向应用的时候,一般现在第一步都回去解决反调试,不然后续步骤无法进行,当然如果你是静态分析的话获取就没必要了。但是有时候必须要借助动态调试方可破解,就需要进行操作了。现阶段反调试策略主要包括以下几种方式:
-
第一、自己附加进程,先占坑,ptrace(PTRACE_TRACEME, 0, 0, 0)!
-
第二、签名校验不可或缺的一个选择,本地校验和服务端校验双管齐下!
-
第三、借助系统api判断应用调试状态和调试属性,最基础的防护!
-
第四、轮训检查android_server调试端口信息和进程信息,防护IDA的一种有效方式!
-
第五、轮训检查自身status中的TracerPid字段值,防止被其他进程附加调试的一种有效方式!
所以本文就来一一讲解如何解决这几种方式的反调试方案。
二、方法总结
这种方式需要采用静态方式分析代码,找到关键方法进行反调试代码功能注释,这种方式可以应对与上面所有的反调试方案,但是对于轮训检查这种方式就不太适合了,为什么?操作过的同学会发现,在去除反调试功能的时候那种痛苦了。所以这种注释代码,个人觉得只适用于以下几种反调试:
第一、自己附加进程
这个可以IDA打开关键so代码,找到这段代码处:ptrace(PTRACE_TRACEME, 0, 0, 0),直接nop掉即可。这个没什么难度,因为就一行代码,说白了就几条arm指令罢了。IDA静态分析so也是无压力的。
第二、签名校验
最后总结了一个比较简单的过滤签名校验的方法:先在Jadx中打开应用之后,全局搜字符串内容:"signatures",这个就可以定位到获取应用签名信息的地方了,然后可以依次跟踪校验的地方了。找到具体地方代码直接注释即可。但是如果服务端交互信息中携带了签名校验,而签名校验又在so中,那么就需要另外操作了,这部分知识点将在后面单独一篇文章详细介绍如何破解。
第三、调用系统api判断当前应用是否处于调试状态
这种方式看到我们实现的逻辑还是比较简单的,直接调用系统的android.os.Debug.isDebuggerConnected()方法和判断当前应用属性:ApplicationInfo.FLAG_DEBUGGABLE,那么可以依然采用全局搜索反编译之后的应用内容,找到这部分内容,然后直接注释代码即可。
第二种:修改IDA通信端口
上面分析完了,直接使用静态方式+注释代码功能解决了之前提到的三种反调试方案。但是还有两种没有解决,下面就会详细介绍一种非常靠谱方便永久的方法。而这部分内容才是本文的重点。首先来看看如何解决之前提到的利用检查IDA调试端口23946这个反调试方案。这个其实思路很简单,因为你检查的端口号是默认的23946,所以我们如果能把这个端口号改成其他值,那么其实就解决了。修改这个端口号,也比较简单:网上有一种方案就是android_server本身支持自定义端口号的,命令很简单:./android_server -p12345;直接加上-p参数即可,注意端口号和参数之间没空格:
有的人说,这方法这么简单,那下面就不介绍了,当然不是,我写文章的目的不是为了简单,而是为了让大家了解更多的知识,宁愿多走弯路,走多条路出来。而且上面的这种方式每次都加-p比较麻烦,我想用另外一种方式去一次性解决问题,同时我更想在这个过程中熟悉一下IDA的使用,使用IDA打开android_server文件,其实他是elf格式的,打开无压力,打开之后使用Shift+12查看字符串内容界面:
找到这三处关键字符串内容,我们可以通过以往运行过android_server之后的提示信息察觉:
找到这三处字符串内容,下面就简单了,一处一处进行修改,双击字符串条目内容:
选中按X键,进行切换:
选择第一个跳转到arm指令处: