2013-12-13 63 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

相關問題