有替换Linux内核函数的错误

时间:2011-06-27 13:33:13

标签: c linux linux-kernel

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/types.h>

#define CODESIZE 7

static unsigned char original_code[CODESIZE];

static unsigned char jump_code[CODESIZE] =
"\xb8\x00\x00\x00\x00" /* movq $0, %rax */
"\xff\xe0"                                                      /* jump *%rax */
    ;

void (*sync_readahead)( struct address_space *mapping, struct file_ra_state *ra, struct        file *filp, pgoff_t offset, unsigned long req_size ) = (void (*)(struct address_space *,  struct file_ra_state *, struct file *, pgoff_t , unsigned long ) )0xc0197100;


int hijack_start(void);
void hijack_stop(void);
void intercept_init(void);
void intercept_start(void);
void intercept_stop(void);
void fake_printk(struct address_space *mapping, struct file_ra_state *ra, struct file *filp, pgoff_t offset, unsigned long req_size);


int hijack_start()
{
printk(KERN_INFO "I can haz hijack?\n" );
intercept_init();

return 0;
}

void hijack_stop()
{
intercept_stop();
return;
}

void intercept_init()
{
printk(KERN_INFO "in the  intercept_init\n" );
memcpy( original_code, sync_readahead, 7 );
*(long *)&jump_code[1] = (long)fake_printk;

memcpy( sync_readahead, jump_code, 7 );

printk(KERN_INFO "in the  hijack?\n" );

//real_printk=NULL;

printk(KERN_INFO "begin the  hijack?\n" );
memcpy( sync_readahead, jump_code, CODESIZE );
printk(KERN_INFO "begin the  hijack?\n" );

return;
}



void intercept_stop()
{
memcpy( sync_readahead, original_code, CODESIZE );
}

void fake_printk(struct address_space *map, struct file_ra_state *a, struct file *fil,    pgoff_t offse, unsigned long req_siz)
{
printk(KERN_INFO "in the fake printk\n");
// return ret;
}
MODULE_LICENSE("GPL");

module_init( hijack_start );
module_exit( hijack_stop );

我想用地址(/proc/kallsyms)替换Linux内核函数,但是当我memcpy地址的新函数(Linux内核)时:

memcpy( sync_readahead, jump_code, CODESIZE );

存在错误(分段错误)。我已经看到一些以相同方式替换Linux内核函数的示例。你能帮我解决一下这个问题吗?非常感谢你。

信息如下:

ubuntu kernel: [  574.826458] *pde = 0087d067 *pte = 00197161 
ubuntu kernel: [  574.826468] Modules linked in: hijack(+) test(+) binfmt_misc bridge stp bnep input_polldev video output vmblock vsock vmmemctl vmhgfs pvscsi acpiphp lp ppdev pcspkr psmouse serio_raw snd_ens1371 gameport snd_ac97_codec ac97_bus snd_pcm_oss snd_mixer_oss snd_pcm snd_seq_dummy snd_seq_oss snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq snd_timer snd_seq_device snd soundcore snd_page_alloc vmci i2c_piix4 parport_pc parport intel_agp agpgart shpchp mptspi mptscsih mptbase scsi_transport_spi floppy fbcon tileblit font bitblit softcursor vmxnet
ubuntu kernel: [  574.826491] 
ubuntu kernel: [  574.826493] Pid: 4694, comm: insmod Tainted: G      D    (2.6.28-11-generic #42-Ubuntu) VMware Virtual Platform
ubuntu kernel: [  574.826496] EIP: 0060:[<f7c92101>] EFLAGS: 00010246 CPU: 0
ubuntu kernel: [  574.826498] EIP is at intercept_init+0x41/0x70 [hijack]
ubuntu kernel: [  574.826499] EAX: f5ec4b60 EBX: 00000000 ECX: ffffffff EDX: 00004c4c
ubuntu kernel: [  574.826501] ESI: f7c9252c EDI: c0197100 EBP: f5edbe18 ESP: f5edbe0c
ubuntu kernel: [  574.826502]  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
ubuntu kernel: [  574.826506]  f7c921a6 f7c92130 00000000 f5edbe24 f7c92147 f7c921d5 f5edbf8c c010111e
ubuntu kernel: [  574.826618] ---[ end trace ccc07e4b4d814976 ]---

1 个答案:

答案 0 :(得分:3)

内核函数劫持是非常棘手的业务,它需要完全正确才能解决各种问题。

我目前正在开发一个执行此操作的模块,它(在撰写本文时)适用于2.6.18+内核:

https://github.com/cormander/tpe-lkm

你最感兴趣的是hijacks.c文件。

此过程的许多部分都是体系结构,内核版本相关,以及CPU功能相关。

<强>更新

模块现在使用0XE9跳转操作码,应该适合你。详细信息在hijacks.c中,您最感兴趣的“高级”逻辑在security.c中的hijack_syscalls()函数中。