linux 核心 hook函式介紹

2021-09-27 08:30:49 字數 3314 閱讀 1497

在編寫linux核心中的網路模組時,用到了鉤子函式也就是hook函式。現在來看看linux是如何實現hook函式的。

先介紹乙個結構體:

struct nf_hook_ops,這個結構體是實現鉤子函式必須要用到的結構體,所在檔案:linux/netfilter.h 定義為:

typedef unsigned int nf_hookfn(unsigned int hooknum,

struct sk_buff *skb,

const struct net_device *in,

const struct net_device *out,

int (*okfn)(struct sk_buff *));

struct nf_hook_ops ;

其中的成員資訊為:

hook  :是乙個函式指標,可以將自定義的函式賦值給它,來實現當有資料報到達是呼叫你自定義的函式。自定義函式的返回值為:

/* responses from hook functions. */

#define nf_drop 0

#define nf_accept 1

#define nf_stolen 2

#define nf_queue 3

#define nf_repeat 4

#define nf_stop 5

#define nf_max_verdict nf_stop

owner:是模組的所有者,一般owner = this_module ;

pf   :是protocol flags,其取值範圍為:

enum ;
hooknum :中存放的是使用者自定義的鉤子函式的呼叫時機,其取值為:

enum nf_inet_hooks ;
其中的每個值的含義為:

priority : 為所定義的鉤子函式的優先順序,其取值為份兩種:分別為ipv4 和 ipv6; 

priority 的ipv4取值為:      

enum nf_ip_hook_priorities ;
所在檔案:linux\netfilter_ipv4.h

priority 的ipv6取值為:

enum nf_ip6_hook_priorities ;
以上是對struct nf_hook_ops結構體中的每個欄位的詳解;

具體例項 

struct nf_hook_ops my_hook = ;

unsigned int myfunction( unsigend int hooknum, struct sk_buff *skb,

const struct net_device *in,

const struct net_device *out,

int (*okfn)(struct sk_buff *))

{}

如上面的**一樣,當定義乙個struct nf_hook_ops結構體,並且對其完成了初始化以後,需要將這個結構體進行註冊,之後這個結構體以及其中的自定義函式才會其作用。

註冊乙個struct nf_hook_ops需要用到的函式為:

int  nf_register_hook(struct nf_hook_ops *reg)
其實這個 int nf_register_hook()函式在核心中的實現也沒有多麼的複雜,

來看看它是如何實現的:

struct list_head nf_hooks[nfproto_numproto][nf_max_hooks] __read_mostly;

export_symbol(nf_hooks);

static define_mutex(nf_hook_mutex);

int nf_register_hook(struct nf_hook_ops *reg)

list_add_rcu(®->list, elem->list.prev);

mutex_unlock(&nf_hook_mutex);

return 0;

}export_symbol(nf_register_hook);

所在檔案:net\netfilter\core.c

當不再需要使用這個struct nf_hook_ops時,需要登出這個結構體,其可用的函式為:

void nf_unregister_hook(struct nf_hook_ops *reg)

export_symbol(nf_unregister_hook);

當一次需要註冊多個struct nf_hook_ops結構體,如:

struct nf_hook_ops myhooks[n]時,使用:

int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n)

return err;

err:

if (i > 0)

nf_unregister_hooks(reg, i);

return err;

}export_symbol(nf_register_hooks);

同樣,當一次需要登出多個struct nf_hook_ops結構體是,使用:

void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)

export_symbol(nf_unregister_hooks);

總結:

struct nf_hook_ops

int nf_register_hook( struct nf_hook_ops *reg );

void nf_unregister_hook( struct nf_hook_ops *reg );

int nf_register_hooks( struct nf_hook_ops *regs, unsigend int n );

void nf_unregister_hooks( struct nf_hook_ops *regs, unsigned int n );

linux核心hook技術之函式位址替換

函式位址替換是一種更為簡單 常見的hook方式,比如對security ops sys call table等結構中的函式進行替換,來完成自己的安全許可權控制。其中security ops是lsm框架中所使用的,sys call table是系統呼叫表結構。當然了,這些結構目前在核心中都已經是唯讀資...

Hook 核心函式技術細節

剛開始看到通過 ssdt 來 hook zw 核心函式的方法時不是很了解,等把 zw 反彙編後才發現技術細節.原來也沒什麼新鮮的,就是找到目標函式在 ssdt 中的位置 偏移量 位置 4 然後儲存並替換偏移量處的值為自己新的函式位址就行了。這種技術現在已是老掉牙了,不過在實際的軟體開發中也比較常用,...

編寫hook函式,改寫hook函式

在conftest裡面加上這麼乙個函式,那麼在命令列裡面使用pytest 會出現如下效果 編寫 命令列新增引數 def pytest addoption parser mygroup parser.getgroup hogwarts group 將下面所有的option都展示最這個group下 my...