-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinputspammer.cpp
More file actions
120 lines (102 loc) · 2.67 KB
/
inputspammer.cpp
File metadata and controls
120 lines (102 loc) · 2.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <time.h>
#include <iostream>
#include "inputspammer.h"
InputSpammer::InputSpammer()
{
// Open the uinput driver
m_fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
if( m_fd < 0 )
{
quit("Failed to open /dm_ev/uinput");
}
// Setup our fake input dm_evice
memset(&m_uidev, 0, sizeof(m_uidev));
snprintf(m_uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-spammer-test");
m_uidev.id.bustype = BUS_USB;
// These IDs identify the provider and dm_evice attached to the USB bus
// In this case just use 0x01. I couldn't find any accepted 'example' value
m_uidev.id.vendor = 0x01;
m_uidev.id.product = 0x01;
m_uidev.id.version = 1;
// Register what our input dm_evice can do
if( ioctl(m_fd, UI_SET_EVBIT, EV_KEY) < 0 )
{
quit("ioctl");
}
if( ioctl(m_fd, UI_SET_KEYBIT, KEY_A) < 0 )
{
quit("ioctl");
}
// And create the dm_evice
if( write(m_fd, &m_uidev, sizeof(m_uidev)) < 0 )
{
quit("Failed to write to m_uidev");
}
if( ioctl(m_fd, UI_DEV_CREATE) < 0 )
{
quit("Failed to create uinput dm_evice");
}
}
InputSpammer::~InputSpammer()
{
// Cleanup and exit
if( ioctl(m_fd, UI_DEV_DESTROY) < 0 )
{
quit( "Failed to destroy input dm_evice" );
}
close(m_fd);
}
void InputSpammer::quit( const char* msg)
{
perror(msg);
exit(1);
}
void InputSpammer::keyPress( int key, bool pressed )
{
// Register the key press m_event
memset(&m_ev, 0, sizeof(input_event));
m_ev.type = EV_KEY;
m_ev.code = KEY_A;
m_ev.value = pressed ? 1 : 0;
if( write(m_fd, &m_ev, sizeof(input_event)) < 0 )
{
quit("Failed to press key");
}
// Register the key release m_event
memset(&m_ev, 0, sizeof(input_event));
m_ev.type = EV_SYN;
m_ev.code = SYN_REPORT;
m_ev.value = 0;
if( write(m_fd, &m_ev, sizeof(input_event)) < 0 )
{
quit("Failed to release key");
}
}
void InputSpammer::run()
{
// TODO: Right now let's have a short delay and let the user start m_evhz in another terminal. Really we want a background thread started to trigger input and a foreground thread to report on the results
for( auto i = 10u; i > 0; --i )
{
std::cout << "Starting input in " << i << " seconds" << std::endl;
sleep(1);
}
std::cout << "Starting input. Use Ctrl+C to stop" << std::endl;
while( true )
{
// Trigger keydown/up with a small wait in between
// We're interested in polling rates up to 1Khz so
// spam m_events at twice this rate
keyPress( KEY_A, true );
usleep(500);
keyPress( KEY_A, false );
usleep(500);
}
}