使用
LinuxKernelModule的一般目的就是扩展
系统的
功能,或者给某些特殊的设备提供
驱动等等。其实利用Linux内核模块我们还可以做一些比较“
黑客”的事情,例如用来拦截系统调用,然后自己处理。嘿嘿,有意思的说。
" C5 r) }) y P; Z) h( D, {
下面给出一个简单的例子,说明了其基本的工作过程。
4 r. W: I" E9 l; v i( C
# ]" T* `: ^+ g7 x j9 f
#defineMODULE
4 `7 ~9 B8 N2 M) M. I
#define__KERNEL__
0 R! Z& g' G( r2 d) U, y* i3 S#include%26lt;linux/module.h%26gt;
3 @( ^3 M( P3 W0 g
#include%26lt;linux/kernel.h%26gt;
+ J0 g& c; ~, K3 E# f#include%26lt;asm/unistd.h%26gt;
" v, n! d9 ?/ B+ N
#include%26lt;sys/syscall.h%26gt;
- D# E" G" v0 j! I5 Y
#include%26lt;linux/
types.h%26gt;
7 I1 E I( {7 b$ i% k$ |#include%26lt;linux/dirent.h%26gt;
R: W- [. ?: u$ v$ v7 l
#include%26lt;linux/string.h%26gt;
! Z1 ~7 w4 L4 C, B$ D8 r. B( G8 S
#include%26lt;linux/fs.h%26gt;
2 i* n5 n& y$ d7 t* n1 C: X6 J#include%26lt;linux/malloc.h%26gt;
, a. t2 i5 {2 S" |# }+ Nexternvoid*sys_call_table[];/*sys_call_tableisexported,sowecanaccessit*/
3 R+ T n; K% a" B8 bint(*orig_mkdir)(constchar*path);/*theoriginalsystemcall*/
7 p: G! O8 p& ~' finthacked_mkdir(constchar*path)
( E6 [9 t% R( \% O* Z1 L$ b. p9 r{
+ T+ Z7 T9 _! V* N6 O, {return0;/*everythingisok,buthenewsystemcall
, C, A' S7 z9 T; P/ {, ydoesnothing*/
$ e% n7 R# v) K8 I! U}
0 P' m( A2 d! I1 ]+ c% Uintinit_module(void)/*modulesetup*/
0 A7 i* e- c& j6 c& z7 c{
4 d4 P% m! f6 j4 I5 Z
orig_mkdir=sys_call_table[SYS_mkdir];
) _' z9 k& b' R) |$ psys_call_table[SYS_mkdir]=hacked_mkdir;
8 f3 [# D' _, M4 d. R+ ]& Treturn0;
4 W( |# V! k5 c+ U# l- K: M4 w
}
* h* C% S# O! R7 S
voidcleanup_module(void)/*moduleshutdown*/
7 e& V) }. d$ o# I5 o/ r* F
{
( a R0 J3 {, Bsys_call_table[SYS_mkdir]=orig_mkdir;/*setmkdirsyscalltotheorigal
2 n7 o( S! s: q7 `! H1 U6 b# f" A' ?
one*/
( w/ T9 Y+ F: p, F' `/ T; _
}
! \9 f1 S4 _% I2 x- Z# z
[color=#FFFFFF']
! d/ f: {0 r7 n4 U7 l6 M7 F
5 A0 Z. U V7 D' l8 K: M1 ]- t4 T, A# g/ t
大家看到前面的代码了,非常简单,我们就是替换了内核的系统调用数组中我们关心的指针的值,系统调用在内核中实际就是一个数组列表指针对应的函数列表。我们通过替换我们想“黑”的函数的指针,就可以达到我们特定的目的。
# b) V! @4 A4 O2 c# T) H: ]/ F 这个例子中我们替换了“mkdir”这个函数。这样,用户的应用
程序如果调用mkdir后,当内核响应的时候,实际上是调用我们“黑”了的函数,而我们实现的函数里面是什么都没有干,所以这里会导致用户运行“mkdir”得不到结果。这个例子很简单,但是我们可以看出,如果我们想截获一个系统调用,那么我们只需要做以下的事情:
% c' v. r- j# x6 ?" I[color=#FFFFFF']
5 h! s( P+ A3 [
( Y* r, ~1 K- r1 G, F 1.查找出感兴趣的系统调用在系统内核数组中的入口位置。可以参看include/sys/syscall.h文件。
$ G y1 G6 C F- S! J8 _
[color=#FFFFFF']
9 f6 C* v! e( U& Y- p6 }. @5 U
; F3 q+ D2 `& d
2.将内核中原来的调用函数对应的指针sys_call_table[X]保留下来。
! T$ U" d" j$ A* w: Y$ G 3.将我们新的伪造的系统函数指针给sys_call_table[X]。