-
Not much progress so far
12/01/2017 at 03:20 • 0 commentsSo far I haven't achieved too much success with my project and those have been the pitfalls I have found along the way. I have never imagined that I would face so much trouble for such a simple project.
- I figured out how to extend the micronucleus bootloader to allow sending packets of data to be recorded on external eeprom instead of flashing it's own flash memory. This would save one step when uploading the scripts, but I couldn't make it work an bricked the AVR several times. At least I am using a DIP8 microcontroller and so it is relatively easy to recover.
- Bad documentation/examples: Digispark has a HID library named DigiUSB but it looks that it have been deprecated and it is recommended to use the DigiCDC library which is poorly documented as well. My linux machine can recognize the USB device but can not detect the correspondent serial port. Dead end again!
- Using a simple keyboard sketch with DigiKeyboard library It was noticed that when the device is plugged on a machine that has no libusb drivers installed the board stalls after the bootloader times out, being not recognized as a HID device. This is not a minor issue as it will require the bootloader to be modified.
At least I got some progress installing the Littlewire firmware which does have support for I2C (and other protocols as well) with a relatively easy interface and some few examples on how to use it.
Time to design a new architecture for the project....
-
Setting the development environment on Linux
06/01/2017 at 01:16 • 0 commentsIn order to continue the development on my Linux machine, it was necessary to:
1) Install the Arduino IDE
Download and unpack the Arduino IDE 1.8.2
https://www.arduino.cc/en/Main/Software
Read the installation guide, but before proceed to the installation it might be necessary to edit the installation script.
https://www.arduino.cc/en/Guide/Linux
If you get errors during installation try this:
Edit the install.sh script and edit the following line:
RESOURCE_NAME=cc.arduino.arduinoide
Change it to :RESOURCE_NAME=arduino-arduinoide
then run the ./install script (note: without sudo!!)
2) Install the Digispark support add-on
https://digistump.com/wiki/digispark/tutorials/connecting
3) Create a udev rule to allow the micronucleus bootloader to work without being root.
https://github.com/micronucleus/micronucleus/wiki/Ubuntu-Linux
This file shall be created as a root. In Ubuntu:
sudo mousepad /etc/udev/rules.d/49-micronucleus.rules
mousepad is the name of the text editor. Can be either gedit, vi, emacs, etc...
-
Added block commands
04/30/2017 at 20:12 • 0 commentsNow it is possible to expand the DuclyScript by repeating blocks of commands.
For example the following script will open 10 notepads an type in Hello World.
DELAY 3000 BEGIN GUI r DELAY 500 STRING notepad DELAY 500 ENTER DELAY 750 STRING Hello World!!! ENTER AGAIN 10
The start of a block is marked by BEGIN command and the end of the block is marked by the AGAIN command which receives an integer parameter.
Sources for the Test Sketch as well as for the Compiler were updated on Github as well.
-
Ugly Player Test Sketch
04/30/2017 at 17:38 • 0 commentsI have developed a Test Sketch for plain Arduino with the objective of verfiy which codes would be sent through USB while developing the Ugly Token player.
The code is available on Github and so far all the commands are working as expected.
-
Initial release of the compiler
04/30/2017 at 04:35 • 0 commentsInitial release of the compiler, based on Python-duckencode by crushedice2000. It generates a .bin file according with Ugly Token version 1.1, except the commands BEGIN and AGAIN
Available now in github
Here's and example of a script file aside with the equivalent tokens
-
New Token definition
04/30/2017 at 03:59 • 0 commentsDuring the development of the compiler I realized that some of the definitions could be discarded, leaving room for future improvements in Duckyscript and at the same time added some extensions.
The improvements are:
- The token for DEFAULT DELAY was changed to 0xDF
- The token for DELAY was changed to 0xDE
the modifications above make easier to track the commands while inspecting the binary file (they are mnemonic just in case you haven't noticed)
- The specific tokens for CONTROL, ALT, SHIFT, GUI (0xA8..0XAB) have been dismissed. Instead the HOLD token (0xAF) is used preceeding the code of the combination key desired.
The HOLD token allows a combination of several keys like CONTROL + ALT + T to invoke a terminal on linux systems.
- The STRING token has been dismissed. Instead the HID keycode of each character is directly stored.
The upper case letters as well as some symbols are preceded by HOLD token plus LSHIFT token in order to produce the desired character, for instance @ is generated by issuing HOLD + LSHIFT + KEY_2 (0xAF, 0xE0, 0x1F)
- The RELEASE token (0xAE) was created as a safeguard to release all keys that eventually have been held by a command.
I suspect that further improvements on the compiler might render this command useless.
- The BEGIN (0xA5) and AGAIN (0xA6) tokens have been created. The objective of such commands is to allow the repetition of blocks of commands.
The latter two commands are only defined by now and both are yet to be implemented.
The new Token specification can be seen in the table below:
-
Talk is cheap
04/21/2017 at 13:19 • 0 commentsTalk is cheap, show me some code...
Here it is, the skeleton of the interpreter
// Ugly Token Player while ( (EEprom_Addr < FLASH_SIZE) && !End_of_Script ) { c = Ext_EEpromRead( EEprom_Addr); switch (c) { case 0xff: !End_of_Script = TRUE ; break; case 0x00: // end of command Last_EEprom_Addr = EEprom_Addr; break; // save this address for // eveventual return case 0xA5: // Set Default Delay Default_Delay = Ext_EEpromRead16 (EEprom_Addr +1); // read value if (Default_Delay==0) // check range Default_Delay = INIT_DEFAULT_DELAY; // //Last_EEprom_Addr = EEprom_Addr; // advance address EEprom_Addr +=2; // case 0xA6: // Delay Time_to_Delay = Ext_EEpromRead16 (EEprom_Addr +1); if (Time_to_Delay==0) // check range Time_to_Delay = INIT_DEFAULT_DELAY; // //Last_EEprom_Addr = EEprom_Addr; // advance address EEprom_Addr +=2; // case 0xA7: // Replay last command if (Replaying) { EEprom_Addr = Last_EEprom_Addr; Replay_Counter--; if (Replay_Counter ==0) { // replay is over! EEprom_Addr += 3 ; // skip to the next command Replaying = RALSE; } } else { Replaying = TRUE; Replay_Counter = Ext_EEpromRead16 (EEprom_Addr +1); if (Replay_Counter==0) // check range Replay_Counter = 1; // EEprom_Addr = Last_EEprom_Addr; // rewind address } case 0xA8: // Hold Shift 0xA9: // Hold ALT 0xAA: // Hold CONTROL 0xAB: // Hold GUI Hold_Next_Key = 1; break ; // Just hold the next key default: // Send the character digiKeyboard.sendKeyPress(c); if (Hold_Next_Key) // If next key should remain hold Hold_Next_Key = 0; // then do nothing else { // digiKeyboard.sendKeyPress(0); // otherwise, send a release of digiKeyboard.delay(Default_Delay); // all key presses } EEprom_Addr++; // advance to the next character } } for (;;); // do nothing after playing the script
-
Replaying Strategy and String command
04/21/2017 at 13:17 • 0 commentsThe interpreter use a flag named 'Replaying' to differentiate the first time the Replay token is found from the consecutive times.Whenever the Replay command is found during the execution the 'Replaying' is check. If its False (zero) then the amount of times to repeat (Replay_Counter) is read from eeprom as an unsigned 16 bit and the flag is set True (not zero) and the 'loop' address is set by attributing to the current address (EEprom_Addr) the last address recorded for this purpose (Last_EEprom_Addr).
The next iterations, with Relaying flag set, will decrement the variable Replay_Counter until it reaches zero. When it occurs, the current address is added by three so it points right after the Replay command.
The last address recorded is in practice a Return Address and it is recorded everytime the interpreter gets a 0x00 command. Thus to repeat a command it shall be preceeded by 0x00. This subtle detail makes possible to repeat not only the last command, but rather it allows to repeat a block of commands.
The way the interpreter is implemented makes the STRING command (0xAC) rather useless, since the HID codes are simply typed in. One remark though, is that shifted characters shall be transmitted as a hold+shift+characterSTRING hello! h e l l o hold shift 1 0x0b 0x08 0x0f 0x0f 0x12 0xA8 0xE1 0x1E
-
Tiny Enhancements
04/21/2017 at 12:34 • 0 commentsI've decided to enhance the mechanism os composing keys. With the original Ducky Scripy it is only possible to compose keys with SHIFT, ALT, CONTROL and GUI.
The solution to allow several keys to be pushed is use a flag Hold_Next_Key which simply tells the Ugly interpreter to not send a key release after the next valid key.
With that, the combination keys tokens 0xa8 to 0xab have the same effect that is to set the Hold_Next_Key flag.With that in mind a GUI R command shall be sent as:
hold gui r 0xAB 0xE3 0x15
Then a CONTROL ALT DEL should be sent as:
hold contol hold alt del 0xAB 0xE0 0xAB 0xE2 0x2A
-
Planning the Tokens
04/07/2017 at 19:14 • 0 commentsStarted to plan the tokens for the translated duckscript file.
The end of line is 0x00, just like the strings.
The end of contents is 0xFF, which will tell the player to stop sending commands.
the commands
DEFAULT_DELAY
DELAY
REPLAY
SHIFT
ALT
CONTROL
GUI
STRING
are allocated on the unused hid codes 0xA5 to 0xAC ( 0xAD to 0xAF and 0xDE 0xDF)
The remaining keys use their own hid code.
The STRING command parse the following characters up to the next 0x00 (or 0xFF) to differentiate between shifted and unshifted characters.
The REPLAY command uses the saved EEPROM address from the previous command to point to the next instruction to be performed. There is one boolean variable, though, to know when to stop replaying the commands.