我试图将kprobe转换为可加载的内核模块。
我可以运行samples/kprobes/
内核树中文件夹中的可用示例。
如果我们在kernel(CONFIG_KPROBES
)中配置kprobes ,则svc_entry
宏将在__und_svc()
处理程序中扩展为64个字节。
参考: http : //lxr.free-electrons.com/source/arch/arm/kernel/entry-armv.S?a=arm#L245
我的目标是不碰内核,将kprobe用作内核模块。
因此在不启用CONFIG_KPROBES的情况下编译内核。因此svc_entry宏将在__und_svc()中扩展为0
我想摆脱这些疑虑。
如果kprobe被处理为未定义的指令异常(仅创建bcos kprobe),则__und_svc()
调用为什么。__und_svc()
处理程序对于kprobes的作用是什么?
如果必须使用64字节的内存,那么如何在不编译内核的情况下进行分配。即如何动态地做到这一点。
请分享您的知识。
您可能没有得到响应,因为您对事物的了解不是很好,并且linux-arm-kernel列表上的任何人都需要一些时间来做出响应。阅读kprobes.txt并详细研究ARM体系结构。
如果kprobe被处理为未定义的指令异常(仅创建bcos kprobe),则
__und_svc()
调用为什么。__und_svc()
处理程序对kprobes的作用是什么?
在ARM上,mode0b11011
是未定义的指令mode。发生未定义指令时的流程是
第四步的主向量表位于,__vectors_start
这只是分支到vector_und
。该代码是一个称为的宏vector_stub
,它决定调用__und_svc
或__und_usr
。堆栈是每个进程保留的4 / 8k页。它是包含任务结构和内核堆栈的内核页面。
kprobe的工作方式是将未定义的指令放在您要探查的代码地址上。即,它涉及未定义的指令处理程序。这应该是很明显的。它调用两个例程,call_fpe
或do_undefinstr()
。您对第二种情况感兴趣,该第二种情况获取操作码并调用call_undef_hook()
。使用register_undef_hook()添加一个钩子;您可以看到arch_init_kprobes()
。主回调使用kprobe_handler
来调用struct pt_regs *regs
,它恰好是中保留的额外内存__und_svc
。请注意,例如,kretprobe_trampoline()
它正在与当前正在执行的堆栈配合使用。
如果必须使用64字节的内存,那么如何在不编译内核的情况下进行分配。即如何动态地做到这一点?
不它不是。您可以使用其他机制,但是可能必须修改kprobes代码。您很有可能必须限制功能。也有可能完全重写堆栈帧并在事后保留额外的64个字节。这是不是一种分配中kmalloc()
。它只是从主管堆栈指针中添加/减去一个数字。我想代码会重写未定义处理程序的返回地址,以在kprobed地址的上下文(ISR,下半部分/线程IRQ,work_queue,内核任务)中执行。但是您可能还没有遇到其他问题。如果arch_init_kprobes()
从未致电过,那么您可以随时在__und_svc
; 它只吃掉64个字节的堆栈,这会使内核堆栈更有可能溢出。即改变
__und_svc:
@ Always reserve 64 bytes, even if kprobe is not active.
svc_entry 64
arch_init_kprobes()
是真正安装该功能的要素。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句