Hello
I'm a programmer and i like to make bots for games more than i like to play the games themselves, i made a bad bot for BDO and i ended up getting a 25 year ban.
The bot was very simple so see it was a bot, was running in the same pc where the game was running, it used the serial console, it captured the screen with the windows api, to top it all off i was using an arduino leonardo without spoofing. Not a surprise i got banned
After that i went into a quest to find a way to cheese the system, especially looking into how to spoof PID and VID, ect, i found how to do it pretty well, but i thought nothing could beat hiding behind a real mouse and keyboard
For a keyboard things are easier because each button on a keyboard is just a switch that can be shorted using an optocoupler (but would require many optos, there's other solutions), but a mouse is more complicated because the movement sensor is communicating with the microcontroller on the mouse via a protocol, often SPI.
If you know MCUs you know most of them are capable of communicating with SPI, often having dedicated peripherals for that.
The PMW3360 sensor has standard 4 wire SPI, it is the slave and the mcu is the master, so can we replace the sensor with a regular mcu like the Pi Pico to feed our own values to the MCU on the mouse?
Yes if manage to understand the protocol, and luckily it is described in the documentation of the PMW336
So i hooked up a logic analyzer to the SPI lines on the sensor did some tests, i found the data was consistent with the documentation
The sensor has a boot sequence, after that the mcu keeps reading the burst register every 1 or 2 miliseconds
The burst register is a special register in the sensor that the mcu can request to read several registers in one SPI communication
In attachment 2 you can see what the mouse mcu reading the burst register looks like, essentially the protocol is the master always first sends the first byte which indicates which register it wants to read or write to, and it sets the first bit of that byte to 0 if it's a read operation, or 1 of it's a write operation, if it's a write operation the master then writes another byte, if it's a read operation the sensor writes a byte
In attachment 2 you see the master writes 0xD0 0x20, this means it wants to write 0x20 to register 0x50, then it writes 0x50 and the sensor replies with 0x20, which means there was no motion detected
In attachment 3 you see instead that the sensor the sensor replies with 0xA0, which means there was motion detected, the mouse moved, and we have more data being sent from the sensor, 0x7F is from the chip observation register, then what we care about we have the movement delta X (two bytes) and delta Y (two bytes).
The MCUs i wanted to use apparently just are not suitable to work as SPI slave the way the sensor does though. The Pi Pico can only do transfer of 1 byte in slave mode, and the ESP32 cannot have access to the data until the master pulls CS high, so knowing what operation and register were requested was impossible.
I ended up doing it with the PIO of the Pico, later i found i could just have done a software SPI in plain C simply with a tight loop (no sleep() calls). The clock on the Pico can be up to 200MHz which should be plenty for this since the SPI clock in this particular mouse was only 2MHz.
I'd say this is definetely not a beginner project, I was able to get it working, however when i restart the pc it seems the Pico doesn't wake up in time to reply to the mouse, and because of that the boot fails and the mouse hangs, and i have to unplug and replug the mouse.
Heres a video of the final concotion, running a circle demo:
[Only registered and activated users can see links. Click Here To Register...]
I'm a programmer and i like to make bots for games more than i like to play the games themselves, i made a bad bot for BDO and i ended up getting a 25 year ban.
The bot was very simple so see it was a bot, was running in the same pc where the game was running, it used the serial console, it captured the screen with the windows api, to top it all off i was using an arduino leonardo without spoofing. Not a surprise i got banned
After that i went into a quest to find a way to cheese the system, especially looking into how to spoof PID and VID, ect, i found how to do it pretty well, but i thought nothing could beat hiding behind a real mouse and keyboard
For a keyboard things are easier because each button on a keyboard is just a switch that can be shorted using an optocoupler (but would require many optos, there's other solutions), but a mouse is more complicated because the movement sensor is communicating with the microcontroller on the mouse via a protocol, often SPI.
If you know MCUs you know most of them are capable of communicating with SPI, often having dedicated peripherals for that.
The PMW3360 sensor has standard 4 wire SPI, it is the slave and the mcu is the master, so can we replace the sensor with a regular mcu like the Pi Pico to feed our own values to the MCU on the mouse?
Yes if manage to understand the protocol, and luckily it is described in the documentation of the PMW336
So i hooked up a logic analyzer to the SPI lines on the sensor did some tests, i found the data was consistent with the documentation
The sensor has a boot sequence, after that the mcu keeps reading the burst register every 1 or 2 miliseconds
The burst register is a special register in the sensor that the mcu can request to read several registers in one SPI communication
In attachment 2 you can see what the mouse mcu reading the burst register looks like, essentially the protocol is the master always first sends the first byte which indicates which register it wants to read or write to, and it sets the first bit of that byte to 0 if it's a read operation, or 1 of it's a write operation, if it's a write operation the master then writes another byte, if it's a read operation the sensor writes a byte
In attachment 2 you see the master writes 0xD0 0x20, this means it wants to write 0x20 to register 0x50, then it writes 0x50 and the sensor replies with 0x20, which means there was no motion detected
In attachment 3 you see instead that the sensor the sensor replies with 0xA0, which means there was motion detected, the mouse moved, and we have more data being sent from the sensor, 0x7F is from the chip observation register, then what we care about we have the movement delta X (two bytes) and delta Y (two bytes).
The MCUs i wanted to use apparently just are not suitable to work as SPI slave the way the sensor does though. The Pi Pico can only do transfer of 1 byte in slave mode, and the ESP32 cannot have access to the data until the master pulls CS high, so knowing what operation and register were requested was impossible.
I ended up doing it with the PIO of the Pico, later i found i could just have done a software SPI in plain C simply with a tight loop (no sleep() calls). The clock on the Pico can be up to 200MHz which should be plenty for this since the SPI clock in this particular mouse was only 2MHz.
I'd say this is definetely not a beginner project, I was able to get it working, however when i restart the pc it seems the Pico doesn't wake up in time to reply to the mouse, and because of that the boot fails and the mouse hangs, and i have to unplug and replug the mouse.
Heres a video of the final concotion, running a circle demo:
[Only registered and activated users can see links. Click Here To Register...]