分类: LINUX
2014-08-15 16:38:30
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static __init int init_function_replace_sample(void)
{
printk(KERN_EMERG"init_function_replace_sample is called \n");
return 0;
}
module_init(init_function_replace_sample);
static __exit void cleanup_function_replace_sample(void)
{
printk(KERN_EMERG"cleanup_function_replace_sample is called \n");
}
module_exit(cleanup_function_replace_sample);
MODULE_LICENSE("GPL");
|
static int my_get_info(struct net *net, void __user *user, int *len, int compat)
{
return 0;
}
|
static void hook(void)
{
u_char *buf;
long p;
buf = (u_char *)get_info;
p = (long)my_get_info - (long)get_info - (long)5;
//printk(KERN_EMERG"%d\n",p);
lock_kernel();
CLEAR_CR0
memcpy(tmp, buf, 5);
buf[0] = 0xe9;
memcpy(buf + 1, &p, 4);
SET_CR0
unlock_kernel();
}
static void unhook(void)
{
u_char *buf;
return;
lock_kernel();
CLEAR_CR0
buf = (u_char *)get_info;
memcpy(buf, tmp, 5);
SET_CR0
unlock_kernel();
}
|
static __init int init_function_replace_sample(void)
{
printk(KERN_EMERG"init_function_replace_sample is called \n");
hook();
return 0;
}
module_init(init_function_replace_sample);
static __exit void cleanup_function_replace_sample(void)
{
printk(KERN_EMERG"cleanup_function_replace_sample is called \n");
unhook();
}
module_exit(cleanup_function_replace_sample);
|
static int get_info(struct net *net, void __user *user, int *len, int compat); |
/root/kprobe/test_iptables/test_iptables.c:113: 错误:‘get_info’未声明(在此函数内第一次使用)
/root/kprobe/test_iptables/test_iptables.c:113: 错误:(即使在一个函数内多次出现,每个未声明的标识符在其
/root/kprobe/test_iptables/test_iptables.c:113: 错误:所在的函数内也只报告一次。)
|
extern int get_info(struct net *net, void __user *user, int *len, int compat); |
WARNING: "get_info" [/root/kprobe/test_iptables/tt.ko] undefined! |
cat /proc/kallsyms | grep get_info |
c067347f t acpi_battery_get_info
c06b6450 t uart_get_info
c07cb720 T tcp_get_info
c09f75cc r __ksymtab_tcp_get_info
c09fc9fc r __kcrctab_tcp_get_info
c0a12fde r __kstrtab_tcp_get_info
f7f0a000 t my_get_info [tt]
f7e36220 t get_info [ip_tables]
f7e44020 t list_version_get_info [dm_mod]
|
SECTIONS
{
per_cpu__current_kprobe = 0xc0b202c0;
kallsyms_lookup_name = 0xc04942b0;
get_info = 0xf7e36220;
}
|
ld -r -o ttt.ko tt.ko -R addrs.dat |
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define IPT_TABLE_MAXNAMELEN 32
#define AF_INET 2
#define NF_INET_NUMHOOKS 5
#define CLEAR_CR0 asm ("pushl %eax\n\t" \
"movl %cr0, %eax\n\t" \
"andl $0xfffeffff, %eax\n\t" \
"movl %eax, %cr0\n\t" \
"popl %eax");
#define SET_CR0 asm ("pushl %eax\n\t" \
"movl %cr0, %eax\n\t" \
"orl $0x00010000, %eax\n\t" \
"movl %eax, %cr0\n\t" \
"popl %eax");
static u_char tmp[5];
extern int get_info(struct net *net, void __user *user, int *len, int compat);
struct ipt_getinfo
{
char name[IPT_TABLE_MAXNAMELEN];
unsigned int valid_hooks;
unsigned int hook_entry[NF_INET_NUMHOOKS];
unsigned int underflow[NF_INET_NUMHOOKS];
unsigned int num_entries;
unsigned int size;
};
struct kprobe kp;
static int my_get_info(struct net *net, void __user *user, int *len, int compat)
{
char name[IPT_TABLE_MAXNAMELEN];
struct xt_table *t;
int ret;
printk(KERN_EMERG "my_get_info is called \n");
if (*len != sizeof(struct ipt_getinfo)) {
printk(KERN_EMERG "length %u != %zu\n", *len,
sizeof(struct ipt_getinfo));
return -EINVAL;
}
printk(KERN_EMERG "msglen=%d \n",*len);
return 0;
if (copy_from_user(name, user, sizeof(name)) != 0)
return -EFAULT;
name[IPT_TABLE_MAXNAMELEN-1] = '\0';
printk(KERN_EMERG "name=%s \n",name);
t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),"iptable_%s", name);
if (t && !IS_ERR(t)) {
struct ipt_getinfo info;
const struct xt_table_info *private = t->private;
info.valid_hooks = t->valid_hooks;
memcpy(info.hook_entry, private->hook_entry,
sizeof(info.hook_entry));
memcpy(info.underflow, private->underflow,
sizeof(info.underflow));
info.num_entries = private->number;
info.size = private->size;
strcpy(info.name, name);
if (copy_to_user(user, &info, *len) != 0)
ret = -EFAULT;
else
ret = 0;
xt_table_unlock(t);
module_put(t->me);
} else
ret = t ? PTR_ERR(t) : -ENOENT;
return ret;
}
/*
//恢复函数
unhook();
//调用原函数
ret = gate_info(net,*user, len, compat );
//恢复hook
hook();
*/
static void hook(void)
{
u_char *buf;
long p;
buf = (u_char *)get_info;
p = (long)my_get_info - (long)get_info - (long)5;
//printk(KERN_EMERG"%d\n",p);
lock_kernel();
CLEAR_CR0
memcpy(tmp, buf, 5);
buf[0] = 0xe9;
memcpy(buf + 1, &p, 4);
SET_CR0
unlock_kernel();
}
static void unhook(void)
{
u_char *buf;
return;
lock_kernel();
CLEAR_CR0
buf = (u_char *)gate_info;
memcpy(buf, tmp, 5);
SET_CR0
unlock_kernel();
}
static __init int init_function_replace_sample(void)
{
printk(KERN_EMERG"init_function_replace_sample is called \n");
hook();
return 0;
}
module_init(init_function_replace_sample);
static __exit void cleanup_function_replace_sample(void)
{
printk(KERN_EMERG"cleanup_function_replace_sample is called \n");
unhook();
}
module_exit(cleanup_function_replace_sample);
MODULE_LICENSE("GPL");
|