用gdb调了下源码,简单记录下,分享给需要的同学。
调试对象:com.android.phone中的librtp_jni.so, Android 6.0.1 angler userdebug, Nexus 6P,对应的源码为AudioGroup.cpp
1、前期准备:关闭dm-verity,并保持system分区可写
因为要替换so,android6.0以后有dm-verity,对system分区文件有校验,所以首先需要关掉它,具体方法:
userdebug版本如果需要remount system分区来push文件debug,不需要重新编译版本disable dm-verity,只需要执行以下adb命令即可。
adb root
adb disable-verity
adb reboot
重新启动后再执行:
adb remount rw,remount /system把system分区remount成rw。
注意:
(1)向system分区push文件后,不能再adb enable-verity,否则就会无法开机,。
(2)adb disable-verity/enable-verity 命令只能在userdebug模式下使用。user版本不支持关闭dm-verity。
2、编译保留符号的librtp_jni.so
在aosp源码目录中,找到librtp_jni.so的源码目录,修改Android.mk,加入或者修改(如果已有的话):
LOCAL_CFLAGS += -ggdb -O0
LOCAL_STRIP_MODULE = false
然后mm重新生成librtp_jni.so,并将其push倒/system/lib64下
3、拨打voip电话,使应用加载librtp_jni.so,此时可以在/proc/$PID/maps目录看到librtp_jni.so的加载
4、在root下运行gdbserver64,切记自处要运行手机CPU位数所对应的binary,因为nexus6P为arm64,因此要运行
gdbserver64 :1234 —-attach $PID
然后在Host上运行
adb forward tcp:1234 tcp:1234
aarch64-linux-android-gdb
target remote :1234
然后在gdb调试环境中运行,
target remote :1234
file $ANDROID_SRC/out/target/product/angler/symbols/system/bin/app_process64
set solib-search-patch $ANDROID_SRC/out/target/angler/symbols/system/lib64/
这里attach com.android.phone过后,上述设置加载符号等操作时间过长,该进程就变为僵尸进程。zygote会重新fork一个新的com.android.phone,导致调试失败
日志中可以看到
Killing 16649:com.android.phone/1001(adj -12): bg anr
这就需要aarch64-linux-android-gdb连上去后迅速输入continue,才不会导致上述情况。
可以考虑用脚本,加快速度
5、编写脚本,自动化测试
由于预先在librtp_jni.so下断点,需要让librtp_jni.so提前被com.android.phone载入,因此可提前打一次sip电话,在目标手机上接听并挂断。然后在host上编写自动化脚本,预先载入符号和断点,否则若动作过慢可能出现前述ANR问题
$ cat gdbcmd
shell adb forward tcp:1234 tcp:1234
target remote :1234
set solib-search-path $ANDROID_SRC/out/target/product/angler/symbols/system/lib64/
break AudioGroup.cpp:425
continue
在手机target上运行
# gdbserver64 :1234 —attach $PID
然后host上运行(需预先拷入源码编译后symbols目录下/system/bin/app_process64)
aarch64-linux-android-gdb -q -x gdbcmd app_process64
然后拨打sip电话接听,可成功触发断点,如图,
0x0000007f900db1b4 in ?? ()
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
Breakpoint 1 at 0x7f77e81fe8: file frameworks/opt/net/voip/src/jni/rtp/AudioGroup.cpp, line 425.
[New Thread 3695]
[Switching to Thread 3695]
gdb-peda$ list
420 if (length (int)sizeof(buffer) ||
421 (ntohl(*(uint32_t *)buffer) & 0xC07F0000) != mCodecMagic) {
422 ALOGV("stream[%d] malformed packet", mSocket);
423 return;
424 }
425 int offset = 12 + ((buffer[0] & 0x0F) <
426 if ((buffer[0] & 0x10) != 0) {
427 offset += 4 + (ntohs(*(uint16_t *)&buffer[offset + 2]) <
428 }
429 if ((buffer[0] & 0x20) != 0) {
gdb-peda$ p length
$3 = 0xe
gdb-peda$ p offset
$4 = 0x0
gdb-peda$ x/16wx buffer
0x7f777f9a98: 0x00006180 0x00000000 0xf90c2ece 0x00000a41
0x7f777f9aa8: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f777f9ab8: 0x00000000 0x00000000 0x00000000 0x00000000
0x7f777f9ac8: 0x00000000 0x00000000 0x00000000 0x00000000
接下来就可以愉快的调试了。
上述buffer为目标手机接收到的rtp header(12字节)及一个字节的payload,与测试发包内容对应
上传的附件:
rtpheader.png
(75.07kb,3次下载)