核心模組編寫從入門到放棄

2021-09-02 17:40:09 字數 2666 閱讀 1559

我是第一次接到寫核心模組的作業,基本是從零開始。該文章適合什麼都不會的小白圍觀,有錯誤希望指正。

以我做的ip包加密任務為例,學習核心模組的編寫。使用的環境是ubuntu和c語言環境。核心模組的編寫和核心版本息息相關,不同的版本的核心函式名和資料結構名都不同,由於網上的教程一般比較老,因此在初學的時候,建議使用核心版本在4.10一下的系統。

核心版本檢視方式是uname -r。

另需要強調的是,測試記得用虛擬機器,不然分分鐘搞崩您的系統。

核心程式一般有很多標頭檔案,例如:

#include

#include

這些標頭檔案能在/usr/include/linux資料夾和/usr/scr/核心版本/include/linux裡找到,其中/usr/scr/核心版本/include/linux是完整的版本。當然在剛剛編寫的時候不需要了解,但在出現如找不到標頭檔案等bug時可能有一點幫助。

插一句:一般標頭檔案找不到都是編譯方法的錯誤。

除了標頭檔案、全域性變數和函式的定義外,核心程式都包含一下內容:

module_init(initmodule);

module_exit(cleanupmodule);

module_license(「gpl」);

分別表示初始化模組,清除模組和license。在插入模組時,執行initmodule,在模組被清除時,執行cleanupmodule。核心模組與一般的c程式不同,並不是把需要做的事以結構化的方式寫在main函式中。以我的ip包加密為例,我只需要在初始化模型時,註冊乙個hook函式,當乙個 ip包通過檢查點是,會啟用這個函式並執行我編寫的加密操作。

static int __init initmodule(void)

初始化模組函式是必要的用來初始化模組的,可以實現的操作有如註冊hook函式、註冊裝置節點檔案等。

static void __exit cleanupmodule(void)

在清除模組時被呼叫,執行的操作有登出hook函式、登出裝置節點檔案等操作。

至此,這就是核心程式的必要結構啦。

首先要強調,核心程式的編譯不是用gcc的!!(天真可愛的我一開始就是這麼編譯的)

編譯核心檔案一般在同目錄下放乙個makefile檔案,內容是:

obj-m += 核心程式檔名.o

kdir := /lib/modules/$(shell uname -r)/build

pwd := $(shell pwd)

default:

$(make) -c (kd

ir)m

=(kdir) m=

(kdir)

m=(pwd) modules

然後!在終端執行make就完成編譯啦!

在default部分後,還可以接其它需要編譯的輔助檔案,如接

gcc ***.c -o ***.o

編譯完會生成一堆如.ko,.mod.c等檔案,具體我們不用了解,我們只要知道怎麼執行就好了!在終端輸入:

sudo insmod 核心程式檔名.ko

就完成插入核心了!此時執行的是剛剛提到的initmodule函式。

當需要清除這個模組時輸入:

sudo rmmod 核心程式檔名.ko

就實現了關閉核心,此時執行cleanupmodule函式。

核心程式的列印使用的函式是printk(),列印在日誌上,檢視方式是$dmesg。

如果需要設定一些程式中有用的引數,一般需要通過檔案傳輸。

首先,寫乙個普通c程式(非核心)進行命令列引數的輸入和提取,並寫入裝置檔案/dev/info

其次,在核心程式中註冊該裝置結點檔案,在initmodule中新增:

register_chrdev(124, 「/dev/info」, &fops)

fops是需要自己定義的檔案操作結構,其中包含結構,有操作函式和owner,操作函式在檔案中讀取引數並賦給程式中的變數。

我寫的是hook,使用的是netfilter完成ip包正文內容的加密,涉及的資料結構有skb。

定義結構體為nf_hook_ops。

在initmodule中註冊和掛載,可以掛載多個函式。需要賦值的內容有

.hook:自己寫的掛載執行的函式名

.hooknum:掛載點

.priority:優先順序

.pf:pf_inet

最後使用nf_register_hook(&myhook)完成註冊

skb結構是ip包傳輸的結構。

skb:tcp/ip堆疊中用於收發包的緩衝區域。具體有:skb->data:資料區起始位置,即ip資料報起始位置。skb->len:資料區總長度。

skb_network_header(skb):獲取ip資料報起始位置。輸入為skb結構。

ip_hdr(skb):資料結構,可獲取ip頭的資訊。輸入為skb。具體有:ip_hdr(skb)->ihl:該資料*4為ip頭長度,可計算出正文開始位置。ip_hdr(skb)->daddr:目的位址。ip_hdr(skb)->protocol:協議型別。ip_hdr(skb)->tot_len:ip包長度,需要大小端轉換。

tcp_hdr(skb):資料結構,可獲取ip頭的資訊。tcp_hdr(skb)->doff:*4為報頭長度。

核心程式可以說耗盡了我所有的耐心,搞崩了我無數的虛擬機器,經歷了這怎麼會跑不通和這怎麼可能跑通兩大必經點。

總之,完成作業還是成就感滿滿,希望諸君順利,寫核心還是需要good luck啦~~

python從入門到放棄 3 模組

python中,乙個.py檔案就稱之為乙個模組 module 模組中包含了python物件定義和python語句.為了避免模組名衝突,python又引入了按目錄來組織模組的方法,稱之為包 package 每乙個包目錄下面都會有乙個 init py 的檔案,這個檔案是必須存在的,否則,python就把...

kmp從入門到放棄

標籤 kmp 擴充套件kmp 給你兩個字串,你需要回答,b串是否是a串的子串 a串是否包含b串 a aaaaaaaaaaaaaaaaaaaaaaaaaab b aaaaaaaab 最壞狀態 o mn 一般做法 for 列舉b在a串中的起始位置 for 向後比較ab是否相等 o n m 傳說中的kmp...

beego 從入門到放棄

beego 的專案基本都是通過 bee命令來建立的,所以在建立專案之前確保你已經安裝了 bee 工具和 beego。如果你還沒有安裝,那麼請查閱 beego 的安裝 和 bee 工具的安裝 現在一切就緒我們就可以開始建立專案了,開啟終端,進入 gopath src 所在的目錄 建立乙個專案名為201...