本文为2015年移动安全挑战赛第二题的writeup。

链接:http://msc.pediy.com/timu.htm
平台:Android
类型:CrackMe

Java层什么都没做,直接把输入传给了SO中的函数securityCheck进行处理,IDA attach后发现程序退出了,好吧,肯定是反调试了。这里顺便说一下检测调试的手段:

  • 读取了/proc//status文件里面的状态和TracerId
  • 调用ptrace(PTRACE_TRACEME,PTRACE_ATTACH)比如子进程attach父进程,子线程traceme自己等等
  • 其他奇淫技巧

这道题是在JNI_OnLoad函数中进行了反调试,那么就需要在APK运行前进行调试,再次记录一下调试方法吧:

  • 准备好调试环境(IDA、adb等)
  • adb shell
  • am start -D -n com.yaotong.crackme/.MainActivity
  • 使用IDA附加上该APK进程,设置加载SO时端下来,在dlopen下断点(在这里下断可以调试INIT和INIT_ARRAY的函数)
  • jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
  • 使IDA continue
  • 此时IDA应该就会断下来,我们再在libcrackme.so的JNI_OnLoad下断点
  • 单步跟踪结合IDA静态分析和F5,并在fgets处下断点,SO是通过读取/proc/pid/status文件中的Tracepid字段来判断是否有调试,如果检测到调试程序将会退出。最终,我用patch跳转指令(IDA的Edit菜单里Patch program->Change byte可以修改指令的机器码,可以改成0 0 0 0)掉了反调试:
    1

过掉反调试接下来就easy了,在Java_com_yaotong_crackme_MainActivity_securityCheck下断点,让IDA continue,最终验证逻辑就是一个简单的字符串比较:
2
最终密码为:aiyou,bucuoo