Giter Club home page Giter Club logo

keylogger's Introduction

Keylogger

Capture global keyboard events on Linux

Build Status GoDoc License MIT

Notes

  • Only Linux based
  • Need root privilages

Installation

go get github.com/MarinX/keylogger

Getting started

Finding keyboard device

There is a helper on finding the keyboard.

 keyboard := keylogger.FindKeyboardDevice()

Which goes through each file device name to find keyword "keyboard"

/sys/class/input/event[0-255]/device/name

and returns the file event path if found

/dev/input/event2

If the function returns empty string, you will need to cat each device name and get the event number. If you know already, you can easily pass it to constructor

keylogger.New("/dev/input/event2")

Getting keypress

Once the keylogger returns channel event, you can switch by event code as described in input_event.go For start, you can listen on keyboard state change

keylogger.EvKey

Once you get desire event, there is a helper to parse code into human readable key.

event.KeyString()

Writing keypress

Best way is to open an text editor and see how keyboard will react There are 2 methods:

func (k *KeyLogger) WriteOnce(key string) error

and

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. This is because pressing and releasing the key are 2 different state change. There is a helper function which you can call to see which type of state change happend

// returns true if key on keyboard is pressed
event.KeyPress()

// returns true if key on keyboard is released
event.KeyRelease()

Example

You can find a example script in example/main.go

Running tests

No magic, just run

go test -v

Creating key sniffer (needs update)

License

This library is under the MIT License

keylogger's People

Contributors

g4z avatar kaloyanyosifov avatar marinx avatar spinzed avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

keylogger's Issues

I use two keyboards (laptop and USB connected), one works, the other doesn't. Why?

My code:

package main

import (
	"fmt"

	"github.com/MarinX/keylogger"
)

func main() {
        // k, err := keylogger.New("/dev/input/event14")
	k, err := keylogger.New("/dev/input/event3")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer k.Close()

	events := k.Read()

	for e := range events {
		switch e.Type {
		case keylogger.EvKey:
			if e.KeyPress() {
				fmt.Println("[event] press key ", e.KeyString())
			}
		}
	}
}

I have two keyboards. One original from the laptop (/dev/input/event3) and one connected to laptop via USB (/dev/input/event14). When I use keylogger.New("/dev/input/event3") and press something on the laptop keyboard everything works as I expect. However, when I change to keylogger.New("/dev/input/event14"), that is, to my other keyboard and press something on that keyboard, nothing happens.

The result of sudo lsinput:


....

/dev/input/event3
   bustype : BUS_I8042
   vendor  : 0x1
   product : 0x1
   version : 43962
   name    : "AT Translated Set 2 keyboard"
   phys    : "isa0060/serio0/input0"
   bits ev : (null) (null) (null) (null) (null)

....

/dev/input/event14
   bustype : BUS_USB
   vendor  : 0x258a
   product : 0x3a
   version : 273
   name    : "SINO WEALTH Gaming KB  Keyboard"
   phys    : "usb-0000:04:00.3-2.3/input1"
   uniq    : ""
   bits ev : (null) (null) (null) (null)

....

Why is this happening? What should I do?

One click is saved as two.

Hello! I made a keylogger based on your library, but for some reason, one press of a button is saved as two. For the most part, I press A, and AA saves. What could be the problem?
Here is my code.

package main

import (
	"fmt"
	"os"

	"github.com/MarinX/keylogger"
)

const (
	// File for logging.
	filename = "/home/slava/file.log"
)

// Append string to file.
func appendIntoFile(filename, content string) {
	// Chech file exists.
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		// Create file for loggin.
		f, err := os.Create(filename)
		if err != nil {
			panic(err)
		}
		defer f.Close()
	}

	file, err := os.OpenFile(filename, os.O_RDWR|os.O_APPEND, 0755)

	if err != nil {
		panic(err)
	}

	if _, err := file.WriteString(content); err != nil {
		panic(err)
	}

	defer file.Close()
}

func main() {
	devs, err := keylogger.NewDevices()

	if err != nil {
		fmt.Println(err)
		return
	}

	for _, val := range devs {
		fmt.Println("Id->", val.Id, "Device->", val.Name)
	}

	// Keyboard device.
	rd := keylogger.NewKeyLogger(devs[4])

	in, err := rd.Read()
	if err != nil {
		fmt.Println("Error!", err)
		return
	}

	for i := range in {
		if i.Type == keylogger.EV_KEY {
			fmt.Println(i.KeyString() + "\n")
			appendIntoFile(filename, i.KeyString()+"\n")
		}
	}
}

Freezes after key sync

Have anyone of you experience freeze after using method writeOnce and after that using key from regular keyboard?

I was using this library to map some keys when I do scroll down or up on my mouse during playing some games. After I do scroll up or scroll down its gonna use for example key F1 and after that when I press arrow I got like mini freeze or lag of the system.

Is this normal?

Proposed feature: add an API that returns all keyboard devices

Since there is an API that returns only the first keyboard device path found in /dev/input/events*/, it would make sense to make one that returns all that can be detected.
This would be useful for users with multiple (external) keyboards, like myself.
The API would look like this:

func FindAllKeyboardDevices() []string {
    // implementation
}

I have implemented this API, I will link the PR when I make it below for review.

Support MAC OS

What are the plans for supporting MAC OS? Or maybe at least there are thoughts how to do this?

Writing back to the keyboard file possible?

Hello! Thanks for making this library, it's been a very useful learning reference. I've been using this library as more of "keyboard" library rather than a "keylogger" library and one thing I've been trying to to figure out is how to write a key back to the keyboard file? I've been trying to write with the following code:

q_down := InputEvent{
    Type:EvKey,
    Value:1,
    Code:16,
}
q_up := InputEvent{
    Type:EvKey,
    Value:0,
    Code:16
}

keyboard_path := findKeyboardDevice()
fmt.Println(keyboard_path)
time.Sleep(2 * time.Seconds)
fmt.Println("start")

var bin_buf1 bytes.Buffer
binary.Write(&bin_buf1, binary.LittleEndian, q_down)
file.Write(bin_buf1.Bytes())

var bin_buf2 bytes.Buffer
binary.Write(&bin_buf2, binary.LittleEndian, q_up)
file.Write(bin_buf2.Bytes())

fmt.Println("finish")

And all I see the text printed but the letter q is never printed. I don't know if this code was ever intended for this purpose but I thought you might know the right direction to take with this. Is it possible to implement a Write method with it's current implementation?

Thanks for your time!

[BUG] Indefinite loop on disconnect

When reading from a device, should it go missing the below logic will keep iterating forever while spewing logs. The error is thrown (and logged) in the private read() method

keylogger/keylogger.go

Lines 63 to 66 in 7f76a35

e := k.read()
if e != nil {
event <- *e
}

My suggestion is to add an error return and close the channel so readers can be aware to retry if needed. Only reason I haven't submitted PR for it is it's a change from expectations the library set, where clients must close events.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.