【发布时间】:2015-07-08 21:38:22
【问题描述】:
我知道如何在现代 Linux 内核中劫持系统调用,以便为它们设计简单的替换。我用来劫持系统调用的代码通常如下所示:
static unsigned long *sys_call_table = (unsigned long*)<address of system call table>;
…
int make_rw(unsigned long address) {
unsigned int level;
pte_t *pte = lookup_address(address, &level);
if (pte->pte &~ _PAGE_RW) {
pte->pte |= _PAGE_RW;
}
return 0;
}
int make_ro(unsigned long address) {
unsigned int level;
pte_t *pte = lookup_address(address, &level);
pte->pte = pte->pte &~ _PAGE_RW;
return 0;
}
…
asmlinkage long (*real_<system call name>)(<system call arguments>);
asmlinkage long hijacked_<system call name>(<hijacked system call arguments>) {
// replacement code goes here
}
…
void hack(void) {
make_rw((unsigned long)sys_call_table);
real_<system call name> = (void*)*(sys_call_table + __NR_<system call name>);
*(sys_call_table + __NR_<system call name>) = (unsigned long)hijacked_<system call name>;
make_ro((unsigned long)sys_call_table);
}
void restore(void) {
make_rw((unsigned long)sys_call_table);
*(sys_call_table + __NR_<system call name>) = (unsigned long)real_<system call name>;
make_ro((unsigned long)sys_call_table);
}
Linux 导出内核内部使用的其他函数(我认为它们被称为“符号”)。一个这样的符号是capable,在linux/capability.c 中定义为:
bool capable(int cap)
{
return ns_capable(&init_user_ns, cap);
}
我的理论是我可以使用与劫持系统调用相同的代码,只是没有sys_call_table 和__NR_<system call name> 之类的位。但我怀疑这可能只是系统调用的情况,因为劫持它们涉及替换指向地址的指针。这可以与其他符号一起使用吗?如果没有,我怎样才能以相当简单的方式劫持它们?
【问题讨论】:
标签: c linux kernel-module