Skip to content

Commit

Permalink
- Removed logrus
Browse files Browse the repository at this point in the history
- Added option to write to keyboard
- Updated docs and README.md
  • Loading branch information
MarinX committed May 28, 2021
1 parent 6d3228f commit 408c947
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 57 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@ Once you get desire event, there is a helper to parse code into human readable k
```go
event.KeyString()
```

### Writing keypress
Best way is to open an text editor and see how keyboard will react
There are 2 methods:
```go
func (k *KeyLogger) WriteOnce(key string) error
```
and
```go
func (k *KeyLogger) Write(direction KeyEvent, key string) error
```
`WriteOnce` method simulates single key press, eg: press and release letter M

`Write` writes to keyboard and sync the event.
This will keep the key pressed or released until you call another write with other direction
eg, if the key is "A" and direction is press, on UI, you will see "AAAAA..." until you stop with release

Probably you want to use `WriteOnce` method

**NOTE**

If you listen on keyboard state change, it will return __double__ results.
Expand Down
2 changes: 2 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@
//
// * Capture state changes
//
// * Write back to keyboard
//
// See README at https://github.com/MarinX/keylogger for more info.
package keylogger
50 changes: 0 additions & 50 deletions example/main.go

This file was deleted.

8 changes: 8 additions & 0 deletions input_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,11 @@ func (i *InputEvent) KeyPress() bool {
func (i *InputEvent) KeyRelease() bool {
return i.Value == 0
}

// KeyEvent is the keyboard event for up/down (press/release)
type KeyEvent int32

const (
KeyPress KeyEvent = 1
KeyRelease KeyEvent = 0
)
78 changes: 71 additions & 7 deletions keylogger.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"os"
"strings"
"syscall"

"github.com/sirupsen/logrus"
)

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

type devices []string

func (d* devices) hasDevice(str string) bool {
func (d *devices) hasDevice(str string) bool {
for _, device := range *d {
if strings.Contains(str, device) {
return true
Expand All @@ -40,7 +38,7 @@ func New(devPath string) (*KeyLogger, error) {
if !k.IsRoot() {
return nil, errors.New("Must be run as root")
}
fd, err := os.Open(devPath)
fd, err := os.OpenFile(devPath, os.O_RDWR, os.ModeCharDevice)
k.fd = fd
return k, err
}
Expand All @@ -55,7 +53,7 @@ func FindKeyboardDevice() string {
for i := 0; i < 255; i++ {
buff, err := ioutil.ReadFile(fmt.Sprintf(path, i))
if err != nil {
logrus.Error(err)
continue
}

deviceName := strings.ToLower(string(buff))
Expand Down Expand Up @@ -86,7 +84,7 @@ func FindAllKeyboardDevices() []string {
break
}
if err != nil {
logrus.Error(err)
continue
}

deviceName := strings.ToLower(string(buff))
Expand Down Expand Up @@ -114,7 +112,6 @@ func (k *KeyLogger) Read() chan InputEvent {
for {
e, err := k.read()
if err != nil {
logrus.Error(err)
close(event)
break
}
Expand All @@ -127,6 +124,59 @@ func (k *KeyLogger) Read() chan InputEvent {
return event
}

// Write writes to keyboard and sync the event
// This will keep the key pressed or released until you call another write with other direction
// eg, if the key is "A" and direction is press, on UI, you will see "AAAAA..." until you stop with release
// Probably you want to use WriteOnce method
func (k *KeyLogger) Write(direction KeyEvent, key string) error {
key = strings.ToUpper(key)
code := uint16(0)
for c, k := range keyCodeMap {
if k == key {
code = c
}
}
if code == 0 {
return fmt.Errorf("%s key not found in key code map", key)
}
err := k.write(InputEvent{
Type: EvKey,
Code: code,
Value: int32(direction),
})
if err != nil {
return err
}
return k.syn()
}

// WriteOnce method simulates single key press
// When you send a key, it will press it, release it and send to sync
func (k *KeyLogger) WriteOnce(key string) error {
key = strings.ToUpper(key)
code := uint16(0)
for c, k := range keyCodeMap {
if k == key {
code = c
}
}
if code == 0 {
return fmt.Errorf("%s key not found in key code map", key)
}

for _, i := range []int32{int32(KeyPress), int32(KeyRelease)} {
err := k.write(InputEvent{
Type: EvKey,
Code: code,
Value: i,
})
if err != nil {
return err
}
}
return k.syn()
}

// read from file description and parse binary into go struct
func (k *KeyLogger) read() (*InputEvent, error) {
buffer := make([]byte, eventsize)
Expand All @@ -141,6 +191,20 @@ func (k *KeyLogger) read() (*InputEvent, error) {
return k.eventFromBuffer(buffer)
}

// write to keyboard
func (k *KeyLogger) write(ev InputEvent) error {
return binary.Write(k.fd, binary.LittleEndian, ev)
}

// syn syncs input events
func (k *KeyLogger) syn() error {
return binary.Write(k.fd, binary.LittleEndian, InputEvent{
Type: EvSyn,
Code: 0,
Value: 0,
})
}

// eventFromBuffer parser bytes into InputEvent struct
func (k *KeyLogger) eventFromBuffer(buffer []byte) (*InputEvent, error) {
event := &InputEvent{}
Expand Down

0 comments on commit 408c947

Please sign in to comment.