免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: 13706808
打印 上一主题 下一主题

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

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

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

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

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

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

回复 #13 qtdszws 的帖子

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

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

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

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

论坛徽章:
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
18 [报告]
发表于 2011-05-16 08:51 |只看该作者
我也遇到了同keith_269 兄相同的问题。求大家指导!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP