tests

# License : GPLv2.0

# copyright (c) 2021 Dave Bailey

# Author: Dave Bailey (dbisu, @daveisu)


import usb_hid

from adafruit_hid.keyboard import Keyboard


# comment out these lines for non_US keyboards

from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS as KeyboardLayout

from adafruit_hid.keycode import Keycode


# uncomment these lines for non_US keyboards

# replace LANG with appropriate language

#from keyboard_layout_win_LANG import KeyboardLayout

#from keycode_win_LANG import Keycode


import supervisor


import time

import digitalio

from digitalio import DigitalInOut, Pull

from adafruit_debouncer import Debouncer

from board import *

import pwmio

import asyncio


led = pwmio.PWMOut(LED, frequency=5000, duty_cycle=0)


def led_pwm_up(led):

for i in range(100):

# PWM LED up and down

if i < 50:

led.duty_cycle = int(i * 2 * 65535 / 100) # Up

time.sleep(0.01)

def led_pwm_down(led):

for i in range(100):

# PWM LED up and down

if i >= 50:

led.duty_cycle = 65535 - int((i - 50) * 2 * 65535 / 100) # Down

time.sleep(0.01)


# led = digitalio.DigitalInOut(LED)

# led.direction = digitalio.Direction.OUTPUT


duckyCommands = {

'WINDOWS': Keycode.WINDOWS, 'GUI': Keycode.GUI,

'APP': Keycode.APPLICATION, 'MENU': Keycode.APPLICATION, 'SHIFT': Keycode.SHIFT,

'ALT': Keycode.ALT, 'CONTROL': Keycode.CONTROL, 'CTRL': Keycode.CONTROL,

'DOWNARROW': Keycode.DOWN_ARROW, 'DOWN': Keycode.DOWN_ARROW, 'LEFTARROW': Keycode.LEFT_ARROW,

'LEFT': Keycode.LEFT_ARROW, 'RIGHTARROW': Keycode.RIGHT_ARROW, 'RIGHT': Keycode.RIGHT_ARROW,

'UPARROW': Keycode.UP_ARROW, 'UP': Keycode.UP_ARROW, 'BREAK': Keycode.PAUSE,

'PAUSE': Keycode.PAUSE, 'CAPSLOCK': Keycode.CAPS_LOCK, 'DELETE': Keycode.DELETE,

'END': Keycode.END, 'ESC': Keycode.ESCAPE, 'ESCAPE': Keycode.ESCAPE, 'HOME': Keycode.HOME,

'INSERT': Keycode.INSERT, 'NUMLOCK': Keycode.KEYPAD_NUMLOCK, 'PAGEUP': Keycode.PAGE_UP,

'PAGEDOWN': Keycode.PAGE_DOWN, 'PRINTSCREEN': Keycode.PRINT_SCREEN, 'ENTER': Keycode.ENTER,

'SCROLLLOCK': Keycode.SCROLL_LOCK, 'SPACE': Keycode.SPACE, 'TAB': Keycode.TAB,

'BACKSPACE': Keycode.BACKSPACE,

'A': Keycode.A, 'B': Keycode.B, 'C': Keycode.C, 'D': Keycode.D, 'E': Keycode.E,

'F': Keycode.F, 'G': Keycode.G, 'H': Keycode.H, 'I': Keycode.I, 'J': Keycode.J,

'K': Keycode.K, 'L': Keycode.L, 'M': Keycode.M, 'N': Keycode.N, 'O': Keycode.O,

'P': Keycode.P, 'Q': Keycode.Q, 'R': Keycode.R, 'S': Keycode.S, 'T': Keycode.T,

'U': Keycode.U, 'V': Keycode.V, 'W': Keycode.W, 'X': Keycode.X, 'Y': Keycode.Y,

'Z': Keycode.Z, 'F1': Keycode.F1, 'F2': Keycode.F2, 'F3': Keycode.F3,

'F4': Keycode.F4, 'F5': Keycode.F5, 'F6': Keycode.F6, 'F7': Keycode.F7,

'F8': Keycode.F8, 'F9': Keycode.F9, 'F10': Keycode.F10, 'F11': Keycode.F11,

'F12': Keycode.F12,


}

def convertLine(line):

newline = []

# print(line)

# loop on each key - the filter removes empty values

for key in filter(None, line.split(" ")):

key = key.upper()

# find the keycode for the command in the list

command_keycode = duckyCommands.get(key, None)

if command_keycode is not None:

# if it exists in the list, use it

newline.append(command_keycode)

elif hasattr(Keycode, key):

# if it's in the Keycode module, use it (allows any valid keycode)

newline.append(getattr(Keycode, key))

else:

# if it's not a known key name, show the error for diagnosis

print(f"Unknown key: <{key}>")

# print(newline)

return newline


def runScriptLine(line):

for k in line:

kbd.press(k)

kbd.release_all()


def sendString(line):

