阅读更多
一、前言
在之前介绍了很多破解相关的文章,在这个过程中我们难免会遇到一些反调试策略,当时只是简单的介绍了如何去解决反调试,其实在去年我已经介绍了一篇关于Android中的安全逆向防护之战的文章:Android安全逆向防护解析;那么这篇文章就来详细总结一下,现阶段比较流行的几种反调试解决方案。

二、反调试策略方案
第一种:先占坑,自己附加
代码非常简单,在so中加上这行代码即可:ptrace(PTRACE_TRACEME, 0, 0, 0);

其中PTRACE_TRACEME代表:本进程被其父进程所跟踪。其父进程应该希望跟踪子进程,一般一个进程只能被附加一次,我们在破解调试的时候都会附加需要调试应用的进程,如果我们先占坑,父进程附加自己,那么后面在附加调试就会失败。加上这段代码我们运行之后看一下效果:

我们在进行破解动态调试的时候都知道附加进程的status文件中的TracerPid字段就是被调试的进程pid,这里我们运行程序之后,查看进程对应的status文件,发现TracerPid值就是进程的父进程pid值。那么后面如果有进程在想附加调试就是会失败的。这种方式启动一定的调试作用,但是不是绝对安全的。关于解决这种反调试方案后面再说。

第二种:签名校验
其实签名校验,准备来说不算是反调试方案,但是也是一种安全防护策略,就在这里提一下了,而签名校验一般现在有很多用途,用意在于防止二次打包,一般方案有两种:
  • 直接在本地做防护,如果发现签名不一致直接退出应用
  • 将签名信息携带请求参数中参与加密,服务端进行签名校验,失败就返回错误数据即可
而这两种方式也都不是最安全的防护,因为只要有签名校验的逻辑,在本地都可以进行过滤掉。而在之前的好几篇文章中都介绍了如何过滤这种签名校验的方法,不了解的同学可以去查看:Android中破解某应用的签名校验;而对于服务器签名校验以及将签名校验放到so中的文章后面会单独在介绍一篇。

第三种:调试状态检查
这种方式是纯属借助Android中的api进行检验,有两种方法:
第一:检查应用是否属于debug模式
直接调用Android中的flag属性:ApplicationInfo.FLAG_DEBUGGABLE,判断是否属于debug模式:

这个其实就是为了防止现在破解者为了调试应用将应用反编译在AndroidManifest.xml中添加:android:debuggable属性值,将其设置true。然后就可以进行调试。

添加这个属性之后,我们可以用 dumpsys package [packagename] 命令查看debug状态:

所以我们可以检查应用的AppliationInfo的flag字段是否为debuggable即可。不过这种方式也不是万能的,后面会介绍如何解决这种反调试问题。
第二:检查应用是否处于调试状态
这个也是借助系统的一个api来进行判断:android.os.Debug.isDebuggerConnected();这个就是判断当前应用有没有被调试,我们加上这段代码之后,按照之前的那篇文章:脱掉360加固保护壳,其中有一个步骤进行jdb连接操作:

jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700,当连接成功之后,这个方法就会返回true,那么我们可以利用这个api来进行判断当前应用是否处于调试状态来进行反调试操作。但是这种方式不是万能的,后面会介绍如何解决这种反调试问题。

第四种:循环检查端口
我们在之前破解逆向的时候,需要借助一个强大利器,那就是IDA,在使用IDA的时候,我们知道需要在设备中启动android_server作为通信,那么这个启动就会默认占用端口23946:

我们可以查看设备的tcp端口使用情况 cat /proc/net/tcp:

其中5D8A转化成十进制就是23946,而看到uid是0,因为我们运行android_server是root身份的,uid肯定是0了。所以我们可以利用端口检查方式来进行反调试策略,当然这种方式不是万能的,后面会详细介绍如何解决这样的反调试方法。

第五种:循环检查TracerPid值
在第一种方式中,我们简单的介绍了如果应用被调试了,那么他的TracerPid值就是调试进程的pid值,而在使用IDA进行调试的时候,需要在设备端启动android_server进行通信,那么被调试的进程就会被附加,这就是android_server进程的pid值了:

查看一下android_server的pid值:

