Skip to content

Instantly share code, notes, and snippets.

@vxcute
Last active February 25, 2023 00:49
Show Gist options
  • Save vxcute/c75096bbe150cbe6f646bdcf6beac5b4 to your computer and use it in GitHub Desktop.
Save vxcute/c75096bbe150cbe6f646bdcf6beac5b4 to your computer and use it in GitHub Desktop.
// sends fake keyboard events to uinput this example print 'a' to the terminal
package main
// #cgo CFLAGS: -g -Wall
// #include <linux/uinput.h>
import "C"
import (
"encoding/binary"
"io"
"log"
"os"
"syscall"
"time"
)
type uinput_user_dev C.struct_uinput_user_dev
type timeval C.struct_timeval
type input_event C.struct_input_event
func Press(f io.Writer, k int) error {
ev := &input_event{
_type: 1,
code: C.__u16(k),
value: 1,
}
err := binary.Write(f, binary.LittleEndian, ev)
if err != nil {
log.Fatal(err)
}
return nil
}
func Release(f io.Writer, k int) error {
ev := &input_event{
_type: 1,
code: C.__u16(k),
value: 0,
}
err := binary.Write(f, binary.LittleEndian, ev)
if err != nil {
log.Fatal(err)
}
return nil
}
func Sync(f io.Writer) error {
ev := &input_event{
_type: 0,
code: 0,
value: 0,
}
err := binary.Write(f, binary.LittleEndian, ev)
if err != nil {
log.Fatal(err)
}
return nil
}
func WriteStringToCCharArray(carr []C.char, s string) []C.char {
cb := carr
for i, c := range s {
cb[i] = C.char(c)
}
return cb
}
func main() {
f, err := os.OpenFile("/dev/uinput", os.O_WRONLY|syscall.O_NONBLOCK, os.ModeDevice)
defer f.Close()
if err != nil {
log.Fatal(err)
}
_, _, errCall := syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), C.UI_SET_EVBIT, uintptr(C.EV_KEY))
if errCall != 0 {
log.Fatal(errCall)
}
_, _, errCall = syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), C.UI_SET_KEYBIT, uintptr(C.KEY_A))
if errCall != 0 {
log.Fatal(errCall)
}
uidev := &uinput_user_dev{}
uidev.id.bustype = C.BUS_USB
uidev.id.vendor = 0x1
uidev.id.product = 0x1
uidev.id.version = 0x1
uidev.name = [80]C.char(WriteStringToCCharArray(uidev.name[:], "Test"))
err = binary.Write(f, binary.LittleEndian, uidev)
if err != nil {
log.Fatal(err)
}
_, _, errCall = syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), C.UI_DEV_CREATE, 0)
if errCall != 0 {
log.Fatal(errCall)
}
time.Sleep(time.Second * 1)
Press(f, C.KEY_A)
Sync(f)
Release(f, C.KEY_A)
Sync(f)
time.Sleep(time.Second * 1)
_, _, errCall = syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), C.UI_DEV_DESTROY, 0)
if errCall != 0 {
log.Fatal(errCall)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment