在編寫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...