windowsの次はlinuxでマウスをカスタマイズします。
プログラムを作って、マウスを乗っ取ります。
仕組みが分かれば簡単にプログラムで作ることができます。
なぜならlinuxはすべてファイル扱いで、 マウスもキーボードもゲームパッドもファイルだからです。
openして、readしてwriteすればいいわけです。
自由自在にカスタマイズできてしまいます。
たとえば、マウスを左クリックするとキーボードのAと入力させることもできます。
ですからゲームパッドをマウス替わりにカスタマイズすることもでてきしまうわけです。
この仕組みがわかればキーロガーも作れてしまいます。
まずはUSBに接続されているデバイスを調べます。
私の場合はこんなかんじ。
マウスとキーボードが認識されています。重要なのはHandlersのeventです。マウスがevent0, キーボードがevent1です。これを記憶しておきます。先ほどのファイルというのがこれです。
マウスは/dev/input/event0, キーボードは/dev/input/event1に対応しています。
試しにマウスを監視してみましょう。
$hexdump /dev/input/event0
同様にキーボード
$hexdump /dev/input/event1
マウスやキーボードの定義は/usr/include/linux/input.hにされています。ここを開いてみてください。
キーボード系
マウス系
判明したのが次のとおり。カスタマイズの内容も書いておきました。

で、ここからが少しやっかい。
BTN_EXTRAをCTRL + Wにすると、
BTN_EXTRA + CTRL + Wになってしまいます。
つまり、BTN_EXTRAとBTN_SIDEの機能を無効にしたいのです。
結論を書くとマウスを無効にし、User Inputという仮想デバイスでマウス機能を再登録します。
ちなみにマウスを無効にするのはたった1行
ioctl(マウスちゃん, EVIOCGRAB, 1);
マウスを元に戻すのも1行
ioctl(マウスちゃん, EVIOCGRAB, 0);
あとはUser Inputでマウス機能を登録すればできあがりです!
コメントを書いておくのでプログラムを読んでください。
5mouse.c
一応マウスを無効にするので注意が必要かと
プログラムを作って、マウスを乗っ取ります。
仕組みが分かれば簡単にプログラムで作ることができます。
なぜならlinuxはすべてファイル扱いで、 マウスもキーボードもゲームパッドもファイルだからです。
openして、readしてwriteすればいいわけです。
自由自在にカスタマイズできてしまいます。
たとえば、マウスを左クリックするとキーボードのAと入力させることもできます。
ですからゲームパッドをマウス替わりにカスタマイズすることもでてきしまうわけです。
この仕組みがわかればキーロガーも作れてしまいます。
まずはUSBに接続されているデバイスを調べます。
pi@raspberrypi:~ $ cat /proc/bus/input/devices
I: Bus=0003 Vendor=1bcf Product=0005 Version=0110
N: Name="USB Optical Mouse"
P: Phys=usb-3f980000.usb-1.2/input0
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/0003:1BCF:0005.0001/input/input0
U: Uniq=
H: Handlers=mouse0 event0
B: PROP=0
B: EV=17
B: KEY=1f0000 0 0 0 0 0 0 0 0
B: REL=143
B: MSC=10
I: Bus=0003 Vendor=0d62 Product=8070 Version=0111
N: Name="ELECOM Wired Keyboard"
P: Phys=usb-3f980000.usb-1.4/input0
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/0003:0D62:8070.0002/input/input1
U: Uniq=
H: Handlers=sysrq kbd leds event1
B: PROP=0
B: EV=120013
B: KEY=10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=1f
私の場合はこんなかんじ。
マウスとキーボードが認識されています。重要なのはHandlersのeventです。マウスがevent0, キーボードがevent1です。これを記憶しておきます。先ほどのファイルというのがこれです。
マウスは/dev/input/event0, キーボードは/dev/input/event1に対応しています。
試しにマウスを監視してみましょう。
$hexdump /dev/input/event0
同様にキーボード
$hexdump /dev/input/event1
マウスやキーボードの定義は/usr/include/linux/input.hにされています。ここを開いてみてください。
キーボード系
#define KEY_Q 16 キーボードのQ
#define KEY_W 17 キーボードのW
#define KEY_E 18
#define KEY_R 19
#define KEY_T 20
マウス系
#define BTN_LEFT 0x110 マウスの左クリック
#define BTN_RIGHT 0x111 マウスの右クリック
#define BTN_MIDDLE 0x112 マウスのホイールクリック
こんなかんじでずらっと登録されています。
マウスやキーボードの入力があるとイベントが発生します。その構造体も定義されています。
event.type
EV_KEY マウスやキーボードがクリックされたとき
EV_REL マウスの位置移動、ホイールが回転したとき
event.code
左クリックやらキーボードの入力キー
event.value
1: キーを押したとき、 0: キーを離したとき
他の数字 移動量
では早速マウスボタンを調べてみましょう。
input.c
110だから左クリックだなとか、value 1は押したとき、value 0は離したとき。マウスやキーボードの入力があるとイベントが発生します。その構造体も定義されています。
struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
event.type
EV_KEY マウスやキーボードがクリックされたとき
EV_REL マウスの位置移動、ホイールが回転したとき
event.code
左クリックやらキーボードの入力キー
event.value
1: キーを押したとき、 0: キーを離したとき
他の数字 移動量
では早速マウスボタンを調べてみましょう。
input.c
//マウス入力を調べるプログラム
#include <stdio.h>
#include <stdlib.h>
#include <linux/input.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int keyboardfd;
int mousefd;
int main(void)
{
mousefd = open("/dev/input/event0", O_RDWR);
keyboardfd = open("/dev/input/event1", O_RDWR);
for (;;) {
struct input_event event;
if (read(mousefd, &event, sizeof(event)) != sizeof(event)) {
exit(EXIT_FAILURE);
}
switch(event.type) {
case EV_KEY:
printf("code:%x value:%x\n", event.code, event.value);
break;
case EV_REL:
//printf("rel:%x ", event.code);
break;
case EV_ABS:
//printf("abs:%x ", event.code);
break;
default:
break;
}
fflush(stdout);
}
close(keyboardfd);
close(mousefd);
}
$gcc -o input input.c
$gcc -o input input.c
pi@raspberrypi:~/Documents $ sudo ./input
code:110 value:0
code:112 value:1
code:110 value:1
code:112 value:0
code:114 value:1
code:114 value:0
code:113 value:1
code:113 value:0
code:110 value:1
code:110 value:0
判明したのが次のとおり。カスタマイズの内容も書いておきました。

で、ここからが少しやっかい。
BTN_EXTRAをCTRL + Wにすると、
BTN_EXTRA + CTRL + Wになってしまいます。
つまり、BTN_EXTRAとBTN_SIDEの機能を無効にしたいのです。
結論を書くとマウスを無効にし、User Inputという仮想デバイスでマウス機能を再登録します。
ちなみにマウスを無効にするのはたった1行
ioctl(マウスちゃん, EVIOCGRAB, 1);
マウスを元に戻すのも1行
ioctl(マウスちゃん, EVIOCGRAB, 0);
あとはUser Inputでマウス機能を登録すればできあがりです!
コメントを書いておくのでプログラムを読んでください。
5mouse.c
//マウスをchromeブラウザ用にカスタマイズするプログラム
//サイドボタンを
//現在のタブを閉じる Ctrl+w
//開いている次のタブに移動する Ctrl+Tab
//に設定する
#include <stdio.h>
#include <stdlib.h>
#include <linux/input.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/uinput.h>
#include <string.h>
//ここでマウスとキーボードのイベントを設定してください。
#define MOUSE_EVENT "/dev/input/event0"
#define KEYBOARD_EVENT "/dev/input/event1"
#define die(str, args...) do { perror(str); exit(EXIT_FAILURE); } while(0)
int keyboardfd;
int mousefd;
int virtualfd;
void create_uinput_device (int fd) {
struct uinput_user_dev uidev;
memset(&uidev, 0, sizeof(uidev));
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "YUKIMOUSE");
uidev.id.bustype = BUS_USB;
uidev.id.vendor = 0xAAAA;
uidev.id.product = 0xBBBB;
uidev.id.version = 1;
if (write(fd, &uidev, sizeof(uidev)) < 0)
die("create_uinput_device: write");
if (ioctl(fd, UI_DEV_CREATE) < 0)
die("create_uinput_device: ioctl");
}
void send_event(int output, int type, int code, int value)
{
struct input_event event;
event.type = type;
event.code = code;
event.value = value;
gettimeofday(&event.time, NULL);
write(output, &event, sizeof(event));
}
int main(void)
{
mousefd = open(MOUSE_EVENT, O_RDWR);
keyboardfd = open(KEYBOARD_EVENT, O_RDWR);
virtualfd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
//マウス機能を登録し、User Inputデバイスを作成する
//ここで左クリックを有効にするよーとか、マウス動かすよーとか登録
ioctl(virtualfd, UI_SET_EVBIT, EV_REL);
ioctl(virtualfd, UI_SET_RELBIT, REL_X);
ioctl(virtualfd, UI_SET_RELBIT, REL_Y);
ioctl(virtualfd, UI_SET_RELBIT, REL_WHEEL);
ioctl(virtualfd, UI_SET_EVBIT, EV_KEY);
ioctl(virtualfd, UI_SET_KEYBIT, BTN_LEFT);
ioctl(virtualfd, UI_SET_KEYBIT, BTN_RIGHT);
ioctl(virtualfd, UI_SET_KEYBIT, BTN_MIDDLE);
create_uinput_device(virtualfd);
//マウスを無効化
ioctl(mousefd, EVIOCGRAB, 1);
for (;;) {
struct input_event event;
if (read(mousefd, &event, sizeof(event)) != sizeof(event)) {
exit(EXIT_FAILURE);
}
switch(event.type) {
case EV_KEY:
if(event.code == BTN_EXTRA && event.value == 1) {//EXTRAボタンを押したときCTRL + W
send_event(keyboardfd, event.type, KEY_LEFTCTRL, 1);
send_event(keyboardfd, event.type, KEY_W, 1);
send_event(keyboardfd, EV_SYN, SYN_REPORT, 0);
}else if(event.code == BTN_EXTRA && event.value == 0) {//EXTRAボタンを離したとき
send_event(keyboardfd, event.type, KEY_W, 0);
send_event(keyboardfd, event.type, KEY_LEFTCTRL, 0);
send_event(keyboardfd, EV_SYN, SYN_REPORT, 0);
}else if(event.code == BTN_SIDE && event.value == 1) {//SIDEボタンを押したとき CTRL + TAB
send_event(keyboardfd, event.type, KEY_LEFTCTRL, 1);
send_event(keyboardfd, event.type, KEY_TAB, 1);
send_event(keyboardfd, EV_SYN, SYN_REPORT, 0);
}else if(event.code == BTN_SIDE && event.value == 0) {//SIDEボタンを離したとき
send_event(keyboardfd, event.type, KEY_TAB, 0);
send_event(keyboardfd, event.type, KEY_LEFTCTRL, 0);
send_event(keyboardfd, EV_SYN, SYN_REPORT, 0);
}else {
send_event(mousefd, event.type, event.code, event.value);
}
break;
case EV_REL:
//printf("%x ", event.code);
send_event(mousefd, event.type, event.code, event.value);
break;
case EV_ABS:
send_event(mousefd, event.type, event.code, event.value);
break;
default:
send_event(mousefd, event.type, event.code, event.value);
//printf("0");
break;
}
fflush(stdout);
}
//マウスを有効に戻す
ioctl(mousefd, EVIOCGRAB, 0);
close(keyboardfd);
close(mousefd);
close(virtualfd);
}
一応マウスを無効にするので注意が必要かと
$gcc -o 5mouse 5mouse.c
$sudo ./5mouse
思っていたようにマウスをカスタマイズすることができました。
あとはスクリプトを作るなり、起動時に自動実行すればいいかと思います。
参考サイト 超絶素晴らしいサイトです。
Linux Input Subsystemの使い方
特定のキーボードを ESC 入力のためのフットペダルにする
サンプルプログラムが分かりやすいです。
ゲームパッドをカスタマイズしよう linux編 に続きます。
思っていたようにマウスをカスタマイズすることができました。
あとはスクリプトを作るなり、起動時に自動実行すればいいかと思います。
参考サイト 超絶素晴らしいサイトです。
Linux Input Subsystemの使い方
特定のキーボードを ESC 入力のためのフットペダルにする
サンプルプログラムが分かりやすいです。
ゲームパッドをカスタマイズしよう linux編 に続きます。
コメント