本文通过ptrace和检测/proc/pid/status实现JNI层的基本反调试,实现详细步骤如下:

1.新建一个类

2.javah生成头文件

在  工程目录/bin/classes   下使用javah生成jni类的头文件:

3.移动生成的jni头文件

在工程目录下新建一个jni文件夹,将上面生成的jni头文件移动至该目录

4.实现cpp代码

本文实现的反调试原理有两个:

  • ptrace(PTRACE_TRACEME,0,0,0) 。ptrace原理见另一篇文章:理解ptrace
  • /proc/pid/status中的TracerPid。进程被调试时该字段为调试进程的pid,看下图:

ptrace00

从头文件中有函数声明,根据声明实现具体的cpp代码

注意在重写JNI_OnLoad时返回值是JNI版本。

5.新建Android.mk文件

在jni文件夹下新建Android.mk,内容如下:

LOCAL_MODULE和LOCAL_SRC_FILES分别改成要生成的so文件名和源cpp文件名。为了能输出调试信息要加上LOCAL_LDLIBS:=-llog。

6.使用ndk-build生成so

在jni文件夹下使用ndk-build:

生成成功如下:

jni

7. 重新编译工程

编译前要先clean一下,否则eclipse可能不会重新编译

8.实现效果

查看示例apk的pid:

ptrr

我们先附加上子进程看看:

ptrr2

可以看到operation not permitted。接下来在附加到主进程,可以看到几秒后(可以改变检测的时间间隔)进程自动被杀死,logcat输出:

ptt2

这时TracerPid是调试进程(gdb)的pid。

 

观看更多有关 的文章?

*

    2015年6月11日

    我测试, 直接ptrace(PTRACE_TRACEME, 0, 0, 0); 就可以了呢, 为啥要fork一个出来检测? 而且我发现fork之后, 主的程序退了, 子的并没有退啊, 会由很多问题….

      burningcodes
      2015年6月12日

      主进程就是正常的apk进程啊,怎么会退出? 反调试的方法有很多,这里演示的是动态检测的方法,像棒棒等加固方案都有用到这种反调试方法。

    anseey
    2015年6月18日

    您好,我正在学习这个,我想请教一下。安卓里面并没有提供gdb命令,请问您如何得到的?

      burningcodes
      2015年6月18日

      去下一个arm平台下的gdb,然后push进模拟器或真机

+
跳转到评论