A64Dbg从1.9.1版本开始,我们正式启用了代码页托管模式的虚拟化调试。这个模式的直接好处是:
当我们拿到一个新样本的时候,用这个模式作为分析的切入点是非常不错的。当然,由于托管了断点所在的代码页,UraniumVM虚拟机在执行性能上肯定是没有Native模式高,但是这并不妨碍我们调试。毕竟,1s执行完毕还是5s执行完毕,对于调试这种场景来说是无所谓的。
下面跟着文章的步骤,我们来一步步搭建环境和做一些基本操作。
Windows用户在如下地址下载最新的桌面主程序:
Intel macOS用户在如下地址下载最新的桌面主程序:
ARM macOS用户在如下地址下载最新的桌面主程序:
注意,非常重要的一个细节:首次启动A64Dbg主程序时,一定要允许其使用网络,如果不小心禁止了,需要在防火墙配置里面允许A64Dbg的网络输入输出。因为,虚拟化调试模式需要在A64Dbg与Debugee之间建立TCP连接,用于传输虚拟机上下文和调试操控协议。
首先,下载最新的服务端程序包,在如下地址:
1.Android用户需要把如下文件夹的内容全部放在手机的/data/local/tmp目录:
注意,非常重要的细节,Android使用虚拟化调试模式时,必须关闭SELinux,否则无法使用Launch APK Activity这个功能,而这是过反调试的关键:
然后,使用A64Dbg主程序之前,请先保持a64dbg-server-arm64/lidadbg-server处于运行状态。
iOS越狱环境由于有CydiaSubstrate/deb框架,因此把代码跑在任意进程相对容易很多。并且Frida-Inject在iOS平台也是使用mach api进行注入,与ptrace不冲突,所以就算App Deny Ptrace了,依旧可以Frida Inject。
Android平台就没有这么幸运了,首先是没有一个成熟的类似于deb这样的插件框架,其次是Frida-Inject的机制基于ptrace,所以如果App先调用了Ptrace-Attach,那么所有基于该机制的工具将无法工作,比如LLDB/Frida。面对这类Debugee,从最原点开始干活的Launch操作就是必须的了。
由于Android机制的特殊性,所有第三方App都是由Zygote Fork出来的,所以,我们需要一种机制,在Zygote Fork出App进程之后第一时间通知A64Dbg Attach。下面介绍A64Dbg使用的两种方案。
步骤一:安装Riru Zygote注入框架
步骤二:安装ADZygote反向Attach框架
对于非Magisk Root环境,需要你手动DIY一下,利用Xpose或者LLDB注入一个so至Zygote进程,然后根据架构主动dlopen:
PoC代码如下:
这段PoC就是cn.yunyoo.adzygote-v25.zip的实现逻辑。而pthread_atfork对等的功能就是Riru这个框架做的事情,只是Riru基于Magisk利用Native Bridge做得更好,功能更强大。
如果你可以把系统ro.debuggable设置为1,那么可以使用jdwp协议来达到从头控制目标样本的目的。
步骤一:系统设置里面的开发者选项将目标样本设置为调试启动,这样启动目标程序时就会弹出等待调试器的对话框;
步骤二:使用A64Dbg Attach之后使用jdwp协议开始程序的运行过程:



如果有些模块不在这个列表中,则使用Refresh菜单刷新一下:

设置Page模型的断点,这种断点模型不会修改代码内存:

操作样本程序,断点击中之后,我们就可以正常调试了,注意它的TracerPid是0,因为我们并没有依赖Ptrace这种调试机制。

此时,授权版本就可以正常的F4、F7、F8、Trace了。免费版本的用户可以开发ADCpp、Decompiler、ADP等等自动化的脚本了。比如右键Decompile一下:
或者写一些ADCpp脚本,这个可以参见这篇文章《ADCpp-实战itunesstored kbsync远程调用》:
Have fun~
https://gitee.com/geekneo/A64Dbg-Win
https://gitee.com/geekneo/A64Dbg-Win
https://gitee.com/geekneo/A64Dbg-Mac
https://gitee.com/geekneo/A64Dbg-Mac
https://gitee.com/geekneo/A64Dbg-iOS
https://gitee.com/geekneo/A64Dbg-iOS
https://gitee.com/geekneo/A64Dbg
https://gitee.com/geekneo/A64Dbg
2021/01/26 11:39 <DIR> a64dbg-server-arm
2021/05/10 15:37 <DIR> a64dbg-server-arm.uvm
2021/01/26 11:39 <DIR> a64dbg-server-arm64
2021/05/10 15:37 <DIR> a64dbg-server-arm64.uvm
2021/01/26 11:39 <DIR> a64dbg-server-arm
2021/05/10 15:37 <DIR> a64dbg-server-arm.uvm
2021/01/26 11:39 <DIR> a64dbg-server-arm64
2021/05/10 15:37 <DIR> a64dbg-server-arm64.uvm
setenforce 0
2019/12/29 19:12 2,390,890 a64dbg-server.deb
2021/05/14 14:46 320,072 a64dbg-server.uvm.deb
https://gitee.com/geekneo/Textobot/blob/master/iOS/Textobot.deb
2019/12/29 19:12 2,390,890 a64dbg-server.deb
2021/05/14 14:46 320,072 a64dbg-server.uvm.deb
https://gitee.com/geekneo/Textobot/blob/master/iOS/Textobot.deb
A64Dbg/launch-apk/riru-v25.zip
A64Dbg/launch-apk/riru-v25.zip
A64Dbg/launch-apk/cn.yunyoo.adzygote-v25.zip
A64Dbg/launch-apk/cn.yunyoo.adzygote-v25.zip
/data/local/tmp/a64dbg-server-arm64.uvm/libadzygote.so
/data/local/tmp/a64dbg-server-arm64.uvm/libadzygote.so
void fork_atchild(void) {
// notify a64dbg in its ctor function
dlopen("/data/local/tmp/a64dbg-server-" AD_ARCH ".uvm/libadzygote.so", RTLD_NOW);
}
// fork_atchild will be invoked after zygote forked the target app
void init_in_zygote(void) {
pthread_atfork(nullptr, nullptr, fork_atchild);
}
void fork_atchild(void) {
// notify a64dbg in its ctor function
dlopen("/data/local/tmp/a64dbg-server-" AD_ARCH ".uvm/libadzygote.so", RTLD_NOW);
}
// fork_atchild will be invoked after zygote forked the target app
void init_in_zygote(void) {
pthread_atfork(nullptr, nullptr, fork_atchild);
}
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
Launching /data/app/so.a64dbg.crackme1-wwI87g4EZ2tZ2mXJssB6MA==/base.apk with am start -S -n so.a64dbg.crackme1/so.a64dbg.crackme1.MainActivity.
Remote new uvm client 192.168.0.100:38071 connected.
uvmdbg : Connected to 192.168.0.105:30331.
Remote uvm debuggee triple aarch64-linux-android, page size 0000000000001000, page mask 0000000000000FFF.
[培训]科锐软件逆向54期预科班、正式班开始火爆招生报名啦!!!