linux 系统调用system call

Linux内核模块编程指南  

所以,如果我们想改变某个系统调用的工作方式,我们需要做的是编写自己的函数来实现它(通常通过添加一些我们自己的代码,然后调用原始的函数),然后更改sys_call_table指向函数的指针。因为我们可能被移除后,我们不想离开系统处于不稳定状态,重要的是cleanup_module表恢复到原来的状态。    下面是一个示例的源代码的内核模块。我们想“间谍”在一个特定的用户,并printk()消息每当用户打开一个文件。实现这一目标,我们系统调用来打开一个文件替换为自己的函数,称为our_sys_open。这个函数检查uid(用户id)当前的过程,如果它等于我们监视的uid,它调用printk()来显示文件的名称被打开。然后,无论哪种方式

注意,所有的相关问题做出系统调用偷unfeasiable供生产使用。为了阻止人们做潜在有害的事情sys_call_table不再是出口。这意味着,如果你想做更多的东西,而不仅仅是一个干燥的运行这个示例,您将不得不当前内核补丁为了sys_call_table出口。在示例目录,你会发现一个自述和补丁。可以想象,这样的修改是不能掉以轻心。不试试这个价值系统(即系统,你并不拥有——或不能恢复容易)。你需要得到本指南的完整源代码里作为一个tarball为了得到补丁和README。根据您的内核版本,你甚至可能需要应用补丁。还在这里吗?嗯,本章也是如此。如果一个内核黑客威尔的大笨狼,这是他想的第一件事。

/*
 *  syscall.c
 *
 *  System call "stealing" sample.
 */

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

/*
 * The necessary header files
 */

/*
 * Standard in kernel modules
 */
#include <linux/kernel.h>	/* We‘re doing kernel work */
#include <linux/module.h>	/* Specifically, a module, */
#include <linux/moduleparam.h>	/* which will have params */
#include <linux/unistd.h>	/* The list of system calls */

/*
 * For the current (process) structure, we need
 * this to know who the current user is.
 */
#include <linux/sched.h>
#include <asm/uaccess.h>

/*
 * The system call table (a table of functions). We
 * just define this as external, and the kernel will
 * fill it up for us when we are insmod‘ed
 *
 * sys_call_table is no longer exported in 2.6.x kernels.
 * If you really want to try this DANGEROUS module you will
 * have to apply the supplied patch against your current kernel
 * and recompile it.
 */
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);

