免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6085 | 回复: 17
打印 上一主题 下一主题

修改sys_call_table后调用参数获取失败<已解决> [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-12-12 23:42 |只看该作者 |正序浏览
环境是内核2.6.22,发行版为ubuntu7.10
模块的源代码如下:
  1. #include <linux/sched.h>
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. #include <linux/init.h>
  5. #include <linux/fs.h>
  6. #include <linux/file.h>

  7. MODULE_AUTHOR("-[email]2@163.com[/email]");
  8. MODULE_DESCRIPTION("By hook system call table, this module can capture system calls.");
  9. MODULE_LICENSE("GPL");

  10. typedef int (*alarm_t)(int);
  11. void** sys_call_table = (void **)0xc02fc540;
  12. alarm_t old_func;

  13. int hook(int arg)
  14. {
  15. printk(KERN_ALERT "<1>You got me partner: %d!\n",arg);
  16. return arg*6;
  17. }
  18. static int patch_init(void)
  19. {
  20.     old_func=(alarm_t)sys_call_table[__NR_alarm];
  21.     sys_call_table[__NR_alarm]=(alarm_t)hook;
  22.     printk(KERN_ALERT "<1>SCT is patched!\n");
  23.     return 0;
  24. }
  25. static void patch_cleanup(void)
  26. {
  27.     sys_call_table[__NR_alarm]=old_func;
  28.     printk(KERN_ALERT "<1>SCT is unpatched!\n");
  29. }
  30. module_init(patch_init);
  31. module_exit(patch_cleanup);
复制代码


附上module编译过程
文件名为sct.c
makefile内容为:object_m := sct.o
gcc -c sct.c -I/usr/src/linux-x.x.x/include SUBDIRS=$(PWD)  modules

编译成功后加载到内核空间:sudo insmod ./sct.ko
经过lsmod查看确认加载成功,同时用例程序(NASM风格)如下:
  1. ; tiny.asm
  2. BITS 32
  3. GLOBAL _start
  4. SECTION .text
  5. _start:
  6. mov eax, 27
  7. mov ebx, 9
  8. int 0x80
  9. push eax
  10. mov eax, 1
  11. pop ebx
  12. int 0x80
复制代码

编译:
nasm -f elf test.s
gcc -Wall -s -nostdlib test.o
编译成功后测试:./a.out ; echo $?
显示为:162
查看内核调试信息:dmesg |tail -3可以看见:
[24495.490900] SCT is patched!
[24539.639316] You got me partner: 27!
[24549.111889] SCT is unpatched!
可以发现系统调用已经被替换了,但是参数获取却出错了,上例中参数为9,却显示获得的为27(貌似是系统调用号);
用C语言的测试结果一样(证明测试程序没有问题)
请问是为什么???
先谢过了!!!

[ 本帖最后由 13706808 于 2007-12-19 17:48 编辑 ]

论坛徽章:
0
18 [报告]
发表于 2011-05-16 08:51 |只看该作者
我也遇到了同keith_269 兄相同的问题。求大家指导!

论坛徽章:
0
17 [报告]
发表于 2008-06-21 10:31 |只看该作者
我用13706808 的方法也写了个类似的模块。编译通过了,但是在insmod的时候会发生段错误,不知道是为什么啊,大侠们帮忙一下,谢谢!
#ifndef __KERNEL__
#define __KERNEL__
#endif

#ifndef MODULE
#define MODULE
#endif

#ifdef CONFIG_MODVERSIONS
#define MODVERSIONS
#include <linux/modversions.h>
#endif

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <asm/unistd.h>
MODULE_LICENSE("GPL");

void** sys_call_table=(void**)0xc06357a0;

int (*orig_open)(const char* filename, int flags,int mode);

int new_open (const char* filename, int flags,int mode)
{
        printk("this is a test\n");
        return orig_open(filename,flags,mode);
} int init_module(void)
{
orig_open=sys_call_table[__NR_open];
sys_call_table[__NR_open]=new_open;
printk("init_module exe\n");
return 0;
}

void cleanup_module(void)
{
sys_call_table[__NR_open]=orig_open;
printk("cleanup_module exe\n");
}

系统报错段错误时我用dmesg看了下错误信息如下:
<1>BUG: unable to handle kernel paging request at virtual address c06357b4
printing eip: d0aac056 *pde = 0e9dd163 *pte = 00635161
Oops: 0003 [#1] SMP
Modules linked in: test2(U) addsym(U) nls_utf8 autofs4 fuse rfcomm l2cap bluetooth sunrpc nf_conntrack_ftp nf_conntrack_ipv4 xt_state nf_conntrack xt_tcpudp ipt_REJECT iptable_filter ip_tables x_tables loop dm_multipath ipv6 snd_ens1371 gameport snd_rawmidi snd_ac97_codec ac97_bus snd_seq_dummy parport_pc snd_seq_oss snd_seq_midi_event parport snd_seq floppy snd_seq_device snd_pcm_oss snd_mixer_oss snd_pcm snd_timer ac button pcnet32 snd i2c_piix4 pcspkr soundcore mii snd_page_alloc i2c_core sr_mod sg cdrom BusLogic dm_snapshot dm_zero dm_mirror dm_mod ata_piix pata_acpi ata_generic libata sd_mod scsi_mod ext3 jbd mbcache uhci_hcd ohci_hcd ehci_hcd

Pid: 3793, comm: insmod Not tainted (2.6.24.7-92.fc8 #1)
EIP: 0060:[<d0aac056>] EFLAGS: 00010286 CPU: 0
EIP is at init_module+0x13/0x29 [test2]
EAX: c0487967 EBX: c3c05268 ECX: 00000000 EDX: c06357b4
ESI: c3c05240 EDI: 00000001 EBP: d0aac480 ESP: ced43ebc
DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process insmod (pid: 3793, ti=ced43000 task=c92d0690 task.ti=ced43000)
Stack: 00000000 c044d064 00000000 00000000 c1025520 00000200 0000001b 00000000
       c3d9b990 00000438 0000be03 c91ea004 00000000 00000000 00000000 00000000
       00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Call Trace:
[<c044d064>] sys_init_module+0x14d6/0x15f9
[<c042f7aa>] printk+0x0/0x1f
[<c04051da>] syscall_call+0x7/0xb
=======================
Code: aa d0 a1 2c c4 aa d0 89 50 14 c7 04 24 04 c1 aa d0 e8 69 37 98 ef 58 c3 83 ec 04 8b 15 2c c4 aa d0 83 c2 14 8b 02 a3 0c d6 aa d0 <c7> 02 6c c0 aa d0 c7 04 24 18 c1 aa d0 e8 42 37 98 ef 31 c0 5a
EIP: [<d0aac056>] init_module+0x13/0x29 [test2] SS:ESP 0068:ced43ebc

看一下错误信息好像是unable to handle kernel paging request at virtual address c06357b4。sys_open的系统调用号是5.我的sys_call_table的地址是c06357a0。而c06357b4刚好是c06357a0+5*4. 是访问sys_call_table[__NR_open]的时候出错了吗?希望大家帮我拍拍错。

论坛徽章:
0
16 [报告]
发表于 2007-12-19 17:47 |只看该作者
明白了
谢谢大家特别是qtdszws的关注与帮助!

论坛徽章:
0
15 [报告]
发表于 2007-12-19 08:58 |只看该作者
>>我记得系统调用是通过寄存器传参 而不是通过栈参数的吧.

不好意思,我指的是sys_xxx函数的传参方式,它们都是通过栈传的。而从用户空间到系统空间的传参方式是通过寄存器。

论坛徽章:
0
14 [报告]
发表于 2007-12-18 22:35 |只看该作者

回复 #13 qtdszws 的帖子

我记得系统调用是通过寄存器传参 而不是通过栈参数的吧.

论坛徽章:
0
13 [报告]
发表于 2007-12-18 21:38 |只看该作者
>>首先是为什么你的机器上面不用这么做???

不知道,可能我的gcc版本默认使用栈传参,而你的则使用寄存器吧,猜的

>>那么参数应该是透過暫存器來傳遞,但是
61:    89 c3                    mov    %eax,%ebx //系统调用号存入ebx
寄存器的值(应该是ebx的值吧?)也不对啊??

系统调用是规定使用栈传参的,因此你的函数也必须配合,而不是要求系统配合你

论坛徽章:
0
12 [报告]
发表于 2007-12-18 21:17 |只看该作者
改成__attribute__((regparm(0))) int hacked_alarm(int arg)
就对了

但是还有一点不明白的地方请指教

首先是为什么你的机器上面不用这么做???
因为我在网上看到的文章里面都没有看见提及要这么做的

其次,网上查找
regparm 的語法是:regparm(number),regparm 屬性只在 Intel 386 平臺上有作用,用來指定最多可以有多少個("number" )參數(arguments)能以暫存器來傳遞,regparm(0) 表示參數都不能透過暫存器來傳遞,因此所有參數都會透過堆疊來傳遞。
如果我没有写regparm(0) ,那么参数应该是透過暫存器來傳遞,但是
61:    89 c3                    mov    %eax,%ebx //系统调用号存入ebx
寄存器的值(应该是ebx的值吧?)也不对啊??
(汇编不甚懂)

谢谢了!!!

论坛徽章:
0
11 [报告]
发表于 2007-12-18 09:13 |只看该作者
我的
00000000 <hook>:                                             
   0:   55                      push   %ebp                  
   1:   89 e5                   mov    %esp,%ebp            
   3:   53                      push   %ebx                  
   4:   83 ec 0c                sub    $0xc,%esp            
   7:   8b 5d 08                mov    0x8(%ebp),%ebx        
   a:   53                      push   %ebx                  
   b:   68 00 00 00 00          push   $0x0                  
  10:   e8 fc ff ff ff          call   11 <hook+0x11>        
  15:   8d 04 5b                lea    (%ebx,%ebx,2),%eax   
  18:   d1 e0                   shl    %eax                  
  1a:   8b 5d fc                mov    0xfffffffc(%ebp),%ebx
  1d:   c9                      leave                        
  1e:   c3                      ret                          
  1f:   90                      nop                          


你的
00000060 <hacked_alarm>:
  60:    53                       push   %ebx
  61:    89 c3                    mov    %eax,%ebx //系统调用号存入ebx
  63:    83 ec 08                 sub    $0x8,%esp
  66:    89 44 24 04              mov    %eax,0x4(%esp)//系统调用号压栈
  6a:    c7 04 24 30 00 00 00     movl   $0x30,(%esp)
  71:    e8 fc ff ff ff           call   72 <hacked_alarm+0x12>
  76:    8d 04 5b                 lea    (%ebx,%ebx,2),%eax
  79:    01 c0                    add    %eax,%eax
  7b:    83 c4 08                 add    $0x8,%esp
  7e:    5b                       pop    %ebx
  7f:    c3                       ret  

说明引用参数方式出现问题

你把int hook(int arg)改成
__attribute__((regparm(0))) int hook(int arg)看看

论坛徽章:
0
10 [报告]
发表于 2007-12-17 19:02 |只看该作者
原帖由 qtdszws 于 2007-12-17 12:02 发表
你能否把sct.o的反汇编代码贴出来?
objdump -D sct.o

Disassembly of section .text:

00000000 <cleanup_module>:
   0:    83 ec 04                 sub    $0x4,%esp
   3:    8b 15 00 00 00 00        mov    0x0,%edx
   9:    a1 00 00 00 00           mov    0x0,%eax
   e:    89 50 6c                 mov    %edx,0x6c(%eax)
  11:    c7 04 24 00 00 00 00     movl   $0x0,(%esp)
  18:    e8 fc ff ff ff           call   19 <cleanup_module+0x19>
  1d:    83 c4 04                 add    $0x4,%esp
  20:    c3                       ret   
  21:    eb 0d                    jmp    30 <init_module>
  23:    90                       nop   
  24:    90                       nop   
  25:    90                       nop   
  26:    90                       nop   
  27:    90                       nop   
  28:    90                       nop   
  29:    90                       nop   
  2a:    90                       nop   
  2b:    90                       nop   
  2c:    90                       nop   
  2d:    90                       nop   
  2e:    90                       nop   
  2f:    90                       nop   

00000030 <init_module>:
  30:    83 ec 04                 sub    $0x4,%esp
  33:    8b 15 00 00 00 00        mov    0x0,%edx
  39:    83 c2 6c                 add    $0x6c,%edx
  3c:    8b 02                    mov    (%edx),%eax
  3e:    a3 00 00 00 00           mov    %eax,0x0
  43:    c7 02 00 00 00 00        movl   $0x0,(%edx)
  49:    c7 04 24 19 00 00 00     movl   $0x19,(%esp)
  50:    e8 fc ff ff ff           call   51 <init_module+0x21>
  55:    31 c0                    xor    %eax,%eax
  57:    83 c4 04                 add    $0x4,%esp
  5a:    c3                       ret   
  5b:    90                       nop   
  5c:    8d 74 26 00              lea    0x0(%esi),%esi

00000060 <hacked_alarm>:
  60:    53                       push   %ebx
  61:    89 c3                    mov    %eax,%ebx
  63:    83 ec 08                 sub    $0x8,%esp
  66:    89 44 24 04              mov    %eax,0x4(%esp)
  6a:    c7 04 24 30 00 00 00     movl   $0x30,(%esp)
  71:    e8 fc ff ff ff           call   72 <hacked_alarm+0x12>
  76:    8d 04 5b                 lea    (%ebx,%ebx,2),%eax
  79:    01 c0                    add    %eax,%eax
  7b:    83 c4 08                 add    $0x8,%esp
  7e:    5b                       pop    %ebx
  7f:    c3                       ret   
Disassembly of section .data:

00000000 <sys_call_table>:
   0:    40                       inc    %eax
   1:    c5 2f                    lds    (%edi),%ebp
   3:    c0                       .byte 0xc0
Disassembly of section .bss:

00000000 <orig_alarm>:
   0:    00 00                    add    %al,(%eax)
    ...

Disassembly of section .debug_abbrev:
Disassembly of section .debug_info:
Disassembly of section .debug_line:
Disassembly of section .rodata.str1.1:
Disassembly of section .modinfo:
Disassembly of section .debug_frame:
Disassembly of section .debug_loc:
Disassembly of section .debug_pubnames:
Disassembly of section .debug_aranges:
Disassembly of section .debug_str:
Disassembly of section .comment:
上面这几个我觉得没有什么关系,没有贴出来,如果需要,我可以补上

原帖由 petsatan 于 2007-12-17 16:03 发表
2.4.7导出了sys_call_table   , 所以qtdszws  试没问题,
在2.4.18后就不导出了.
我想很可能是这个问题.

在2.4.18后的确不导出sys_call_table了,但是我们可以通过其他方式得到这个地址
我用的是grep sys_call_table System.map的方法,简单但是可移植性差
而且的确已经正确的用我们的函数替换了原有的函数,记录中可以看见
[24539.639316] You got me partner: 27!
但是参数获取却出错了
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP