mirror of
https://github.com/dbisu/pico-ducky.git
synced 2025-12-06 02:41:45 +00:00
Add functions, while loops, and vars support (#264)
* Add functions, while loops, and vars support * Add back REPEAT * Add support for nested WHILE loops in function --------- Co-authored-by: Tony Le <tonyle@coxautoinc.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
# copyright (c) 2023 Dave Bailey
|
# copyright (c) 2023 Dave Bailey
|
||||||
# Author: Dave Bailey (dbisu, @daveisu)
|
# Author: Dave Bailey (dbisu, @daveisu)
|
||||||
|
|
||||||
|
import re
|
||||||
import time
|
import time
|
||||||
import digitalio
|
import digitalio
|
||||||
from digitalio import DigitalInOut, Pull
|
from digitalio import DigitalInOut, Pull
|
||||||
@@ -47,6 +47,10 @@ duckyCommands = {
|
|||||||
'F12': Keycode.F12,
|
'F12': Keycode.F12,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variables = {}
|
||||||
|
functions = {}
|
||||||
|
|
||||||
def convertLine(line):
|
def convertLine(line):
|
||||||
newline = []
|
newline = []
|
||||||
# print(line)
|
# print(line)
|
||||||
@@ -68,15 +72,17 @@ def convertLine(line):
|
|||||||
return newline
|
return newline
|
||||||
|
|
||||||
def runScriptLine(line):
|
def runScriptLine(line):
|
||||||
|
if isinstance(line, str):
|
||||||
|
line = convertLine(line)
|
||||||
for k in line:
|
for k in line:
|
||||||
kbd.press(k)
|
kbd.press(k)
|
||||||
kbd.release_all()
|
kbd.release_all()
|
||||||
|
|
||||||
def sendString(line):
|
def sendString(line):
|
||||||
layout.write(line)
|
layout.write(line)
|
||||||
|
|
||||||
def parseLine(line):
|
def parseLine(line, script_lines):
|
||||||
global defaultDelay
|
global defaultDelay, variables, functions
|
||||||
|
line = line.strip()
|
||||||
if(line[0:3] == "REM"):
|
if(line[0:3] == "REM"):
|
||||||
# ignore ducky script comments
|
# ignore ducky script comments
|
||||||
pass
|
pass
|
||||||
@@ -110,6 +116,46 @@ def parseLine(line):
|
|||||||
if(button1Pushed):
|
if(button1Pushed):
|
||||||
print("Button 1 pushed")
|
print("Button 1 pushed")
|
||||||
button_pressed = True
|
button_pressed = True
|
||||||
|
elif line.startswith("VAR"):
|
||||||
|
_, var, _, value = line.split()
|
||||||
|
variables[var] = int(value)
|
||||||
|
elif line.startswith("FUNCTION"):
|
||||||
|
func_name = line.split()[1]
|
||||||
|
functions[func_name] = []
|
||||||
|
line = next(script_lines).strip()
|
||||||
|
while line != "END_FUNCTION":
|
||||||
|
functions[func_name].append(line)
|
||||||
|
line = next(script_lines).strip()
|
||||||
|
elif line.startswith("WHILE"):
|
||||||
|
condition = re.search(r'\((.*?)\)', line).group(1)
|
||||||
|
var_name, _, condition_value = condition.split()
|
||||||
|
condition_value = int(condition_value)
|
||||||
|
loop_code = []
|
||||||
|
line = next(script_lines).strip()
|
||||||
|
while line != "END_WHILE":
|
||||||
|
if not (line.startswith("WHILE")):
|
||||||
|
loop_code.append(line)
|
||||||
|
line = next(script_lines).strip()
|
||||||
|
while variables[var_name] > condition_value:
|
||||||
|
for loop_line in loop_code:
|
||||||
|
parseLine(loop_line, {})
|
||||||
|
variables[var_name] -= 1
|
||||||
|
elif line in functions:
|
||||||
|
updated_lines = []
|
||||||
|
inside_while_block = False
|
||||||
|
for func_line in functions[line]:
|
||||||
|
if func_line.startswith("WHILE"):
|
||||||
|
inside_while_block = True # Start skipping lines
|
||||||
|
updated_lines.append(func_line)
|
||||||
|
elif func_line.startswith("END_WHILE"):
|
||||||
|
inside_while_block = False # Stop skipping lines
|
||||||
|
updated_lines.append(func_line)
|
||||||
|
parseLine(updated_lines[0], iter(updated_lines))
|
||||||
|
updated_lines = [] # Clear updated_lines after parsing
|
||||||
|
elif inside_while_block:
|
||||||
|
updated_lines.append(func_line)
|
||||||
|
elif not (func_line.startswith("END_WHILE") or func_line.startswith("WHILE")):
|
||||||
|
parseLine(func_line, iter(functions[line]))
|
||||||
else:
|
else:
|
||||||
newScriptLine = convertLine(line)
|
newScriptLine = convertLine(line)
|
||||||
runScriptLine(newScriptLine)
|
runScriptLine(newScriptLine)
|
||||||
@@ -151,21 +197,23 @@ def runScript(file):
|
|||||||
|
|
||||||
duckyScriptPath = file
|
duckyScriptPath = file
|
||||||
try:
|
try:
|
||||||
f = open(duckyScriptPath,"r",encoding='utf-8')
|
with open(duckyScriptPath, "r", encoding='utf-8') as f:
|
||||||
|
script_lines = iter(f.readlines())
|
||||||
previousLine = ""
|
previousLine = ""
|
||||||
for line in f:
|
for line in script_lines:
|
||||||
line = line.rstrip()
|
print(f"runScript: {line}")
|
||||||
|
|
||||||
if(line[0:6] == "REPEAT"):
|
if(line[0:6] == "REPEAT"):
|
||||||
for i in range(int(line[7:])):
|
for i in range(int(line[7:])):
|
||||||
#repeat the last command
|
#repeat the last command
|
||||||
parseLine(previousLine)
|
parseLine(previousLine, script_lines)
|
||||||
time.sleep(float(defaultDelay)/1000)
|
time.sleep(float(defaultDelay) / 1000)
|
||||||
else:
|
else:
|
||||||
parseLine(line)
|
parseLine(line, script_lines)
|
||||||
previousLine = line
|
previousLine = line
|
||||||
time.sleep(float(defaultDelay)/1000)
|
time.sleep(float(defaultDelay) / 1000)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
print("Unable to open file ", file)
|
print("Unable to open file", file)
|
||||||
|
|
||||||
def selectPayload():
|
def selectPayload():
|
||||||
global payload1Pin, payload2Pin, payload3Pin, payload4Pin
|
global payload1Pin, payload2Pin, payload3Pin, payload4Pin
|
||||||
|
|||||||
13
examples/functions.dd
Normal file
13
examples/functions.dd
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
REM Example Function
|
||||||
|
FUNCTION COUNTDOWN()
|
||||||
|
REM The next four lines open Notepad in Windows and type "Hello World!"
|
||||||
|
GUI r
|
||||||
|
DELAY 1000
|
||||||
|
STRING notepad
|
||||||
|
ENTER
|
||||||
|
DELAY 2000
|
||||||
|
STRING Hello World!
|
||||||
|
ENTER
|
||||||
|
END_FUNCTION
|
||||||
|
COUNTDOWN()
|
||||||
|
|
||||||
7
examples/while_loops.dd
Normal file
7
examples/while_loops.dd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
VAR $TIME = 3
|
||||||
|
WHILE ($TIME > 0)
|
||||||
|
STRING .
|
||||||
|
DELAY 500
|
||||||
|
STRING While Looop!!
|
||||||
|
ENTER
|
||||||
|
END_WHILE
|
||||||
Reference in New Issue
Block a user