1.下载并编译arm64平台上的crash工具
从github上下载crash工具源代码:
git clone https://github.com/crash-utility/crash.git
编译针对arm64平台的crash工具:
make target=ARM64
sudo make install
2.解析高通的ramdump数据
使用crash加载ramdump数据,使用如下crash命令:
crash vmlinux --kaslr=0x5d8800000 --machdep kimage_voffset=0xffffff8560800000 DDRCS0_0.BIN@0x80000000,DDRCS0_1.BIN@0x100000000,DDRCS1_0.BIN@0x140000000,DDRCS1_1.BIN@0x1c0000000
我们可以看到它有多个参数,各个参数都有它的含义,对于内核使能了KASLR功能特性,那么需要传递对应kaslr offset值给到crash工具,由于使能了kaslr功能,它是内核的一个安全特性,为了防止黑客修改内核数据,该特性会使内核的运行地址和vmlinux中编译出来的地址并不相符,并且是每次reboot后内核加载运行的地址都不一样,因此我们需要针对每次dump获取到对应的kimage_voffset偏移量并传递给crash工具进行解析。
经过我的调查发现,实际上 --machdep kimage_voffset=0xffffff8560800000
参数可以不用配置,参考github提交:
https://github.com/crash-utility/crash/pull/7/commits
发现实际上crash工具已经有patch实现从kaslr offset计算出对应的kimage_offset的功能,因此该命令可以简化为:
crash vmlinux --kaslr=0x5d8800000 DDRCS0_0.BIN@0x80000000,DDRCS0_1.BIN@0x100000000,DDRCS1_0.BIN@0x140000000,DDRCS1_1.BIN@0x1c0000000
等待一段时间后,crash成功打印出解析情况:
crash 7.2.8++
Copyright (C) 2002-2020 Red Hat, Inc.
Copyright (C) 2004, 2005, 2006, 2010 IBM Corporation
Copyright (C) 1999-2006 Hewlett-Packard Co
Copyright (C) 2005, 2006, 2011, 2012 Fujitsu Limited
Copyright (C) 2006, 2007 VA Linux Systems Japan K.K.
Copyright (C) 2005, 2011 NEC Corporation
Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions. Enter "help copying" to see the conditions.
This program has absolutely no warranty. Enter "help warranty" for details.
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=aarch64-elf-linux"...
WARNING: kernel relocated [23944MB]: patching 130501 gdb minimal_symbol values
KERNEL: vmlinux
DUMPFILES: /var/tmp/ramdump_elf_EWmlOx [temporary ELF header]
DDRCS0_0.BIN
DDRCS0_1.BIN
DDRCS1_0.BIN
DDRCS1_1.BIN
CPUS: 8
DATE: Sat Jan 10 13:08:25 1970
UPTIME: 00:00:17
LOAD AVERAGE: 0.61, 0.13, 0.04
TASKS: 465
NODENAME: (none)
RELEASE: 4.14.78+
VERSION: #2 SMP PREEMPT Fri Dec 7 13:10:24 CST 2018
MACHINE: aarch64 (unknown Mhz)
MEMORY: 5.6 GB
PANIC: "[4:574:modprobe] kernel BUG at /home/flyme/NewFlyme/Code/jenkins-FLYME7-M1971_QPF7_base-USER-192/kernel/msm-4.14/mm/usercopy.c:72!"
PID: 574
COMMAND: "modprobe"
TASK: ffffffff9fba8080 [THREAD_INFO: ffffffff9fba8080]
CPU: 4
STATE: TASK_RUNNING (PANIC)
crash> bt
PID: 574 TASK: ffffffff9fba8080 CPU: 4 COMMAND: "modprobe"
3.参数的获取
上面已经介绍了如何使用crash去解析高通的ramdump,但是还有一个问题没有解决,就是如何确定kaslr的值?后面传递的DDRCS0_0.BIN 是什么?
-
如何确定kaslr?
高通平台上获取kaslr,可以使用如下命令:
hexdump -e '16/4 "%08x " "\n"' -s 0x03f6d4 -n 8 OCIMEM.BIN d8800000 00000005
这里打印出来
d8800000 00000005
需要进行一下组合,变成0x5d8800000
然后传入即可参数即可。OCIMEM.BIN
文件是高通QPST工具抓取ramdump数据中的一个文件。
怎么确定kaslr地址的呢?实际上从高通提供的ramparser解析工具中可以查看,不同平台可能会不一样,比如如下:
self.imem_start = 0x14680000
self.kaslr_addr = 0x146bf6d0
self.imem_file_name = 'OCIMEM.BIN'
0x146bf6d0 - 0x14680000 = 0x03f6d0
因此只需要hexdump出来OCIMEM.BIN中的对应地址即可看到kaslr的值。
-
DDRCS0_0.BIN文件是什么?
从名字上看,它就是DDR中的内容,高通QPST是用于在手机crash之后进行内存数据收集的工具,收集出来的内存数据都会以此来命名,
DDRCS0_0.BIN DDRCS0_1.BIN DDRCS1_0.BIN DDRCS1_1.BIN
等。上面的crash命令遵循MEMORY-IMAGE@[ADDRESS]
的格式来传入dumpfile,这些address在高通同一个平台上是固定的,具体要参考高通对应平台的文档。
参考:
https://github.com/crash-utility/crash/pull/7/commits
https://blog.csdn.net/tuyerv/article/details/86230908
https://sysprogs.com/VisualKernel/tutorials/kaslr/