与系统调用表从播放LKM

我重写SYS_READ在Linux操作系统(3.X)从系统调用表,但是卸载模块本身,当我遇到一些麻烦。 我第一次加载我模块,它发现系统调用表,然后启用RW ,覆盖SYS_READ我自己SYS_READ功能(这其实并不做任何事情比调用原来别的SYS_READ ),那么我稍等片刻,然后卸载模块。 在我模块的卸载方法我恢复原来的SYS_READ功能回到系统调用表,并设置回系统调用表到RO

原来SYS_READ功能已恢复正常,但我得到这个,当我卸载模块:http://pastebin.com/JyYpqYgL

我在想什么? 我应该做一些恢复真正经过SYS_READ

编辑:GitHub的链接项目:https://github.com/alexandernst/procmon

编辑:

这是我得到的系统调用表地址:

void **sys_call_table; struct idt_descriptor{ unsigned short offset_low; unsigned short selector; unsigned char zero; unsigned char type_flags; unsigned short offset_high; } __attribute__ ((packed)); struct idtr{ unsigned short limit; void *base; } __attribute__ ((packed)); void *get_sys_call_table(void){ struct idtr idtr; struct idt_descriptor idtd; void *system_call; unsigned char *ptr; int i; asm volatile("sidt %0" : "=m" (idtr)); memcpy(&idtd, idtr.base + 0x80 * sizeof(idtd), sizeof(idtd)); system_call = (void*)((idtd.offset_high<<16) | idtd.offset_low); for(ptr=system_call, i=0; i<500; i++){ if(ptr[0] == 0xff && ptr[1] == 0x14 && ptr[2] == 0x85) return *((void**)(ptr+3)); ptr++; } return NULL; } sys_call_table = get_sys_call_table();

这是我怎么设置RW / RO:

unsigned long set_rw_cr0(void){ unsigned long cr0 = 0; unsigned long ret; asm volatile("movq %%cr0, %%rax" : "=a"(cr0)); ret = cr0; cr0 &= 0xfffffffffffeffff; asm volatile("movq %%rax, %%cr0" : : "a"(cr0)); return ret; } void set_ro_cr0(unsigned long val){ asm volatile("movq %%rax, %%cr0" : : "a"(val)); }

最后,这是我如何定义我的系统调用和更改系统调用表:

asmlinkage ssize_t (*real_sys_read)(unsigned int fd, char __user *buf, size_t count); asmlinkage ssize_t hooked_sys_read(unsigned int fd, char __user *buf, size_t count); //set my syscall real_sys_read = (void *)sys_call_table[__NR_read]; sys_call_table[__NR_read] = (void *)hooked_sys_read; //restore real syscall sys_call_table[__NR_read] = (void *)real_sys_read;

--------------解决方案-------------

如果你想卸载该拦截系统调用意识到的情况下,当某个进程仍然在系统调用处理程序和代码(模块的文本段)去从离内存模块。 这导致页面错误时,过程从一些内核函数(即睡)到你的代码的代码不存在了作为返回。

所以,正确的模块卸载方案必须检查可能在大呼过瘾的系统调用眠的processess。 只是,如果有可能的卸车没有一个过程,在系统调用挂钩睡觉。

UPD

请看到,证明了我的理论的补丁。 它增加了原子计数器的递增和递减时hooked_sys_read电话。 所以,我认为有,在仍然在等待的过程read_sys_read而你模块已经被卸载。 这个补丁表明,与printk(read_counter)并打印出1对我来说,这意味着有人不减少read_counter

http://pastebin.com/1yLBuMDY

下面是一些随机随笔,我从确保任何/所有的它使多大意义很远,但天色已晚,我宁愿把它写下来,并得到睡觉比试图准确找出哪些(如果有的话)实际上是问题。 希望事情会有所帮助:

我想你已经检查你的实际恢复恢复指针-例如打印的内容sys_call_table[__NR_read]

我肯定会通过的OR-ing回您清除该位,而不是恢复旧值恢复CR0 - 它可能不是最重要的时间,但也有在CR0其他位可能会改变不时 - 大概只有真正的TS位,不过这也够糟糕的 - 让陈旧的浮点一些随机恢复或丢失浮点恢复是一件坏事[和猜测是多么容易弄清楚的原因,一些长期运行的数学突然得到完全不正确的结果,因为你的代码卸下几个小时前?]。 这几乎可以肯定不是,为什么你的代码崩溃,但它几乎肯定会在一个点或另一个造成问题,如果您加载/卸载模块足够的时间。 [此外,还要确保你没有处理器之间的交换,当您更改CR0 -可能是最好的做一些锁定,以确保您留在同一处理器上,同时做全更新sys_call_table东西。

我觉得你的代码崩溃的原因,但是,缺乏缓存刷新(OS没有期待这个内存改变 - 而这个过程将其视为只读的,因此它不应该需要检查无效宣告]你需要刷新的所有处理器缓存的sys_call_table的进入我不知道该怎么做的最简单/最好的办法是,我认为。 void flush_icache_range(unsigned long start, unsigned long end)是你所需要的电话-但我不知道这是当前的或旧的功能从这里:。https://www.kernel.org/doc/Documentation/cachetlb.txt

正如我最初所说,这是更漫记比实际寻找到事情的内核,等的时间内工作,深为我的美容觉 - 我需要尽可能多的,当我可以得到...;)

分类:C# 时间:2012-01-01 人气:0
本文关键词: linux下,模块,linux内核
分享到:

