2011-10-21 60 views
8

在x86系統上,我有一個Linux內核模塊(「監視器模塊」),每次加載特定內核模塊(「目標」)時都會收到內核通知。幾乎任何內核模塊都可以成爲目標。我在an instrumentation system中使用這個工作。有沒有辦法讓內核模塊找到另一個加載模塊的段地址?

當觀察者模塊處理這樣的通知時,如果觀察者知道加載的目標模塊的ELF部分的地址,那麼它可能很方便。任何想法如何在內核空間中獲得這些信息?

當然,我可能會在目標加載後立即在用戶空間中獲取/sys/module/<target_name>/sections/中相應文件的內容,然後以某種方式將此數據傳遞給觀察器模塊,但這太笨拙。我想找到一種方法直接在內核空間中獲取這些信息。

就我所見到的模塊加載器的源代碼而言,它不會在struct module中存儲段地址,只是爲段創建sysfs文件。也許有可能以某種方式找到與這些文件相對應的內核對象並從這些對象中讀取所需的數據?或者可能使用其他方法?

+0

看來,包含在'struct module'中的kobject('mkobj。kobj'字段)涉及sysfs中模塊的表示。當我有空時,我會進一步深入。有可能獲得包含使用該kobject的部分的名稱和地址作爲起點的屬性。 – Eugene

回答

5

在深入瞭解有關模塊各部分的信息如何進入sysfs之後,我發現無法在不使用內核內部的結構定義的情況下檢索它。在我的項目中使用這些東西不是一種選擇,所以我終於實現了另一種方法,希望它更可靠。

總之,這個想法如下。我的內核模塊使用用戶模式助手API來啓動用戶空間進程(實際上是執行我的腳本的shell)。該進程獲取「目標」內核模塊的名稱作爲參數,並從sysfs收集有關其部分的信息(/sys/module/<target_name>/sections/)。從用戶空間,這個信息可以很容易地獲得。之後,它通過debugfs中的文件將收集的數據作爲字符串傳遞給我的內核模塊。該模塊解析字符串並驗證其內容。如果一切正常,ELF部分的名稱和起始地址將可用。

我承認,用戶模式幫手的訣竅很笨拙,但它完成了工作。

我準備了上述方法的示例實現 - 請參閱"Sections" example

有關用戶模式幫助程序API的詳細信息,請參閱內核源代碼<linux/kmod.c><linux/kmod.h>,即call_usermodehelper()的定義。示例以及API的典型用法的說明可在this article中找到。

請注意,來自that article的示例有點不準確:模塊的init函數在那裏返回call_usermodehelper()的結果。但是,後者會返回2字節的狀態碼(至少在調用UMH_WAIT_PROC時),而不是0或預期返回init函數的負面錯誤代碼。這可能會導致運行時警告。 call_usermodehelper()實際返回的是here

1

文件linux/kernel/module.c與module_address_lookup()有一些非靜態函數(但前面沒有這個EXPORT_SYMBOL),但是這些函數使用像preempt_disable()和_enable()這樣的函數。我寧願不使用這個函數,而是建議使用sysfs-interface,而你的驅動程序已經處於內核模式。

+0

謝謝你的答案。是的,我知道'module_address_lookup()'等等。它們用於kallsyms系統中用於符號查找等。但是我需要一個不同的東西,即模塊的_sections_(.text,.devinit.text,.exit.text等)的地址而不是符號。我可以獲取模塊的「init」和「core」區域的地址,但每個區域可能包含多個ELF部分。 – Eugene

+0

從加載程序的源代碼看來,在發出加載通知時,只有在sysfs中才會提供有關剛剛加載的模塊部分的信息。如果我沒有弄錯,sysfs中的每個文件都由內核對象支持。如果你有一個想法,我的模塊怎麼能找到與'/ sys/module/'中的文件相對應的對象,那就太好了。 – Eugene

+0

我沒有辦法從內核中獲取這些信息,除非你修改kernel/module.c來導出一個符號或函數。你可以嘗試發送一個合理的消息補丁,爲什麼你會這樣想。 –

相關問題