Skip to content

About

Cross-platform Bezier curve hardware mouse jiggler using an RP2350-One. Spoofs a USB optical mouse with human-like cursor movement.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

Mouse Jiggler — Bezier Curve Edition

demo.gif

A hardware mouse jiggler using the Waveshare RP2350-One (CircuitPython) that masks as an optical mouse to prevent sleep.

The device sends Bezier curve mouse movements — smooth, curved paths with natural acceleration that mimic human usage. Unlike simple pixel twitches or rigid straight lines, Bezier curves introduce random variation in angle, distance, and speed that makes it harder for endpoint detection software (EDR) to identify the repetitive patterns typical of automated movement.

When done correctly, it should make it harder to tell the difference between the Waveshare and a standard optical mouse because the device sends legitimate USB descriptor data with the correct VID/PID (0x093A:0x2510).

Software-based mouse jigglers are detectable by monitoring software that analyzes USB activity patterns. Hardware-based jigglers operate at the USB protocol level, the computer sees a physical mouse device, not a running process. Commercial hardware jigglers exist, but a programmable microcontroller like the RP2350-One provides the same functionality with full control over the USB identity.

Would we need to alter the code or do something special for the mouse jiggler to work cross-OS?

No. The code used here already works on the common operating systems like Windows, macOS, and Linux. This is due to the use of the USB HID standard. It is a universal protocol that has been built into the core of all modern operating systems for decades. The computer doesn't read the code on the Waveshare, it only reads the standardized USB signals.

Table of Contents


Prerequisites

Required Components

  • Waveshare RP2350-One (a Raspberry PI Pico/Pico W will suffice)

  • If going with a PI Pico/Pico W a micro-USB to USB-A cable (must support data transfer, not just charging).

  • A computer (to flash the initial code).

Software and Firmware

It is recommended to use CircuitPython instead of MicroPython. CircuitPython makes it straightforward to alter the USB descriptors (the "fingerprint" the computer sees).

  • CircuitPython Firmware: Flashed onto the device.

  • Adafruit HID Library: Contains the mouse control functions.


Setup Guide

Step A: Flash CircuitPython

  1. Hold the BOOTSEL button on the device (Waveshare or Pico).

  2. Plug it into the computer.

  3. Release the button; a drive named RPI-RP2 will appear.

  4. Download the latest stable .uf2 file for Waveshare (or Pico) from: https://circuitpython.org/board/waveshare_rp2350_one/

  5. Drag and drop the .uf2 file onto the RPI-RP2 drive. The device will reboot as a drive named CIRCUITPY.


Step B: Install the Required Libraries

  1. Download the Adafruit CircuitPython Library Bundle from: https://circuitpython.org/libraries

  2. Select the bundle matching your CircuitPython version. For version 10.2.1, download the file named: adafruit-circuitpython-bundle-10.x-mpy-YYYYMMDD.zip

  3. Unzip the bundle on your computer.

  4. Open the extracted folder and navigate to its lib directory.

  5. Copy ONLY the following into the lib folder on your CIRCUITPY drive:

    • The folder named adafruit_hid
    • The file named neopixel.mpy

instruction_image

Do not copy the entire bundle. The RP2350-One has 4MB flash and the bundle contains hundreds of libraries that will not fit.


Step C: Spoof the USB Descriptors

CircuitPython looks for specific filenames during its boot sequence. Your USB configuration file must be named exactly boot.py and placed in the root directory of the CIRCUITPY drive (the same level as boot_out.txt).

instruction_image2

Why: USB identification code must run before the computer's operating system enumerates the USB device. CircuitPython explicitly looks for boot.py at startup for this purpose. This is where the VID/PID spoofing (0x093A:0x2510) and the storage/CDC/MIDI disabling are configured.


Step D: Add the Jiggler script

The mouse movement file must be named exactly code.py and placed in the root directory, replacing the original "Hello World" file.

Why: Once the device boots, CircuitPython automatically executes code.py as the main loop in an infinite cycle.

The code.py in this project uses cubic Bezier curves to generate smooth, natural mouse movements rather than rigid robotic lines (which corporate monitoring software flags).

The cursor wanders across the screen in curved arcs with natural acceleration — slow start, fast middle, slow end, mimicking how a human moves a mouse. Paths range from 30–200 pixels, sent every 5–15 seconds.


Step E: Disable storage

By default, the device (regardless of it being the Waveshare RP2350-One, a Raspberry Pi Pico or Pico W) acts as both a mouse and a flash drive (CIRCUITPY folder). An IT department looking closely at device logs will see a "Composite Device" (Mouse + Mass Storage). The storage.disable_usb_drive() call in boot.py hides the drive, making it look more like a mouse.

Note: If you disable the USB drive via boot.py, the CIRCUITPY drive will no longer appear when the device is plugged in. To regain access, see Recovery: Unlocking a Hidden Device.

You need to go into the boot.py code and uncomment the line

storage.disable_usb_drive()

After you have done that you can unmount (be sure to not unmount to not risk any files being corrupted) the device and either press the BOOT button on the device or unplug and plug the device into the desired device.


Recovery: Unlocking a Hidden Device

If you disable the USB drive via boot.py, the CIRCUITPY drive will no longer appear when the device is plugged in. To regain access:

  1. Press the BOOT button on the circuit board.

  2. You will see a yellow blinking light. Press the RESET button once.

The device will now appear on the computer, but it will be named CIRCUITPY (not the device you choose to mask it as via the boot.py).

Now you can edit the files again.


How It Works

Bezier Curves

A cubic Bezier curve is a smooth path defined by four points:

P0 (start) --- P1 (control) --- P2 (control) --- P3 (end)

The math:

B(t) = (1-t)^3*P0 + 3*(1-t)^2*t*P1 + 3*(1-t)*t^2*P2 + t^3*P3

Where t goes from 0.0 (at P0) to 1.0 (at P3). The control points P1 and P2 pull the curve toward them without the curve passing through them, creating natural arcs and S-curves.

Why it looks human:

  • Curved paths — Humans rarely move in straight lines. Control points offset perpendicular to the travel direction create natural arcs.
  • Variable speed — A smoothstep easing function (t^2 * (3 - 2t)) makes the cursor accelerate out of the start and decelerate into the end, just like a real hand movement.
  • Random variation — Each path has a random angle, distance, curvature, and duration. No two movements are alike.

Why it mitigates detection: Endpoint detection software (EDR) flags straight lines at constant speed, identical movements repeating on a timer, and movements of exactly 1-2 pixels back and forth.

Bezier curves produce curved, irregular trajectories with variable speed and random path length and duration each time.


LED Status Colors

The built-in RGB LED on the RP2350-one indicates the device's current state:

Color Meaning What's Happening
🟢 Green Idle USB bus is silent — mimicking a human not using the mouse
🟡 Yellow Moving HID reports being sent along a Bezier curve
🔴 Red Error HID write failed

Illustration of failure

failure_illustration


Static Electricity Precautions

When handling bare circuit boards like the RP2350-One, electrostatic discharge (ESD) can damage surface-mount components. Before touching the board:

  • Ground yourself by touching a grounded metal surface (such as a computer case plugged into a wall outlet).

  • Alternatively, wear an anti-static wrist strap connected to ground.

  • Store the board in an anti-static bag when not in use.

  • Avoid working on carpet or synthetic surfaces that generate static.

To further protect the board you could make use of a case either buy one or 3D print a case.

Community-designed cases for the RP2350-One are available at:

Search for "RP2350".

For this project the 3D printed RP2350-One clip on case by @jbp_1792760 at https://www.printables.com was used.

project_image


Why Waveshare RP2350-One

  • We don't need a cable because the USB connector is part of the circuit board, we just plug it into the USB port like a regular flash drive.

  • Small form factor makes it portable and could be complemented with a 3D-printed case to blend in and look like a regular flash drive.

  • Radio silence: It uses the RP2350A chip that doesn't have any Wi-Fi or Bluetooth.

  • More than enough disk space: With 4 MB flash memory we have more than enough space for CircuitPython and other scripts.

  • RGB light that can be used for notifying the end user of script execution.


Further Reading


Attribution & Licensing

This repository is licensed under the Creative Commons Attribution 4.0 International (CC BY 4.0) license.

Attribution Requirements

Any redistribution, mirroring, or derivative use of this project must credit the source repository:

  1. Author Name: HelixCipher

  2. Source Link: https://github.com/HelixCipher/mouse-jiggler

  3. Change Log: Clearly state if modifications were made to the original code structure.

Example Reference Block

This research utilizes materials from the mouse-jiggler repository by HelixCipher, licensed under CC BY 4.0. Source: https://github.com/HelixCipher/mouse-jiggler


Terms of Use

For the complete legal framework, waiver of liability, and systemic compliance definitions, review the DISCLAIMER.md before cloning this repository.


Legal & Ethical Note

This repository is for educational purposes. Use the tool responsibly and lawfully. Do not use to facilitate illegal activity.


Credits & Attribution

The 3D printed case used in this project is based on the work of @jbp_1792760 at https://www.Printables.com, used under a Creative Commons (4.0 International License) Attribution—Noncommercial—No Derivatives license. You can find the case here.

About

Cross-platform Bezier curve hardware mouse jiggler using an RP2350-One. Spoofs a USB optical mouse with human-like cursor movement.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages