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
.
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!