Linux系统调用函数替换
===================
#### 获取系统调用数组首地址
首先寻找一个系统调用函数,我们选择sys_close函数。根据这个地址进行偏移,当某个偏移地址+__NR_close的值等于sys_close相等时,则认为此偏移后的地址为系统调用首地址。
-
unsigned long **find_sys_call_table(void) {
-
unsigned long ptr;
-
unsigned long *p;
-
pr_err("Start found sys_call_table.\n");
-
for (ptr = (unsigned long)sys_close;
-
ptr < (unsigned long)&loops_per_jiffy;
-
ptr += sizeof(void *)) {
-
p = (unsigned long *)ptr;
-
if (p[__NR_close] == (unsigned long)sys_close) {
-
pr_err("Found the sys_call_table!!! __NR_close[%d] sys_close[%lx]\n"
-
" __NR_execve[%d] sct[__NR_execve][0x%lx]\n",
-
__NR_close,
-
(unsigned long)sys_close,
-
__NR_execve,
-
p[__NR_execve]);
-
return (unsigned long **)p;
-
}
-
}
-
return NULL;
-
}
#### 修改指定的系统调用
因为系统调用的数组是只读类型的,所以其值是不可以修改的,因此我们需要将只读保护位去掉。
cr0中有一个WP位,wp位0禁止写保护
实模式。wp为1开启写保护 保护模式。
wp对应的位为:0x00010000
-
unsigned long original_cr0;
-
original_cr0 = read_cr0(); #获取rc0寄存器数据
-
write_cr0(original_cr0 & ~0x00010000); #将常量保护标记位去掉
-
##此处修改系统调用表等操作
-
write_cr0(original_cr0); #将寄存器值恢复,常量保护恢复
代码如下:
内核模块init时:
-
void *orig_sys_call_table [NR_syscalls];
-
original_cr0 = read_cr0();
-
write_cr0(original_cr0 & ~0x00010000);
-
pr_err("Loading module change_write, sys_call_table at %p\n", sys_call_table_ptr);
-
for(i = 0; i < NR_syscalls - 1; i ++) {
-
orig_sys_call_table[i] = sys_call_table_ptr[i];
-
}
-
orig_write = (void *)(sys_call_table_ptr[__NR_write]);
-
sys_call_table_ptr[__NR_write]= (void *)my_write;
-
write_cr0(original_cr0);
内核模块exit时,恢复正常write函数:
-
write_cr0(original_cr0 & ~0x00010000);
-
sys_call_table_ptr[__NR_write] = (void *)orig_write;
-
write_cr0(original_cr0);
syscall_write_hook.rar
#### 修改sys_execve系统调用
修改sys_execve函数不像普通系统调用一样,在此系统调用执行之前先进拦截或者记录相关信息的操作,就需要进行平衡栈。
在替换系统调用时需要调用此汇编函数,将my_stub_execve_hook替换原有的系统调用,当进入此函数时,先将寄存器入栈,再执行自定义函数(比如行为记录,行为拦截等功能),自定义函数执行完成后,将之前入栈的寄存器恢复出来,然后再执行原生的execve函数:
sys_call_table_ptr[__NR_execve]= (void
*)my_stub_execve_hook;
execve必须执行栈平衡,这是和其他系统调用区别的地方。
-
.text
-
.global my_stub_execve_hook
-
my_stub_execve_hook:
-
pushq %rbx
-
pushq %rdi
-
pushq %rsi
-
pushq %rdx
-
pushq %rcx
-
pushq %rax
-
pushq %r8
-
pushq %r9
-
pushq %r10
-
pushq %r11
-
call my_execve_hook
-
pop %r11
-
pop %r10
-
pop %r9
-
pop %r8
-
pop %rax
-
pop %rcx
-
pop %rdx
-
pop %rsi
-
pop %rdi
-
pop %rbx
-
jmp *orig_sys_call_table(, %rax, 8)
syscall_execve_hook.rar
阅读(10041) | 评论(0) | 转发(0) |