usedbytes / ducky-tools

Tools for working with Ducky One keyboard firmware updates
MIT License
22 stars 1 forks source link

Ducky One 3 firmware support #2

Open williewillus opened 2 years ago

williewillus commented 2 years ago

Hi! The Ducky One 3 has a V1.07 firmware that fixes some bad ghosting/sticking issues.

Link: https://duckychannel.net/download/ONE3/Firmware/V1.07/Ducky_One3_V1.07.exe

I found this tool, but it seems like it doesn't recognize the file.

$ ./ducky extract ~/Downloads/Ducky_One3_V1.07.exe 
ERROR: unrecognised exe version 'V1.07'

using the rewrite branch

$ ./ducky extract ~/Downloads/Ducky_One3_V1.07.exe 
ERROR: couldn't load using any known versions

$ ./ducky devices
ERROR: didn't find any devices

let me know how else I can help!

usedbytes commented 2 years ago

Hi there!

I just had a quick poke around at that firmware. Unfortunately this looks like another case of Ducky using different hardware and different protocols between products. As far as I can tell, this keyboard is using a Nuvoton chip (whereas the One and One2 that I reverse engineered so far were using Holtek chips), and it has a different updater as well as presumably a different update protocol.

This means that it's not a simple case of adding the magic numbers for this specific .exe (which ideally would have been the case), instead it will require a time-consuming process of fully reverse engineering this new kind of updater.

I'm afraid I don't have time at the moment to dive in to trying to do that. Maybe one day...

dariox86 commented 1 year ago

I have successfully upgraded the firmware for my Ducky One 3 TKL RGB on GNU/Linux: link.

Wakeful-Cloud commented 1 year ago

Based on @dariox86's instructions, I've created the below step-by-step guide for calculating the start address/offset for theoretically any Ducky firmware. Note that you'll need a computer/VM with Windows installed on it.

1. Install [Ghidra](https://ghidra-sre.org) and [WireShark](https://wireshark.org) (With USBPCap) 2. Open WireShark and select the appropriate USB interface, and start capturing USB packets (You can tell if the interface is the right one by pressing keys on your keyboard and seeing if the incoming packets roughly correlate with when you pressed the keys) 3. Use the firmware update utility to update your keyboard's firmware like you would normally 4. Stop the capture 5. Apply a display filter to show only USB packets sent to your keyboard (i.e.: `usb.dst == "X.Y.Z"`; replace `X.Y.Z` with the appropriate address) 6. Choose a random packet (Generally avoid the first/last ~10 packets as well as those with lower entropy/lots of `0`'s) 7. Copy ~8 bytes from near end of the HID Data field (Again avoid anything with lower entropy/lots of `0`'s) 8. Open Ghidra, create a new project, import the firmware update utility, and actually open the firmware update utility (in Ghidra) 9. Press `s` or click `Search` in the menu bar, paste the bytes you copied from step 7, click `Advanced >>`, select `Big Endian` for the byte order, then click `Search All` 10. If Ghidra shows anything other than exactly one match, go back to step 6 and choose a different packet 11. Click on the match to go to the address 12. Press `CTRL + ALT + T` or click the vertical arrow in the menu bar to toggle the code unit search direction (Make sure the arrow points upwards) 13. Press `CTRL + ALT + L` or click the blue `L` icon to go to the previous label 14. In Wireshark, press `CTRL + F` or click on the search icon, search for the **next** ~8 bytes from the address you're currently at in Ghidra, and ensure it matches one of the **first** few packets (This ensures you're at the start of the firmware) 15. Back in Ghidra, hover over the address and record the byte source offset (Ignore the `+` and `h`; this is the start address) 16. Press `CTRL + ALT + T` or click the vertical arrow in the menu bar to toggle the code unit search direction (Make sure the arrow points downwards) 17. Press `CTRL + ALT + L` or click the blue `L` icon to go to the next label 18. In Wireshark, press `CTRL + F` or click on the search icon, search for the **previous** ~8 bytes from the address directly **preceeding** the one you're currently at in Ghidra, and ensure it matches one of the **last** few packets (This ensures you're at the end of the firmware) 19. Back in Ghidra, hover over the **preceding** address and record the byte source offset (Ignore the `+` and `h`; this is the end address) 20. Extract the firmware: ```powershell # Windows $startAddress = 0xYYYYYY # Replace with the start address $endAddress = 0xZZZZZZ # Replace with the end address $raw = Get-Content -Path UTILITY_PATH -AsByteStream -Raw # Replace UTILITY_PATH with the path to the utility $firmware = $raw[$startAddress..($endAddress - 1)] Set-Content -Path firmware.bin -Value $firmware -AsByteStream ``` or ```bash # Linux startAddress=$((0xYYYYYY)) # Replace with the start address endAddress=$((0xZZZZZZ)) # Replace with the end address dd if=UTILITY_PATH of=firmware.bin bs=1 skip=$startAddress count=$(($endAddress - $startAddress)) # Replace UTILITY_PATH with the path to the utility ```
dunkelstern commented 6 months ago

If your Keyboard does not function well with the newest firmware (as mine did, keys bouncing all the time), i have a rather radical solution: Convert to QMK with a Raspberry Pi Pico replacement. Blog entry for the conversion here: https://dunkelstern.de/articles/2024-03-09/index.html

I know this is not the idea of this repository, but the frustration is real ;) Feel free to delete the comment if you feel this does not fit the conversation.

dariox86 commented 5 months ago

@dunkelstern, this is a radical solution indeed. I have read countless reports of Ducky owners suffering from this issue. I think I must be lucky that I have never experienced anything like that.

I would like to add that there is an unmerged port of QMK's operating system to the Ducky One 3 microcontroller. There are also two ports of QMK for older models from Ducky.

dariox86 commented 2 months ago

For the record, this is what I did to update my Ducky One 3 TKL RGB to the latest firmware version 1.13.

Prerequisites:

$ git clone https://github.com/libusb/hidapi
$ git clone https://github.com/todbot/hidapitester
$ cd hidapitester
$ make
$ cargo install nu-isp-cli
$ export PATH=~/.cargo/bin:$PATH
$ curl -O https://duckychannel.net/download/ONE3/Firmware/V1.13/Ducky_One_3_TKL_RGB_V1.13.exe
$ dd if=Ducky_One_3_TKL_RGB_V1.13.exe of=Ducky_One_3_TKL_RGB_V1.13.exe.bin skip=2158272 count=43600 iflag=skip_bytes,count_bytes
$ echo -n 'b990dd803215d0dab6b7ca415b6757627a463a7a1bc60d6a2e7ccea076170502ac2f7726bad0ed4e19720ccb6a18d1fd7a3067b792665281ab4711b580f75833 Ducky_One_3_TKL_RGB_V1.13.exe.bin' | sha512sum -c -
$ sudo sh -c './hidapitester --vidpid 3233/8311 -l 8 --open --send-output 204,0,0,0,18,0,0,0; sleep 5; nu-isp-cli 3233:8310 flash Ducky_One_3_TKL_RGB_V1.13.exe.bin'