Jump to content

[Payload Converter] Duckuino - Duckyscript to Arduino


Recommended Posts

The Duckuino

I recently learned that the Arduino Leonardo and the Arduino Micro are both capable of pressing keys as an HID. Instantly I thought of USB Rubber Ducky and Duckyscript. I had some spare time, so I decided to write this, Duckuino, a simple Duckyscript to Arduino converter. It's not very pretty, but it seems to be reliable.

Features:

  • Convert Duckyscript to Arduino(Duh!)
  • Basic program memory storage(works better with large programs than traditional SRAM)
  • Arduino code and Duckyscript combo! (fairly buggy in some places)

What was that about Arduino code alongside Duckyscript?

Due to the nature of the converter, quite a bit of Arduino code can be programmed inside the Duckyscript before conversion. This is useful for things the program doesn't auto-add such as loops and if statements.

Known bugs:

  • Letters may occasionally get offsetted
  • For some reason the usage of 'CTRL C' doesn't work but 'CTRL c' does...

Examples:

Input:

DELAY 100
STRING Hello world! I am Duckuino!
ENTER
CTRL ALT DELETE

Output:

void setup() {
Keyboard.begin();

delay(100);


print(F("Hello world! I am Duckuino!"));


type(KEY_RETURN);


press(KEY_LEFT_CTRL); 
press(KEY_LEFT_ALT); 
press(KEY_DELETE);
Keyboard.releaseAll();
Keyboard.end();
}
void type(int key) {
Keyboard.press(key);
Keyboard.release(key);
}
void print(const __FlashStringHelper *value) {
Keyboard.print(value);
}
void loop(){}

IMPORTANT NOTE:

I am not responsible for anything evil you do or generate with this.

Also, this program will only work on Arduinos that support the keyboard library.

I'm not the best at Duckyscript so I apologize if I've missed any commands or functions, feel free to contribute and/or download here: https://github.com/Plazmaz/Duckuino

If you've made something cool with Duckuino, I'd love to hear about it, send me a PM or post a reply!

EDIT: Almost forgot to give credit to http://ctrlaltnarwhal.wordpress.com/2012/10/31/installing-usb-rubber-ducky-on-3rd-party-devices/ for the idea!

Edited by Plazmaz
Link to comment
Share on other sites

Looks pretty useful for migrating scripts to a teensy! Although, in my opinion, it would be better to drop duckyscript altogether and move to a more elegant scripting language that promotes readability and usability (and takes advantage of some of the cool things a teensy can do: waiting for drivers, multiple payloads, etc).

The "look and feel" of duckyscript is pretty poor and the readability of Arduino/C also is not fantastic when it comes to this kind of thing... The output works but is not very clear.

What is the best solution? I have a few ideas and something in the works that I might finish off and release at some point in the future...

Link to comment
Share on other sites

About the javascript code...

I would highly recommend that you place the produced Arduino code in a separate set of lines rather than converting the existing lines.

10: var input = document.getElementById("duckyscript").value;

The getElementById result can be null.

11: var script = input.split('\n');

Poor choice of variable name. 'input' is your script. These are the lines of the script.

Also note that this will strip the \n from the resulting line, so the replace you do on line 15 isn't necessary.

13: var line = script;

Now this would be an excellent place to call trim()

14: var isModifier = isModifierFunction(script);

Rather than script you should be using the line variable here.

Replace with:

var firstWord = line.split(" ",1)[0];
var isModifier = functions.indexOf( firstWord ) > 0;

You'll reuse that firstWord var in a bit.

15: line = line.replace("\n", "").trim();

As stated on 11, there's no \n in a line and trimming at this stage is kinda late.

14-19:

None of the data you produce here is used until line 43, so move it to just above there and save a few CPU cycles.

20, 23-25, 28-30, 33:

Now that you have the first word of a line in the firstWord var, you can simply compare it against the given value as opposed to constantly creating a copy of a string to compare against.

You should also use "if ... else if .... else if ... else" to make it abundantly clear you can't end up entering more than one if and this will allow you to remove the continue statements.

The final else of that will contain the logic of lines 38-49

35-37:

Replacing ALL references to F-keys on a line is best done like this:

line.replace(/ F([0-9]{1,2})([$\s])/g, "Keyboard.press(KEY_F$1);$2" );

80-89:

Get the result of isModifierFunction as an extra parameter from the main method since it has already determined this.

Set a variable to either 'press' or 'type' based on this parameter and then have just 1 loop that puts the appropriate value in the produced string.

Knowing what you know now I'm sure you can find a couple more improvements by yourself. :)

Edited by Cooper
Link to comment
Share on other sites

About the javascript code...

I would highly recommend that you place the produced Arduino code in a separate set of lines rather than converting the existing lines.

10: var input = document.getElementById("duckyscript").value;

The getElementById result can be null.

11: var script = input.split('\n');

Poor choice of variable name. 'input' is your script. These are the lines of the script.

Also note that this will strip the \n from the resulting line, so the replace you do on line 15 isn't necessary.

13: var line = script;

Now this would be an excellent place to call trim()

14: var isModifier = isModifierFunction(script);

Rather than script you should be using the line variable here.

Replace with:

var firstWord = line.split(" ",1)[0];
var isModifier = functions.indexOf( firstWord ) > 0;

You'll reuse that firstWord var in a bit.

15: line = line.replace("\n", "").trim();

As stated on 11, there's no \n in a line and trimming at this stage is kinda late.

14-19:

None of the data you produce here is used until line 43, so move it to just above there and save a few CPU cycles.

20, 23-25, 28-30, 33:

Now that you have the first word of a line in the firstWord var, you can simply compare it against the given value as opposed to constantly creating a copy of a string to compare against.

You should also use "if ... else if .... else if ... else" to make it abundantly clear you can't end up entering more than one if and this will allow you to remove the continue statements.

The final else of that will contain the logic of lines 38-49

35-37:

Replacing ALL references to F-keys on a line is best done like this:

line.replace(/ F([0-9]{1,2})([$\s])/g, "Keyboard.press(KEY_F$1);$2" );

80-89:

Get the result of isModifierFunction as an extra parameter from the main method since it has already determined this.

Set a variable to either 'press' or 'type' based on this parameter and then have just 1 loop that puts the appropriate value in the produced string.

Knowing what you know now I'm sure you can find a couple more improvements by yourself. :)

Thanks, I really appreciate the suggestions :) will be implementing these soon

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...