使用简单字符驱动来做Kernel Hacking

事先声明,本人菜鸟一枚,文中如有不正确之处,敬请大侠指正委屈.

(本文中举例均以4.5版本的x86_64的linux内核为例)

字符驱动算是linux驱动里面比较简单的一种。说白了,就是可以对内存读哇写哇什么的。既然是对内存读写,那为什么还要驱动呢?简单的

int a;
a = 10;
不就是对内存写吗?干嘛还要搞个驱动,这么麻烦?
哈哈,利用驱动对内存的读写优势在于,可以对内核地址空间的内存进行读写。这下就不得了了,整个操作系统(也就是内核)都是在内核空间的,当然包括线程相关的一些内核数据什么的,也统统都栖身于内核空间,从而达到操作系统对数据的保护作用,一般人是碰不到这些数据的。那么当你把内存驱动加载到内核之后,会发生什么呢?哈哈,这些内核空间所保护的数据全部都暴露在你的内核驱动之下啦,因为你的字符驱动也是运行于内核空间的,说白了,你的字符驱动和内核空间的所有数据都是一家人啦,可以随意读写。这对于喜欢玩弄内核数据的人来说,有点小激动 大笑

闲话扯到这,上代码吧:

#include <linux/module.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/ptrace.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <linux/cdev.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("GAO");
MODULE_DESCRIPTION("HELLO");

dev_t dev;
extern struct task_struct init_task;

static inline unsigned long size_inside_page(unsigned long start,
                                             unsigned long size)
{
	unsigned long sz;
	sz = PAGE_SIZE - (start & (PAGE_SIZE - 1));
	return min(sz, size);
}

static loff_t my_chr_dev_seek(struct file *file, loff_t offset, int orig)
{
	loff_t ret;

	mutex_lock(&file_inode(file)->i_mutex);
	switch (orig) {
	case SEEK_CUR:
		offset += file->f_pos;
	case SEEK_SET:
		/* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */
		if (IS_ERR_VALUE((unsigned long long)offset)) {
			ret = -EOVERFLOW;
			break;
		}
		file->f_pos = offset;
		ret = file->f_pos;
		force_successful_syscall_return();
		break;
	default:
		ret = -EINVAL;
	}
	mutex_unlock(&file_inode(file)->i_mutex);
	return ret;
}

static ssize_t do_write_kmem(unsigned long p, const char __user *buf,
				size_t count, loff_t *ppos)
{
	ssize_t written, sz;
	unsigned long copied;

	written = 0;

	while (count > 0) {
		char *ptr;

		sz = size_inside_page(p, count);

		/*
		 * On ia64 if a page has been mapped somewhere as uncached, then
		 * it must also be accessed uncached by the kernel or data
		 * corruption may occur.
		 */
		ptr = xlate_dev_kmem_ptr((char *)p);

		copied = copy_from_user(ptr, buf, sz);
		if (copied) {
			written += sz - copied;
			if (written)
				break;
			return -EFAULT;
		}
		buf += sz;
		p += sz;
		count -= sz;
		written += sz;
	}

	*ppos += written;
	return written;
}
static ssize_t my_chr_dev_write(struct file *file, const char __user *buf,
			  size_t count, loff_t *ppos)
{
	unsigned long p = *ppos;
	ssize_t wrote = 0;
	ssize_t virtr = 0;
	char *kbuf; 
	int err = 0;

/*	if (!capable(CAP_COMPROMISE_KERNEL))
		return -EPERM;
		*/

	if (p < (unsigned long) high_memory) {
		unsigned long to_write = min_t(uns
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值