使用kprobes檢視核心內部資訊
wushuan10141 2013-04-08 16:50:43
一、首先核心必須支援kprobes、jprobes:
#makemenuconfig
general setup --->
[*]kprobes
使核心支援kprobes。
二、kprobes的使用方法:
1、分配乙個kprobe結構體供kprobes執行時使用。
2、在kprobe結構體的addr成員中設定要插入偵測器的函式位址,可以通過檢視system.map查詢,或者通過proc檔案系統查詢
# cat/proc/kallsyms | grep "do_execve"
c00bbfb8t do_execve
3、如果不想設定addr成員,可以設定symbol_name成員為"do_execve"(想要偵測的函式),需要核心版本在2.6.19以上才支援。
4、在kprob結構的pre_handler成員設定偵測函式exec_pre_handler。
5、呼叫register_kprobe函式註冊偵測器函式。
以下是乙個用kprobes監測do_execve()函式的例子,在每次呼叫do_execve()函式之前,就會列印當前的程序pid、jiffies值等全域性變數資訊。#include module
.h>
#include
#include
struct kprobe exec_kp;
static
int exec_pre_handler(
struct kprobe *p,
struct pt_regs *regs)
static __init int kprobes_exec_init(
void
)static __exit void kprobes_exec_cleanup(
void
)module_init(kprobes_exec_init)
;module_exit(kprobes_exec_cleanup)
;module_license(
"gpl");
編譯並insmod上述ko,那麼在do_execve()函式執行之前就會先執行kprobes的pre_handler所指向的exec_pre_handler,列印核心的當前程序pid、jiffies等全域性變數的值。由於do_exec函式用於生成程序,因此每次執行ls等命令都會顯示一次:
pt_regs:c52ebf08,pid:110, jiffies:155286
pt_regs:c5313f08,pid:113, jiffies:159137
pt_regs:c52ebf08,pid:112, jiffies:159137
利用kprobes也可以檢視核心函式內部任意位置的資訊,此時需要把核心函式反彙編,確定想要檢視位置相對於函式起始位址的偏移量,在初始化kprobes時,設定kprobe結構體的offset成員,就可以檢視核心內部函式任意位置的資訊。
三、jprobes的使用方法
用kprobes可以方便的檢視核心內部任意位置的資訊,相反,jprobes則是特別為函式開頭的偵測準備的,通過jprobes,可以更容易的獲取傳遞給函式的引數。使用jprobes與使用kprobes大體上一樣,主要有以下區別:
1、分配給jprobes的結構體是jprobe結構體,並將指標傳遞給register_jprobe。jprobe結構的成員如下所示,只包括kprobe和entry兩者。
struct jprobe ;
struct kprobe kp成員設定的是要偵測函式的符號或位址,entry中為通過jprobe_entry()巨集處理過的偵測器處理程式。
2、偵測器處理程式的引數應當與需要偵測的函式的引數相同,這樣可以方便的列印被偵測函式的形參。使用kprobes時,必須通過暫存器或者棧才能計算出引數的值。而計算方法還依賴於cpu架構,如果使用jprobes,則無須了解架構的詳細知識,也能檢視引數的值。
3、偵測器處理函式的尾部必須加上jprobe_return();
以下是使用jprobes列印do_execve函式的引數的例子,每次呼叫do_execve之前,都會列印相應的引數:
#include module
.h>
#include
#include
struct jprobe exec_jp;
int jp_do_execve(
const
char
* filename,
const
char __user *
const __user *argv,
const
char __user *
const __user *envp,
struct pt_regs * regs)
static __init int jprobes_exec_init(
void
)static __exit void jprobes_exec_cleanup(
void
)module_init(jprobes_exec_init)
;module_exit(jprobes_exec_cleanup)
;module_license(
"gpl");
每次執行ls時都會呼叫do_execve函式,具體的列印如下:
# ls
filename = /bin/ls
argv[0] = ls
簡單的核心記憶體檢視方法
有時候需要除錯核心的記憶體,又不想搭建qemu除錯環境的話,可以簡單寫乙個核心模組,來測試一下。直接看 注意 環境ub16 函式 get free page不要用get free page cat hello.c include include include unsigned char pagem...
用kprobes實現核心反射機制
用kprobes實現核心反射機制 作者 li xianjing 2007 5 29 前幾天在設計事件管理器時,我就在考慮磁碟滿的問題,磁碟滿是乙個典型的系統事件,沒有什麼好說的,問題是應該何時何地觸發它呢?如果由應用程式在操作檔案時觸發,那將有很多地方需要修改,這不是我們期望的。如果能在乙個地方統一...
用kprobes實現核心反射機制
用kprobes實現核心反射機制 作者 li xianjing 前幾天在設計事件管理器時,我就在考慮磁碟滿的問題,磁碟滿是乙個典型的系統事件,沒有什麼好說的,問題是應該何時何地觸發它呢?如果由應用程式在操作檔案時觸發,那將有很多地方需要修改,這不是我們期望的。如果能在乙個地方統一處理,那就省事多了,...