2009-09-28 33 views
14

Si estoy trabajando en una aplicación y presiono la tecla del teclado, ¿cómo puedo capturar esa clave (o cadena), incluido el nombre de la aplicación fuente, en C, bajo GNU/LINUX, en el usuario, sin X11 :)Captura de pulsaciones de teclas en GNU/Linux en C

Gracias.

+1

Usted debe [1] estado en el que un problema un poco más claramente (se puede acceder a la fuente de la aplicación? La cáscara? El sistema operativo? De cualquier manera en que exactamente se colgó) y [2] convencernos de que estaríamos haciendo algo bueno para el mundo, en lugar de ayudarlo a escribir otro rootkit (ya ve, su manejo no le está haciendo ningún favor en este sentido). – dmckee

+2

Así que quiere escribir el keylogger 52 para Linux. Vaya cosa. Tu moralidad no va a detenerlo. Al menos él no ha terminado con el superusuario y le pregunta dónde descargar uno. ;) –

+4

@dmckee una asignación de registrador de teclas es una asignación común de C/Ensamblador en la universidad. Él bien podría ser un guionista chiquillo que busca cabrear a la gente, pero ¿y qué? Hizo una pregunta y se merece una respuesta, independientemente de su intención. –

Respuesta

1

Una posibilidad: busque y consulte la fuente de 'sudosh', la 'carcasa de sudo' (o una de sus sustituciones, ya que no se ha modificado desde hace tiempo; Google es su amigo).

Enloquece con pseudo-ttys y rastrea todas las entradas y salidas al grabar también la información en un archivo.

Si eso es lo suficientemente preciso para usted es quizás más debatible; registraría todas las pulsaciones de teclado para todas las aplicaciones. Tampoco estoy seguro de cómo funciona con X11, si funciona con X11.

2

Puede leer los datos de uno de los archivos en/dev/input. Cuál depende de tu sistema Puede ser/dev/input/event0 o/dev/input/by-path/platform-i8042-serio-0-event-kbd u otra cosa. El formato se especifica en el encabezado kernel input.h. Es

struct input_event { 
     struct timeval time; 
     __u16 type; 
     __u16 code; 
     __s32 value; 
}; 

Puede ejecutar

od -tx2 FILENAME 

y escriba algo para ver qué pasa.

En cuanto a averiguar qué aplicación recibió el evento clave, no estoy seguro. Podrías intentar verificar cuál está leyendo de la tty principal.

+0

¿cómo puedo averiguar qué archivo representa el teclado? –

20

Bueno, sin X11 este problema es mucho más difícil.
Para la parte de pulsaciones de teclas se puede utilizar un código similar a éste, pero usted tiene que pasar como argumento el dispositivo que usted está leyendo (teclado, normalmente/dev/input/event0)

#include <linux/input.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <unistd.h> 

int main(int argc, char **argv) 
{ 
    int fd; 
    if(argc < 2) { 
     printf("usage: %s <device>\n", argv[0]); 
     return 1; 
    } 
    fd = open(argv[1], O_RDONLY); 
    struct input_event ev; 

    while (1) 
    { 
    read(fd, &ev, sizeof(struct input_event)); 

    if(ev.type == 1) 
     printf("key %i state %i\n", ev.code, ev.value); 

    } 
} 

credits No vayas a mí, este código está tomado del truco de Ventriloctrl para obtener pulsaciones de teclas. http://public.callutheran.edu/~abarker/ventriloctrl-0.4.tar.gz

Espero que sea de alguna ayuda.

+9

tenga en cuenta que dicho programa debería ejecutarse como root, ya que los archivos/dev/input/event * son propiedad y están restringidos a la raíz. –

+0

¿cómo se puede manejar la combinación de múltiples teclas, por ejemplo: ctrl + c, etc.? –

1

Para un buen ejemplo, eche un vistazo al código de showkey.

En particular, aquí está el ciclo principal. Todo lo que hace es obtener el terminal, copiarlo, convertir el copiado al modo raw, y hasta que se dé una secuencia de tecla 'quit' o 'interrupt', simplemente imprime qué tecla se le dio al terminal.

/* 
* showkey.c -- display cooked key sequences 
* 
* Invoke this (no arguments needed) to see keycap-to-keystrokes mappings. 
* 
* by Eric S. Raymond <[email protected]>, 1 Nov 88 
* - fix for little-endian machines (version 1.1), 21 Oct 1996. 
* - cleanup and modern packaging (version 1.2), 1 Aug 2002. 
* - changed to use termios (version 1.3), 26 Aug 2002. 
* See the RPM spec file changelog for more recent stuff. 
*/ 
#include <stdio.h> 
#include <termios.h> 
#include <signal.h> 
#include <string.h> 
#include <stdbool.h> 
static int signalled; 

// ... 

main() 
{ 
    struct termios cooked, raw; 
    unsigned char c; 
    unsigned int i, timeouts; 
    char intrchar[32], quitchar[32]; 

    for (i = SIGHUP; i <= SIGIO; i++) 
    (void) signal(c, catcher); 

    // Get the state of the tty 
    (void) tcgetattr(0, &cooked); 
    // Make a copy we can mess with 
    (void) memcpy(&raw, &cooked, sizeof(struct termios)); 
    // Turn off echoing, linebuffering, and special-character processing, 
    // but not the SIGINT or SIGQUIT keys. 
    raw.c_lflag &=~ (ICANON | ECHO); 
    // Ship the raw control blts 
    (void) tcsetattr(0, TCSANOW, &raw); 

    (void) printf("Type any key to see the sequence it sends.\n"); 
    visualize(raw.c_cc[VINTR], intrchar); 
    visualize(raw.c_cc[VQUIT], quitchar); 
    (void) printf("Terminate with your shell interrupt %s or quit %s character.\n", 
      intrchar, quitchar); 
    signalled = 0; 
    while (!signalled) 
    { 
    char cbuf[32]; 

    read(0, &c, 1); 
    visualize(c, cbuf); 
    (void)fputs(cbuf, stdout); 
    (void) fflush(stdout); 
    } 

    (void) printf("\nBye...\n"); 
    // Restore the cooked state 
    (void) tcsetattr(0, TCSANOW, &cooked); 
} 
+5

Creo que necesitan algunos modelos más 'vacíos' ... –

Cuestiones relacionadas