0x00 背景
之前的文章介绍了iOS程序动态debug方法,本文将介绍Android程序的动态debug方法。
0x01 各种安装
-
在Android手机上安装gdbserver:
打开Android Studio,打开Tools->Android->SDK Manager,打开SDK Tools 选项卡,选择安装Android NDK。安装完之后,用everything搜索gdbserver,根据自己的手机的cpu选择gdbserver,我的是32位arm,则选择arm。将该gdbserver用adb push 拷贝到手机上。
-
在NDK的目录下找到bin/gdb,作为客户端。
2. 在电脑上(windows)下载arm-gdb。 -
(optional)最好在手机上安装busybox,里面有很多常用命令(pgrep等),比较方便。
-
(optional)安装adbd-insecure,使得你的adbd可以以root身份运行。
5.(optional)Ubuntu上可以安装gdb-multiarch:sudo apt-get install gdb-multiarch
。
0x02 开始debug
-
在Android上使用
ps | grep AppName
或pgrep AppName
来找到App的进程号pid -
在Android上启动debugserver,attach上刚刚的进程号
./gdbserver tcp:9090 --attach [pid]
-
还需要将tcp端口转发,在电脑上执行:
adb forward tcp:9090 tcp:9090
-
在电脑上启动ndk的gdb:
gdb (gdb)set architecture arm (gdb)target remote :9090 (gdb)set arm force-mode thumb // or arm if the instructions look weird
-
在电脑上启动gdb,如果是gdb-multiarch (
sudo apt-get install gdb-multiarch
):gdb-multiarch (gdb)set architecture arm (gdb)layout asm (gdb)target remote :9090 (gdb)set arm force-mode thumb // or arm if the instructions look weird
如果是arm-gdb:
arm-none-eabi-gdb.exe (gdb)target remote :9090 (gdb)set arm force-mode thumb // or arm if the instructions look weird
0x03 gdb使用方法
查看寄存器信息:
info register
info register rip
设置断点:
b *0x7583e652
b func_name
查询App基址:
在Android上执行
cat /proc/`pgrep AppName`/maps | grep libcocos2d.so
或者在gdb中输入
info proc mappings
设置寄存器的值
p $pc=0xFFFFFFFF
0x04 注意点
要安装最新的ndk(我装的是NDK12),否则gdb会有很多bug。
此时电脑上的gdb客户端使用prebuilt\windows-x86_64\bin\gdb.exe
(Mac的话是prebuilt/darwin-x86_64/bin/gdb
)。
然后将prebuilt\android-arm64\gdbserver
push到手机上,作为服务器端。当然如果你是32位的安卓,则用32位的gdbserver即可。
设置断点
设置断点时要注意设置的地方的函数是arm模式还是thumb模式的,不同的模式断点的字节数和命令是不一样的,如下:
set arm force-mode arm
> f0 01 f0 e7
set arm force-mode thumb
> 01 de
不知出于什么原因,有时候在设置断点后必须删除或者disable断点,否则即使输入c程序也无法执行。再不行的话把原来的字节写回内存,强制取消断点:
set {int}0x83040 = 4
更简单的方法
直接从这个网站下载Android用的gdb就好了,可以直接在Android上运行。http://dan.drown.org/android/howto/gdb.html。
该项目虽然已经不再维护,但是还是挺好用的,AOS 5.0以下可以使用该项目,5.0以上可以使用termux(未测试)。