安卓逆向_17 --- IDA 动态调试【 环境搭建、so库调试【动态普通、动态debug模式】、JNI_OnLoad调试分析、java_ 开头函数分析】
哔哩哔哩视频:https://www.bilibili.com/video/BV1UE411A7rW?p=54
IDA Pro调试so,附加完毕,跳到目标so基址,但是内容都是DCB伪指令?:https://bbs.pediy.com/thread-222646.htm
Android 中 adb shell ps 查看手机中进程信息:https://blog.csdn.net/qq_15212357/article/details/81063622
ida pro 动态调试步骤:https://www.jianshu.com/p/d2d28920940c
1. 创建虚拟机
通过 Android Studio 的 AVD Manager 新建一个虚拟机
点击 AVD Manager 新建一个虚拟机
2. 设置 IDA Pro 的远程调试
将 IDA Pro 中 android_server 这个文件传到 虚拟机中
使用IDA 进行远程调试( 原理 ):https://blog.csdn.net/eqera/article/details/8239622
ARM Linux下搭建IDA Pro远程调试环境:https://bbs.pediy.com/thread-224337.htm
这里以 雷电模拟器 为例,首先确定 雷电模拟器 的 安卓版本,安装 device info hw.apk ( https://www.cr173.com/soft/845060.html ),打开 app 即可查看 安卓平台类型
所以选择 andriod_x86_server 文件,使用 adb push 传文件到 模拟器,并添加 可执行 权限,然后运行。
adb push 源文件 目的地址
这里是导入 源文件 到 /data/local/tmp 目录下。
然后加上可执行权限 chmod a+x andriod_server ( 或者 chmod 777 andriod_server )
3. 启动 android_server 和 执行 端口转发
执行 android_server
在打开一个 cmd 窗口,执行 端口转发:adb forward tcp:23946 tcp:23946
如果有多个设备时,可以使用 -s 参数连接指定的设备
adb forward 简单使用
adb forward 的功能是建立一个转发
示例:( 将PC端的11111端口收到的数据,转发到手机中22222端口。 )
adb forward tcp:11111 tcp:22222
但是光执行这个命令还不能转发数据,还需要完成两个步骤才能传数据。这两个步骤是:
1. 在手机端,建立一个端口为 22222 的 server,并打开 server 到监听状态。
2. 在PC端,建立一个 socket client 端,连接到端口为 11111 的 server 上。
这两个步骤有先后顺序,
步骤1 要先执行。
步骤2 即 adb forward tcp:11111 tcp:22222 后执行
adb forward 的一些基本操作 ( adb forward 命令的一些帮助信息,可以直接执行 adb 看到。 )
配好 adb 的环境,连上手机,执行 adb forward tcp:11111 tcp:22222
如果执行成功的话,没有任何输出。
此时,通过运行 adb forward --list 查看刚才的执行结果:
$ adb forward --list
4391b53a tcp:11111 tcp:22222
可以通过 adb forward --remove tcp:11111 删除建立的转发。
PC端:端口为 11111 的 server
执行 adb forward tcp:11111 tcp:22222 之后,通过 netstat -a 可以看到下面的信息:
TCP 127.0.0.1:11111 LAPTOP-B0112F9S:0 LISTENING
在PC端,adb forward 创建了一个监听本机11111端口的server。
通过adb 转发的数据,需要先发到11111端口(在本例中如此)。
这个11111端口是约定好的,你也可以改成其他端口。
PC端的应用通过socket连接到11111端口,以准备发送数据。
但是连接到11111端口之前,还需要在手机端启动端口为22222的server。
手机端:端口为 22222 的 server
在PC端的应用开始连接之前,手机端要启动端口为 22222 的 server(socket server)。
手机中adb 的 daemon进程将连接到22222端口,这样PC端应用就可以连接PC端的11111端口了,
连接上之后就可以从PC端的应用发送数据给手机端的应用,
手机端的应用也可以发送数据给PC端的应用。
4. IDA Pro 的 Debugger 设置
( 动态调试的时候不需要再使用 IDA 打开 so 文件了,但是需要 IDA 附加到对应进程。 )
打开 IDA Pro ,选择 go,即 直接进入IDA,不打开任何文件
然后 Debugger —> Attach —> Remote ARM Linux/Android debugger,填写ip地址、端口 ( 这个端口就是上面命令转发的端口 )
如果是 arm linux 虚拟机和真机,选择 Remote ARM Linux/Android debugger ,如果是 x86 的虚拟机,则选择 Remote Linux Debugger
点击 OK ,就会连接到虚拟机,如果连接成功,会弹出一个窗口,上面显示了虚拟机中运行的进程,
选择要进行附加的进程,点击 ok,载入成功后,如图所示,程序断到了 libc.so 的位置。 9′ 50”
( *************** 雷电模拟器4下完断点,无法断到 libc.so, 雷电模拟器3 可以在 libc.so 断下 *************** )
因为要调试的 so 是 javandk1,所以可以在 modules 里面直接搜索 javandk1,双击对应模块进入模块。
( 也可以 ctrl + s 找到要调试的so文件 选择用X字样(可执行的))
IDA Pro 的 Modules这个子窗口功能是 “列出加载的所有 so”,所以可以在 Modules 里面搜索 要调试的so库 javandk1
双击搜索结果,跳转到对应so库里面,然后可以查看 so 库里面的方法
查看 so 库里面的方法,如图所示:
跳转到 so库中函数对应位置,这里以 getText 函数为例进行跳转,并 下断点
触发断点( 雷电模拟器下完断点,无法断到 libc.so )
调试 so
小技巧:按下ESC 或者 直接点击PC寄存器 ( 右边寄存器列表可以找到PC寄存器 ) 或者 右键—>jump,即可以直接返回上一步操作所在位置。。。
5. 动态 普通调试 的 调试步骤
https://www.bilibili.com/video/BV1UE411A7rW?p=55
上面的 “IDA Pro 的 Debugger 设置” 就是 动态 普通调试。
动态 普通调试 步骤总结:
##################################################################################
普通调试模式 ( 界面出现后,可以手动操作界面 )
1. 将 IDA Pro 中 dbgsrv 目录下的 android_server 文件导入到手机端
adb push D:\Software\IDA_Pro_v7.2\dbgsrv\android_server /data/local/tmp
2. 查看是否导入成功,并添加可执行权限,然后运行
adb devices # 列出设备
adb shell # 连接手机,进入 shell
su # 切换 root
cd /data/local/tmp # 切换到导入的目录
ls -al # 列出所有文件
chmod a+x android_server # 添加可执行权限
./android_server # 执行程序,(端口号默认是:23946)
3. 执行 端口转发
adb forward tcp:23946 tcp:23946
远程调试分为主动连接调试,和被动连接调试
- 主动连接调试:服务端配置监控端口,本地IDE连接远程监听端口进行调试,一般调试问题用这种方式。
- 被动连接调试:本地IDE监听某端口,等待远程连接本地端口。一般用于远程服务启动不了,启动时连接到本地调试分析。
程序挂起后, Debugger —> Debugger option ,勾选 3 个复选框
就可以断点到 so 载入和卸载,如果想在自己打断点的位置断下,则去掉三项,然后运行即可断下。。。
6. 动态 debug模式 的 调试步骤
https://www.bilibili.com/video/BV1UE411A7rW?p=56
然后执行 jdb 命令,即可开始进行 so 库 的 调试。使用JDB进行调试:https://www.jianshu.com/p/5a64ed722b91
am 这个指令是 activity manager 的缩写。这个命令可以启动 Activity、打开或关闭进程、发送广播等操作。
根据 Intent 启动 Activity。am 命令格式:adb shell am <command>
options 参数如下:( -D 开启 debug 模式 )
-D: 开启debug模式
-W: 等待启动完成
--start-profiler<FILE>: 将profiler中的结果输出到指定文件中
-P: 和 --start-profiler 一样,区别在于,在app进入idle状态时profiler结束
-R <Count>: 重复启动Activity,但每次重复启动都会关闭掉最上面的Activity
-S: 关闭Activity所属的App进程后再启动Activity
--opengl-trace: 开启OpenGL tracing
--user <USER_ID>: 使用指定的用户来启动activity,如果不输入,则使用当前用户执行
第八步所使用的端口就是 8602
动态 调试模式 的 调试步骤:( 动态调试步骤:ida动态调试:https://www.cnblogs.com/LuLuLuHao/p/12866289.html )
##################################################################################
debug 调试模式
( 如果一些执行比较早的函数,也就是在界面出现之前,就只有使用 debug 调试模式 )
1. 将 IDA Pro 中 dbgsrv 目录下的 android_server 文件导入到手机端
adb push 文件名 /data/local/tmp/as
2. 查看是否导入成功,并添加可执行权限,然后运行
打开一个cmd窗口:运行 android_server。步骤:
1) adb shell 连接手机
2)给一个最高权限:su
3)来到 /data/local/tmp 目录,cd /data/local/tmp
4) 给 androi_server 最高的权限:chomd 777 android_server
5) 查看 android_server 是否拥有权限:ls -l
6) 运行 andorid_server。命令: ./android_server(端口号默认是:23946)
补充:运行 andorid_server 并且修改端口号: ./android_server -p 端口号
3. 执行 端口转发
adb forward tcp:23946 tcp:23946
4. 打开 ddms 或者 monitor,后面会用到
5. 获取要调试的app的 包名 和 入口页面。
(可以使用 AndroidKiller 找到 AndroidManifest.xml)
package="com.example.calc"
<activity android:name="com.example.calc.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
6. 挂起程序:
adb shell am start -D -n 包名/类名
例子: adb shell am start -D -n com.example.javandk1/.MainActivity
执行完 adb shell am start -D -n 包名/类名 后,
真机或者模拟器上会显示 Waiting For Debuger
补充:此时观察 DDMS,被调试的程序前面有一个 红色 的虫子;
7. 打开 IDA,然后在 IDA 里面勾选三项。
1)打开ida ---> 工具栏的debugger ---> Attach ---> Remote ARMlinux(第四项)
2)添加 hostname 和 portt:
hostname:主机号(默认127.0.0.1)
port:端口号(之前android_server运行时的端口号或者端口转发的端口号)
3)出来进程列表:选择要调试的程序( 可以 ctrl+f,搜索包名)
4)进来后,勾选三项:
Suspend on process entry point 程序入口点 断下
Suspend on thread start/exit 线程的退出或启动 断下
Suspend on library load/unload 库的加载和卸载 断下
8. 挂载、(主动连接调试)。
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=端口号
端口号是在 ddms 或者 monitor 里面看到的
补充:此时观察 DDMS,被调试的程序前面有一个 绿色 的虫子;
9. 点击IDA上面的 运行(即绿色三角符号),运行程序,会在勾选的三项的位置断下来,
查看 IDA 下面的 log 输出,看要调试的so是否加载,
如果没有加载,则再次点击 运行 (每点击一次,加载一个so)
( 或者 ctrl + s ,ctrl + f ,搜索 对应的so,看有没有加载 )
如果加载,就可以在so中函数下断点,然后取消三项,点击运行,就可以在断点处断下。
10. 然后就可以在 JNI_Onload 下断点了。
通过 AndroidManifest.xml 找到 ” 包名 “,
然后以 debug 模式启动,如图所示
命令:adb shell am start -D -n com.example.javandk1/.MainActivity
下边的步骤就和上面 普通模式 的一样了,打开 IDA Pro,附加到进程,如图所示:
这时在 Modules 里面搜索 要调试的so库 javandk1,发现搜索不到
勾选三项,在 进程入口点、线程开始和退出、so加载和卸载 的时候 断下来。
*****************************************************************************************
IDA Pro 报 FFFFFFFF: got SIGILL signal (Illegal instruction) (exc.code 4, tid 2536) 这个警告,
百度了下这个警告,看雪论坛( https://bbs.pediy.com/thread-206348-1.htm ) 说是使用root真机不会出现这个警告,
还有说是 拟器为x86架构,而so程序是ARM架构的原因(https://blog.csdn.net/whklhhhh/article/details/78352083)
猜测上面不能断点调试也是这原因,有时间搞真机试试。。。
*****************************************************************************************
7. JNI_OnLoad 调试分析( ARM 汇编 和 寄存器 分析 )
https://www.bilibili.com/video/BV1UE411A7rW?p=57
10′ 16” 14’05” ( 按 C 键,识别为 code )
8. Java_ 开头 的 方法 的 调试
https://www.bilibili.com/video/BV1UE411A7rW?p=58
打开 ddms 或者 monitor ,如果可以看到进程列表,说明系统的调试开关是开启的。。。
java_ 开头函数分析 9′ 40”
9. 动态 内存数据修改
游戏辅助原理
https://www.bilibili.com/video/BV1UE411A7rW?p=59
同步 PC 寄存器
修改内存数据,然后提交修改 3′ 25”
免责声明:全网优质文章转载,以作为收藏留档之用,文章均不代表本人立场!
请尊重原创作者,如需转载请标注原创作者链接