相关文章

  • 如何注册Linux安全模块在内核2.6? 2013-08-01

    我想利用LSM框架内核的Ubuntu 2.6.36. 当我编译内核模块,它写道: 警告:"register_security"不确定! 很多googlings后,我找到了原因在于register_security()符号在2.6内核不再出口. 所以我加了EXPORT_SYMBOL(register_security)在../security/security.c文件,并重新编译内核. 新内核启动后,我加extern int register_security(struct securi

  • Linux下的Adobe Flex的Apache模块 2012-08-13

    我试图从这里使用Adobe Flex的阿帕奇(2.2)模块在Linux下- http://labs.adobe.com/wiki/index.php/Flex_Module_for_Apache_and_IIS手动安装). 我有一个很好的工作的Apache系统,与Ubuntu 8.10和Sun JDK V6更新10所以安装这不是关于支持工具. 我无法弄清楚如何使这个Apache模块的工作. 我的httpd.conf显示了这个: LoadModule flex_module /usr/lib/ap

  • CVS标签用于完成在Linux下的模块 2013-02-24

    我怎样才能得到选项卡完成的工作选择(最好使用bash)在Linux下CVS模块? 例如,"CVS合作"+选项卡将列出模块我可以检出. 我听说它很容易使用的zsh做,但我仍然没能得到它的工作无论是. 另外,我怎么可以列出所有可用的模块(或仓库?)在CVSROOT可用? --------------解决方案------------- 还有就是bash补项目. 它有一些CVS完成它,我不是100%,如果能确定所有的模块结帐. 但是,这将是一个良好的开端. 我已经有这种行为,我认为(没有可靠的

  • 谁能告诉我怎么内核编程在Linux下完成的,因为Windows DDK在Windows 2014-09-19

    我知道Windows内核,但新的Linux内核. 我只需要知道它在linux下如何做,即程序的开发. --------------解决方案------------- 您可以检查那里(free-electrons.com),它是内核的研究与开发一个很好的信息来源. (专门从事嵌入式Linux,但大部分的文档都可用标准制定) 你也有经典的Linux设备的驱动程序,这是非常完整的,相关详细. 最后但并非最不重要的,Linux内核文件. Linux没有稳定的内核API. 这是由设计,所以你一般应该避免,

  • linux下推荐的方法1ms的分辨率计时器 2012-06-17

    我需要一个计时器刻度与linux下的1ms的分辨率. 它被用来增加,反过来被用于查看是否各种活动应当触发的定时器值. 的POSIX timerfd_create是因为glibc的要求,不是一种选择. 我想timer_create和timer_settimer,但最好的,我从他们身上得到的是10ms的决议,较小的值似乎默认为10ms的决议. Getittimer和setitimer函数必须按照手册页10毫秒的分辨率. 要做到这一点定时器我目前可以想到的唯一方法是使用clock_gettime与CL

  • 指定非标准波特率Linux下FTDI的虚拟串口 2012-09-23

    我有一个USB设备我想拥有的ftdi_sio内核模块提供了一个虚拟串口通信. 不过,我有一些麻烦波特率的端口设置为14400: termios.h没有指定一个常数14400,所以我不能用cfsetispeed和cfsetospeed . 在源ftdi_sio内核模块,通讯基地设置为2400,并似乎没有成为一个办法去改变它. 这意味着我不能使用自定义的除数与TIOCSSERIAL的ioctl,并获得14400波特率的方式. 该模块源有评论使得它听起来像设置alt_speed的成员tty_struc

  • 为什么Linux的称为单内核? 2014-11-16

    我读了Linux是一个单内核. 难道单内核意味着编译和完整的内核代码链接到一个可执行文件? 如果Linux是能够支持模块,为什么不打破所有的子系统成模块,并加载它们在必要的时候? 在这种情况下,内核不必加载所有模块最初和能保持的功能的索引的模块中,并将其装载在必要时. --------------解决方案------------- 一种单片内核是一个内核,其中所有服务(文件系统,VFS,设备驱动程序等)以及核心功能(调度,存储器分配,等)是一个紧针织组共享相同的空间. 这直接反对一个微内核. 微

  • 编辑Windows注册表中,在Python,Linux下 2012-01-27

    我在找一个Python API(或C API,因为我很愿意绑定),用于从Linux系统中编辑的Windows注册表从XP到7. 在Windows目标将是Linux下安装的卷. 我愿意,如果不存在的代码库. 因此,在注册表中的任何文档或内部就得心应手了. 任何帮助,大大appriciated. --------------解决方案------------- 好了,你是一个配置单元文件编辑器后? 我写了一个winregistry做这个(适用于NT和WIN9X荨麻疹)模块. 这不是真的准备好市民,但工

  • 是否有任何用户模式的多线程库/框架的C + + Linux下? 2012-02-05

    我在寻找用户模式的多线程库/框架,C ++在Linux下. 我熟悉的boost ::线程ACE_Thread_Manager但AFAIK他们两人最终使用操作系统本地线程的支持. 建议将不胜感激. --------------解决方案------------- 是MTasker那种你要找的东西? 这也是一个合作的多任务处理库. 您可能还需要考虑只是掀起了一些状态机. 另外,请查阅国家线程和麻省理工学院的Pthreads. 这个工具会帮助分层状态机,它可以用于此目的的产生:CHSM GNU PTH:

  • 在Linux下用C ++和GCC,是有可能的虚拟地址转换成物理地址? 2012-02-16

    在Linux下,C ++和GCC,我可以得到一个给定的虚拟地址的物理地址? 我知道我将无法操纵物理地址作为一个物理地址. --------------解决方案------------- 都能跟得上. 有没有保证的虚拟地址基于物理地址(也可能是映射文件在内存中没有代表,例如.)同时,该操作系统是免费的物理内存中随时来回移动虚拟地址,所以谁也不能保证,一个物理地址将保持正确的或有效的. 为什么你认为你需要一个物理地址? 什么是你要完成? 我相信你可以写一个Linux内核模块,它会告诉你如何你的地址空

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.741 (s). 10 q(s)