ducky-tools
ducky-tools copied to clipboard
Ducky One 3 firmware support
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!
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...
I have successfully upgraded the firmware for my Ducky One 3 TKL RGB on GNU/Linux: link.
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.
- Install Ghidra and WireShark (With USBPCap)
- 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)
- Use the firmware update utility to update your keyboard's firmware like you would normally
- Stop the capture
- Apply a display filter to show only USB packets sent to your keyboard (i.e.:
usb.dst == "X.Y.Z"; replaceX.Y.Zwith the appropriate address) - Choose a random packet (Generally avoid the first/last ~10 packets as well as those with lower entropy/lots of
0's) - Copy ~8 bytes from near end of the HID Data field (Again avoid anything with lower entropy/lots of
0's) - Open Ghidra, create a new project, import the firmware update utility, and actually open the firmware update utility (in Ghidra)
- Press
sor clickSearchin the menu bar, paste the bytes you copied from step 7, clickAdvanced >>, selectBig Endianfor the byte order, then clickSearch All - If Ghidra shows anything other than exactly one match, go back to step 6 and choose a different packet
- Click on the match to go to the address
- Press
CTRL + ALT + Tor click the vertical arrow in the menu bar to toggle the code unit search direction (Make sure the arrow points upwards) - Press
CTRL + ALT + Lor click the blueLicon to go to the previous label - In Wireshark, press
CTRL + For 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) - Back in Ghidra, hover over the address and record the byte source offset (Ignore the
+andh; this is the start address) - Press
CTRL + ALT + Tor click the vertical arrow in the menu bar to toggle the code unit search direction (Make sure the arrow points downwards) - Press
CTRL + ALT + Lor click the blueLicon to go to the next label - In Wireshark, press
CTRL + For 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) - Back in Ghidra, hover over the preceding address and record the byte source offset (Ignore the
+andh; this is the end address) - Extract the firmware:
# 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
# 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
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.
@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.
For the record, this is what I did to update my Ducky One 3 TKL RGB to the latest firmware version 1.13.
Prerequisites:
- C/C++ development packages (base-devel in Arch-based distributions, build-essential in Debian and derivatives);
- cargo;
- curl (needed to download the firmware upgrade executable, you can use whatever you like);
- git;
- libusb, binary and development packages;
- sudo (installed and working).
$ 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'