实现自己的系统调用针对linux-2.6.34【转】

转自:http://biancheng.dnbcw.net/linux/303362.html

 在linux下实现自己的系统调用。主要功能是:遍历系统的进程,并将相关的进程信息存放在自己定义的结构体中,同时编写系统调用,实现内核数据向用户空间的文件中写入。

首先实现相关的系统调用:

1.修改系统调用表:

在目录/usr/src/linux-2.6.33.1/arch/x86/kernel

修改文件:syscall_table_32.S 在文件的末尾处添加自己的系统调用表项。

如下:

        .long sys_rt_tgsigqueueinfo /* 335 */

.long sys_perf_event_open

.long sys_recvmmsg

.long sys_sayhello

        .long sys_getdata

        .long sys_datawrite

        .long sys_dataflush

其中绿色部分是上一个简单的系统调用测试。下面3个红色部分的是我现在要实现的从内核部分向用户空间写文件。

2.添加系统调用号。

在目录/usr/src/linux-2.6.33.1/arch/x86/include/asm/

修改文件unistd_32.h文件,在文件中添加自己的系统调用号。

如下:

#define __NR_perf_event_open 336

#define __NR_recvmmsg 337

#define __NR_syahello 338

#define  __NR_getdata                 339

#define  __NR_datawrite               340

#define  __NR_dataflush               341

同时修改接下来的定义:

#define NR_syscalls                   342          //这个表示的当前系统调用的总数

其中绿色部分是上一个简单的系统调用测试。下面3个红色的是我们当前需要关心的。

3.编写系统调用的处理函数:

原则上你可一在内核文件的任何位置添加你的处理函数。我这里选择在kernel目录下新建一个自己的C文件。

get_data.c

这就需要修改相关的Makefile文件。修改get_data.c所在的目录下的Makefile文件

找到大概16行,添加你的编译目标

如下(红色部分为自己添加的):

obj-y += groups.o

obj-y += get_data.o

get_data.c文件的内容:


#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#define TASK_COMM_LEN 16
#define TMP_DATA_LEN 50
typedef struct my_task_struct {
    volatile long state;
    int prio, static_prio, normal_prio;
    pid_t pid;
    pid_t tgid;
    char comm[TASK_COMM_LEN];
    struct my_task_struct *next;
}my_struct_t, *my_struct_p;
my_struct_p get_data
(void)
{
    my_struct_p p, head, h;
    struct task_struct *task = NULL;
    head
= (my_struct_p)kmalloc(sizeof(my_struct_t), GFP_ATOMIC);
    head->next = NULL;
    h = head;
    for_each_process
(task) {
        p = (my_struct_p)kmalloc(sizeof(my_struct_t), GFP_ATOMIC);
        p
->state = task->state;
        p->prio = task->prio;
        p->static_prio = task->static_prio;
        p->normal_prio = task->normal_prio;
        p->pid = task->pid;
        p->tgid = task->tgid;
        
memset(p->comm, '\0', sizeof(p->comm));
        strncpy(p->comm, task->comm, TASK_COMM_LEN-1);
        p
->next = h->next;
        h->next = p;
        h = p;
    }
    return head;
}
int filewrite(const char * filename, my_struct_p head)
{
    struct file *filp;
    mm_segment_t fs;
    my_struct_p data;
    char *change_line = "\t";
    char *menu_line = "state\tprio\tstatic_prio\tnormal_prio\tpid\ttgid\tcomm\n";
    char tmpdata[TMP_DATA_LEN];
    data
= head->next;
    filp = filp_open(filename, O_RDWR|O_APPEND|O_CREAT, 0644);
    if(IS_ERR(filp)) {
        printk("open error!\n");
        return 1;
    }
    fs = get_fs();
    set_fs(KERNEL_DS);
    filp->f_op->write(filp, menu_line, strlen(menu_line), &filp->f_pos);
    
while(NULL != data) {
        memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->state), "%ld", data->state);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->prio), "%d", data->prio);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->static_prio), "%d", data->static_prio);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->normal_prio), "%d", data->normal_prio);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->pid), "%d", data->pid);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->tgid), "%d", data->tgid);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
memset(tmpdata, '\0', TMP_DATA_LEN);
        snprintf(tmpdata, sizeof(data->comm), "%s", data->comm);
        strcat(tmpdata, change_line);
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        
        memset(tmpdata, '\0', TMP_DATA_LEN);
        strcpy(tmpdata, "\n");
        filp->f_op->write(filp, tmpdata, strlen(tmpdata), &filp->f_pos);
        data
= data->next;
    }
    set_fs(fs);
    filp_close(filp, NULL);
    return 0;
}
int data_flush(my_struct_p head)
{
    my_struct_p data;
    data = head;
    while(NULL != data) {
        head = head->next;
        kfree(data);
        data = head;
    }
    return 0;
}
asmlinkage my_struct_p sys_getdata
(void)
{
    my_struct_p res;
    res = get_data();
    return res;
}
asmlinkage
int sys_datawrite(const char *filename, my_struct_p head)
{
    return filewrite(filename, head);
}
asmlinkage
int sys_dataflush(my_struct_p head)
{
    return data_flush(head);
}

用户空间测试程序:test.c


#include <asm/unistd.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <stdlib.h>
#include <string.h>
#define SYS_SAYHELLO 338
#define SYS_GETDATA 339
#define SYS_FILEWRITE 340
#define SYS_DATAFLUSH 341
struct my_struct {
    
volatile long state;
    int prio, static_prio, normal_prio;
    pid_t pid;
    pid_t tgid;
    char comm[16];
    struct my_struct *next;
};
int main(void)
{
    struct my_struct * data;
    
    data = syscall(SYS_GETDATA);
    syscall(SYS_FILEWRITE, "file", data);
    syscall(SYS_DATAFLUSH, data)
    return 0;
}
 

