记Android逆向学习之路。
CrackMe01.apk(见附件)(无壳,存在反调试和密码验证逻辑)
分析apk java层代码-->安装apk并开启IDA监听端口-->IDA以Debug模式动态调试apk-->破除反调试-->取得明文密码
工欲善其事,必先利其器
工具:Windows10;IDA7.0(Window);ajdx-gui;DDMS(adt-bundle-windows-x86_64_20140101里面tools中的monitor.bat,先打开);ARM架构模拟器(这里是armeabi-v7a,SDK里面的相关组件可以创建模拟器)
把apk拖进ajdx-gui中
可得知密码验证在so层
使用adb install 电脑apk路径 安装CrackMe01.apk,界面如下:
开启IDA监听端口(要事先把IDA-dbgsrv目录下的android-server置到模拟器中,这里是/data/local/tmp下,修改名称为as并赋给可执行权限),用./as开启端口监听,默认端口是23946,app崩溃
猜测可能存在端口检测,更改端口为31928,命令:./as -p31928
成功过app调试端口检测,接着进行端口转发
先打开DDMS,用于模拟器进程监听。
打开app主界面,使用adb shell dumpsys activity top命令获取当前界面信息
使用adb shell am start -D -n com.yaotong.crackme/.MainActivity命令以Debug模式启动app指定界面
然后打开IDA Debugger附加CrackMe01.apk app进程
勾选Debug选项(加载so要挂起载入)
IDA Debug模式动态调试配置完成。
为什么不用直接动态调试?经发现,该apk运行时会自己附加一个子进程,IDA中直接动态调试会显示两个Pid的该进程(可以进入/proc/进程id/status进行信息查看,子进程的TracePid就是父进程的Pid),由于一个进程只能被附加一次
,因此不能再对子进程进行附加,对父进程调试也发生了错误,而Debug模式动态调试则没有问题。
F9然后执行jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=端口号,端口号是DDMS对应进程的端口,且执行后图标变成绿色。
加载libwolf.so进来(进程现在挂起状态),找到这个so的导出函数(Debugger-Module list)
在jni_onload函数下断点,然后F9
程序断在这里
经测试函数在下图中的函数执行后会使调试中断
怀疑是反调试相关函数,尝试不让这个函数执行,找到改指令对应的内存指令数据
并修改为(00)(据说是注释)
变为
应用之,反调试成功破除。
从导出函数列表中可以看到许多加解密相关,猜测是把密文解密成明文然后与输入作比较,直接在Decrypt函数中的CMP(compare)指令下断点。
按F9让相关so加载进来,之后回到apk随便输入然后点按钮验证以触发解密函数。
按F9程序在指定地方断下,密码明文很可能在某一个寄存器中,找到R7寄存器(指向堆)jump过去查看存放内容
红圈存放的hello5.1应该就是密码
果然
点点滴滴,循序渐进。
[赠书活动] 《云计算安全》和《云存储安全实践》上线!老师留下通讯地址,即可获得赠书一套!送100套,送完为止!
最后于 19小时前 被mb_gujpacap编辑 ,原因: