linuxシステム呼び出しsystem call


Linuxカーネルモジュールプログラミングガイド
したがって、システム呼び出しの動作を変更するには、独自の関数を作成して実現し(通常、独自のコードを追加して元の関数を呼び出す)、sys_を変更する必要があります.call_tableは関数のポインタを指します.除去された後、システムから離れたくないので、cleanup_が重要です.moduleテーブルは元の状態に戻ります.次に、ソースコードのカーネルモジュールの例を示します.スパイは特定のユーザーで、printk()メッセージはユーザーがファイルを開くたびにしたいと思っています.この目標を達成するには、our_と呼ばれるファイルを自分の関数に置き換えるためにシステム呼び出します.sys_open.この関数はuid(ユーザid)の現在のプロセスをチェックし、私たちが監視しているuidと等しい場合はprintk()を呼び出してファイルの名前が開かれていることを示します.そして、どんな方法でも
すべての関連する問題は、生産のためにunfeasiableを盗むシステム呼び出しを行うことに注意してください.人々が潜在的に有害なことをするのを阻止するためにsys_call_tableはもう出口ではありません.これは、乾燥した実行例だけでなく、より多くのことをしたい場合は、現在のカーネルパッチをsys_call_table出口.サンプルディレクトリでは、Readmeとパッチが表示されます.このような修正は油断できないと想像できる.この価値システムを試してみない(つまり、システムは、あなたが持っていない--回復が容易ではない).このマニュアルの完全なソースコードをtarballとしてパッチとREADMEを得る必要があります.カーネルバージョンによっては、パッチを適用する必要もあります.まだここにいるの?ええ、本章もそうです.もしカーネルハッカーのウィルの大愚かなオオカミだったら、これは彼が考えた最初のことです.
/*
 *  syscall.c
 *
 *  System call "stealing" sample.
 */

/* 
 * Copyright (C) 2001 by Peter Jay Salzman 
 */

/* 
 * The necessary header files 
 */

/*
 * Standard in kernel modules 
 */
#include 	/* We're doing kernel work */
#include 	/* Specifically, a module, */
#include 	/* which will have params */
#include 	/* The list of system calls */

/* 
 * For the current (process) structure, we need
 * this to know who the current user is. 
 */
#include 
#include 

/* 

 *     (    )。    *      ,     *    “   insmod”
   *   * sys_call_table     2.6。x  。  *               
  *               *      
 */
extern void *sys_call_table[];

/* 
 * UID we want to spy on - will be filled from the
 * command line 
 */
static int uid;
module_param(uid, int, 0644);

/*            。    
 *       ,            *(sys_open),      
 *            。   ,   *  100%  ,         
  *  sys_open     ,         *       ,       *       。 
 *   *       ,      sys_open。  *        ,      。
 *
 */
asmlinkage int (*original_call) (const char *, int, int);

/* 
 * The function we'll replace sys_open (the function
 * called when you call the open system call) with. To
 * find the exact prototype, with the number and type
 * of arguments, we find the original function first
 * (it's at fs/open.c).
 *
 * In theory, this means that we're tied to the
 * current version of the kernel. In practice, the
 * system calls almost never change (it would wreck havoc
 * and require programs to be recompiled, since the system
 * calls are the interface between the kernel and the
 * processes).
 */
asmlinkage int our_sys_open(const char *filename, int flags, int mode)
{
	int i = 0;
	char ch;

	/* 
	 * Check if this is the user we're spying on 
	 */
	if (uid == current->uid) {
		/* 
		 * Report the file, if relevant 
		 */
		printk("Opened file by %d: ", uid);
		do {
			get_user(ch, filename + i);
			i++;
			printk("%c", ch);
		} while (ch != 0);
		printk("
"); } /* * Call the original sys_open - otherwise, we lose * the ability to open files */ return original_call(filename, flags, mode); } /* * Initialize the module - replace the system call */ int init_module() { /* * Warning - too late for it now, but maybe for * next time... */ printk(KERN_ALERT "I'm dangerous. I hope you did a "); printk(KERN_ALERT "sync before you insmod'ed me.
"); printk(KERN_ALERT "My counterpart, cleanup_module(), is even"); printk(KERN_ALERT "more dangerous. If
"); printk(KERN_ALERT "you value your file system, it will "); printk(KERN_ALERT "be \"sync; rmmod\"
"); printk(KERN_ALERT "when you remove this module.
"); /* * Keep a pointer to the original function in * original_call, and then replace the system call * in the system call table with our_sys_open */ original_call = sys_call_table[__NR_open]; sys_call_table[__NR_open] = our_sys_open; /* * To get the address of the function for system * call foo, go to sys_call_table[__NR_foo]. */ printk(KERN_INFO "Spying on UID:%d
", uid); return 0; } /* * Cleanup - unregister the appropriate file from /proc */ void cleanup_module() { /* * Return the system call back to normal */ if (sys_call_table[__NR_open] != our_sys_open) { printk(KERN_ALERT "Somebody else also played with the "); printk(KERN_ALERT "open system call
"); printk(KERN_ALERT "The system may be left in "); printk(KERN_ALERT "an unstable state.
"); } sys_call_table[__NR_open] = original_call; }