Linux 内核 调试笔记

2020-07-08 00:00:00 函数 专区 内核 地址 打桩

使用kallsyms_lookup_name读取

kallsyms_lookup_name本身也是一个内核符号,如果这个符号被导出了,那么就可以在内核模块中调用kallsyms_lookup_name("do_page_fault")来获得do_page_fault的符号地址。

这种方法的局限性在于kallsyms_lookup_name本身不一定被导出。

CONFIG_KALLSYMS 依赖该内核选项

头文件 linux/kallsyms.h

使用 Kprobes 调试内核

ftrace kprobe调试 - CSDN博客


ARM64内核态 函数打桩

头文件依赖

#include <asm/cacheflush.h>

#include <linux/bitops.h>

#include <linux/sizes.h>

#include <linux/byteorder/generic.h>

后一个头文件待考证

set_memory_rw这个函数需要在内核里面手动export

1、跳转指令

#define BRANCH_INSN 0x14000000

addr_old被打桩函数地址 addr_new新的桩函数地址

offset就是两个函数之间的地址差值小于正负128M

offset = ((long)addr_old- (long)addr_new);

insn = BRANCH_INSN

mask = BIT(26) - 1;

insn &= ~(mask);

insn |= ((offset >> 2) & mask);

2、修改mem属性为RW

set_memory_rw(addr_old&PAGE_MASK, 1);

3、刷新跳转指令到原函数

*(unsigned int *)old = cpu_to_le32(insn);

4、刷新cache

flush_icache_range(addr_old,addr_old + 4);

完成打桩,但打桩前需要备份被打桩的函数,否则无法恢复



linux存储内核架构图参考

Linux Storage Stack Diagram


UIO的事例 包括了多地址映射和用户态select 中断

UIO 示例 - 积极工作,积极生活 - 开源中国

相关文章