diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2012-04-02 05:15:43 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2012-04-02 05:15:43 +0200 |
commit | 8ed56c37de24088052fe7a0eed4cd96bc38b50dc (patch) | |
tree | fa7b5016cff65c961aff9887ee89745b2b66594c | |
parent | Initial commit. (diff) | |
download | android-connect-blinker-8ed56c37de24088052fe7a0eed4cd96bc38b50dc.tar.xz android-connect-blinker-8ed56c37de24088052fe7a0eed4cd96bc38b50dc.zip |
Hook the ops table.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | hook-ip.c | 41 | ||||
-rw-r--r-- | inet-connect-hook.c | 49 |
3 files changed, 50 insertions, 42 deletions
@@ -1,4 +1,4 @@ -obj-m := hook-ip.o +obj-m := inet-connect-hook.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) diff --git a/hook-ip.c b/hook-ip.c deleted file mode 100644 index 290e463..0000000 --- a/hook-ip.c +++ /dev/null @@ -1,41 +0,0 @@ -#include <linux/init.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/unistd.h> -#include <linux/socket.h> -#include <linux/sched.h> - -unsigned long *syscall_table = (unsigned long *)0xffffffff818001e0; -void (*set_pages_rw)(struct page *page, int numpages) = (void *)0xffffffff8102be40; -void (*set_pages_ro)(struct page *page, int numpages) = (void *)0xffffffff8102be00; - -asmlinkage long (*original_connect)(int, struct sockaddr __user *, int); -asmlinkage long new_connect(int fd, struct sockaddr __user *uservaddr, int addrlen) -{ - printk(KERN_ALERT "Hooked connect."); - return (*original_connect)(fd, uservaddr, addrlen); -} -static void* set_syscall(int syscall, void *new_function) -{ - void *original; - struct page *sys_call_page; - sys_call_page = virt_to_page(syscall_table); - set_pages_rw(sys_call_page, 1); - original = (void *)syscall_table[syscall]; - syscall_table[syscall] = (unsigned long)new_function; - set_pages_ro(sys_call_page, 1); - return original; -} -static int init(void) -{ - original_connect = set_syscall(__NR_connect, new_connect); - return 0; -} -static void exit(void) -{ - set_syscall(__NR_connect, original_connect); -} -module_init(init); -module_exit(exit); - - diff --git a/inet-connect-hook.c b/inet-connect-hook.c new file mode 100644 index 0000000..caca0d2 --- /dev/null +++ b/inet-connect-hook.c @@ -0,0 +1,49 @@ +#include <linux/module.h> +#include <linux/net.h> +#include <linux/mm.h> + +extern struct proto_ops inet_stream_ops; + +static void disable_page_protection(void) +{ + unsigned long value; + asm volatile("mov %%cr0,%0" : "=r" (value)); + if (value & 0x00010000) { + value &= ~0x00010000; + asm volatile("mov %0,%%cr0": : "r" (value)); + } +} +static void enable_page_protection(void) +{ + unsigned long value; + asm volatile("mov %%cr0,%0" : "=r" (value)); + if (!(value & 0x00010000)) { + value |= 0x00010000; + asm volatile("mov %0,%%cr0": : "r" (value)); + } +} + +int (*old_connect)(struct socket *sock, struct sockaddr *vaddr, int sockaddr_len, int flags); +int connect(struct socket *sock, struct sockaddr *vaddr, int sockaddr_len, int flags) +{ + printk(KERN_ALERT "Hooked connect."); + return (*old_connect)(sock, vaddr, sockaddr_len, flags); +} +static int init(void) +{ + old_connect = inet_stream_ops.connect; + disable_page_protection(); + inet_stream_ops.connect = connect; + enable_page_protection(); + return 0; +} +static void exit(void) +{ + disable_page_protection(); + inet_stream_ops.connect = old_connect; + enable_page_protection(); +} +module_init(init); +module_exit(exit); + + |