linux内核分析通常需要编译带符号的文件或安装带符号的内核才方便分析,这里记录下直接解压vmlinuz从导入 sudo cat /proc/kallsyms实现二进制分析linux内核
解压内核
lier@lier-vm:~$ sudo bash
//1查找压缩文件位置 位于1f 8b 08
root@lier-vm:/home/lier# od -t x1 -A d code/vmlinuz-5.8.0-55-generic | grep "1f 8b 08"
0016800 8d 80 00 02 00 00 ff e0 1f 8b 08 00 00 00 00 00
root@lier-vm:/home/lier# cd code/
//2.解压内核skip偏移位于16800+8, 偏移处
root@lier-vm:/home/lier/code# dd if=vmlinuz-5.8.0-55-generic bs=1 skip=16808 | zcat >vmlinux-jay5-8
9779096+0 records in
9779096+0 records out
9779096 bytes (9.8 MB, 9.3 MiB) copied, 9.7599 s, 1.0 MB/s
gzip: stdin: decompression OK, trailing garbage ignored
root@lier-vm:/home/lier/code# file vmlinux-jay5-8
vmlinux-jay5-8: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=446519eb5d6d021a525bf98dd4b51924c50852e0, stripped
root@lier-vm:/home/lier/code# exit
exit
导出内核符号
lier@lier-vm:~$ sudo cat /proc/kallsyms > kallsyms.txt
ida解析脚本导入内核符号
import idaapi
import idautils
import idc
def do_rename(l):
splitted = l.split()
straddr = splitted[0]
strname = splitted[2].replace("\r", "").replace("\n", "")
eaaddr = int(straddr, 16)
#idc.MakeCode(eaaddr)
#idc.MakeFunction(eaaddr)
#idc.MakeNameEx(int(straddr, 16), strname, idc.SN_NOWARN)
idc.set_name(eaaddr, strname, idc.SN_NOWARN)
if __name__ == "__main__":
with open( "D:\\code\\kallsym.txt", "r") as f:
for l in f:
do_rename(l)
这时内核部分的符号就恢复的差不多了。
其它问题
内核较高版本估计会默认开启随机化,脚本执行半天没反应,而且ida7.5对python脚本不友好。
解决办法是根据startup的地址,计算随机化偏移。rebase ida 的image segment, 或者直接修改脚本中的符号地址
结果
下图为正在恢复的符号