Pranks. Keep calm and do not move your mouse

(pico) #1

Let’s put away the serious stuff for a while and let’s have some fun. What about some hacking pranks!. Let’s start with something simple, the so called nervous mouse.

Note: The code is a modification of some example from internet. I cannot recall where I got it, but it is, let’s say, the default example you will find when searching for uinput tutorials.

Nervous Mouse

Nervous Mouse is a simple program that abuses the uinput device to inject fake mouse events in a linux box and move the mouse randomly every five seconds. It is a pretty stupid prank program but a funny way to get introduced to this useful device.

The uinput device is pretty straightforward to use.

  • Configure the events we want to generate
  • Create a device for that configuration
  • Write events to the device

Let’s see how to write your own

Opening and Configuring the Device

This part of the program is quite standard, we open the /dev/uinput device, execute a bunch of ioctl syscalls to configure it and we are good to go.

Something like this:

    if ((fd = open ("/dev/uinput", O_WRONLY | O_NONBLOCK)) < 0) die ("error: open");

    /* And we also want to produce mouse events */
    if (ioctl (fd, UI_SET_EVBIT,  EV_REL) < 0)    die ("error: ioctl");
    if (ioctl (fd, UI_SET_RELBIT, REL_X) < 0)     die ("error: ioctl");
    if (ioctl (fd, UI_SET_RELBIT, REL_Y) < 0)     die ("error: ioctl");

    /* Time to register our virtual device */
    memset (&uidev, 0, sizeof(uidev));
    snprintf (, UINPUT_MAX_NAME_SIZE, "uinput-sample"); = BUS_USB;  = 0x1; = 0x1; = 1;

    if (write (fd, &uidev, sizeof(uidev)) < 0) die ("error: write");
    if (ioctl (fd, UI_DEV_CREATE) < 0) die ("error: ioctl");

The first part of the program opens the uinput device and then configures the events we want to inject. In this case we are using EV_REL to inject mouse movement events.

After that we have to create the device. We are kind of defining a USB mouse and as for any USB device we have to provide vendor and user ides as well as a version number. Basically just enter the values in the code to get it running. Honestly I haven’t when deep enough on this to be able to tell you the importance of these values.

The we write the struct into our uinput device and call UI_DEV_CREATE ioctrl to create our virtual input device.

Now we just have to inject our events

Moving the Mouse

In order to move the mouse, the main function of Nervous Mouse, we have to inject EV_REL events. This events represent a relative movement of a pointing device. So, let’s write a function to move our mouse:

move_mouse (int fd, int dx, int dy)
  struct input_event     ev;

  memset (&ev, 0, sizeof(struct input_event));
  ev.type = EV_REL;
  ev.code = REL_X;
  ev.value = dx;
  if (write (fd, &ev, sizeof(struct input_event)) < 0)  die ("error: write");

  memset (&ev, 0, sizeof(struct input_event));
  ev.type = EV_REL;
  ev.code = REL_Y;
  ev.value = dy;
  if (write (fd, &ev, sizeof(struct input_event)) < 0) die("error: write");
  memset (&ev, 0, sizeof(struct input_event));
  ev.type = EV_SYN;
  ev.code = 0;
  ev.value = 0;
  if(write(fd, &ev, sizeof(struct input_event)) < 0)     die("error: write");
  return 0;

I think you can figure out how does this work, just looking to the code, but in case you don’t.

Well, events are sent to the system writing into our uinput device an event structure. The event structure has the following fields:

  • type. Indicates the type of event. EV_REL (relative movement), EV_KEY (key press including mouse buttons), EV_SYN (the synchronization event),…
  • code. Each kind of event supports multiple codes. For instance, for the EV_REL event (that we are using) we have a code to move the mouse on the X coordinate (REL_X) and another event to move it in the Y coordinate REL_Y.
  • value. Some codes, requires a value. For our EV_REL event, the value will indicate the numbers of pixels to move in the direction indicated by the code field

So, the function above, takes two values dx and dy and use them to move the mouse cursor dx pixel in the X coordinate and dy pixels in the Y coordinate. Some events, to be interpreted correctly, requires us to send an extra event of type EV_SYNC.

Nervous Mouse

By now, you should already be able to figure out how to make your mouse look nervous… I guess so. But otherwise, this is a way of doing it.

    while (1)
        for (i = 0; i < 100; i++)
	    move_mouse (fd, rand() % 10 -5 , rand()%10 - 5);
	sleep (5);

Sure, every 5 seconds the mouse moves a maximum of 5 pixels away from its last position in each direction 100 hundred times.

Not just a Prank

Now, seriously. I have used this technique in the past to easily interface special devices to standard applications in an easy way. An example was a small keyboard composed of two buttons, connected to two RPi GPIOs, used to interact with some kiosk application.

A small program in the Rpi read the GPIO pins, and produced uinput events. The main application just have to read the keyboard. This technique will allow us to control standard programs using special devices in a very easy way…

You can get the whole code from my github, as usual. The code in github also includes a click after the mouse movement so you may get windows or menus activated in unexpected ways.

The program has to be executed as root, by the way.

Hack fun!



Bloody hell, I’m gonna have fun with this one :wink:. Nice job mate thanks for sharing!

1 Like


@0x00pf Wow! Very interesting, thanks a lot! I’m guessing using similar technique you can “press buttons” on a keyboard as well?


(pico) #4

Hey @afiskon sure you can. You have to issue event EV_KEY and provide the proper code. The value field, as far as I remember is used to press/release the key.

You have to register all the keys you want to use though. One for each key, using ioctrl with the UI_SET_KEYBIT request .

@Cromical Thanks mate. Glad you liked it


(Leader & Offsec Engineer & Forum Daddy) #5

Seems like it might be my solution to my computer sleeping when watching films xD


(system) closed #6

This topic was automatically closed after 30 days. New replies are no longer allowed.