关于Linux内核级后门的原理和简单实战
作者:unknown 来源:chinaunix 添加时间:2006-5-26 13:55:39系统控制权就会转向真正的系统调用, 用来完成你的请求并返回。 然后_system_call()调用_ret_from_sys_call()来检查不同的返回值, 并且最后返回到用户内存。
* libc
这int $0x80 并不是直接被用作系统调用; 更确切地是, libc函数,经常用来包装0x80中断,这样使用的。
libc通常利用_syscallX()宏来描述系统调用, X是系统调用的总参数个数。
举个例子吧, libc中的write(2)就是利用_syscall3这个系统调用宏来实现的, 因为实际的write(2)原型需要3个参数。在调用0x80中断之前,这个_syscallX宏假定系统调用的堆栈结构和要求的参数列表,最后,当_system_call()(通过int &0x80来引发)返回的时候,_syscallX()宏将会查出错误的返回值(在%eax)并且为其设置errno。
让我们看一下另一个write(2)例程并看看它是如何进行预处理的。
[root@plaguez kernel]# cat no2.c
#include #include #include #include #include #include #include #include #include _syscall3(ssize_t,write,int,fd,const void *,buf,size_t,count);/*构建一个write调用*/ main() { char *t = "this is a test.n"; write(0, t, strlen(t)); } [root@plaguez kernel]# gcc -E no2.c > no2.C [root@plaguez kernel]# indent no2.C -kr indent:no2.C:3304: Warning: old style assignment ambiguity in "=-". Assuming "= -" [root@plaguez kernel]# tail -n 50 no2.C #9 "no2.c" 2 ssize_t write(int fd, const void *buf, size_t count) { long __res; __asm__ __volatile("int $0x80":"=a"(__res):"0"(4), "b"((long) (fd)), "c"((long) (buf)), "d"((long) (count))); if (__res >= 0) return (ssize_t) __res; errno = -__res; return -1; }; main() { char *t = "this is a test.n"; write(0, t, strlen(t)); } [root@plaguez kernel]# exit