深入理解Android逆向调试原理


本文为看雪论坛优秀文章
看雪论坛作者ID:kxliping
一、为什么要写这篇文章
二、文本的目标读者是谁
1. 刚入门Android逆向的同学。
三、阅读本文的潜在收益是什么
阅读本文的潜在收获包括但不限于如下几点:
1. 对Android调试原理较为深入的理解;
2. 对Android逆向调试原理的深入理解;
3. 掌握Android逆向调试的操作步骤;
4. 掌握在没有DDMS的情况下逆向调试Android的操作技巧。
1. 对JDWP协议细节的介绍;
2. 对调试器内部原理的介绍;
3. 相关原理源代码的详细分析。
四、Android逆向调试的几个关键步骤
Adb shell下执行命令:
am start -D -n com.outdoor.debugtest/.MainActivity

ringtag:/data/local/tmp # ./android_server64
IDA Android 64-bit remote debug server(ST) v1.22. Hex-Rays (c) 2004-2017
Listening on 0.0.0.0:23946...
adb forward tcp:23946 tcp:23946





C:\Users\reverser>jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=55555
设置未捕获的java.lang.Throwable
设置延迟的未捕获的java.lang.Throwable
正在初始化jdb...
>
IDA output窗口显示目标SO文件被加载:
PDBSRC: loading symbols for '/data/app/com.outdoor.debugtest-iQxBx29FyKFuLtnU6wwQag==/lib/arm64/libnative-lib.so'...
在IDA Modules模块中搜索目标SO库并双击选中,找到目标函数下断,即可开启调试流程。
a. DDMS展示的端口号,是怎么得来的?有没有更加便捷的方式获取这个端口号?
b. Jdb connect命令是Java VM调试相关的命令,在SO调试中为什么要用它?它在和哪个模块进行通信?IDA附加上进程之后为什么不能直接开始调试?
c. Adb、android_server、IDA之间的关系是什么?IDA与应用进程之间的调试连接到底是如何建立的?IDA调试Android SO的技术原理是什么?
五、Android调试模型分析
1. Android源码对调试模型建立的描述
(1)当adbd启动之后,它会创建一个unix类型的server socket套接字,名字叫@jdwp-control;
(2)当一个新的JDWP守护线程在一个新的VM进程中启动时,这个新启动的JDWP线程会创建一个到@jdwp-control的连接,以宣告它自己的可用性:
50 JDWP thread @jdwp-control
51 | |
52 |-------------------------------> |
53 | hello I'm in process <pid> |
54 | |
55 | |
(5)Adbd收到命令后,执行如下操作:
调用socketpair()创建一对“equivalent sockets”; 将第一个socket附加到本地socket,本地socket本身又连接到远程socket;
使用sendmsg()将第二个socket的文件描述符直接发送给JDWP进程。
JDWP thread @jdwp-control
| |
| <----------------------|
| OK, try this file descriptor |
| |
| |
(6)接着,JDWP线程使用这个新的socket描述符作为它与调试器的通信通道(接收JDWP-Handshake消息,应答调试器的消息等等)。
____________________________________
| |
| ADB Server (host) |
| |
Debugger <---> LocalSocket <----> RemoteSocket |
| ^^ |
|___________________________||_______|
||
Transport ||
(TCP for emulator - USB for device) ||
||
___________________________||_______
| || |
| ADBD (device) || |
| VV |
JDWP <======> LocalSocket <----> RemoteSocket |
| |
|____________________________________|


