9
9
"os"
10
10
"strings"
11
11
"syscall"
12
-
13
- "github.com/sirupsen/logrus"
14
12
)
15
13
16
14
// KeyLogger wrapper around file descriptior
@@ -20,7 +18,7 @@ type KeyLogger struct {
20
18
21
19
type devices []string
22
20
23
- func (d * devices ) hasDevice (str string ) bool {
21
+ func (d * devices ) hasDevice (str string ) bool {
24
22
for _ , device := range * d {
25
23
if strings .Contains (str , device ) {
26
24
return true
@@ -40,7 +38,7 @@ func New(devPath string) (*KeyLogger, error) {
40
38
if ! k .IsRoot () {
41
39
return nil , errors .New ("Must be run as root" )
42
40
}
43
- fd , err := os .Open (devPath )
41
+ fd , err := os .OpenFile (devPath , os . O_RDWR , os . ModeCharDevice )
44
42
k .fd = fd
45
43
return k , err
46
44
}
@@ -55,7 +53,7 @@ func FindKeyboardDevice() string {
55
53
for i := 0 ; i < 255 ; i ++ {
56
54
buff , err := ioutil .ReadFile (fmt .Sprintf (path , i ))
57
55
if err != nil {
58
- logrus . Error ( err )
56
+ continue
59
57
}
60
58
61
59
deviceName := strings .ToLower (string (buff ))
@@ -86,7 +84,7 @@ func FindAllKeyboardDevices() []string {
86
84
break
87
85
}
88
86
if err != nil {
89
- logrus . Error ( err )
87
+ continue
90
88
}
91
89
92
90
deviceName := strings .ToLower (string (buff ))
@@ -114,7 +112,6 @@ func (k *KeyLogger) Read() chan InputEvent {
114
112
for {
115
113
e , err := k .read ()
116
114
if err != nil {
117
- logrus .Error (err )
118
115
close (event )
119
116
break
120
117
}
@@ -127,6 +124,59 @@ func (k *KeyLogger) Read() chan InputEvent {
127
124
return event
128
125
}
129
126
127
+ // Write writes to keyboard and sync the event
128
+ // This will keep the key pressed or released until you call another write with other direction
129
+ // eg, if the key is "A" and direction is press, on UI, you will see "AAAAA..." until you stop with release
130
+ // Probably you want to use WriteOnce method
131
+ func (k * KeyLogger ) Write (direction KeyEvent , key string ) error {
132
+ key = strings .ToUpper (key )
133
+ code := uint16 (0 )
134
+ for c , k := range keyCodeMap {
135
+ if k == key {
136
+ code = c
137
+ }
138
+ }
139
+ if code == 0 {
140
+ return fmt .Errorf ("%s key not found in key code map" , key )
141
+ }
142
+ err := k .write (InputEvent {
143
+ Type : EvKey ,
144
+ Code : code ,
145
+ Value : int32 (direction ),
146
+ })
147
+ if err != nil {
148
+ return err
149
+ }
150
+ return k .syn ()
151
+ }
152
+
153
+ // WriteOnce method simulates single key press
154
+ // When you send a key, it will press it, release it and send to sync
155
+ func (k * KeyLogger ) WriteOnce (key string ) error {
156
+ key = strings .ToUpper (key )
157
+ code := uint16 (0 )
158
+ for c , k := range keyCodeMap {
159
+ if k == key {
160
+ code = c
161
+ }
162
+ }
163
+ if code == 0 {
164
+ return fmt .Errorf ("%s key not found in key code map" , key )
165
+ }
166
+
167
+ for _ , i := range []int32 {int32 (KeyPress ), int32 (KeyRelease )} {
168
+ err := k .write (InputEvent {
169
+ Type : EvKey ,
170
+ Code : code ,
171
+ Value : i ,
172
+ })
173
+ if err != nil {
174
+ return err
175
+ }
176
+ }
177
+ return k .syn ()
178
+ }
179
+
130
180
// read from file description and parse binary into go struct
131
181
func (k * KeyLogger ) read () (* InputEvent , error ) {
132
182
buffer := make ([]byte , eventsize )
@@ -141,6 +191,20 @@ func (k *KeyLogger) read() (*InputEvent, error) {
141
191
return k .eventFromBuffer (buffer )
142
192
}
143
193
194
+ // write to keyboard
195
+ func (k * KeyLogger ) write (ev InputEvent ) error {
196
+ return binary .Write (k .fd , binary .LittleEndian , ev )
197
+ }
198
+
199
+ // syn syncs input events
200
+ func (k * KeyLogger ) syn () error {
201
+ return binary .Write (k .fd , binary .LittleEndian , InputEvent {
202
+ Type : EvSyn ,
203
+ Code : 0 ,
204
+ Value : 0 ,
205
+ })
206
+ }
207
+
144
208
// eventFromBuffer parser bytes into InputEvent struct
145
209
func (k * KeyLogger ) eventFromBuffer (buffer []byte ) (* InputEvent , error ) {
146
210
event := & InputEvent {}
0 commit comments