In my early endeavours into kernel programming I'm trying to replace/hook into the ioctl syscall, with the purpose of logging and eventually inspecting every ioctl call done.
The target system is a mips (o32) system with kernel 3.10.
Based on similar projects/examples I've seen for x86 based systems I've arrived at a basic snippet I thought would work. I don't have access to a System.map but I noticed the sys_call_table address, so I based my attempts on the address found /proc/kallsyms
on the target system. I know this address will change from kernel build to build but that doesn't matter at this point; this is for experimental purposes only.
The module in its entirety:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>
static u32 **sct = (u32**)0x80008660; // `grep sys_call_table /proc/kallsyms`
asmlinkage int (*ioctl_orig)(s32 fd, u32 cmd, void* addr);
asmlinkage int ioctl_new(s32 fd, u32 cmd, void* addr)
{
printk("[IOC] Intercepted ioctl 0x%x to addr 0x%p\n", cmd, addr);
return ioctl_orig(fd, cmd, addr);
}
static int __init _enter(void)
{
ioctl_orig = (void*)sct[__NR_ioctl];
sct[__NR_ioctl] = (u32*)ioctl_new;
printk("[IOC] Original IOCTL addr: %p\n", ioctl_orig);
printk("[IOC] New IOCTL addr: %p\n", sct[__NR_ioctl]);
return 0;
}
static void __exit _exit(void)
{
sct[__NR_ioctl] = (u32 *)ioctl_orig;
printk("[IOC] Unloaded\n");
}
module_init(_enter);
module_exit(_exit);
MODULE_LICENSE("GPL");
Obviously this doesn't work or I wouldn't be here scraping the walls. The module loads fine and the printk
s from _enter
/_exit
do indeed appear, but nothing happens when I do ioctls towards the kernel in any way (I would expect to see the "Intercepted ioctl" message from ioctl_new
), which leads me to believe I'm modifying the wrong spot.
Questions:
- Obviously: What am I doing wrong?
- Can I rely on
/proc/kallsyms
providing the correct pointer to the beginning of the syscall table? - Am I right in my assumption that the value associated with
sys_ioctl
in/proc/kallsyms
should match*sct[__NR_ioctl]
or am I missing something? - Am I casting correctly?
- Is this method of modifying the sctable even applicable on mips?