Closed Desperationis closed 1 year ago
I am not likely to merge this commit. While I appreciate the effort, this doesn't match my coding preferences and style.
I have no issues if you want to create something similar using the Pico C++ interface. I created this tool because it was useful to me and others have found it useful also. If it would be more useful to you to use C++, then by all means go for it.
DuckyScript 3.0
This is an interpreter for DuckyScript 3.0 that can handle variables, constants, conditional statements, nested conditional statements, loops, and functions. Almost all of the functionality in
duckyinpython.py
is implemented except payload-selection using GPIO pins. Other than that, it is a drop-in replacement that makes the language turing-complete.No advanced features have been added. This means randomization, holding keys, payload control, jitter, payload hiding, storage activity, lock keys, exfiltration, and extensions have not been added. No internal variables either. However, adding the implementation of these commands should be super easy based on the structure of this script.
Example
Example Output (Written by my own pico-ducky)
Implementation Details
DuckyScript is luckily a pretty basic language so the interpreter is not too complicated. Here is the general outline of the algorithm for interpretation:
DuckyParser
.DuckyInterpreter
):DuckyInterpreter
):DuckyKeyboard
).Drawbacks
DuckyScript Ambiguity
I don't own a Ducky myself, so I had to take some creative liberties in deciding how certain things (that aren't mentioned in the documentation) worked. My approach was to make the language probably more flexible than DuckyScript itself so I wouldn't miss anything.
((($FOO >> 8) & 0x00FF) | (($FOO << 8) & 0xFF00))
work perfectly fine.ALT
orCTRL
, soA CTRL ALT
works just fine.Performance
The speed at which the interpreter runs should be as fast as the original
duckyinpython.py
even with the included control flow operations.The real bottleneck of running this interpreter is memory. Compared to the original
duckyinpython.py
, this program's base memory usage is around 10-20kb more than the original (numbers may be off since it's hard to measure memory usage). Considering that the Pico only has about 220k left after CircuitPython is installed makes this not negligible. From my testing, this can run around ~800-1000 lines of DuckyScript with no nested structures before running out of memory.Recursion in python makes the memory issue worse. Nested IF, WHILE, and FUNCTION statements all rely on recursion, so using any of these inside another IF, WHILE, FUNCTION uses way more memory. It is for this reason that using && and || is heavily encouraged to not use as many nested structures.
Issues with CircuitPython
Circuit python has a fixed amount of memory reserved for the stack, 1.5kb. While you should in theory be able go around 30-40 levels deep in IFs, WHILEs, and FUNCTIONs without running out memory, CircuitPython crashes at around 3-4 levels deep with
pystack exhausted
.The fix for this would be to manually compile CircuitPython and change
CIRCUITPY_PYSTACK_SIZE
to a bigger size in the code as defined in https://github.com/adafruit/circuitpython/issues/3742 . Alternatively, you could just avoid using nested IF statements that don't go deeper than 3 levels.Final Remarks
This interpreter is in no way perfect, so fixes or optimizations would be greatly appreciated. I hope that by passing this milestone more attention can be put in developing the advanced functions in DuckyScript 3.0 rather than worrying about the language itself.
Hope this helps #117
Happy New Years!