/*
 * A pointer to the original system call. The reason
 * we keep this, rather than call the original function
 * (sys_open), is because somebody else might have
 * replaced the system call before us. Note that this
 * is not 100% safe, because if another module
 * replaced sys_open before us, then when we‘re inserted
 * we‘ll call the function in that module - and it
 * might be removed before we are.
 *
 * Another reason for this is that we can‘t get sys_open.
 * It‘s a static variable, so it is not exported.
 */
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("\n");
	}

	/*
	 * 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.\n");
	printk(KERN_ALERT "My counterpart, cleanup_module(), is even");
	printk(KERN_ALERT "more dangerous. If\n");
	printk(KERN_ALERT "you value your file system, it will ");
	printk(KERN_ALERT "be \"sync; rmmod\" \n");
	printk(KERN_ALERT "when you remove this module.\n");

	/*
	 * 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\n", 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\n");
		printk(KERN_ALERT "The system may be left in ");
		printk(KERN_ALERT "an unstable state.\n");
	}

	sys_call_table[__NR_open] = original_call;
}
时间: 2024-10-29 19:11:40

linux 系统调用system call的相关文章

Linux系统调用和库函数调用的区别

Linux下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions).系统调用实际上就是指最底层的一个调用,在linux程序设计里面就是底层调用的意思.面向的是硬件.而库函数调用则面向的是应用开发的,相当于应用程序的api,采用这样的方式有很多种原因,第一:双缓冲技术的实现.第二,可移植性.第三,底层调用本身的一些性能方面的缺陷.第四:让api也可以有了级别和专门的工作面向. 1.系统调用 系统调用提供的函数如open, close, read,

linux平台学x86汇编(十七):在汇编中使用linux系统调用

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 在前面章节我们已经看到,启动系统调用需要使用INT指令.linux系统调用位于中断0x80,执行INT指令时,所有操作转移到内核中的系统调用处理程序,完成后执行转移到INT指令之后的下一条指令. linux的系统调用在如下文件(32位系统)可以查看: $ cat /usr/include/asm/unistd_32.h #ifndef _ASM_X86_UNISTD_32_H

ARM Linux系统调用的原理

转载自:http://blog.csdn.net/hongjiujing/article/details/6831192 ARM Linux系统调用的原理 操作系统为在用户态运行的进程与硬件设备进行交互提供了一组接口.在应用程序和硬件之间设置一个额外层具有很多优点.首先,这使得编程更加容易,把 用户从学习硬件设备的低级编程特性中解放出来.其次,这极大地提高了系统的安全性,因为内核在试图满足某个请求之前在接口级就可以检查这种请求的正确性. 最后,更重要的是这些接口使得程序具有可移植性,因为只要内核

Linux系统调用过程分析

參考: <Linux内核设计与实现> 0 摘要 linux的系统调用过程: 层次例如以下: 用户程序------>C库(即API):INT 0x80 ----->system_call------->系统调用服务例程-------->内核程序 先说明一下,我们常说的用户API事实上就是系统提供的C库. 系统调用是通过软中断指令 INT 0x80 实现的,而这条INT 0x80指令就被封装在C库的函数中. (软中断和我们常说的硬中断不同之处在于,软中断是由指令触发的,而不

Linux系统调用Hook姿势总结

相关学习资料 http://xiaonieblog.com/?post=121 http://hbprotoss.github.io/posts/li-yong-ld_preloadjin-xing-hook.html http://www.catonmat.net/blog/simple-ld-preload-tutorial/ http://os.51cto.com/art/201004/195510.htm http://sebug.net/paper/pst_WebZine/pst_We

三种方法实现Linux系统调用

这篇文章主要介绍了三种方法实现Linux系统调用,感兴趣的朋友可以参考一下系统调用(System Call)是操作系统为在用户态运行的进程与硬件设备(如CPU.磁盘.打印机等)进行交互提供的一组接口.当用户进程需要发生系统调用时,CPU 通过软中断切换到内核态开始执行内核系统调用函数.下面介绍Linux 下三种发生系统调用的方法: 一.通过 glibc 提供的库函数glibc 是 Linux 下使用的开源的标准 C 库,它是 GNU 发布的 libc 库,即运行时库.glibc 为程序员提供丰富

对于linux下system()函数的深度理解(整理)

对于linux下system()函数的深度理解(整理) (2013-02-07 08:58:54) 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为是其他的代码影响到这个,或是内核驱动文件系统什么的异常导致,昨天有出现了这个问题,就随手百了一下度,问题出现了,很多人都说system()函数要慎用要少用要能不用则不用,system()函数不稳定?

Linux的system()和popen()差异

Linux的system()和popen()差异 1. system()和popen()简介 在linux中我们可以通过system()来执行一个shell命令,popen()也是执行shell命令并且通过管道和shell命令进行通信. system().popen()给我们处理了fork.exec.waitpid等一系列的处理流程,让我们只需要关注最后的返回结果(函数的返回值)即可. 2. system().popen()源码 首先我们来看一下这两个函数在源码(伪代码)上面的差异. int s

Linux系统调用列表(转)

以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数.这可能是你在互联网上所能看到的唯一一篇中文注释的Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完全也是很罕见的. 按照惯例,这个列表以man pages第2节,即系统调用节为蓝本.按照笔者的理解,对其作了大致的分类,同时也作了一些小小的修改,删去了几个仅供内核使用,不允许用户调用的系统调用,对个别本人稍觉不妥的地方作了一些小的修改,并对所有列出的系统调用附上简要注释. 其中有一些函数的作用完全