duck2spark converter
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
# Digispark Attiny85 payloads
|
||||||
|
|
||||||
|
Original encoder and duck2spark converter from [paulopera](https://github.com/paulopera/duck2spark) (converted from Python2 to Python3).
|
||||||
|
|
||||||
|
## Usage:
|
||||||
|
(Replace `-l fr` with the target keyboard layout.)
|
||||||
|
```bash
|
||||||
|
java -jar encoder.jar -i payload.duck -o payload.bin -l fr
|
||||||
|
python3 duck2spark.py -i payload.bin -l 1 -f 1000 -o payload.ino
|
||||||
|
rm payload.bin
|
||||||
|
```
|
||||||
|
Then flash your Digispark Attiny85 using arduino IDE.
|
||||||
|
|||||||
Executable
+252
@@ -0,0 +1,252 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import getopt
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def generate_source(
|
||||||
|
payload,
|
||||||
|
init_delay=2500,
|
||||||
|
loop_count=-1,
|
||||||
|
loop_delay=5000,
|
||||||
|
blink=True,
|
||||||
|
):
|
||||||
|
head = '''/*
|
||||||
|
* Sketch generated by duck2spark from Marcus Mengs aka MaMe82
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "DigiKeyboard.h"
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
init = '''
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
// initialize the digital pin as an output.
|
||||||
|
pinMode(0, OUTPUT); // LED on Model B
|
||||||
|
pinMode(1, OUTPUT); // LED on Model A
|
||||||
|
DigiKeyboard.delay(%d); // wait %d milliseconds before first run,
|
||||||
|
// to give target time to initialize
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
''' % (init_delay, init_delay)
|
||||||
|
|
||||||
|
body = '''
|
||||||
|
// should code be runned in this loop?
|
||||||
|
if (i != 0) {
|
||||||
|
DigiKeyboard.sendKeyStroke(0);
|
||||||
|
|
||||||
|
// parse raw duckencoder script
|
||||||
|
for (int i = 0; i < DUCK_LEN; i += 2)
|
||||||
|
{
|
||||||
|
uint8_t key = pgm_read_word_near(duckraw + i);
|
||||||
|
uint8_t mod = pgm_read_word_near(duckraw + i + 1);
|
||||||
|
|
||||||
|
if (key == 0) // delay (a delay > 255 is split into a sequence of delays)
|
||||||
|
{
|
||||||
|
DigiKeyboard.delay(mod);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DigiKeyboard.sendKeyStroke(key, mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i--;
|
||||||
|
DigiKeyboard.delay(%d); // wait %d milliseconds before next loop iteration
|
||||||
|
}
|
||||||
|
else if (blink)
|
||||||
|
{
|
||||||
|
digitalWrite(0, HIGH); // turn the LED on
|
||||||
|
digitalWrite(1, HIGH);
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
digitalWrite(0, LOW); // turn the LED off
|
||||||
|
digitalWrite(1, LOW);
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
''' % (loop_delay, loop_delay)
|
||||||
|
|
||||||
|
tail = '''}
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Generate the payload declaration in FLASH memory.
|
||||||
|
payload_len = len(payload)
|
||||||
|
|
||||||
|
declare = (
|
||||||
|
"#define DUCK_LEN "
|
||||||
|
+ str(payload_len)
|
||||||
|
+ "\nconst PROGMEM uint8_t duckraw [DUCK_LEN] = {\n\t"
|
||||||
|
)
|
||||||
|
|
||||||
|
# In Python 3, payload is bytes, so payload[c] is already an int.
|
||||||
|
for c in range(payload_len - 1):
|
||||||
|
declare += f"{hex(payload[c])}, "
|
||||||
|
|
||||||
|
if payload_len > 0:
|
||||||
|
declare += f"{hex(payload[-1])}\n"
|
||||||
|
|
||||||
|
declare += (
|
||||||
|
"};\n"
|
||||||
|
f"int i = {loop_count}; "
|
||||||
|
"// how many times the payload should run (-1 for endless loop)\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
if blink:
|
||||||
|
declare += "bool blink=true;\n"
|
||||||
|
else:
|
||||||
|
declare += "bool blink=false;\n"
|
||||||
|
|
||||||
|
return head + declare + init + body + tail
|
||||||
|
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
usagescr = '''MaMe82 duck2spark 1.0
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Converts payload created by DuckEncoder to sourcefile for DigiSpark Sketch
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python3 duck2spark.py -i [file ..]
|
||||||
|
build Sketch from specified RubberDucky payload file
|
||||||
|
|
||||||
|
python3 duck2spark.py -i [file ..] -o [file ..]
|
||||||
|
save Sketch source to specified output file
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
-i [file ..] Input File (Payload encoded with DuckEncoder)
|
||||||
|
-o [file ..] Output File for Sketch, if omitted stdout is used
|
||||||
|
-l <count> Loop count (1=single run (default), -1=endless run,
|
||||||
|
3=3 runs etc.)
|
||||||
|
-f <millis> Delay in milliseconds before initial payload run
|
||||||
|
(default 1000)
|
||||||
|
-r <millis> Delay in milliseconds between loop runs
|
||||||
|
(default 5000)
|
||||||
|
-n Don't blink status LED after finish of payload execution
|
||||||
|
|
||||||
|
Remark:
|
||||||
|
In order to use DEAD KEYS (e.g. ^ and ` on German keyboard layout)
|
||||||
|
a SPACE should be appended in the ducky script
|
||||||
|
(e.g. "STRING ^ working deadkey").
|
||||||
|
'''
|
||||||
|
print(usagescr)
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
ifile = ""
|
||||||
|
ofile = None
|
||||||
|
payload = None
|
||||||
|
|
||||||
|
loop_count = 1
|
||||||
|
blink = True
|
||||||
|
init_delay = 1000
|
||||||
|
loop_delay = 5000
|
||||||
|
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(
|
||||||
|
argv,
|
||||||
|
"hi:o:l:nf:r:",
|
||||||
|
[
|
||||||
|
"help",
|
||||||
|
"input=",
|
||||||
|
"output=",
|
||||||
|
"loopcount=",
|
||||||
|
"noblink",
|
||||||
|
"initdelay=",
|
||||||
|
"repeatdelay=",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
except getopt.GetoptError as exc:
|
||||||
|
print(f"Error: {exc}", file=sys.stderr)
|
||||||
|
usage()
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
for opt, arg in opts:
|
||||||
|
if opt in ("-h", "--help"):
|
||||||
|
usage()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
elif opt in ("-i", "--input"):
|
||||||
|
ifile = arg
|
||||||
|
|
||||||
|
if not os.path.isfile(ifile) or not os.access(ifile, os.R_OK):
|
||||||
|
print(
|
||||||
|
f"Input file {ifile} doesn't exist or isn't readable",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
with open(ifile, "rb") as f:
|
||||||
|
payload = f.read()
|
||||||
|
|
||||||
|
elif opt in ("-o", "--output"):
|
||||||
|
ofile = arg
|
||||||
|
|
||||||
|
elif opt in ("-l", "--loopcount"):
|
||||||
|
try:
|
||||||
|
loop_count = int(arg)
|
||||||
|
except ValueError:
|
||||||
|
print(
|
||||||
|
f"Invalid loop count: {arg}",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
elif opt in ("-f", "--initdelay"):
|
||||||
|
try:
|
||||||
|
init_delay = int(arg)
|
||||||
|
except ValueError:
|
||||||
|
print(
|
||||||
|
f"Invalid initial delay: {arg}",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
elif opt in ("-r", "--repeatdelay"):
|
||||||
|
try:
|
||||||
|
loop_delay = int(arg)
|
||||||
|
except ValueError:
|
||||||
|
print(
|
||||||
|
f"Invalid repeat delay: {arg}",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
elif opt in ("-n", "--noblink"):
|
||||||
|
blink = False
|
||||||
|
|
||||||
|
if payload is None:
|
||||||
|
print(
|
||||||
|
"You have to provide a payload generated by DuckEncoder "
|
||||||
|
"(-i option)",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
# Generate source code for Sketch.
|
||||||
|
result = generate_source(
|
||||||
|
payload,
|
||||||
|
init_delay=init_delay,
|
||||||
|
loop_count=loop_count,
|
||||||
|
loop_delay=loop_delay,
|
||||||
|
blink=blink,
|
||||||
|
)
|
||||||
|
|
||||||
|
if ofile is None:
|
||||||
|
# Print to stdout.
|
||||||
|
print(result, end="")
|
||||||
|
else:
|
||||||
|
# Write to output file.
|
||||||
|
with open(ofile, "w", encoding="utf-8") as f:
|
||||||
|
f.write(result)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
usage()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
main(sys.argv[1:])
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
DELAY 1000
|
||||||
|
CTRL-ALT T
|
||||||
|
DELAY 1000
|
||||||
|
STRING firefox https://hadow.fr
|
||||||
|
ENTER
|
||||||
BIN
Binary file not shown.
Reference in New Issue
Block a user