Reputation: 1261
I have been trying to intercept the system call at the kernel level. I got the basic idea from this question . The system call I was trying to intercept was the fork(). So I found out the address of the sys_fork() from System.map and it turned out to be 0xc1010e0c.Now I wrote the module as below.
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/unistd.h>
#include<linux/semaphore.h>
#include<asm/cacheflush.h>
MODULE_LICENSE("GPL");
void **sys_call_table;
asmlinkage int (*original_call)(struct pt_regs);
asmlinkage int our_call(struct pt_regs regs)
{
printk("Intercepted sys_fork");
return original_call(regs);
}
static int __init p_entry(void)
{
printk(KERN_ALERT "Module Intercept inserted");
sys_call_table=(void *)0xc1010e0c;
original_call=sys_call_table[__NR_open];
set_memory_rw((long unsigned int)sys_call_table,1);
sys_call_table[__NR_open]=our_call;
return 0;
}
static void __exit p_exit(void)
{
sys_call_table[__NR_open]=original_call;
set_memory_ro((long unsigned int)sys_call_table,1);
printk(KERN_ALERT "Module Intercept removed");
}
module_init(p_entry);
module_exit(p_exit);
However , after compiling the module and when I tried to insert it to the kernel, I got the following from the dmesg output.
Of course its not intercepting the system call.Can you help me figure out the problem? I am using 3.2.0-4-686 version of Linux kernel.
Upvotes: 10
Views: 3719
Reputation: 1
It is not clear if you solved your problem, but depending on how you test your module glib don't use sys_fork anymore, but use sys_clone instead.
Upvotes: 0
Reputation: 140569
http://lxr.linux.no/linux+*/arch/x86/mm/pageattr.c#L874
says
if (*addr & ~PAGE_MASK) {
*addr &= PAGE_MASK;
/*
* People should not be passing in unaligned addresses:
*/
WARN_ON_ONCE(1);
}
So the warning is because your sys_call_table
variable is not page-aligned.
It should be said that patching the system call table is officially discouraged by the kernel maintainers, and they've put some deliberate roadblocks in your way -- you've probably already noticed that you can't access the real sys_call_table
symbol, and the write protection is also deliberate. If you can possibly find another way to do what you want, then you should. Depending on your larger goal, you might be able to accomplish it using ptrace
and no kernel module at all. The trace_sched_process_fork
hook may also be useful.
Upvotes: 8
Reputation: 21507
original_call=sys_call_table[__NR_open];
....
sys_call_table[__NR_open]=our_call;
If you're intercepting fork
, the entry for open
is not what you want to change.
And instead of the address of the sys_fork() from System.map, you should have used the address of sys_call_table
.
Upvotes: 2