Skip to content

Commit 408c947

Browse files
committed
- Removed logrus
- Added option to write to keyboard - Updated docs and README.md
1 parent 6d3228f commit 408c947

File tree

5 files changed

+100
-57
lines changed

5 files changed

+100
-57
lines changed

README.md

+19
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,25 @@ Once you get desire event, there is a helper to parse code into human readable k
4646
```go
4747
event.KeyString()
4848
```
49+
50+
### Writing keypress
51+
Best way is to open an text editor and see how keyboard will react
52+
There are 2 methods:
53+
```go
54+
func (k *KeyLogger) WriteOnce(key string) error
55+
```
56+
and
57+
```go
58+
func (k *KeyLogger) Write(direction KeyEvent, key string) error
59+
```
60+
`WriteOnce` method simulates single key press, eg: press and release letter M
61+
62+
`Write` writes to keyboard and sync the event.
63+
This will keep the key pressed or released until you call another write with other direction
64+
eg, if the key is "A" and direction is press, on UI, you will see "AAAAA..." until you stop with release
65+
66+
Probably you want to use `WriteOnce` method
67+
4968
**NOTE**
5069

5170
If you listen on keyboard state change, it will return __double__ results.

doc.go

+2
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@
1010
//
1111
// * Capture state changes
1212
//
13+
// * Write back to keyboard
14+
//
1315
// See README at https://github.com/MarinX/keylogger for more info.
1416
package keylogger

example/main.go

-50
This file was deleted.

input_event.go

+8
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,11 @@ func (i *InputEvent) KeyPress() bool {
6363
func (i *InputEvent) KeyRelease() bool {
6464
return i.Value == 0
6565
}
66+
67+
// KeyEvent is the keyboard event for up/down (press/release)
68+
type KeyEvent int32
69+
70+
const (
71+
KeyPress KeyEvent = 1
72+
KeyRelease KeyEvent = 0
73+
)

keylogger.go

+71-7
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import (
99
"os"
1010
"strings"
1111
"syscall"
12-
13-
"github.com/sirupsen/logrus"
1412
)
1513

1614
// KeyLogger wrapper around file descriptior
@@ -20,7 +18,7 @@ type KeyLogger struct {
2018

2119
type devices []string
2220

23-
func (d* devices) hasDevice(str string) bool {
21+
func (d *devices) hasDevice(str string) bool {
2422
for _, device := range *d {
2523
if strings.Contains(str, device) {
2624
return true
@@ -40,7 +38,7 @@ func New(devPath string) (*KeyLogger, error) {
4038
if !k.IsRoot() {
4139
return nil, errors.New("Must be run as root")
4240
}
43-
fd, err := os.Open(devPath)
41+
fd, err := os.OpenFile(devPath, os.O_RDWR, os.ModeCharDevice)
4442
k.fd = fd
4543
return k, err
4644
}
@@ -55,7 +53,7 @@ func FindKeyboardDevice() string {
5553
for i := 0; i < 255; i++ {
5654
buff, err := ioutil.ReadFile(fmt.Sprintf(path, i))
5755
if err != nil {
58-
logrus.Error(err)
56+
continue
5957
}
6058

6159
deviceName := strings.ToLower(string(buff))
@@ -86,7 +84,7 @@ func FindAllKeyboardDevices() []string {
8684
break
8785
}
8886
if err != nil {
89-
logrus.Error(err)
87+
continue
9088
}
9189

9290
deviceName := strings.ToLower(string(buff))
@@ -114,7 +112,6 @@ func (k *KeyLogger) Read() chan InputEvent {
114112
for {
115113
e, err := k.read()
116114
if err != nil {
117-
logrus.Error(err)
118115
close(event)
119116
break
120117
}
@@ -127,6 +124,59 @@ func (k *KeyLogger) Read() chan InputEvent {
127124
return event
128125
}
129126

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+
130180
// read from file description and parse binary into go struct
131181
func (k *KeyLogger) read() (*InputEvent, error) {
132182
buffer := make([]byte, eventsize)
@@ -141,6 +191,20 @@ func (k *KeyLogger) read() (*InputEvent, error) {
141191
return k.eventFromBuffer(buffer)
142192
}
143193

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+
144208
// eventFromBuffer parser bytes into InputEvent struct
145209
func (k *KeyLogger) eventFromBuffer(buffer []byte) (*InputEvent, error) {
146210
event := &InputEvent{}

0 commit comments

Comments
 (0)