工作准备
- ida7.0
- jdk8
- android6手机-小米4(请用真机模拟器会有你想不到的问题)
so的加载过程
.init->->.init array->->JNI_Onload->->java_com_XXX;
脱壳的过程中会在一些系统级的.so中下断点比如:fopen,fget,dvmdexfileopen,等等
而.init以及.init_array一般会作为壳的入口地方,那我们索性叫它外壳级的.so文件
godbolt 在线查看汇编
https://godbolt.org/
Unicorn是一个轻量级的多平台,多体系结构的CPU仿真器框架。官网:http://www.unicorn-engine.org/
Capstone是一个轻量级的多平台,多体系结构的反汇编框架。官网:http://www.capstone-engine.org/
参考:https://bbs.pediy.com/thread-224330.htm
1.IDA目录下的android_server 服务传入设备,给权限,启动服务。
IDA 7.0\dbgsrv 目录存放的是不同平台转发服务的二进制可执行程序
- android_server:arm指令的安卓手机调试服务
- android_server64 :arm64指令的安卓手机调试服务
- android_x64_server :x64指令的安卓手机调试服务
push服务到手机
adb push android_server /data/local/tmp
用su权限启动服务(特别注意su权限,否则不能attach到app上哦)
#电脑终端执行
adb shell
su
#重命名
mv /data/local/tmp/android_server /data/local/tmp/androidStr
#设置可执行权限
chmod 777 /data/local/tmp/androidStr
#Android5以上要多做这一步
setenforce 0
#启动服务默认端口23946-这里指定好端口,可避开简单的检测
/data/local/tmp/androidStr -p88888
#看运行可以看到启动后会监听88888端口
#查看android进程
adb shell ps |findstr android
#杀死进程
kill -9 8260
特别注意Android5.0之后默认启用了 SELinux/SEAndroid (如果找不到要调试的进程)
解决办法:
setenforce 0
或者
echo 0 > /sys/fs/selinux/enforce
2:端口转发--(另外打开一个终端)
另外打开一个终端,进行端口转发,签名那个窗口不要关闭
#把android上的8888端口转发到电脑的23946端口
#特别注意的是第一个端口是pc的端口,第二个端口才是手机的端口
adb forward tcp:23946 tcp:88888
3.按debug方式启动一个app
#am start -D -n (apk包名)/(启动类名)
#比如启动微信
#adb shell am start -D -n com.tencent.mm/.ui.LauncherUI
#本案例采用apk是:https://pan.baidu.com/s/1CQwBF7rNVSaIK9MR0eRuZA提取码:2gh1
adb shell am start -D -n com.green.weihelper/.ui.startup.StartupActivity
4.进入ida开始配置 attach进程
ida/Debugger/Attach/Remote ARMLinux/android debugger
设置好端口
- Suspend on process entry point:挂起进程入口;
- Suspend on thread start/exit:挂起线程入口;
-
Suspend on library load/unload: 挂起so加载和释放入口
5选择要调试的应用包名
找到要调试的应用包名的进程
确定后可以看到ida已经连接上andriod_server
等待ida加载后可以看到加载的模块等之类的信息
6再次勾选Debugger 选择(其实第一次:设置Debugger option选项,主要是设置在loadlibrary函数的时候开始挂起操作
设置好了,以后开始执行f9 ,开始调试操作。)
7、在hex view 中右键同步R0寄存器
ARM/THUMB汇编(补丁开发类)基础教程
IDA调试android so的.init_array数组--详细介绍do_dlopen逻辑
动态方式破解apk进阶篇(IDA调试so源码)-libcrackme.so过反调试
android调试系列--使用ida pro调试so-阿里安全挑战
ARM模式:
一般通用寄存器:R0~R12
R7:栈帧指针(Frame Pointer)和链接寄存器(link register, lr)在栈上的地址。
堆栈指针:R13
链接寄存器:R14
程序计数器:R15
THUMB模式:
一般通用寄存器:R0~R7
堆栈指针:SP
链接寄存器:LR(一般push 到寄存器,等函数返回时,在取出)
程序计数器:PC
比如:STRID s=STR(“你好”);
R0存的是“你好”,汇编要转成Unicode。R1存的是0,R2存的是0xFFFF
7、把手机中的/system/bin/linker 文件pull到电脑,并新打开一个ida打开该问题
把手机中的/system/bin/linker 文件pull到电脑
adb pull /system/bin/linker d:\temp\
新打开一个ida窗口,并大概刚才pull处理的文件
shfit+f12查找dlopen,ctrl+x查看引用
记住这个便宜地址:00001CD0
8、设置断点
设置断点1
在modules视窗搜索选择/system/lib/libart.so,双击
在Module:libart.so中搜索某个函数比如opendex,然后双击,并设置断点
设置断点2:
在modules视窗搜索选择/system/bin/linker,双击
记住 linker的基地址:B6F26000
基地址+便宜地址=B6F26000+00001CD0 =B6F27CD0
按g键跳转到:基地址+偏移地址
发现全部是DCB形式的代码(代码没有解析出来), 这个时候我们需要对linker进行分析, 操作如下: 右键->Analyze Module
分析linker模块
让ida获取linker模块快照
ida获取快照后可以看到正常的汇编代码,此时我们给它下个断点
9、然后按F9运行
然后按F9,注意观察寄存器窗口, 当有显示调试的是你想要断的so的时候开始注意
10、jdb方式启动
用ddsm查看一下app的端口
jdb方式通知apk继续执行。
#(jdb指令为jdk目录bin下的exe,没有环境变量要到该目录执行)
#其中8609就是你在ddsm上看到的端口号
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8609
测试app跳过刚才卡在debug状态的界面
ida中继续运行
说明:the execution will be resumed after the exception
其他 查看app的内存映射
####查app对应的进程id
adb shell ps |findstr weih
查看app的内存映射
#cat /proc/[pid]/maps
cat /proc/19339/maps
hook_dlopen时需要注意,去看看linker里或libc里面的函数名字,否则方法hook不到
每个手机会不一样
jni.h 的实现在哪里
arm/runtime/去找jni_inter xxx.cc