所以我们可以在自己的应用中的native层加上一个循环检查自己status中的TracerPid字段值,如果非0或者是非自己进程pid(如果采用了第一种方案的话,这里也是需要做一次过滤的);那么就认为被附加调试了。当然这里还有一种方案,就是可以检查进程列表中有没有android_server进程,不过这种方式都不是万能的,后面会详细介绍如何解决这种反调试方案。

三、方案策略总结
下面简单几句话总结这几种方案:
第一、自己附加进程,先占坑,ptrace(PTRACE_TRACEME, 0, 0, 0)!
第二、签名校验不可或缺的一个选择,本地校验和服务端校验双管齐下!
第三、借助系统api判断应用调试状态和调试属性,最基础的防护!
第四、轮训检查android_server调试端口信息和进程信息,防护IDA的一种有效方式!
第五、轮训检查自身status中的TracerPid字段值,防止被其他进程附加调试的一种有效方式!

上面就简单的介绍了现在流行的几种应用反调试策略方案,这几种方案可以全部使用,也可以采用几种使用,但是要记住一点,就是如果要做到更安全点,记得把反调试方案放到native层中,时机最早,一般在JNI_OnUnload函数里面,为了更安全点,native中的函数可以自己手动注册,函数名自己混淆一下也是可以的。具体可参见这篇文章:Android安全逆向防护解析。现在一些加固平台为了更有效的防护,启动的多进程之间的防护监听,多进程一起参与反调试方案,这种方式对于破解难度就会增大,但是也不是绝对安全的。文章中对于每种方式最后都说到了,都不是万能安全的,都有方法解决,而这内容放到下一篇来详细介绍了。

反调试方案策略代码下载:https://github.com/fourbrother/android_anti_debug

四、总结
本文主要介绍了Android中应用在进行反调试反破解的几种方案,对于每种方案进行了详细原理分析,代码也给出了下载地址,可以自行运行看效果,而对于这几种反调试方案并非是绝对安全的,后面会再详细介绍如何解决这些反调试功能,但是为了应用安全,这几种方案也不可以不用,有总比没有好!最后读完文章,记得多多点赞分享扩散,要是有打赏就最好啦啦!

更多内容:点击这里
  • 大小: 10.3 KB
  • 大小: 12.8 KB
  • 大小: 19.2 KB
  • 大小: 78 KB
  • 大小: 6.1 KB
  • 大小: 7.4 KB
  • 大小: 4 KB
  • 大小: 5.6 KB
  • 大小: 31.1 KB
  • 大小: 14.3 KB
  • 大小: 96.1 KB
2
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 运算符重载方法,扩展方法,以及方法参数

    运算符重载方法 一 些编程语言允许定义运算符如果操作类型的实例,例如System.String,System.Decimal,和System.DateTime,它们 重载了==和!=运算符。但是对于CLR来说,它是完全不知道像“==”和“!=”这些运算符是干什么的。编程语言定义了每一种运算符的意义以及当这些运 算符的符号出现时应该生成什么样的代码。例如C#里面,数值类型的当遇到“+”这个符号时,...

  • C#2.0 中 new 和 override 的区别

    如果一个重写的方法没有使用override关键字,编译器会报告一条警告信息:“Console.Application.B.MethodA()”将隐藏继承的成员“ConsoleApplication.A.MethodA()”。若要使当前成员重写该实现,请添加关键字override。否则,请添加关键字new。显然,添加关键字override可以重写父类的方法。还有一个解决方案是关键字new。

  • c# virtual虚函数的new、override实现

    c#中基类(父类)中的某方法若想在派生类(子类)中被重写(override),必须将基类中的方法定义为virtual,即虚函数。若派生类将方法修饰为new,即有意隐藏基类中的方法。 下面看一组代码: public class Father{ public void hand() { Console.WriteLine("Father

  • 覆盖与重载(override/overload) [C#]

    1. 方法签名与方法的显式隐藏     以下程序中,子类B与父类A存在签名相同的函数,将产生方法隐藏。由于没有显式使用new修饰符,编译时出现警告。 签名相同简单的讲是指忽略访问控制符、函数返回值、参数名后其它内容相同。 如:internal int Print(int x)      public void Print(int y)      protected float Print...

  • 把new、virtual、override说透

    我们先看下面一段程序:    ///      /// 父类 /// 作者:周公 /// 首发地址:http://blog.csdn.net/zhoufoxcn/archive/2008/09/02/2864429.aspx/// 日期:2008-09-01     ///      public class Father    {        pub

  • Android安全防护之旅---应用"反调试"操作的几种方案解析

    在这个过程中我们难免会遇到一些反调试策略,当时只是简单的介绍了如何去解决反调试,其实在去年我已经介绍了一篇关于Android中的安全逆向防护之战的文章:Android安全逆向防护解析;那么这篇文章就来详细总结一下,...

  • Android逆向之旅---应用的"反调试"方案解析(附加修改IDA调试端口和修改内核信息)

    在前一篇文章中详细介绍了Android现阶段可以采用的几种反调试方案策略,我们在破解逆向应用的时候,一般现在第一步都回去解决反调试,不然后续步骤无法进行,当然如果你是静态分析的话获取就没必要了。但是有时候...

  • Android逆向之旅---动态方式破解apk进阶篇(IDA调试so源码)

    今天我们继续来看破解apk的相关知识,在前一篇:Eclipse动态调试smali源码破解apk我们今天主要来看如何使用IDA来调试Android中的native源码,因为现在一些app,为了安全或者效率问题,会把一些重要的功能放到native...

  • Android逆向之旅---Android应用的安全的攻防之战

    Android逆向之旅---Android应用的安全的攻防之战

  • 重写导致的问题

    类中的一个方法,忘记了加override关键字,重写了基类方法,导致调用基类中此方法的按钮,一直执行不到子类的方法。 没有发现这一点时,翻来覆去看代码逻辑,都没有问题呀,后来看到了这个绿色的波浪线,恍然大悟。 看来编译器的警告也不能忽略,就是这种警告: “My.xxx()”将隐藏继承的成员“Base.xxx()”。若要使当前成员重写该实现,请添加关键字 override。否则,添加关键字 n...

  • Android逆向之旅---动态方式破解apk前奏篇(Eclipse动态调试smail源码)

    今天我们开始apk破解的另外一种方式:动态代码调试破解,之前说的主要采用的是静态方式,步骤也很简单,首先使用apktool来反编译apk,得到smail源码,然后分析smail代码,采用代码注入技术来跟踪代码,然后找到关键...

  • Android逆向之旅---动态方式破解apk终极篇(如何破解加固apk)

    现在要说的就是最后一篇了,如何应对Android中一些加固apk安全防护,在之前的两篇破解文章中,我们可以看到一个是针对于Java层的破解,一个是针对于native层的破解,还没有涉及到apk的加固,那么今天就要来介绍一下....

  • Android逆向之旅---解析编译之后的Resource.arsc文件格式

    一、前言 快过年了,先提前祝贺大家新年快乐,这篇文章也是今年最后一篇了。今天我们继续来看逆向的相关知识,前篇文章中我们介绍了如何解析Android中编译之后的AndroidManifest

  • Android逆向之旅---Android中的sharedUserId属性详解

    Android逆向之旅---Android中的sharedUserId属性详解

  • Android逆向之旅---动态方式破解apk终极篇(加固apk破解方式)

    现在要说的就是最后一篇了,如何应对Android中一些加固apk安全防护,在之前的两篇破解文章中,我们可以看到一个是针对于Java层的破解,一个是针对于native层的破解,还没有涉及到apk的加固,那么今

  • Android逆向之旅---Android中如何获取在非Root设备中获取应用隐私数据

    Android逆向之旅---Android中如何获取在非Root设备中获取应用隐私数据

  • 一个男人和三个女人的故事[《.net框架程序设计》_第十一章 多事件示例]

    第十一章 多事件示例[一个男人和三个女人的故事] 摘要:        应用FCL中的System.ComponentModel.EventHandlerList示例一个类型中发布多事件的应用   场景:一个男生有三个女朋友,各自有不同的爱好,女朋友A爱好音乐,女朋友B爱好美食,女朋友C爱好XXX,为满足各个女朋友,此男生必须进行唱歌、烹饪食物、xxx。 以此制作程序演示单类型多事件的应用,并假设

Global site tag (gtag.js) - Google Analytics