LINUX设备驱动

Linux设备驱动代码一枚,可用于练习各种漏洞利用。

一、设备驱动

/* demo.c */

#include <linux/cdev.h>

#include <linux/device.h>

#include <asm/uaccess.h> 

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

MODULE_LICENSE("Dual BSD/GPL");

#define DEMO_MAJOR      255

#define DEMO_MINOR      0

#define DEMO_COUNT      1

dev_t dev = 0;

u32 demo_major = 0;

u32 demo_minor = 0;

struct cdev demo_cdev;

struct class *dev_class = NULL;

struct device *dev_device = NULL;

int demo_open(struct inode* inode, struct file *filp) {

        printk("enter demo_open() ");

        return 0;

}

ssize_t demo_read(struct file *filp, char __user *buf, size_t count, loff_t *offset) {

        char s[10] = {0};

        printk("enter demo_read() ");

        /* ADD CODE HERE */

        copy_from_user(s, buf, sizeof(s)-1);

        printk("read from userspace = %s ", s);

        return 0;

}

ssize_t demo_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset) {

        printk("enter demo_write() ");

        return 0;

}

/*

int demo_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data)

{

        printk("enter demo_ioctl() ");

        return 0;

}

*/

int demo_release(struct inode *inode, struct file *filp) {

        printk("enter demo_release() ");

        return 0;

}

struct file_operations demo_fops = {

        .owner = THIS_MODULE,

        .open = demo_open,

        .read = demo_read,

        .write = demo_write,

        /*.ioctl = demo_ioctl,*/

        .release = demo_release,

        };

int __init demo_init(void) {

        int ret = 0;

        printk("enter demo_init() ");

        if(demo_major) {

                dev = MKDEV(DEMO_MAJOR, DEMO_MINOR);

                ret = register_chrdev_region(dev, DEMO_COUNT, "demo_demo");

        } else {

                ret = alloc_chrdev_region(&dev, demo_minor, DEMO_COUNT, "demo_demo02");

        }

        if(ret < 0) {

                printk("register_chrdev_region failed! ");

                goto fail_register_chrdev;

        }

        demo_major = MAJOR(dev);

        printk("demo_major = %d ", demo_major);

        cdev_init(&demo_cdev, &demo_fops);

        ret = cdev_add(&demo_cdev, dev, DEMO_COUNT);

        if(ret < 0) {

                printk("cdev_add failed! ");

                goto fail_cdev_add;

        }

        dev_class = class_create(THIS_MODULE, "demo_class");

        if(IS_ERR(dev_class)) {

                printk("class_create failed! ");

                ret = PTR_ERR("dev_class");

                goto fail_class_create;

        }

        dev_device = device_create(dev_class, NULL, dev, NULL, "demo%d", demo_minor);

        if(IS_ERR(dev_device)) {

                printk("device_create failed! ");

                ret = PTR_ERR(dev_device);

                goto fail_device_create;

        }

        return 0;

fail_device_create:

        class_destroy(dev_class);

fail_class_create:

        cdev_del(&demo_cdev);

fail_cdev_add:

        unregister_chrdev_region(dev, DEMO_COUNT);

fail_register_chrdev:

        return ret;

}

void __exit demo_exit(void) {

        printk("enter demo_exit() ");

        device_destroy(dev_class, dev);

        class_destroy(dev_class);

        cdev_del(&demo_cdev);

        unregister_chrdev_region(dev, DEMO_COUNT);

}

module_init(demo_init);

module_exit(demo_exit);

二、Makefile 文件

/* Makefile */

ifneq ($(KERNELRELEASE),)

        obj-m := demo.o

else

        KERNELDIR ?= /lib/modules/$(shell uname -r)/build

        PWD := $(shell pwd)

default:

        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

endif

clean:

        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules.order Module.symvers

三、驱动安装脚本

/* setup.sh */

rmmod demo

insmod ./demo.ko

chmod 666 /dev/demo0

四、简单测试

/* client.c */

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/ioctl.h>

int 

main(int arg, char **argv) {

        char *s = (char*)malloc(20);

        memcpy(s, "hello driver.", 10);

        int fd = -1; 

        if (-1 == (fd = open("/dev/demo0", O_RDONLY))) {

                perror("open");

                return (-1);

        }

        read(fd, s, 0, 0);

        //system("/bin/sh");

        return (0);

}

五、测试结果

kiiim@ubuntu :~/__demo_driver$ ./client
kiiim@ubuntu :~/__demo_driver$ dmesg

……

[ 4405.506553] enter demo_init()

[ 4405.506558] demo_major = 247

[ 4408.702358] enter demo_open()

[ 4408.702365] enter demo_read()

[ 4408.702366] read from userspace = hello dri 

[ 4408.702527] enter demo_release()

kiiim@ubuntu :~/__demo_driver$ 

原文地址:https://www.cnblogs.com/gm-201705/p/9864078.html