Advertisement
michalmonday

Malduino Elite (added ALT-NUMPAD-METHOD for Windows)

Oct 5th, 2018
516
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.69 KB | None | 0 0
  1. /*
  2. Code with added "ALT-NUMPAD-METHOD" keyword/command for ducky script.
  3. It can be used like:
  4.  
  5. REM Example of ducky script
  6. ALT-NUMPAD-METHOD 1
  7. STRING some text that will be typed regardless of system language setting (but it will be typed only on Windows)
  8. ALT-NUMPAD-METHOD 0
  9. STRING some normally typed text
  10.  
  11. How to test its' usability?
  12. Download and set "French(Canadian)" as the main Windows language for a moment and try to use the following ducky script:
  13. STRING <> \
  14.  
  15. Instead of typing these characters it will type:
  16. '"à
  17.  
  18. That's not good... So that's where the ALT-NUMPAD-METHOD comes handy:
  19. ALT-NUMPAD-METHOD 1
  20. STRING <> \
  21.  
  22. Such ducky script will type the proper text:
  23. <> \
  24.  
  25. More info:
  26. https://en.wikipedia.org/wiki/Alt_code
  27. https://support.office.com/en-us/article/insert-ascii-or-unicode-latin-based-symbols-and-characters-d13f58d3-7bcb-44a7-a4d5-972ee12e50e0
  28. */
  29.  
  30.  
  31. /*
  32.   ==============================================================
  33.     Copyright (c) 2017 Seytonic, Spacehuhn (Licensed under MIT)
  34.       For more information see: github.com/seytonic/malduino
  35.   ==============================================================
  36. */
  37.  
  38. #include <SPI.h>
  39. #include <SD.h>
  40. #include "Keyboard.h"
  41. #include "Mouse.h"
  42.  
  43. #define debug true // <-- uncomment to turn serial output on
  44. #define CSpin 4 //Chip-Select of the SD-Card reader
  45. #define ledPin 3
  46. #define blinkInterval 50
  47.  
  48. //Dip-Switch Pins:
  49. #define dip1 6
  50. #define dip2 8
  51. #define dip3 9
  52. #define dip4 10
  53.  
  54. #define buffersize 256
  55.  
  56. #define KEYPAD_0 234
  57. #define KEYPAD_1 225
  58. #define KEYPAD_2 226
  59. #define KEYPAD_3 227
  60. #define KEYPAD_4 228
  61. #define KEYPAD_5 229
  62. #define KEYPAD_6 230
  63. #define KEYPAD_7 231
  64. #define KEYPAD_8 232
  65. #define KEYPAD_9 233
  66. #define KEYPAD_ASTERIX 221
  67. #define KEYPAD_ENTER 224
  68. #define KEYPAD_MINUS 222
  69. #define KEYPAD_PERIOD 235
  70. #define KEYPAD_PLUS 223
  71. #define KEYPAD_SLASH 220
  72. #define PRINTSCREEN 206
  73.  
  74. File payload;
  75. char* buf = malloc(sizeof(char)*buffersize);
  76. char* repeatBuffer = malloc(sizeof(char)*12);
  77.  
  78. int bufSize = 0;
  79. int defaultDelay = 5;
  80. int defaultCharDelay = 5;
  81. bool ledOn = true;
  82. int rMin = -100;
  83. int rMax = 100;
  84.  
  85.  
  86. int getSpace(int start, int end){
  87.   for(int i=start;i<end;i++){
  88.     if(buf[i] == ' ') return i;
  89.   }
  90.   return -1;
  91. }
  92.  
  93. bool equals(char* strA, int start, int end, char* strB, int strLen){
  94.   if(end-start != strLen) return false;
  95.   for(int i=0;i<strLen;i++){
  96.     if(strA[start+i] != strB[i]) return false;
  97.   }
  98.   return true;
  99. }
  100.  
  101. int toPositive(int num){
  102.   if(num < 0) return num*(-1);
  103.   else return num;
  104. }
  105.  
  106. bool equalsBuffer(int start, int end, char* str){ return equals(buf, start, end, str, String(str).length()); }
  107.  
  108. int getInt(char* str, int pos){
  109.   if(equals(str, pos+1, pos+7, "RANDOM", 6)){
  110.     return random(rMin, rMax);
  111.   }else{
  112.     return String(str).substring(pos+1,pos+6).toInt();
  113.   }
  114. }
  115.  
  116. // MODIFIED
  117. byte KEYPAD[10] = {234, 225, 226, 227, 228, 229, 230, 231, 232, 233};
  118. bool use_alt_numpad_method = false;
  119. // MODIFIED
  120. void KeyboardWrite(uint8_t c){
  121.   if (use_alt_numpad_method && !IsModifier(c) && ((!isalnum(c) && c != ' ') || IsException(c)))    
  122.   {
  123.    
  124.     byte hundreds = (byte)c / 100;
  125.     byte dozens = ((byte)c - (hundreds*100)) / 10;
  126.     byte singles = (byte)c - (hundreds*100) - (dozens*10);
  127.  
  128.     Keyboard.press(KEY_LEFT_ALT);
  129.     PressRelease((char)KEYPAD[hundreds], 5);
  130.     PressRelease((char)KEYPAD[dozens], 5);
  131.     PressRelease((char)KEYPAD[singles], 5);
  132.     Keyboard.releaseAll();
  133.   }
  134.   else{
  135.     Keyboard.press(c);
  136.     delay(defaultCharDelay);
  137.     Keyboard.release(c);
  138.   }
  139. }
  140.  
  141. void runLine(){
  142.   #ifdef debug
  143.     Serial.println("run: '"+String(buf).substring(0,bufSize)+"' ("+(String)bufSize+")");
  144.   #endif
  145.  
  146.   int space = getSpace(0,bufSize);
  147.  
  148.   if(space == -1) runCommand(0,bufSize);
  149.   else{
  150.     if(equalsBuffer(0,space,"DEFAULTDELAY") || equalsBuffer(0,space,"DEFAULT_DELAY")) defaultDelay = getInt(buf,space);
  151.     else if(equalsBuffer(0,space,"DEFAULTCHARDELAY") || equalsBuffer(0,space,"DEFAULT_CHAR_DELAY")) defaultCharDelay = getInt(buf,space);
  152.     else if(equalsBuffer(0,space,"DELAY")) delay(getInt(buf,space));
  153.     else if(equalsBuffer(0,space,"STRING")){
  154.       for(int i=space+1;i<bufSize;i++) KeyboardWrite(buf[i]);
  155.     }
  156.     else if(equalsBuffer(0,space,"MOUSE")){
  157.       int nSpace = getSpace(space+1,bufSize);
  158.       int x = getInt(buf,space);
  159.       int y = getInt(buf,nSpace);
  160.       Mouse.move(x,y);
  161.       #ifdef debug
  162.         Serial.println("Move mouse "+(String)x+" "+(String)y);
  163.       #endif
  164.     }
  165.     else if(equalsBuffer(0,space,"SCROLL")) Mouse.move(0,0,getInt(buf,space));
  166.     else if(equalsBuffer(0,space,"RANDOMMIN")) rMin = getInt(buf,space);
  167.     else if(equalsBuffer(0,space,"RANDOMMAX")) rMax = getInt(buf,space);
  168.     else if(equalsBuffer(0,space,"ALT-NUMPAD-METHOD")) use_alt_numpad_method = (bool)getInt(buf,space);
  169.     else if(equalsBuffer(0,space,"REM") || equalsBuffer(0,space,"REPEAT")){}
  170.     else{
  171.       runCommand(0,space);
  172.       while(space >= 0 && space < bufSize){
  173.         int nSpace = getSpace(space+1,bufSize);
  174.         if(nSpace == -1) nSpace = bufSize;
  175.         runCommand(space+1,nSpace);
  176.         space = nSpace;
  177.       }
  178.     }
  179.   }
  180.  
  181.   Keyboard.releaseAll();
  182.   delay(defaultDelay);
  183. }
  184.  
  185. void runCommand(int s, int e){
  186.  
  187.   #ifdef debug
  188.     Serial.println("Press '"+String(buf).substring(s,e)+"'");
  189.   #endif
  190.  
  191.   if(e - s < 2) Keyboard.press(buf[s]);
  192.   else if(equalsBuffer(s,e,"ENTER")) Keyboard.press(KEY_RETURN);
  193.   else if(equalsBuffer(s,e,"GUI") || equalsBuffer(s,e,"WINDOWS")) Keyboard.press(KEY_LEFT_GUI);
  194.   else if(equalsBuffer(s,e,"SHIFT")) Keyboard.press(KEY_LEFT_SHIFT);
  195.   else if(equalsBuffer(s,e,"ALT")  ||equalsBuffer(s,e,"ALT_LEFT") ||equalsBuffer(s,e,"ALTLEFT")) Keyboard.press(KEY_LEFT_ALT);
  196.   else if(equalsBuffer(s,e,"ALT_RIGHT") ||equalsBuffer(s,e,"ALTRIGHT")) Keyboard.press(KEY_RIGHT_ALT);
  197.   else if(equalsBuffer(s,e,"CTRL") || equalsBuffer(s,e,"CONTROL")) Keyboard.press(KEY_LEFT_CTRL);
  198.   else if(equalsBuffer(s,e,"CAPSLOCK")) Keyboard.press(KEY_CAPS_LOCK);
  199.   else if(equalsBuffer(s,e,"DELETE")) Keyboard.press(KEY_DELETE);
  200.   else if(equalsBuffer(s,e,"END")) Keyboard.press(KEY_END);
  201.   else if(equalsBuffer(s,e,"ESC") || equalsBuffer(s,e,"ESCAPE")) Keyboard.press(KEY_ESC);
  202.   else if(equalsBuffer(s,e,"HOME")) Keyboard.press(KEY_HOME);
  203.   else if(equalsBuffer(s,e,"INSERT")) Keyboard.press(KEY_INSERT);
  204.   else if(equalsBuffer(s,e,"PAGEUP")) Keyboard.press(KEY_PAGE_UP);
  205.   else if(equalsBuffer(s,e,"PAGEDOWN")) Keyboard.press(KEY_PAGE_DOWN);
  206.   else if(equalsBuffer(s,e,"SPACE")) Keyboard.press(' ');
  207.   else if(equalsBuffer(s,e,"TAB")) Keyboard.press(KEY_TAB);
  208.   else if(equalsBuffer(s,e,"BACKSPACE")) Keyboard.press(KEY_BACKSPACE);
  209.  
  210.   else if(equalsBuffer(s,e,"UP") || equalsBuffer(s,e,"UPARROW")) Keyboard.press(KEY_UP_ARROW);
  211.   else if(equalsBuffer(s,e,"DOWN") || equalsBuffer(s,e,"DOWNARROW")) Keyboard.press(KEY_DOWN_ARROW);
  212.   else if(equalsBuffer(s,e,"LEFT") || equalsBuffer(s,e,"LEFTARROW")) Keyboard.press(KEY_LEFT_ARROW);
  213.   else if(equalsBuffer(s,e,"RIGHT") || equalsBuffer(s,e,"RIGHTARROW")) Keyboard.press(KEY_RIGHT_ARROW);
  214.  
  215.   else if(equalsBuffer(s,e,"PRINTSCREEN")) Keyboard.press(PRINTSCREEN);
  216.  
  217.   else if(equalsBuffer(s,e,"F1")) Keyboard.press(KEY_F1);
  218.   else if(equalsBuffer(s,e,"F2")) Keyboard.press(KEY_F2);
  219.   else if(equalsBuffer(s,e,"F3")) Keyboard.press(KEY_F3);
  220.   else if(equalsBuffer(s,e,"F4")) Keyboard.press(KEY_F4);
  221.   else if(equalsBuffer(s,e,"F5")) Keyboard.press(KEY_F5);
  222.   else if(equalsBuffer(s,e,"F6")) Keyboard.press(KEY_F6);
  223.   else if(equalsBuffer(s,e,"F7")) Keyboard.press(KEY_F7);
  224.   else if(equalsBuffer(s,e,"F8")) Keyboard.press(KEY_F8);
  225.   else if(equalsBuffer(s,e,"F9")) Keyboard.press(KEY_F9);
  226.   else if(equalsBuffer(s,e,"F10")) Keyboard.press(KEY_F10);
  227.   else if(equalsBuffer(s,e,"F11")) Keyboard.press(KEY_F11);
  228.   else if(equalsBuffer(s,e,"F12")) Keyboard.press(KEY_F12);
  229.  
  230.   else if(equalsBuffer(s,e,"NUM_0")) KeyboardWrite(KEYPAD_0);
  231.   else if(equalsBuffer(s,e,"NUM_1")) KeyboardWrite(KEYPAD_1);
  232.   else if(equalsBuffer(s,e,"NUM_2")) KeyboardWrite(KEYPAD_2);
  233.   else if(equalsBuffer(s,e,"NUM_3")) KeyboardWrite(KEYPAD_3);
  234.   else if(equalsBuffer(s,e,"NUM_4")) KeyboardWrite(KEYPAD_4);
  235.   else if(equalsBuffer(s,e,"NUM_5")) KeyboardWrite(KEYPAD_5);
  236.   else if(equalsBuffer(s,e,"NUM_6")) KeyboardWrite(KEYPAD_6);
  237.   else if(equalsBuffer(s,e,"NUM_7")) KeyboardWrite(KEYPAD_7);
  238.   else if(equalsBuffer(s,e,"NUM_8")) KeyboardWrite(KEYPAD_8);
  239.   else if(equalsBuffer(s,e,"NUM_9")) KeyboardWrite(KEYPAD_9);
  240.   else if(equalsBuffer(s,e,"NUM_ASTERIX")) KeyboardWrite(KEYPAD_ASTERIX);
  241.   else if(equalsBuffer(s,e,"NUM_ENTER")) KeyboardWrite(KEYPAD_ENTER);
  242.   else if(equalsBuffer(s,e,"NUM_Minus")) KeyboardWrite(KEYPAD_MINUS);
  243.   else if(equalsBuffer(s,e,"NUM_PERIOD")) KeyboardWrite(KEYPAD_PERIOD);
  244.   else if(equalsBuffer(s,e,"NUM_PLUS")) KeyboardWrite(KEYPAD_PLUS);
  245.  
  246.   else if(equalsBuffer(s,e,"CLICK")  || equalsBuffer(s,e,"CLICK_LEFT") || equalsBuffer(s,e,"MOUSECLICK")) Mouse.click();
  247.   else if(equalsBuffer(s,e,"CLICK_RIGHT")) Mouse.click(MOUSE_RIGHT);
  248.   else if(equalsBuffer(s,e,"CLICK_MIDDLE")) Mouse.click(MOUSE_MIDDLE);
  249.  
  250.   else if(equalsBuffer(s,e,"PRESS") || equalsBuffer(s,e,"PRESS_LEFT")) Mouse.press();
  251.   else if(equalsBuffer(s,e,"PRESS_LEFT")) Mouse.press(MOUSE_RIGHT);
  252.   else if(equalsBuffer(s,e,"PRESS_MIDDLE")) Mouse.press(MOUSE_MIDDLE);
  253.   else if(equalsBuffer(s,e,"RELEASE") || equalsBuffer(s,e,"RELEASE_LEFT")) Mouse.release();
  254.   else if(equalsBuffer(s,e,"RELEASE_LEFT")) Mouse.release(MOUSE_RIGHT);
  255.   else if(equalsBuffer(s,e,"RELEASE_MIDDLE")) Mouse.release(MOUSE_MIDDLE);
  256.  
  257. #ifdef debug
  258.   else Serial.println("failed to find command");
  259. #endif
  260.   /* not implemented
  261.   else if(equalsBuffer(s,e,"APP")) Keyboard.press();
  262.   else if(equalsBuffer(s,e,"MENU")) Keyboard.press();
  263.   else if(equalsBuffer(s,e,"BREAK") || equalsBuffer(s,e,"PAUSE",5)) Keyboard.press();
  264.   else if(equalsBuffer(s,e,"NUMLOCK")) Keyboard.press();
  265.   else if(equalsBuffer(s,e,"SCROLLLOCK")) Keyboard.press();
  266.   */
  267. }
  268.  
  269. void setup() {
  270.   #ifdef debug
  271.     Serial.begin(115200);
  272.     delay(2000);
  273.     Serial.println("Started!");
  274.   #endif
  275.  
  276.   randomSeed(analogRead(0));
  277.    
  278.   pinMode(ledPin, OUTPUT);
  279.   digitalWrite(ledPin, HIGH);
  280.  
  281.   String scriptName = ""; // Name of the file that will be opened
  282.  
  283.   pinMode(dip1, INPUT_PULLUP);
  284.   pinMode(dip2, INPUT_PULLUP);
  285.   pinMode(dip3, INPUT_PULLUP);
  286.   pinMode(dip4, INPUT_PULLUP);
  287.  
  288.   if(digitalRead(dip1) == LOW){scriptName += '1';} else {scriptName += '0';}
  289.   if(digitalRead(dip2) == LOW){scriptName += '1';} else {scriptName += '0';}
  290.   if(digitalRead(dip3) == LOW){scriptName += '1';} else {scriptName += '0';}
  291.   if(digitalRead(dip4) == LOW){scriptName += '1';} else {scriptName += '0';}
  292.  
  293.   scriptName += ".txt";
  294.  
  295.   if(!SD.begin(4)) {
  296.     #ifdef debug
  297.       Serial.println("couldn't access sd-card :(");
  298.     #endif
  299.     return;
  300.   }
  301.  
  302.   payload = SD.open(scriptName);
  303.   if(!payload){
  304. #ifdef debug
  305.     Serial.println("couldn't find script: '"+String(scriptName)+"'");
  306. #endif
  307.     return;
  308.   }else{
  309.     Keyboard.begin();
  310.     Mouse.begin();
  311.     while(payload.available()){
  312.  
  313.       buf[bufSize] = payload.read();
  314.       if(buf[bufSize] == '\r' || buf[bufSize] == '\n' || bufSize >= buffersize){
  315.         if(buf[bufSize] == '\r' && payload.peek() == '\n') payload.read();
  316.        
  317.         //---------REPEAT---------    
  318.         int repeatBufferSize = 0;
  319.         int repeats = 0;
  320.         unsigned long payloadPosition = payload.position();
  321.        
  322.         for(int i=0;i<12;i++){
  323.           if(payload.available()){
  324.             repeatBuffer[repeatBufferSize] = payload.read();
  325.             repeatBufferSize++;
  326.           }else break;
  327.         }
  328.  
  329.         if(repeatBufferSize > 6){
  330.           if(equals(repeatBuffer, 0, 6, "REPEAT", 6)){
  331.             repeats = getInt(repeatBuffer, 6);
  332.           }
  333.         }
  334.  
  335.         for(int i=0;i<repeats;i++) runLine();
  336.        
  337.         payload.seek(payloadPosition);
  338.         //------------------------
  339.        
  340.         runLine();
  341.         bufSize = 0;
  342.       }
  343.       else bufSize++;
  344.     }
  345.     if(bufSize > 0){
  346.       runLine();
  347.       bufSize = 0;
  348.     }
  349.     payload.close();
  350.     Mouse.end();
  351.     Keyboard.end();
  352.   }
  353. }
  354.  
  355. void loop() {
  356.   ledOn = !ledOn;
  357.   digitalWrite(ledPin, ledOn);
  358.   delay(blinkInterval);
  359. }
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366. /*
  367.  *
  368.  * Stuff below is added for multilang method
  369.  * additionally "KeyboardWrite" function was modified
  370.  * in previous part of the code
  371. */
  372.  
  373.  
  374.  
  375. void PressRelease(char c, byte timeDelay)
  376. {
  377.   Keyboard.press(c);
  378.   delay(timeDelay);
  379.   Keyboard.release(c);
  380. }
  381.  
  382. /*
  383. Exceptions are the letters that require different button being pressed in different lang settings
  384. (so if letter == exception then use alt+numpad method, otherwise use the normal typing because it's faster to press 1 instead of 4 buttons)
  385. these exceptions are listed to make the typing process faster because using alt+numpad method for all the characters appears to be too slow
  386.  
  387. german - yz
  388. french - qamwz
  389. dutch - qamwz
  390. turkish - i
  391. azerbaijani - totally uncompatible
  392. */
  393.  
  394. #define EXCEPTIONS_SIZE 24
  395. char exceptions[EXCEPTIONS_SIZE] = {
  396.   'y','Y',
  397.   'z','Z',
  398.   'q','Q',
  399.   'a','A',
  400.   'm','M',
  401.   'w','W',
  402.   'i','I',
  403.   '0','1','2','3','4','5','6','7','8','9',
  404. };
  405.  
  406.  
  407. bool IsException(char c)                    // check whether this character is one of these that have to be typed differently using other language settings
  408. {
  409.   for(byte i=0; i<EXCEPTIONS_SIZE; i++)
  410.   {
  411.     if(c == exceptions[i])
  412.     {
  413.       return true;
  414.     }
  415.   }
  416.   return false;
  417. }
  418.  
  419.  
  420. bool IsModifier(char c)                   // is key like shift, alt, "GUI" key, etc.
  421. {
  422.   byte b = (byte)c;
  423.   if((b >= 128 && b <=135) || (b >= 176 && b <=179) || (b >= 193 && b <=205) || (b >= 209 && b <=218))
  424.   {
  425.     return true;
  426.   }
  427.   return false;
  428. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement