工具 jeb + androidkiller + IDA6.8 + winhex + cmder
part1 前期侦察准备工作:
静态分析 apk smali
按照正常流程走,直接拖入到andriod killer中,发现其中只有两个activity程序,主程序中定义了一个native程序
public native boolean securityCheck(string){
}
这个程序将用户输入的字符串信息,直接传入到securityCheck()函数中做比较,如果程序返回不为0,则表示密码正确
invoke-interface {v2}, Landroid/text/Editable;->toString()Ljava/lang/String;
move-result-object v1
.line 34
.local v1, "result":Ljava/lang/String;
iget-object v2, p0, Lcom/yaotong/crackme/MainActivity$1;->this$0:Lcom/yaotong/crackme/MainActivity;
invoke-virtual {v2, v1}, Lcom/yaotong/crackme/MainActivity;->securityCheck(Ljava/lang/String;)Z
move-result v2
if-eqz v2, :cond_0 --->提示 校验码校验失败
v2不为0的流程,启动ResultActivity,显示程序破解成功
new-instance v0, Landroid/content/Intent;
iget-object v2, p0, Lcom/yaotong/crackme/MainActivity$1;->this$0:Lcom/yaotong/crackme/MainActivity;
const-class v3, Lcom/yaotong/crackme/ResultActivity;
invoke-direct {v0, v2, v3}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V
.line 36
.local v0, "i":Landroid/content/Intent;
iget-object v2, p0, Lcom/yaotong/crackme/MainActivity$1;->this$0:Lcom/yaotong/crackme/MainActivity;
invoke-virtual {v2, v0}, Lcom/yaotong/crackme/MainActivity;->startActivity(Landroid/content/Intent;)V
.line 42
.end local v0 # "i":Landroid/content/Intent;
:goto_0
return-void
ida打开so程序找到该native方法:
并发现有JNI_OnLoad函数和securityCheck native方法。我想我们需要调试该方法了。
先运行app程序,然后附加程序,程序断下来后,又运行,这时IDA提示一个很小的框,然后程序直接退出了,界面如下所示:
说明该so有专门的函数模块,对程序进行了监控,发现自己被调试,直接退出了
补充知识点:
看看怎么以调试模式启动程序
既然so中有反调试的代码,那么我们可以在程序还没有运行的情况下,就附加程序,这样就可以赶在程序运行反调试代码之前,附加上程序。(这里跟windows下使用 OD直接打开exe程序是一样的。虽然没有立刻过掉反调试,至少我们已经掌握主动权)
将手机root并准备好软件调试环境
1、这里准备的环境要多一些了:
1) 手机root、xposed和xinstaller都安装上 强制修改ro.debugable = 1
使用 cat default.prop查看 ro.debugable的状态:
2、使用命令adb jdwp,查看可以调试进程列表如下
3、am start -D -n启动程序后,ida率先附加上app,然后设置ida在加载library时断下来。也可以在其他so当中设置断点。
有时 IDA 使用remote arm/linux anroid 附加程序时,附加不上,多半是android_server没有高权限运行,一般使用root权限运行./android_server
adb forward tcp:23946 tcp23946,有时使用bat脚本也不太管事,所以最好手动输入。
正常附加上,如上图所示,找到要调试app,会在libc中断下来,此时再设置IDA 在加载或者卸载so库时的断点。设置好后,就让IDA全速运行。
4、这时就可以 采用jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700 来调试apk的java层代码
这里为啥要用jdb -connect来启动,回想一下我们在android studio中调试代码,列表的输出信息,可以看到android studio使用am 命令以调试模式启动了程序,
然后我们再点击进程附加(其实就相当于调用了jdb -connect),但是我们又不要真的调试,所以这里采用jdb 命令直接附加程序
参看博文:使用jdb调试apk - 疯狂的pythoner - 推酷
正常情况下,jdb connect会连接成功
当设置ida的loadlibrary断点后(Debuger option中设置),此时会提醒app正在加载libcrackme.so程序
当然 jdb -connect连接调试程序也有时也会失败:暂时未找到原因,多尝试几次
继续后续的操作:
jdb 当程序运行后,(ida这边会接收到加载so库的断点)
此时程序正好断在 linker.c的代码中(前面有两个章节专门对so链接的代