Fn+f5转成c语言伪代码
shift+f12 查看文件中所有常量字符串的值
ctrl+s查看so文件字段信息
JNI函数方法名还原 选中v3 按y建 作用(类型还原)
v3 + 676 前面是一个指针 比如 *(_DWORD *)v3 + 676 表示 v3 是JNIEnv *类型
形如 *(_DWORD *)vX + YYY 皆是
可选中v3 按y键进行类型替换,替换为JNIEnv *
为伪代码添加注释 : /
g跳转到指定地址
IDA动态调试
目的:找到自毁程序的内置密码
IDA下载配置 mac需要在10.15以下版本才可以使用
首先,需要准备安卓真机,最好是pxiel 6.0的系统,
将ida文件夹里面的dbgsrv下的android_server放入真机的/data/local/tmp/下 添加777权限 chmod 777 xxx
./android_server运行服务并且监听端口23946 adb forward tcp:23946 tcp:23946
后面再运行ida 32 点go打开ida new是静态调试
我们选择 debugger-->attach -remote ARMLinux/Android debugger
输入127.0.0.1点ok。会出来如下界面,如果说链接拒绝,请检查前面启动服务和监听端口是否正常
我们找到需要调试的进程com.yaotong.crackme点ok
稍等一会儿之后会出来如下界面
由于我们之前说过,这个函数的验证密码的函数叫securityCheck
我们现在需要跳到这个函数的内存地址,去调试这个函数,如何找到这个函数的内存地址呢
函数运行实际内存地址=头so文件的基地址(根据实际运行情况,此基基地值app每次执行的值都不一样) + 该函数的偏移量(固定不变.so文件可查看)
我们现在另外打开一个ida 以静态方法打开此apk的libcrackme.so文件找到securityCheck函数的偏移量为11A8
再打开以动态方法调试的ida 按control+s(显示app中的so文件)
我们找到libcrackme.so 找到第一个标有x权限的so文件
打开
显示的内存地址为F4395000
我们打开电脑上的科学计算器,计算方法以16进制进行计算
用F4395000+11A8得到的就是实际的securityCheck运行的的内存地址 F43961A8
我们在动态的ida里面按下G 输入刚才得到的内存地址,跳到此内存地址
跳转后的界面如下
现在我们对此函数进行调试,我们需要在Java_com_yaotong_crackme_MainActivity_securityCheck函数这里进行打断点调试,右键addbreakpoint
断点后的样子
调试有两个快捷键,F7 和F8
F7单步调试,要进入函数
F8单步调试,不进入函数
一般都是F8。进入函数步骤太多了。看不出来。我们F8尝试调试
发现报错,没关系 我们再次尝试
再次报错,一直都报错,此时 我们想到,可能是此app用了反调试
IDA调试原理 是利用Linux系统 ptrace 来实现
当应用被调试时,应用内存里的TracerPid 字段就不为0
进入设备查看ptrace字段:
//进入设备
adb shell
//获得APP的进程ID
ps | grep 包名
//打印该APP里内存状态信息
cat /proc/pid(进程ID)/status
TracerPid为 0代表 没有被调试,不为0代表在被调试。
反调试的原理,检测TracerPid是否被占用,如果被调用。阻止app继续运行
反反调试
动态调试,找到检测TracerPid的代码,不执行此代码
方法:
此检查代码一般在.init_arra 和 JNI_OnLoad两处。此函数都是在程序最开始运行的时候执行
在JNI_OnLoad函数出打断点调试,找到检测TracerPid的代码,修改so文件的执行函数,不执行此代码
IDA调试反调试小经验 如何找到反调试代码:
结合IDA静态时的代码,观察程序逻辑
指令一般会整过执行完,直到函数末尾。
so文件在加载阶段会执行JNI_ONLoad函数。此后便不再执行。要在so文件加载阶段才能给JNI_ONLoad打断点。
分下面几个步骤:
1.修改APP的AndroidManifest.xml文件的application字段,再后面加上一段代码android:debuggable=‘‘ture".然后重新打包签名安装
2.运行的时候检查是否允许debuggable项
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(MainActivity是application 下的第一个activity.此activity为初始启动界面)
挂起 的程序就像上图这样。一直等待调试,
4.我们打开ida动态调试,对此app再次进行调试
打开好找到 Debugger-->Debugger options 勾选下图红色选框内容
再点击一下左上角对运行按钮
5.再进入设备查看进程对PId ps |grep 包名 或者frida-ps -Ua也可以
6.使JDB命令使程序恢复运行
adb forward tcp:8700 jdwp:18776(APP的PID)
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
7.so文件在被加载时。ida会停住此文件对加载,我们用control+s来一步步查看libcrackme.so文件是否被加载。并且加载对so文件需要有x权限
如果未加载。我们再点击左上角对运行按钮,来一步步对尝试,如此反复,直到出现带有x权限对libcrackme.so文件
点进去,我们得到libcrackme.so文件本次运行的基地址,我们现在需要跳转到JNIONLOAD函数里 对此函数进行调试 G ,然后和JNI_onload内存值相加
得到这样的图
现在我们对JNI_onload进行打断点 点左上角的运行三角形,让程序进行运行。F8进行调试
(对JNI_inload进行调试是找出此段代码中检测tracepid的代码,对检测tracepid的代码进行定位,找到 pthread_create() 的位置。后修改so文件的十六进制内容,从而让此段代码不执行)
每一步的F8调试,我们都一一都找,鼠标放上去,看到里面运行的代码,找寻 pthread_create这个函数,由于这个函数是一直不停的去检测,应该是个while循环,我们可以按照里面的箭头,线路图,是否有往回走的,来判断pthread_create大致在哪里
如图 ,找到了 位置在BLX R7位置。现在我们到静态so文件里面 找到blx r7的执行命令
鼠标点在blx R7 在点hexview1 阴影的地方就是该函数的运行指令的16进制
我们现在把37 FF 2E E1复制一下,用文本方式打开so文件,在里面搜索37 FF 2E E1 将搜到的37 FF 2E E1全部改为 00 00 00 00,
让指令变为空指令
改完以后报错,再重新打包,签名 安装
安装完成后,我们就可以重新对securityCheck进行动态调试了
继续接之前的
现在继续调试就不会报错了
我们一步步的F8向下走。看看程序执行,(在此之前在app上随便输入个密码)
我们试想这个密码肯定是错的。程序会判断密码是对是错,如果错了,肯定会走错的流程,对了肯定走对的流程,我们一步步的F8,发现
发现红红色圈子的箭头一直闪,正常应该走短的哪个箭头,结果却绕过短的执行了长的,我们把鼠标放在R0上
发现寄存器里面的值正好是我们输入的1111 由此可判断这部分函数应该是判断密码和输入的是否正却,我们F5转化为伪代码进行查看
仔细看这段代码 判断v7不等于v5 break ,v7是v6赋值的。我们把鼠标放在v6上。发现v6的值为aiyou,bucuoo 前面的unsigned __int8可以上网上查下含义,大致的意识是定义类型,
我们把得到的密码输入进入尝试,发现密码正确,完成
学自猿人学
原文:https://www.cnblogs.com/wuxianyu/p/14276369.html