2009-09-28 14 views
14

Jeśli pracuję w aplikacji i naciskam klawisz z klawiatury, w jaki sposób mogę przechwycić ten klucz (lub ciąg), w tym nazwę aplikacji źródłowej, w C, pod GNU/LINUX, w przestrzeni użytkownika, bez X11 :)Przechwytywanie klawiszy w GNU/Linux w C

Dzięki.

+1

Należy [1] Stan ty problemem trochę jaśniej (można uzyskać dostęp do źródła aplikacji? The powłoki? Os? Tak czy owak, gdzie dokładnie jesteś zawieszony) i [2] nas przekonać, że robilibyśmy coś dobrego dla świata, zamiast pomagać ci pisać kolejny rootkit (widzisz, twoja rączka nie robi ci żadnych przysług w tym względzie). – dmckee

+2

Chce napisać 52-gi keylogger dla Linuksa. Wielka rzecz. Twoja moralność go nie powstrzyma. Przynajmniej nie jest w superużytkowniku, pytając, gdzie go pobrać. ;) –

+4

@dmckee Przypisanie keyloggera jest typowym przydziałem C/Asembler na uczelni. Mógłby być skryptowym kiddy, który chce się wkurzyć, ale co z tego? Zadaje pytanie i zasługuje na odpowiedź, niezależnie od jego intencji. –

Odpowiedz

1

Jedna z możliwości: znajdź i spójrz na źródło "sudosh", "sudo shell" (lub jednego z jego zamienników, ponieważ nie zostało ono od jakiegoś czasu zmodyfikowane, Google jest twoim przyjacielem).

Prześmiewa pseudo-tty i śledzi wszystkie wejścia i wyjścia, także rejestrując informacje do pliku.

To, czy jest to wystarczająco precyzyjne, jest prawdopodobnie bardziej dyskusyjne; rejestrowałby wszystkie naciśnięcia klawiszy dla wszystkich aplikacji. Nie jestem również pewien, jak to działa z X11 - jeśli działa z X11.

2

Możesz odczytać dane z jednego z plików w/dev/input. Który z nich zależy od twojego systemu. Może to być/dev/input/event0 lub/dev/input/by-path/platform-i8042-serio-0-event-kbd lub coś innego. Format jest określony w nagłówku jądra input.h. Jest

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

można uruchomić

od -tx2 FILENAME 

i wpisać coś zobaczyć, co się dzieje.

Jeśli chodzi o ustalenie, która aplikacja otrzymała kluczowe wydarzenie, nie jestem pewien. Możesz spróbować sprawdzić, który czytasz z głównego tty.

+0

jak mogę się dowiedzieć, jaki plik oznacza klawiatura? –

20

Cóż, bez X11 ten problem jest znacznie trudniejszy.
Do naciśnięcia klawisza części można użyć kodu podobnego do tego, ale trzeba przekazać jako argument urządzenie, które czytasz (klawiatura, zwykle/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); 

    } 
} 

kuponów zrobienia Nie idźcie do mnie, ten kod jest pobierany z haka Ventriloctrl, aby uzyskać naciskanie klawiszy. http://public.callutheran.edu/~abarker/ventriloctrl-0.4.tar.gz

Mam nadzieję, że przyda mi się pomoc.

+9

Zauważ, że taki program musiałby być uruchamiany jako root, ponieważ pliki/dev/input/event * są własnością i są ograniczone do root. –

+0

jak może obsługiwać wiele kombinacji klawiszy, np: ctrl + c itp? –

1

Dla całkiem dobrego przykładu, spójrz na kod showkey.

W szczególności tutaj jest główna pętla. Wystarczy, że pobierze terminal, skopiuje go, przekieruje skopiowany do trybu nieprzetworzonego i dopóki nie zostanie wydana sekwencja klawiszy "quit" lub "interrupt", to po prostu wydrukuje klucz podany terminalowi.

/* 
* 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

Myślę, że potrzebują więcej rzutów typu "void" ... –

Powiązane problemy