【练习】IDA调试Android native(Crackme)
本帖最后由 PJ头狼 于 2016-12-12 13:31 编辑阿里Crackme分析(native)
这段时间在学习IDA动态调试Android native,之前发过一个IDA动态调试的基础帖子:IDA调试Android native,没有基础的可以先看一下。这个Crackme分析时之前阿里安全挑战赛的第二题,在修改掉其so反调试的过程,刚好可以练习练习IDA的动态调试。这个破解方法会比较复杂,就当作练习用,后边有简单粗暴的方法
帖子比较长。。。多图。。。
实例apk:AliCrackme.apkapk运行界面如下: 1.用apktool进行反编译,确定程序的主活动通过反编译得到AndroidManifest.xml,查看文件内容如下,可以确定该程序的主活动为com.yaotong.crackme.MainActivity。 2.结合dex2jar和jd-gui两个工具,分析主活动源码 分析源码可知,主活动中加载了crackme这个动态库,在按下按钮后便会调用动态库中的securityCheck方法对输入的字符串进行检验。 3.使用IDA分析动态库中的检验算法定位到securityCheck方法的程序位置,按F5,经过修改、简化代码,得到方法相应的C代码程序: 这里v5对应输入的字符串,而v6对应的是进行比较的密码,进到v6的字符串存放位置查看得: 将上边的wojiushidaan输入,没有成功,可见在进行比较前,程序已经对这里的字符串进行了修改,程序的前半部分便是对字符串进行改写的操作,大致分析程序修改逻辑,无法快速摸清程序中字符修改的实现方法,尝试用动态调试进行分析。 4.尝试动态调试,分析检验方法在securityCheck方法的反汇编代码起始处设下断点动态加载该程序,按下F9运行,结果程序直接退出,动态调试失败 再重新加载,继续尝试动态调试,仍是直接退出,可确定该程序在加载crackme动态库前,有进行反调试检验。 5.反调试原理分析IDA是使用android_server在root环境下注入到被调试的进程中,用到的技术是Linux中的ptrace,Android中如果一个进程被另外一个进程ptrace了之后,在它的status文件中有一个字段:TracerPid 可以标识是被哪个进程trace。在没使用IDA对程序进行调试时,其status文件内容如下,TracerPid为0,没有被trace 当使用IDA来动态加载该程序时,查看其status文件内容,TracerPid标识着该进程正在被860这个进程trace 查看860进程信息,果真是android_server所在的进程反调试原理便是在程序运行过程中,循环检测进程中的TracerPid标识来确定程序是否被调试。只要一运行程序,就退出了调试界面,说明这个循环检测程序执行的时机非常早,已知最早的两个时机是:一个是.init_array,一个是JNI_OnLoad.init_array是一个so最先加载的一个段信息,时机最早,现在一般so解密操作都是这里做的;JNI_OnLoad是so被System.loadLibrary调用的时候执行,时机要早于native方法执行,但是没有.init_array时机早 6.检测是否在JNI_OnLoad方法执行过程中启动反调试检测由于JNI_OnLoad方法很早就被启动,所以不能用之前的动态调试方法,这里要采用debug方式来启动程序进行分析。①使用am以debug方式启动adbshell am start -D -n com.yaotong.crackme/.MainActivity 这时程序便会处于waiting for debugger的状态: ②使用IDA加载程序在attach该程序前,应先进行debugger options配置,Debugger-Debugger Options进入配置窗口,勾选下边Events中的3个选项:然后加载程序到IDA中,这时使用Ctrl+S是查找不到crackme动态库的,说明使用这种debug方式启动程序,so文件是还没加载到内存的。 ③使用jdb来attach程序Java,使程序跑起来jdb-connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
结果attach失败,这种情况是因为该程序被设置为不可调试,查看程序AndroidManifest.xml可知,没有设置android:debuggable,默认为false。修改xml文件,重新编译、打包、签名、安装程序。④重新进行调试重新进行前边几个步骤,以debug方式来动态调试该程序。当jdb执行成功后,程序界面便会结束waiting:同时IDA上成功加载程序后,便会进入到linker模块: ⑤定位到JNI_OnLoad方法位置在另一静态IDA程序中确定JNI_OnLoad方法的偏移量,为1B9C: 确定crackme动态库的起始地址,为4A847000: 跳转到JNI_OnLoad方法的起始地址4A848B9C: ⑥设下断点,进行单步调试 单步步过,当执行下边BLX R7指令后,程序便会调试失败、退出其中R7寄存器的地址值对应的是pthread_create函数,这个是Linux中新建一个线程的方法,可推测出在该线程中执行的便是,循环读取/proc//status文件中的TrackerPid字段值,来确定程序是否被调试。 7.去掉相关指令,删除反调试检测由上边可知,应将BLX R7指令给nop掉,来实现删除反调试的操作。在IDA静态程序中确定指令的偏移位置,为1C58,对应的二进制为37 FF 2F E1: 使用010Editor进行二进制代码修改,将1C58中对应的37 FF 2F E1修改为00 00 00 00保存后,可查看指令已被修改 8.动态调试securityCheck方法,分析密码检测过程对上边修改后的程序进行重新编译、打包、安装,加载程序并在securityCheck方法设下断点,F9运行,输入任意密码点击按钮:
成功执行到securityCheck方法的起始地址
F8,开始单步步过调试
可以发现,程序在执行到上边CMP R3,R1指令处,便是进行密码的匹配检测,其中R1便是对应R0中存放的地址;R3则是对应R2中存放的地址。跳转到R0存放的地址,可发现,便是存放着输入的密码:那么R2则是程序中真正的密码了: 输入aiyou,bucuoo,破解成功: 简单粗暴的破解方法上边通过nop掉反调试检测机制来实现动态跟踪程序,获取到最终比较的密码字符串。通过这样的实操、分析,可以更好地掌握Android Native的动态调试方法以及native层反调试机制实现的原理。这里有一种更为简单快捷的方法,来获取到最终的密码。就是通过对so进行patch操作,使程序帮助我们打印出密码来。注意到在程序最后进行输入字符串与正确密码进行比较前,调用了android_log_print函数: 允许程序,过滤打印信息得到:这里就是调用android_log_print来打印<tag>为yaotong的信息,我们可以尝试直接patch这个libcrackme.so,修改打印的内容,直接利用这个函数输出此时真正的密码。选择的patch方法是直接把这个log函数往下移,因为在0x12A4地址处正好有我们需要的打印的数据地址赋值给了R2寄存器,因此将代码段从0x1284到0x129C的地方都用NOP改写,在0x12AC的地方调用log函数,同时为了不影响R1的值,把0x12A0处的R1改成R3:①0x1284-0x129c:NOP(00 00A0 E1)②0x12A8:MOV R0,#4(0400 A0 E3)③0x12AC:BL__android_log_print(88 FF FF EB)这里的88是由一开始在0x1284的92 FFFF EB得出的,两个地址相差40个字节,应除以4,对应就为:0x92-0x88=10。④0x12A40-0x12A84:将R1修改为R3(60 30 9F E5 07 20 93 E7) 这里R1对应<tag>不修改使用010editor进行机器码修改: 修改后的so的反汇编代码如下: 重新打包、签名、安装程序,运行后打印的信息如下:
赞一个!
另外android:debuggeable="true"这个标签是不是应该加载application里?
另外我在做的时候,启动jdb调试那步,ida会弹出错误提示"IDA could not find the file"data/app-lic/com.yaotong.crackme-1/libcrackme.so" if that file can be accessed ,please specify its directory这个错误提示,我点击取消以后,jdb就显示断开连接里,不能到linker
大神有遇到过这个问题吗?
PJ头狼 发表于 2016-11-30 22:48
如果有反调试,跑到检测的地方就会退出的。你得看看你的是不是因为程序反调试了
我是照着人家的教程做的,用的教程提供的app。脱360的壳,mmap下断,教程直接函数首尾下断,函数尾直接几次F9,我有时一次F9就中断退出了,有时可以F9几次,但是不管是直接F9还是单步都是会中断退出,单步连mmap函数尾没走到就退出了。。 希望大神多多分享移动端方面的教程,ida工具的使用以及ARM汇编基础{:301_987:} 以后pc不玩的时候 也玩玩移动方面的 学习了,以后就可以练练 wangsheng66 发表于 2016-11-27 18:50
希望大神多多分享移动端方面的教程,ida工具的使用以及ARM汇编基础
大神。。。还远着呢{:1_896:},IDA的使用应该有教程帖子,也可以看《IDA pro 的权威指南》;ARM基础是自己补的,感觉不好写{:301_977:} 不明觉历,小白路过~~ PJ头狼 发表于 2016-11-27 19:53
大神。。。还远着呢,IDA的使用应该有教程帖子,也可以看《IDA pro 的权威指南》;ARM基础是自 ...
好的,英文差{:301_972:} 楼主多发点好教程啊{:301_993:}期待 感谢楼主分享 感谢,学习了。