Skip to content

Commit 7f76a35

Browse files
author
Marin
committed
2019 Rewrite library
1 parent cec0b2a commit 7f76a35

File tree

9 files changed

+424
-283
lines changed

9 files changed

+424
-283
lines changed

.travis.yml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
language: go
2+
go:
3+
- 1.11.x

README.md

+64-40
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,81 @@
1-
# KeyLogger
1+
# Keylogger
22

3-
# Description
43
Capture global keyboard events on Linux
54

6-
# Installation
7-
go get github.com/MarinX/keylogger
8-
# Notes
5+
[![Build Status](https://travis-ci.org/MarinX/keylogger.svg?branch=master)](https://travis-ci.org/MarinX/keylogger)
6+
[![GoDoc](https://godoc.org/github.com/MarinX/keylogger?status.svg)](https://godoc.org/github.com/MarinX/keylogger)
7+
[![License MIT](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](LICENSE)
8+
9+
## Notes
910
* Only Linux based
1011
* Need root privilages
1112

13+
## Installation
14+
```sh
15+
go get github.com/MarinX/keylogger
16+
```
1217

13-
# Example
14-
package main
15-
16-
import (
17-
"fmt"
18-
"github.com/MarinX/keylogger"
19-
)
18+
## Getting started
2019

21-
func main() {
22-
devs, err := keylogger.NewDevices()
23-
if err != nil {
24-
fmt.Println(err)
25-
return
26-
}
20+
### Finding keyboard device
21+
There is a helper on finding the keyboard.
22+
```go
23+
keyboard := keylogger.FindKeyboardDevice()
24+
```
25+
Which goes through each file device name to find keyword "keyboard"
26+
```sh
27+
/sys/class/input/event[0-255]/device/name
28+
```
29+
and returns the file event path if found
30+
```sh
31+
/dev/input/event2
32+
```
33+
If the function returns empty string, you will need to cat each device name and get the event number.
34+
If you know already, you can easily pass it to constructor
35+
```sh
36+
keylogger.New("/dev/input/event2")
37+
```
2738

28-
for _, val := range devs {
29-
fmt.Println("Id->", val.Id, "Device->", val.Name)
30-
}
39+
### Getting keypress
40+
Once the keylogger returns channel event, you can switch by event code as described in [input_event.go](https://github.com/MarinX/keylogger/blob/master/input_event.go)
41+
For start, you can listen on keyboard state change
42+
```go
43+
keylogger.EvKey
44+
```
45+
Once you get desire event, there is a helper to parse code into human readable key.
46+
```go
47+
event.KeyString()
48+
```
49+
**NOTE**
3150

32-
//keyboard device file, on your system it will be diffrent!
33-
rd := keylogger.NewKeyLogger(devs[3])
51+
If you listen on keyboard state change, it will return __double__ results.
52+
This is because pressing and releasing the key are 2 different state change.
53+
There is a helper function which you can call to see which type of state change happend
54+
```go
55+
// returns true if key on keyboard is pressed
56+
event.KeyPress()
3457

35-
in, err := rd.Read()
36-
if err != nil {
37-
fmt.Println(err)
38-
return
39-
}
58+
// returns true if key on keyboard is released
59+
event.KeyRelease()
60+
```
4061

41-
for i := range in {
62+
### Example
63+
You can find a example script in ```example/main.go```
4264

43-
//we only need keypress
44-
if i.Type == keylogger.EV_KEY {
45-
fmt.Println(i.KeyString())
46-
}
47-
}
48-
}
65+
### Running tests
66+
No magic, just run
67+
```sh
68+
go test -v
69+
```
4970

50-
# Creating key sniffer
51-
* [sniffing global keyboard eventy in go](https://medium.com/@marin.basic02/sniffing-global-keyboard-events-in-go-e5497e618192/)
71+
## Creating key sniffer (needs update)
72+
* [sniffing global keyboard events in go](https://medium.com/@marin.basic02/sniffing-global-keyboard-events-in-go-e5497e618192/)
5273

5374

54-
# License
75+
## License
5576
This library is under the MIT License
56-
# Author
57-
Marin Basic
77+
78+
## Donate
79+
I don't drink beer, so energy drink will do :)
80+
81+
BTC: 19AtHE6dgKX3R9vJSCSKRyF1saexLcBRep

doc.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Package keylogger is a go library for linux to capture keyboard events. About:
2+
//
3+
// * No C deps
4+
//
5+
// * Events ported from uapi/linux/input.h
6+
//
7+
// * Needs root privilages
8+
//
9+
// * Transfer keyboard code into human readable key
10+
//
11+
// * Capture state changes
12+
//
13+
// See README at https://github.com/MarinX/keylogger for more info.
14+
package keylogger

example/main.go

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package main
2+
3+
import (
4+
"github.com/MarinX/keylogger"
5+
"github.com/sirupsen/logrus"
6+
)
7+
8+
func main() {
9+
10+
// find keyboard device, does not require a root permission
11+
keyboard := keylogger.FindKeyboardDevice()
12+
13+
// check if we found a path to keyboard
14+
if len(keyboard) <= 0 {
15+
logrus.Error("No keyboard found...you will need to provide manual input path")
16+
return
17+
}
18+
19+
logrus.Println("Found a keyboard at", keyboard)
20+
// init keylogger with keyboard
21+
k, err := keylogger.New(keyboard)
22+
if err != nil {
23+
logrus.Error(err)
24+
return
25+
}
26+
defer k.Close()
27+
28+
events := k.Read()
29+
30+
// range of events
31+
for e := range events {
32+
switch e.Type {
33+
// EvKey is used to describe state changes of keyboards, buttons, or other key-like devices.
34+
// check the input_event.go for more events
35+
case keylogger.EvKey:
36+
37+
// if the state of key is pressed
38+
if e.KeyPress() {
39+
logrus.Println("[event] press key ", e.KeyString())
40+
}
41+
42+
// if the state of key is released
43+
if e.KeyRelease() {
44+
logrus.Println("[event] release key ", e.KeyString())
45+
}
46+
47+
break
48+
}
49+
}
50+
}

input_event.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package keylogger
2+
3+
import (
4+
"syscall"
5+
"unsafe"
6+
)
7+
8+
const (
9+
// EvSyn is used as markers to separate events. Events may be separated in time or in space, such as with the multitouch protocol.
10+
EvSyn EventType = 0x00
11+
// EvKey is used to describe state changes of keyboards, buttons, or other key-like devices.
12+
EvKey EventType = 0x01
13+
// EvRel is used to describe relative axis value changes, e.g. moving the mouse 5 units to the left.
14+
EvRel EventType = 0x02
15+
// EvAbs is used to describe absolute axis value changes, e.g. describing the coordinates of a touch on a touchscreen.
16+
EvAbs EventType = 0x03
17+
// EvMsc is used to describe miscellaneous input data that do not fit into other types.
18+
EvMsc EventType = 0x04
19+
// EvSw is used to describe binary state input switches.
20+
EvSw EventType = 0x05
21+
// EvLed is used to turn LEDs on devices on and off.
22+
EvLed EventType = 0x11
23+
// EvSnd is used to output sound to devices.
24+
EvSnd EventType = 0x12
25+
// EvRep is used for autorepeating devices.
26+
EvRep EventType = 0x14
27+
// EvFf is used to send force feedback commands to an input device.
28+
EvFf EventType = 0x15
29+
// EvPwr is a special type for power button and switch input.
30+
EvPwr EventType = 0x16
31+
// EvFfStatus is used to receive force feedback device status.
32+
EvFfStatus EventType = 0x17
33+
)
34+
35+
// EventType are groupings of codes under a logical input construct.
36+
// Each type has a set of applicable codes to be used in generating events.
37+
// See the Ev section for details on valid codes for each type
38+
type EventType uint16
39+
40+
// eventsize is size of structure of InputEvent
41+
var eventsize = int(unsafe.Sizeof(InputEvent{}))
42+
43+
// InputEvent is the keyboard event structure itself
44+
type InputEvent struct {
45+
Time syscall.Timeval
46+
Type EventType
47+
Code uint16
48+
Value int32
49+
}
50+
51+
// KeyString returns representation of pressed key as string
52+
// eg enter, space, a, b, c...
53+
func (i *InputEvent) KeyString() string {
54+
return keyCodeMap[i.Code]
55+
}
56+
57+
// KeyPress is the value when we press the key on keyboard
58+
func (i *InputEvent) KeyPress() bool {
59+
return i.Value == 1
60+
}
61+
62+
// KeyRelease is the value when we release the key on keyboard
63+
func (i *InputEvent) KeyRelease() bool {
64+
return i.Value == 0
65+
}

0 commit comments

Comments
 (0)