layout.write(line)


def parseLine(line):

global defaultDelay

if(line[0:3] == "REM"):

# ignore ducky script comments

pass

elif(line[0:5] == "DELAY"):

time.sleep(float(line[6:])/1000)

elif(line[0:6] == "STRING"):

sendString(line[7:])

elif(line[0:5] == "PRINT"):

print("[SCRIPT]: " + line[6:])

elif(line[0:6] == "IMPORT"):

runScript(line[7:])

elif(line[0:13] == "DEFAULT_DELAY"):

defaultDelay = int(line[14:]) * 10

elif(line[0:12] == "DEFAULTDELAY"):

defaultDelay = int(line[13:]) * 10

elif(line[0:3] == "LED"):

if(led.value == True):

led.value = False

else:

led.value = True

else:

newScriptLine = convertLine(line)

runScriptLine(newScriptLine)


kbd = Keyboard(usb_hid.devices)

layout = KeyboardLayout(kbd)


# turn off automatically reloading when files are written to the pico

supervisor.disable_autoreload()


# sleep at the start to allow the device to be recognized by the host computer

time.sleep(.5)


led_pwm_up(led)


#init button

button1_pin = DigitalInOut(GP22) # defaults to input

button1_pin.pull = Pull.UP # turn on internal pull-up resistor

button1 = Debouncer(button1_pin)


#init payload selection switch

payload1Pin = digitalio.DigitalInOut(GP4)

payload1Pin.switch_to_input(pull=digitalio.Pull.UP)

payload2Pin = digitalio.DigitalInOut(GP5)

payload2Pin.switch_to_input(pull=digitalio.Pull.UP)

payload3Pin = digitalio.DigitalInOut(GP10)

payload3Pin.switch_to_input(pull=digitalio.Pull.UP)

payload4Pin = digitalio.DigitalInOut(GP11)

payload4Pin.switch_to_input(pull=digitalio.Pull.UP)


def getProgrammingStatus():

# check GP0 for setup mode

# see setup mode for instructions

progStatusPin = digitalio.DigitalInOut(GP0)

progStatusPin.switch_to_input(pull=digitalio.Pull.UP)

progStatus = not progStatusPin.value

return(progStatus)



defaultDelay = 0


def runScript(file):

global defaultDelay


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)

except OSError as e:

print("Unable to open file ", file)


def selectPayload():

global payload1Pin, payload2Pin, payload3Pin, payload4Pin

payload = "payload.dd"

# check switch status

# payload1 = GPIO4 to GND

# payload2 = GPIO5 to GND

# payload3 = GPIO10 to GND

# payload4 = GPIO11 to GND

payload1State = not payload1Pin.value

payload2State = not payload2Pin.value

payload3State = not payload3Pin.value

payload4State = not payload4Pin.value



if(payload1State == True):

payload = "payload.dd"


elif(payload2State == True):

payload = "payload2.dd"


elif(payload3State == True):

payload = "payload3.dd"


elif(payload4State == True):

payload = "payload4.dd"


else:

# if all pins are high, then no switch is present

# default to payload1

payload = "payload.dd"



return payload



async def blink_pico_led(led):

print("starting blink_pico_led")

led_state = False

while True:

if led_state:

#led_pwm_up(led)

print("led up")

for i in range(100):

# PWM LED up and down

if i < 50:

led.duty_cycle = int(i * 2 * 65535 / 100) # Up

await asyncio.sleep(0.01)

led_state = False

else:

#led_pwm_down(led)

print("led down")

for i in range(100):

# PWM LED up and down

if i >= 50:

led.duty_cycle = 65535 - int((i - 50) * 2 * 65535 / 100) # Down

await asyncio.sleep(0.01)

led_state = True

await asyncio.sleep(0)


async def monitor_buttons(button1):

global inBlinkeyMode, inMenu, enableRandomBeep, enableSirenMode,pixel

print("starting monitor_buttons")

button1Down = False

while True:

button1.update()


button1Pushed = button1.fell

button1Released = button1.rose

button1Held = not button1.value


if(button1Pushed):

print("Button 1 pushed")

button1Down = True

if(button1Released):

print("Button 1 released")

if(button1Down):

print("push and released")


if(button1Released):

if(button1Down):

# Run selected payload

payload = selectPayload()

print("Running ", payload)

runScript(payload)

print("Done")

button1Down = False


await asyncio.sleep(0)




progStatus = False

progStatus = getProgrammingStatus()


if(progStatus == False):

# not in setup mode, inject the payload

payload = selectPayload()

print("Running ", payload)

runScript(payload)


print("Done")

else:

print("Update your payload")


led_state = False


async def main_loop():

global led,button1

pico_led_task = asyncio.create_task(blink_pico_led(led))

button_task = asyncio.create_task(monitor_buttons(button1))

await asyncio.gather(pico_led_task, button_task)


asyncio.run(main_loop())