对test.c编译运行之后在当前目录下应该可以看到打印出的进程信息在文件file中。

时间: 2024-10-31 02:02:35

实现自己的系统调用针对linux-2.6.34【转】的相关文章

Rekoobe:一款针对Linux的恶意软件

来自俄罗斯杀毒厂商Dr. Web的专家发现了Rekoobe,这是一款针对Linux系统的恶意软件. Dr.Web在10月时发现了Rekoobe,之后的两个月,专家们对它进行了分析.Rekoobe木马最初只会感染Linux SPARC架构,之后它经过升级,可以感染运行于32位和64位英特尔芯片上的的Linux电脑. 木马介绍 专家解释称,Rekoobe木马本身十分简单,但它难以检测.它会使用加密手段来保护配置文件和它与C&C服务器交换的数据. "Linux.Rekoobe.1会使用加密的配

每天一个linux命令(34):du 命令

 转载自:http://www.cnblogs.com/peida/archive/2012/12/10/2810755.html 每天一个linux命令(34):du 命令 Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的. 1.命令格式: du [选项][文件] 2.命令功能: 显示每个文件和目录的磁盘使用空间. 3.命令参数: -a或-all  显示目录中个别文件的大小.    -b或-byte

针对Linux内存管理知识学习总结

现在的服务器大部分都是运行在Linux上面的,所以,作为一个程序员有必要简单地了解一下系统是如何运行的.对于内存部分需要知道: 地址映射 内存管理的方式 缺页异常 先来看一些基本的知识,在进程看来,内存分为内核态和用户态两部分,经典比例如下: 从用户态到内核态一般通过系统调用.中断来实现.用户态的内存被划分为不同的区域用于不同的目的: 当然内核态也不会无差别地使用,所以,其划分如下: 下面来仔细看这些内存是如何管理的. 地址 在Linux内部的地址的映射过程为逻辑地址–>线性地址–>物理地址,

如何安装 pandom : 一个针对 Linux 的真随机数生成器

本教程只针对 amd64/x86_64 架构 Linux 内核版本大于等于 2.6.9 的系统.本文将解释如何安装 pandom,这是一个由 ncomputers.org 维护的定时抖动真随机数生成器. 简介 在现在的计算机状况下,比如说配置了固态硬盘(SSD)的个人电脑和虚拟专用服务器(VPS)的环境中,Linux 内核内置的真随机数发生器提供的吞吐量很低. 而出于各种不同的加密目的使得对真随机数的需求持续增长,从而使得这个低吞吐量问题在 Linux 实现中变得越来越严重. 在与上述相同的物理

如何安装pandom : 一个针对Linux的真随机数生成器

本教程只针对 amd64/x86_64 架构 Linux 内核版本大于等于 2.6.9 的系统.本文将解释如何安装 pandom,这是一个由 ncomputers.org 维护的定时抖动真随机数生成器. 简介 在现在的计算机状况下,比如说配置了固态硬盘(SSD)的个人电脑和虚拟专用服务器(VPS)的环境中,Linux 内核内置的真随机数发生器提供的吞吐量很低. 而出于各种不同的加密目的使得对真随机数的需求持续增长,从而使得这个低吞吐量问题在 Linux 实现中变得越来越严重. 在与上述相同的物理

新勒索软件针对 Linux 系统

安全公司对一种新的勒索软件发出了警告,称它针对了Linux操作系统.该勒索软件被称为Linux.Encoder.1,主要瞄准运行Linux的Web服务器,加密内容后索要1BTC.攻击者利用了 Magento CMS 的一个漏洞感 染系统.Magneto被很多电子商务网站使用,它的一个高危漏洞在10月31日公开.该勒索软件需要管理员权限才能执行,运行之后它会加密主目录和所有 与网站相关的文件.它会在加密的每个目录下丢下一个文本文件 README_FOR_DECRYPT.txt,列出了支付方式和一个

针对Linux集群技术的要点解析

  现在很多的企业,网站都在应用Linux操作系统,Linux的优点使人们舍弃了微软.今天就讲讲Linux集群技术,让你更一步了解Linux,知道Linux集群技术强大功能.给你挑选系统起到参考的作用. Linux竞争力很强的原因之一,是它可以运行于极为普及的PC机上,不需要购买昂贵的专用硬件设备.在几台运行Linux的PC机上,只要加入相应的集群软件,就可以组成具有超强可靠性.负载能力和计算能力的Linux集群.集群中的每台服务器称为一个节点. 按照侧重点的不同,可以把Linux集群分为三类.

针对Linux集群的高级监控工具sinfo概述

你是不是面临这种情况:想搭建某种网络集群,但又要处理许多不同的计算机,想密切跟踪这所有计算机几乎是不可能的事?如果你负责满满一屋子的计算机,还要负责使用这些机器的那些用户,又该如何是好?sinfo也许正是你苦苦寻觅的那款工具.Freshmeat网站上的介绍如下: Sinfo是一款监视工具,使用广播方案来发布关于你本地网络上每一台计算机的运行状况的信息.它支持显示多方面的内容,比如处理器.内存使用情况.网络负载以及关于每一台计算机上五个主要进程的信息.Sinfo使用ncurses,以一目了然的方式

linux基础命令(34) du命令

Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du 命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的. 1.命令格式: du [选项][文件] 2 .命令功能: 显示每个文件和目录的磁盘使用空间. 3.命令参数: -a或-all  显示目录中个别文 件的大小. -b或-bytes  显示目录或文件大小时,以byte为单位. -c或--total   除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和. -k或--kilobytes  以K