归纳而言之,原生基于JDWP的调试框架与IDA的android调试框架,是两个层面上的调试实现,前者是虚拟机层面的实现,后者是整个进程层面的实现。理解这一点对理解Android逆向调试的原理至关重要。
六、逆向调试关键步骤解密
有了以上知识的铺垫,我们就可以开始研究第四章中提出的几个问题了。
1. DDMS展示的端口号,是怎么得来的?有没有更加便捷的方式获取这个端口号?
根据前一章的阐述,调试器通过执行“adb forward tcp:<hostport> jdwp:<pid>”命令将host机器上的hostport端口转发到Android上的调试进程,以便调试器通过这个端口连接到目标进程。所以这个hostport是调试器指定的,据此推测,DDMS便是通过这种转发方式获取到这个端口并展示到界面上。
因此,我们可以通过“adb forward tcp:<hostport> jdwp:<pid>”命令,替代使用DDMS的方式。
与问题1相关的进一步思考
当我们以调试模式启动应用时,应用会输出如下形式的日志信息:
--------- beginning of system
03-08 10:01:05.709 6761 6761 W ActivityThread: Application com.outdoor.appcomvulbypassactivityperm is waiting for the debugger on port 8100...
日志信息表明应用在端口8100处等待调试连接,那是不是表明我们可以直接将hostport转发至Android 8100端口呢,尝试后你会发现不会成功。原因如下:
Android应用的调试模式有“dt_socket”和“dt_android_adb”两种,即通过socket或者adb连接到JDWP线程。所以理论上,通过将hostport转发到8100也是可以实现的。但进一步分析源码之后发现,Android虚拟机默认以“dt_android_adb”的模式启动,并且这个启动参数硬编码在源文件之中,不可手动配置的。
601 int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
602 {
……
772
773 /*
774 * Enable debugging only for apps forked from zygote.
775 * Set suspend=y to pause during VM init and use android ADB transport.
776 */
777 if (zygote) {
778 addOption("-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y");
779 }
……
995 if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
996 ALOGE("JNI_CreateJavaVM failed\n");
997 return -1;
998 }
999
1000 return 0;
1001 }
在前面一章中,我们明确了通过原生JDWP的方式调试与使用IDA调试是两个层面的调试手段。
____________________________________
| |
| IDA (host) |
| |
| RemoteSocket |
| ^^ |
|___________________________||_______|
||
Transport ||
(TCP for emulator - USB for device) ||
||
___________________________||_______
| || |
| android_server (device) || |
| VV |
PROCESS <======> ptrace <----> RemoteSocket |
| |
|____________________________________|
七、总结
经过以上几个章节的阐述,我希望已经讲清楚我提出的那些问题,也希望这篇文章能够达到它的目的。
看雪ID:kxliping
https://bbs.pediy.com/user-home-508256.htm
*这里由看雪论坛 kxliping原创,转载请注明来自看雪社区。
# 往期推荐


球分享

球点赞

球在看

点击“阅读原文”,了解更多!
-
谷歌发布Android 2月例行安全更新 修复已被黑客利用的高危安全漏洞
谷歌已经向 Android 项目发布 2025-02-01 和 2025-02-05 安全补丁级别,这是谷歌面向安卓系统发布的 2025-02 月例行安全更新,至于为什么有两个补丁级别是因为 02-0
-
谷歌从Chromium for Android中删除密码存储 这导致第三方软件出问题
据开源浏览器项目 Cromite 用户提交的反馈信息,自 Chromium for Android M132 版开始,浏览器的已保存密码会变成空白状态。尽管检查设置可以看到保存密码但实际情况是无论是新
-
安卓用户务必注意!新型木马病毒肆虐全球:小心账户一夜归零
据媒体报道,一款名为“ToxicPanda”的新型木马病毒正在广泛传播,专门针对Android系统设备,企图通过复杂手段绕过银行安全措施,窃取用户账户甚至存款。报道称,这款新型恶意软件最初由米兰网络安
[广告]赞助链接:
关注数据与安全,洞悉企业级服务市场:https://www.ijiandao.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

随时掌握互联网精彩
- 网易云音乐接入 DeepSeek-R1 大模型 用于歌曲智能推荐等领域
- Mermaid基于文本的可视化工具
- 微软修复Outlook(Win32版)复制内容卡死和无法添加谷歌Gmail账号的问题
- Proxmox,开源虚拟化与邮件安全的强大解决方案
- Sedo,全球知名的域名交易管理平台
- 张勇发阿里云全员信:要求视客户信任为生命;苹果因不送充电器在美面临新集体诉讼;Kotlin 1.8.0 发布|极客头条
- 高通汽车业务订单总估值增长至300亿美元
- 卷到自己?继 Imagen 之后,推出200 亿文本生成的图像模型惊呆网友!
- 浙商银行与华为公司签署战略合作协议
- 什么是代码签名证书
- Redmi AirDots 3真无线蓝牙耳机:诚意升级,宠爱双耳
- Qualcomm推出全新骁龙480 5G移动平台,首次将5G扩展至搭载骁龙4系的移动终端