2013-12-13 29 views
4

我试图将kprobe转换为可加载的内核模块。未定义异常处理程序(__und_svc)在kprobes中的作用是什么?

我能够从 内核树中运行samples/kprobes/文件夹中可用的示例。

如果我们配置的内核(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宏会用0扩展为 __und_svc()

我想从这些疑惑中解脱出来。

  1. 如果kprobe被处理未定义的指令异常(BCOS kprobe 仅创建),那么为什么__und_svc()被调用。 __und_svc()处理程序对kprobes的作用是什么?

  2. 如果64字节内存是强制性的,那么如何在没有 的情况下分配内核编译。即如何动态地做到这一点。

请分享您的知识。

+0

虽然我喜欢SO的精确问题,但恐怕这个问题太具体了。你是否尝试过与内核相关的邮件列表? –

+0

是的。我在systemtap邮件列表以及linux-arm邮件列表上发布了这个问题。运气不好在linux-arm中尚未公布。 – Jeyaram

回答

5

由于您对事物的理解不是很好,因此您需要一段时间才能对linux-arm-kernel列表中的任何人做出响应。请阅读kprobes.txt并详细研究ARM体系结构。

如果kprobe处理了未定义的指令异常(bcos kprobe只创建),那么为什么__und_svc()被调用。 __und_svc()处理程序对于kprobes有什么作用?

在ARM,模式0b11011未定义指令模式。一个未定义指令发生当流量,是undef指令的

  1. lr_und = PC + 4
  2. SPSR_und = CPSR的发生指令,其中模式。
  3. 将模式更改为禁用中断的ARM。
  4. PC =矢量基地+ 4

步骤4位于__vectors_start的主要矢量表和这只是分支到 vector_und。该代码是一个名为vector_stub的宏,它可以调用__und_svc__und_usr。堆栈是每个进程保留的4/8k页面。它是包含任务结构和内核堆栈的内核页面。

kprobe作品放置在代码的地址,你想探测未定义指令。也就是说,它涉及未定义的指令处理程序。这应该是非常明显的。它调用两个例程,call_fpedo_undefinstr()。您对第二种情况感兴趣,它获取操作码并调用call_undef_hook()。用register_undef_hook()添加一个钩子;你可以看到arch_init_kprobes()。主回调kprobe_handler被称为struct pt_regs *regs,这恰好是在__und_svc中保留的额外内存。请注意,例如kretprobe_trampoline(),它正在使用当前正在执行的堆栈玩弄技巧。

如果64字节的内存是强制性的,那么如何在不编译内核的情况下进行分配。即如何动态地做到这一点。?

不,它不是。您可以使用不同的机制,但您可能需要修改代码kprobes。很可能你将不得不限制功能。也可以完全重写堆栈帧并在事实之后保留额外的64字节。它是而不是如kmalloc()中的分配。它只是从管理员堆栈指针中添加/减去一个数字。我猜测代码会重新写入来自未定义处理程序的返回地址,以便在地址的上下文(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()是实际安装该功能。

+0

感谢您启发'call_undef_hook()'相关的东西。更多信息。但是我不能从entry-armv.S中更改__und_svc()。在提交'd30a0c8bf99f0e6a7d8c57bd4524039585ffbced'中只添加了这个64字节。所以我想了解,他们添加了哪些功能/错误。 – Jeyaram

+0

只需修补你的内核。使用调整任务的代码设置* entry-armv.S *,'svc_entry',然后始终使用'svc_entry 64'。你不需要拉完整个补丁集。 'git diff d30a0c8bf99〜1..d30a0c8bf99'给了我一个完整的补丁。你可以保存并运行'echo svc_entry.patch | patch -p1'。或者你问你是否不能重新编译内核并修复它?这几乎是不可能的;你必须重写所有的* arm/kernel/kprobes.c *代码。 –

+0

我的要求是不对内核应用任何补丁或甚至单个更改,将kprobes修改为LKM。所以除了重写arm/kernel/kprobes.c以外,我没有选项。 – Jeyaram

相关问题