安卓逆向10-ida,动态调试
###
动态调试的准备工作:
IDA动态调试:
配置:
#把本地文件推送进手机目录
将ida文件夹里面的dbgsrv下的android_server放入真机的/data/local/tmp/下
adb push android_x86_server(cpu型号要对应 模拟器是x86) /data/local/tmp/
如果是64位,就选64位的,
#进入手机shell
adb shell
#真机要使用 su 命令 切换到root用户,模拟器不用
#进入手机tmp目录
cd /data/local/tmp/
#修改权限
chmod 777 android_server
#运行
./android_server
#在本地执行adb 做端口转发
adb forward tcp:23946 tcp:23946
要动态调试,要用真机调试,最好使用安卓6,7,安卓5会问题很多,
####
IDA动态调试
目的:找到自毁程序的内置密码
第一步,我们再开一个ida程序,不要关闭静态调试的那个窗口
这就是ida双开,
本地打开IDA,选中Go
然后连接到手机的服务,确保上面的配置,是正确的,服务是开启的,
第二步:
点击上面的连接真机,然后弹出下面的弹框,然后输入127.0.0.1,因为都是本地调试,所以就是输入这个本地ip就可以了,
第三步,
点击上面的,如果正常,就会弹出选择app的页面了,
这是把所有的进程都展示出来了,还可以搜索,
如果找不到这个app,那就重新打开一下app,
###
第四步,上面一步打开app可能有点慢,要等一等,
然后进行ctrl+s,进行搜索我们要调试的so文件,
注意后面的权限,我们选择第一个有X权限的,就是有可执行权限,我们要调试这种的,
start就是内存地址,我们叫做基地址,
##
第五步,
我们看到有很多个,怎么找到我们要调试的方法的那个地址??
按键盘G键, 输入绝对地址,跳转到要调试的函数处
如何计算要调试函数的绝对地址:
绝对地址 = so文件的基地址 + 该函数的偏移量
so文件的基地址在哪儿找:
快捷键 ctrl + s 找到目标so文件 Start 那一项就是 基地址
DC9E6000
函数的偏移量在哪儿找:
以静态方式打开so文件,函数列表里
这个就是函数的偏移量,
000011A8
####
你要动态调试,你还是要先看懂了静态调试,才好去调试,
看看静态调试的c代码,
你逆向,不能从头看,你要有逻辑,不能从第一行看,你这样看不懂的,
可以从return看,
上面我们已经分析过了,
v5就是我们输入的密码
v7就是真实密码,而v7是来自于v6,所以v6就是真正的密码,而v是一个常量
所以我们的目的就是调出来v6这个常量,
####
然后我们动态调试,怎么跳,
怎么加
用16进制的计算器,DC9E6000+000011A8 =DC9E71A8
然后使用快捷键 g 输入地址,DC9E71A8
然后就调到这里了,
第六步,上面的面板
是有很多的分支流程的,这就是条件语句,
F8是单步调试,这个就是不进入函数
F7单步调试,这个是要进入函数,
一般我们就是使用F8,因为F7进入之后太多了,调试难度大,
你要调试,你要先打断点,然后才可以单步调试,
选中然后进行右键,添加断点,就可以了,添加之后会标红的
然后让程序恢复执行
如果你点击了之后报错,一直报错,可能就是加入了反调试了,
#####
下面介绍一下反调试,
so反调试
IDA调试原理 是利用Linux系统 ptrace 来实现
当应用被调试时,应用内存里的TracerPid 字段就不为0
如果为什么会有反调试,
就是因为ida是利用的Linux的pTrace来实现的,
而调试的时候,TracerPid 字段就不为0
进入设备查看ptrace字段:
//进入设备
adb shell
//获得APP的进程ID
ps | grep 包名
//打印该APP里内存状态信息
cat /proc/pid(进程ID)/status
###
反反调试
动态调试,找到检测TracerPid的代码,不执行此代码
方法:
此检查代码一般在.init_arra 和 JNI_OnLoad两处
在JNI_OnLoad函数出打断点调试,找到检测TracerPid的代码,不执行此代码
IDA调试反调试小经验 如何找到反调试代码:
结合IDA静态时的代码,观察程序逻辑
指令一般会整过执行完,直到函数末尾。
多次IDA中,如果指令在中途某个地方退出了,说明该处就是反调试指令。
####
如何在JNI_OnLoad函数打断点:
so文件在加载阶段会执行JNI_ONLoad,此后不再执行,要在so文件加载阶段才能给
JNI_OnLoad打断点
1).修改APP AndroidMenifest.xml文件, APP加上可调试权限,android:debuggable="true",
重新打包APP,
apktool.sh b ./AliCrackme_密码在so文件debug模式
签名,keytool -genkey -keystore my-release-key.keystore -alias my_alias -keyalg RSA -keysize 4096 -validity 10000
打包,jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore my-release-key.keystore -signedjar AliCrackme_密码在so文件sign.apk AliCrackme_密码在so文件.apk my_alias
安装,
如果有签名校验,你还要过校验,这是一个复杂的事情,
2).检查flags中是否有应许debug项
adb shell dumpsys package com.yaotong.crackme
3).以调试模式启动APP APP此时会挂住
adb shell am start -D -n 包名/.类名
adb shell am start -D -n com.yaotong.crackme/.MainActivity
让app停在这里,不要动,
然后把ida动态调试失败的页面关闭,不要保存
路径:file-close,
然后重新来一遍上面的流程,
这个时候你是看不到so文件的,因为app现在是卡住的状态,
然后进入下一步
4).在debugger-DebuggerOptions
DebuggerOptions里勾选 Suspend on thread start/exit Suspend on library load/unload
JNI_OnLoad函数是lib刚加载时就会执行,必须要在lib载入时就让程序停下来,才能调试JNI_OnLoad
5).点击运行按钮
6).在设备里查看APP的进程ID
要adb shell先进入设备运行如下命令,过滤出该应用信息
ps | grep 应用包名
7). 使用JDB命令让APP 恢复运行
adb forward tcp:8700 jdwp:873(APP的PID)
adb forward tcp:8700 jdwp:29404
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
8).在so文件被加载时,IDA会停止住,使用ctrl+s 查看目标so文件是否加载
一开始肯定是搜不到的,因为还没有加载进来,
然后你点击ida右上角的运行按钮,一步一步的运行,这个时候要很小心,
若加载点选目标so文件,
找地址JNI_OnLoad
计算JNI_OnLoad的绝对地址,按G键跳转到JNI_OnLoad出设置断点,
打断点
恢复APP执行,
会变成蓝色
###
找到反调试代码处,pthread_create(),
如何找到反调试代码处?(关键地方,可按f5,把汇编代码转成C语言辅助)
反复按F8单步执行,程序退出处(前面),既为反调试处
如果按F8,继续往下走,说明没有问题,如果有地方不往下走了,往回走了,这个地方就有问题了,
继续往下F8,就直接退出了,
下面我们就是把指令不执行,
####
如何让反调试代码不执行?
让该指令变为空指令,既 NOP,NOP指令的16进制是 00 00 00 00
我们要做的就是把这个BLX R7,变成空,
记住反调试处的汇编指令,这个时候我们就要回到这个静态调试了,
同时以静态方式再打开一个IDA(也叫双开IDA 以动态和静态方式各打开一个IDA ),
打开so文件,在静态ida里查找到此汇编指令,鼠标选中后面寄存器,然后切换到Hex View,会显示该指令的16进制,
然后copy下来,
37 FF 2F E1
去改so文件的二进制代码
然后又要重新打包so文件,上面的都要重新来一遍,
###
因为你已经找到反调试的地方,并且干掉了
所以就不需要从debugger模式运行了
我们直接运行app,直接调试我们的加密的方法那里,不需要调试JNI_OnLoad方法了,
1,启动ida动态 调试,
2,找到app,
3,找到so文件,直接进入
4,计算地址,跳转到加密方法那里
5,打断点
然后我手机输入密码,点击一下,才会触发这个方法,到这个so文件里面来
这一点要注意,你要去触发,
到了这一步,发现了不往下走了,会有跳到下一个,
这个地方就有问题了,
然后是出现了R1就是我们输入的密码1111,
说明R3就是真实的密码了,因为有一个比较,
这个时候可以点击R3查看,
还可以按F5,转成c代码,看看,
这个时候,把鼠标放到v6,我们看到就密码已经出来了,
####
动态调试libcrackme拿到密码:
1.分析出密码判断的函数是哪一个
2.IDA静态分析此函数,理清脉络
3.在此函数处下断点调试
4.单步调试,观察指令执行流程
5.密码不对时,指令会跨越执行,不再顺序执行
6.动态调试时,在关键指令处按F5,把指令转成c代码辅助分析
7.动态调试时鼠标移动到寄存器上,会显示该寄存器里的值
8.动态调试时,把指令转换成C代码,把鼠标移动到C代码的变量上,会显示该变量的值
###