C Linux驱动程序开发-挂接开放系统调用导致崩溃
我想了解更多关于在Linux中挂接系统调用的信息。当文件被打开时,我正试图让我的驱动程序向我报告。最终,为了做到这一点,我认为最好将syscall_挂接在open上。我运行了systrace(下面的部分)来查看实际使用的是哪个opensyscall,看起来像是使用了OpenAt。然而,每当我钩住它,我的虚拟机就会崩溃。我的代码有问题吗 下面是我的代码C Linux驱动程序开发-挂接开放系统调用导致崩溃,c,linux,linux-kernel,driver,fopen,C,Linux,Linux Kernel,Driver,Fopen,我想了解更多关于在Linux中挂接系统调用的信息。当文件被打开时,我正试图让我的驱动程序向我报告。最终,为了做到这一点,我认为最好将syscall_挂接在open上。我运行了systrace(下面的部分)来查看实际使用的是哪个opensyscall,看起来像是使用了OpenAt。然而,每当我钩住它,我的虚拟机就会崩溃。我的代码有问题吗 下面是我的代码 #include <linux/init.h> #include <linux/module.h> #include &l
#include <linux/init.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/kallsyms.h>
#include <linux/slab.h>
#include <linux/kern_levels.h>
#include <linux/gfp.h>
#include <asm/unistd.h>
#include <asm/paravirt.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Axel");
MODULE_DESCRIPTION("Simple Hooking Of a Syscall");
MODULE_VERSION("1.0");
unsigned long **SYS_CALL_TABLE;
void EnablePageWriting(void){
write_cr0(read_cr0() & (~0x10000));
}
void DisablePageWriting(void){
write_cr0(read_cr0() | 0x10000);
}
//define our origional function.
asmlinkage int ( *original_open ) ( const char __user * pathname, int flags, mode_t mode );
//Create Our version of Open Function.
asmlinkage int HookOpen( const char __user * pathname, int flags, mode_t mode ){
printk(KERN_INFO "Open Syscall Called -- File Opened ");
return (*original_open)(pathname, flags, mode);
}
// Set up hooks.
static int __init SetHooks(void) {
// Gets Syscall Table **
SYS_CALL_TABLE = (unsigned long**)kallsyms_lookup_name("sys_call_table");
printk(KERN_INFO "Hooks Will Be Set.\n");
printk(KERN_INFO "System call table at %p\n", SYS_CALL_TABLE);
// Opens the memory pages to be written
EnablePageWriting();
// Replaces Pointer Of Syscall_open on our syscall.
original_open = (void*)SYS_CALL_TABLE[__NR_openat];
SYS_CALL_TABLE[__NR_openat] = (unsigned long*)HookOpen;
DisablePageWriting();
return 0;
}
static void __exit HookCleanup(void) {
// Clean up our Hooks
EnablePageWriting();
SYS_CALL_TABLE[__NR_openat] = (unsigned long*)original_open;
DisablePageWriting();
printk(KERN_INFO "HooksCleaned Up!");
}
module_init(SetHooks);
module_exit(HookCleanup);
好的,我有一个答案,我让作者发了一个关于这个的视频 这是youtube上的一段视频,我也在关注这段视频
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
模块许可证(“GPL”);
模块作者(“Axel”);
模块描述(“系统调用的简单挂钩”);
模块_版本(“1.0”);
无符号长**系统调用表;
void启用页面写入(void){
写cr0(读cr0()&(~0x10000));
}
无效禁用页面写入(无效){
写入_cr0(读取_cr0()| 0x10000);
}
//定义我们的原始功能。
ASMLINKING int(*原始打开)(int dirfd,常量字符*路径名,int标志);
//创建我们的开放函数版本。
ASMLINKING int HOOK OPEN(int dirfd,常量字符*路径名,int标志){
字符字母;
int i=0;
字符目录[255];
char OurFile[14]=“断点”;
而(字母!=0 | | i<6){//if(字母==0x41 | |字母<0x7a)可能是为了防止坏字符进入字符串缓冲区
//此宏将单个简单变量从用户空间复制到内核空间。
//因此,这将把路径名[i]复制到ch;
获取用户(字母、路径名+i);
目录[i]=字母;
i++;
}
if(strcmp(OurFile,directory)==0){
printk(KERN_INFO“文件已访问!!!%s”,目录);
}
memset(目录,0255);
//跳转到原始区域OpenAt()
返回(*原始打开)(dirfd、路径名、标志);
}
//设置挂钩。
静态int\uu init SetHooks(void){
//获取系统调用表**
SYS_CALL_TABLE=(无符号长**)kallsyms_lookup_name(“SYS_CALL_TABLE”);
printk(将设置KERN_INFO“挂钩。\n”);
printk(内核信息“位于%p\n的系统调用表”,系统调用表);
//打开要写入的内存页
启用页面写入();
//替换系统调用上的Syscall\u open指针。
原始打开=(无效*)系统调用表[\uuuuuuunr\uOpenat];
SYS\u CALL\u TABLE[\uu NR\u openat]=(无符号长*)HookOpen;
禁用页面写入();
返回0;
}
静态void\uu退出钩子清理(void){
//清理我们的钩子
启用页面写入();
系统调用表[\uuuunr\uopenat]=(无符号长*)原始打开;
禁用页面写入();
printk(KERN_INFO“hooks clean Up!”);
}
模块_init(设置挂钩);
模块_出口(挂钩清理);
好的,我有一个答案,我让作者在上面贴了一个视频
这是youtube上的一段视频,我也在关注这段视频
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
模块许可证(“GPL”);
模块作者(“Axel”);
模块描述(“系统调用的简单挂钩”);
模块_版本(“1.0”);
无符号长**系统调用表;
void启用页面写入(void){
写cr0(读cr0()&(~0x10000));
}
无效禁用页面写入(无效){
写入_cr0(读取_cr0()| 0x10000);
}
//定义我们的原始功能。
ASMLINKING int(*原始打开)(int dirfd,常量字符*路径名,int标志);
//创建我们的开放函数版本。
ASMLINKING int HOOK OPEN(int dirfd,常量字符*路径名,int标志){
字符字母;
int i=0;
字符目录[255];
char OurFile[14]=“断点”;
而(字母!=0 | | i<6){//if(字母==0x41 | |字母<0x7a)可能是为了防止坏字符进入字符串缓冲区
//此宏将单个简单变量从用户空间复制到内核空间。
//因此,这将把路径名[i]复制到ch;
获取用户(字母、路径名+i);
目录[i]=字母;
i++;
}
if(strcmp(OurFile,directory)==0){
printk(KERN_INFO“文件已访问!!!%s”,目录);
}
memset(目录,0255);
//跳转到原始区域OpenAt()
返回(*原始打开)(dirfd、路径名、标志);
}
//设置挂钩。
静态int\uu init SetHooks(void){
//获取系统调用表**
SYS_CALL_TABLE=(无符号长**)kallsyms_lookup_name(“SYS_CALL_TABLE”);
printk(将设置KERN_INFO“挂钩。\n”);
printk(内核信息“位于%p\n的系统调用表”,系统调用表);
//打开要写入的内存页
启用页面写入();
//替换系统调用上的Syscall\u open指针。
原始打开=(无效*)系统调用表[\uuuuuuunr\uOpenat];
SYS\u CALL\u TABLE[\uu NR\u openat]=(无符号长*)HookOpen;
禁用页面写入();
返回0;
}
静态void\uu退出钩子清理(void){
//清理我们的钩子
启用页面写入();
系统调用表[\uuuunr\uopenat]=(无符号长*)原始打开;
禁用页面写入();
printk(KERN_INFO“hooks clean Up!”);
}
模块_init(设置挂钩);
模块_出口(挂钩清理);
我可能有一个解决方案。我想我可能有办法解决这个问题。检查
//STRACE
/*
root@anonHost:~# strace cat somefile
execve("/bin/cat", ["cat", "somefile"], 0x7ffd43175fe8 ) = 0
brk(NULL) = 0x5614699df000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=169782, ...}) = 0
mmap(NULL, 169782, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f459a155000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f459a153000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4599b67000
mprotect(0x7f4599d4e000, 2097152, PROT_NONE) = 0
mmap(0x7f4599f4e000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f4599f4e000
mmap(0x7f4599f54000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f4599f54000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f459a154540) = 0
mprotect(0x7f4599f4e000, 16384, PROT_READ) = 0
mprotect(0x56146832f000, 4096, PROT_READ) = 0
mprotect(0x7f459a17f000, 4096, PROT_READ) = 0
munmap(0x7f459a155000, 169782) = 0
brk(NULL) = 0x5614699df000
brk(0x561469a00000) = 0x561469a00000
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=4547104, ...}) = 0
mmap(NULL, 4547104, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f4599710000
close(3) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
openat(AT_FDCWD, "somefile", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=46, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
mmap(NULL, 139264, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f459a15d000
read(3, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 131072) = 46
write(1, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 46aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
) = 46
read(3, "", 131072) = 0
munmap(0x7f459a15d000, 139264) = 0
close(3) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/kallsyms.h>
#include <linux/slab.h>
#include <linux/kern_levels.h>
#include <linux/gfp.h>
#include <asm/unistd.h>
#include <asm/paravirt.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Axel");
MODULE_DESCRIPTION("Simple Hooking Of a Syscall");
MODULE_VERSION("1.0");
unsigned long **SYS_CALL_TABLE;
void EnablePageWriting(void){
write_cr0(read_cr0() & (~0x10000));
}
void DisablePageWriting(void){
write_cr0(read_cr0() | 0x10000);
}
//define our origional function.
asmlinkage int ( *original_open ) (int dirfd, const char *pathname, int flags);
//Create Our version of Open Function.
asmlinkage int HookOpen(int dirfd, const char *pathname, int flags){
char letter ;
int i = 0;
char directory[255];
char OurFile[14] = "breakpoints";
while (letter != 0 || i < 6){ // if (letter == 0x41 || letter < 0x7a) Maybe to prevent bad chars from entering string buffer
//This macro copies a single simple variable from user space to kernel space.
//So this will copy pathname[i] to ch;
get_user(letter, pathname+i);
directory[i] = letter ;
i++;
}
if (strcmp(OurFile , directory ) == 0 ){
printk(KERN_INFO "File Accessed!!! %s", directory);
}
memset(directory, 0, 255);
// Jump to origional OpenAt()
return (*original_open)(dirfd, pathname, flags);
}
// Set up hooks.
static int __init SetHooks(void) {
// Gets Syscall Table **
SYS_CALL_TABLE = (unsigned long**)kallsyms_lookup_name("sys_call_table");
printk(KERN_INFO "Hooks Will Be Set.\n");
printk(KERN_INFO "System call table at %p\n", SYS_CALL_TABLE);
// Opens the memory pages to be written
EnablePageWriting();
// Replaces Pointer Of Syscall_open on our syscall.
original_open = (void*)SYS_CALL_TABLE[__NR_openat];
SYS_CALL_TABLE[__NR_openat] = (unsigned long*)HookOpen;
DisablePageWriting();
return 0;
}
static void __exit HookCleanup(void) {
// Clean up our Hooks
EnablePageWriting();
SYS_CALL_TABLE[__NR_openat] = (unsigned long*)original_open;
DisablePageWriting();
printk(KERN_INFO "HooksCleaned Up!");
}
module_init(SetHooks);
module_exit(HookCleanup);