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
|
||||
# Author: Dave Bailey (dbisu, @daveisu)
|
||||
|
||||
|
||||
import re
|
||||
import time
|
||||
import digitalio
|
||||
from digitalio import DigitalInOut, Pull
|
||||
@@ -47,6 +47,10 @@ duckyCommands = {
|
||||
'F12': Keycode.F12,
|
||||
|
||||
}
|
||||
|
||||
variables = {}
|
||||
functions = {}
|
||||
|
||||
def convertLine(line):
|
||||
newline = []
|
||||
# print(line)
|
||||
@@ -68,15 +72,17 @@ def convertLine(line):
|
||||
return newline
|
||||
|
||||
def runScriptLine(line):
|
||||
if isinstance(line, str):
|
||||
line = convertLine(line)
|
||||
for k in line:
|
||||
kbd.press(k)
|
||||
kbd.release_all()
|
||||
|
||||
def sendString(line):
|
||||
layout.write(line)
|
||||
|
||||
def parseLine(line):
|
||||
global defaultDelay
|
||||
def parseLine(line, script_lines):
|
||||
global defaultDelay, variables, functions
|
||||
line = line.strip()
|
||||
if(line[0:3] == "REM"):
|
||||
# ignore ducky script comments
|
||||
pass
|
||||
@@ -110,6 +116,46 @@ def parseLine(line):
|
||||
if(button1Pushed):
|
||||
print("Button 1 pushed")
|
||||
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:
|
||||
newScriptLine = convertLine(line)
|
||||
runScriptLine(newScriptLine)
|
||||
@@ -151,21 +197,23 @@ def runScript(file):
|
||||
|
||||
duckyScriptPath = file
|
||||
try:
|
||||
f = open(duckyScriptPath,"r",encoding='utf-8')
|
||||
previousLine = ""
|
||||
for line in f:
|
||||
line = line.rstrip()
|
||||
if(line[0:6] == "REPEAT"):
|
||||
for i in range(int(line[7:])):
|
||||
#repeat the last command
|
||||
parseLine(previousLine)
|
||||
time.sleep(float(defaultDelay)/1000)
|
||||
else:
|
||||
parseLine(line)
|
||||
previousLine = line
|
||||
time.sleep(float(defaultDelay)/1000)
|
||||
with open(duckyScriptPath, "r", encoding='utf-8') as f:
|
||||
script_lines = iter(f.readlines())
|
||||
previousLine = ""
|
||||
for line in script_lines:
|
||||
print(f"runScript: {line}")
|
||||
|
||||
if(line[0:6] == "REPEAT"):
|
||||
for i in range(int(line[7:])):
|
||||
#repeat the last command
|
||||
parseLine(previousLine, script_lines)
|
||||
time.sleep(float(defaultDelay) / 1000)
|
||||
else:
|
||||
parseLine(line, script_lines)
|
||||
previousLine = line
|
||||
time.sleep(float(defaultDelay) / 1000)
|
||||
except OSError as e:
|
||||
print("Unable to open file ", file)
|
||||
print("Unable to open file", file)
|
||||
|
||||
def selectPayload():
|
||||
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