Somehow or another, I was playing around in a Linux terminal and discovered the program `
showkey`. This program shows you the decimal key code for any key on the keyboard that you type in, and quits after 10 seconds since your last keypress.
More interestingly, it warned me that the X Server was running, and that the results might be off a little because the X Server also reads from
/dev/console outputs some binary for all your keypresses, and only root has read access to it (this is probably a good thing). I'm not sure yet what
/dev/console binds to, but it seems that whatever your active console (or X session) is, that's what keypresses can be seen there.
If you do `
cat /dev/console` as root and type stuff, the terminal prints two binary characters for each keypress. With this one could theoretically make a keylogger. So, out of boredom and to see if I could, I started writing a Perl script to read from
/dev/console. For obvious reasons I won't release any code, but for the curious (and those more knowledgeable than the script kiddies)...
I'm relatively sure that the two bytes should be read together as a signed short 32-bit integer. That is, I convert it to decimal and then 4 hex characters by doing this:
my $dec = unpack("S", $buffer); my $hex = sprintf("%04x", $dec);From now on, a "byte" refers to a pair of hexadecimal characters. So "1e9c" is two bytes, 1e and 9c.
It seems that the first byte tends to indicate the key typed on the keyboard, and when converted to decimal shows the same number as
showkey does. The second byte might be a modifier on the first byte, for example all four arrow keys send the key code 0xE0 as their first byte, and then the second byte is 0x48 for up, 0x50 for down, 0x4D for right and 0x4B for left.
There's almost no documentation about how to read the binary coming in from /dev/console. I had to look at the source code of
showkey.c to get more of an idea. Once I realized that the first byte lines up with the decimal codes given by
showkey, that helped a lot. The second byte is weird though: it seems to depend on the character you typed before it. For instance:
1e 9c - Pressed a 1e 9e - Pressed a 1e 9e - Pressed a 30 9e - Pressed b 30 b0 - Pressed b 30 b0 - Pressed b 1e b0 - Pressed a 1e 9e - Pressed a 1e 9e - Pressed a 30 9e - Pressed b 1e b0 - Pressed aSo my Perl script catches a lot of keys, then every now and then the "mode" randomly changes or something and the whole entire keymap gets shifted by about 100; I've figured these were for capital letters or when the shift key was pressed and added the capital letters to my key map, but I don't know why it does this. At any rate, I forgot I left my script running when I locked my screen, and unlocked it to see that it logged my entire password.
It'd be great if there was actually some documentation about this, but I've discovered a lot about it just from tinkering with it so far.