1 #include "fixscancodemap.h"
\r
2 #include "registry.h"
\r
5 #include <tlhelp32.h>
\r
7 typedef HMODULE (WINAPI *FpGetModuleHandleW)(LPCWSTR);
\r
8 typedef FARPROC (WINAPI *FpGetProcAddress)(HMODULE, LPCSTR);
\r
9 typedef BOOL (WINAPI *FpUpdatePerUserSystemParameters)(DWORD, BOOL);
\r
10 typedef HANDLE (WINAPI *FpOpenProcess)(DWORD, BOOL, DWORD);
\r
11 typedef BOOL (WINAPI *FpOpenProcessToken)(HANDLE, DWORD, PHANDLE);
\r
12 typedef BOOL (WINAPI *FpImpersonateLoggedOnUser)(HANDLE);
\r
13 typedef BOOL (WINAPI *FpRevertToSelf)(VOID);
\r
14 typedef BOOL (WINAPI *FpCloseHandle)(HANDLE);
\r
18 TCHAR advapi32_[64];
\r
19 CHAR impersonateLoggedOnUser_[32];
\r
20 CHAR revertToSelf_[32];
\r
21 CHAR openProcessToken_[32];
\r
22 FpGetModuleHandleW pGetModuleHandle;
\r
23 FpGetProcAddress pGetProcAddress;
\r
24 FpUpdatePerUserSystemParameters pUpdate;
\r
25 FpOpenProcess pOpenProcess;
\r
26 FpCloseHandle pCloseHandle;
\r
29 #pragma runtime_checks( "", off )
\r
30 static DWORD invokeFunc(InjectInfo *info)
\r
35 FpImpersonateLoggedOnUser pImpersonateLoggedOnUser;
\r
36 FpRevertToSelf pRevertToSelf;
\r
37 FpOpenProcessToken pOpenProcessToken;
\r
39 hAdvapi32 = info->pGetModuleHandle(info->advapi32_);
\r
41 pImpersonateLoggedOnUser = (FpImpersonateLoggedOnUser)info->pGetProcAddress(hAdvapi32, info->impersonateLoggedOnUser_);
\r
42 pRevertToSelf = (FpRevertToSelf)info->pGetProcAddress(hAdvapi32, info->revertToSelf_);
\r
43 pOpenProcessToken = (FpOpenProcessToken)info->pGetProcAddress(hAdvapi32, info->openProcessToken_);
\r
45 HANDLE hProcess = info->pOpenProcess(PROCESS_QUERY_INFORMATION, FALSE, info->pid_);
\r
46 if (hProcess == NULL) {
\r
50 ret = pOpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_DUPLICATE , &hToken);
\r
55 ret = pImpersonateLoggedOnUser(hToken);
\r
60 info->pUpdate(0, 1);
\r
62 ret = pRevertToSelf();
\r
67 info->pCloseHandle(hToken);
\r
68 info->pCloseHandle(hProcess);
\r
71 static void afterFunc(void){}
\r
72 #pragma runtime_checks( "", restore )
\r
74 int FixScancodeMap::acquirePrivileges()
\r
77 HANDLE hToken = NULL;
\r
79 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
\r
85 if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
\r
90 TOKEN_PRIVILEGES tk_priv;
\r
91 tk_priv.PrivilegeCount = 1;
\r
92 tk_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
\r
93 tk_priv.Privileges[0].Luid = luid;
\r
95 if (!AdjustTokenPrivileges(hToken, FALSE, &tk_priv, 0, NULL, NULL)) {
\r
101 if (hToken != NULL) {
\r
102 CloseHandle(hToken);
\r
108 DWORD FixScancodeMap::getWinLogonPid()
\r
111 DWORD mySessionId = 0;
\r
113 if (ProcessIdToSessionId(GetCurrentProcessId(), &mySessionId) == FALSE) {
\r
117 HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
\r
118 if (hSnap == INVALID_HANDLE_VALUE) {
\r
123 pe.dwSize = sizeof(pe);
\r
125 BOOL bResult = Process32First(hSnap, &pe);
\r
127 if (!_tcscmp(pe.szExeFile, _T("winlogon.exe"))) {
\r
130 if (ProcessIdToSessionId(pe.th32ProcessID, &sessionId) != FALSE) {
\r
131 if (sessionId == mySessionId) {
\r
132 pid = pe.th32ProcessID;
\r
137 bResult = Process32Next(hSnap, &pe);
\r
140 CloseHandle(hSnap);
\r
145 int FixScancodeMap::injectThread(DWORD dwPID)
\r
151 HANDLE hProcess = NULL;
\r
152 LPVOID remoteMem = NULL;
\r
153 LPVOID remoteInfo = NULL;
\r
154 DWORD invokeFuncAddr = (DWORD)invokeFunc;
\r
155 DWORD afterFuncAddr = (DWORD)afterFunc;
\r
156 DWORD memSize = afterFuncAddr - invokeFuncAddr;
\r
160 info.pid_ = GetCurrentProcessId();
\r
162 memcpy(&info.advapi32_, _T("advapi32.dll"), sizeof(info.advapi32_));
\r
163 memcpy(&info.impersonateLoggedOnUser_, "ImpersonateLoggedOnUser", sizeof(info.impersonateLoggedOnUser_));
\r
164 memcpy(&info.revertToSelf_, "RevertToSelf", sizeof(info.revertToSelf_));
\r
165 memcpy(&info.openProcessToken_, "OpenProcessToken", sizeof(info.openProcessToken_));
\r
167 hMod = GetModuleHandle(_T("user32.dll"));
\r
168 if (hMod != NULL) {
\r
169 info.pUpdate = (FpUpdatePerUserSystemParameters)GetProcAddress(hMod, "UpdatePerUserSystemParameters");
\r
170 if (info.pUpdate == NULL) {
\r
175 hMod = GetModuleHandle(_T("kernel32.dll"));
\r
176 if (hMod != NULL) {
\r
177 info.pGetModuleHandle = (FpGetModuleHandleW)GetProcAddress(hMod, "GetModuleHandleW");
\r
178 if (info.pGetModuleHandle == NULL) {
\r
182 info.pGetProcAddress = (FpGetProcAddress)GetProcAddress(hMod, "GetProcAddress");
\r
183 if (info.pGetProcAddress == NULL) {
\r
187 info.pOpenProcess = (FpOpenProcess)GetProcAddress(hMod, "OpenProcess");
\r
188 if (info.pOpenProcess == NULL) {
\r
192 info.pCloseHandle = (FpCloseHandle)GetProcAddress(hMod, "CloseHandle");
\r
193 if (info.pCloseHandle == NULL) {
\r
198 if ((hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) == NULL) {
\r
203 remoteMem = VirtualAllocEx(hProcess, NULL, memSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
\r
204 if (remoteMem == NULL) {
\r
206 err = GetLastError();
\r
210 wFlag = WriteProcessMemory(hProcess, remoteMem, (char*)invokeFunc, memSize, (SIZE_T*)0);
\r
211 if (wFlag == FALSE) {
\r
216 remoteInfo = VirtualAllocEx(hProcess, NULL, sizeof(info), MEM_COMMIT, PAGE_READWRITE);
\r
217 if (remoteInfo == NULL) {
\r
219 err = GetLastError();
\r
223 wFlag = WriteProcessMemory(hProcess, remoteInfo, (char*)&info, sizeof(info), (SIZE_T*)0);
\r
224 if (wFlag == FALSE) {
\r
232 _stprintf_s(buf, sizeof(buf)/sizeof(buf[0]),
\r
233 _T("execute UpdatePerUserSystemParameters(), inject code to winlogon.exe?\r\n")
\r
234 _T("invokeFunc=0x%p\r\n")
\r
235 _T("afterFunc=0x%p\r\n")
\r
236 _T("afterFunc - invokeFunc=%d\r\n")
\r
237 _T("remoteMem=0x%p\r\n")
\r
238 _T("remoteInfo=0x%p(size: %d)\r\n"),
\r
239 invokeFunc, afterFunc, memSize, remoteMem, remoteInfo, sizeof(info));
\r
240 if (MessageBox((HWND)NULL, buf, _T("upusp"), MB_OKCANCEL | MB_ICONSTOP) == IDCANCEL) {
\r
241 (info.pUpdate)(0, 1);
\r
246 HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
\r
247 (LPTHREAD_START_ROUTINE)remoteMem, remoteInfo, 0, NULL);
\r
248 if (hThread == NULL) {
\r
253 if (WaitForSingleObject(hThread, 5000) == WAIT_TIMEOUT) {
\r
258 GetExitCodeThread(hThread, &result);
\r
260 CloseHandle(hThread);
\r
263 if (remoteMem != NULL) {
\r
264 VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE);
\r
267 if (remoteInfo != NULL) {
\r
268 VirtualFreeEx(hProcess, remoteInfo, 0, MEM_RELEASE);
\r
271 if (hProcess != NULL) {
\r
272 CloseHandle(hProcess);
\r
278 int FixScancodeMap::update()
\r
280 MINIMIZEDMETRICS mm;
\r
283 if (acquirePrivileges()) {
\r
289 if ((dwPID = getWinLogonPid()) == 0) {
\r
294 memset(&mm, 0, sizeof(mm));
\r
295 mm.cbSize = sizeof(mm);
\r
296 SystemParametersInfo(SPI_GETMINIMIZEDMETRICS, sizeof(mm), &mm, 0);
\r
298 if (injectThread(dwPID)) {
\r
303 SystemParametersInfo(SPI_SETMINIMIZEDMETRICS, sizeof(mm), &mm, 0);
\r
309 int FixScancodeMap::fix()
\r
311 ScancodeMap *origMap, *fixMap;
\r
312 Registry reg(HKEY_CURRENT_USER, _T("Keyboard Layout"));
\r
313 // Windows7 RC not support Scancode Map on HKCU?
\r
314 //Registry reg(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"));
\r
315 DWORD origSize, fixSize;
\r
319 // save original Scancode Map
\r
320 ret = reg.read(_T("Scancode Map"), NULL, &origSize, NULL, 0);
\r
322 origMap = reinterpret_cast<ScancodeMap*>(malloc(origSize));
\r
323 if (origMap == NULL) {
\r
328 ret = reg.read(_T("Scancode Map"), reinterpret_cast<BYTE*>(origMap), &origSize, NULL, 0);
\r
329 if (ret == false) {
\r
334 fixSize = origSize;
\r
335 fixMap = reinterpret_cast<ScancodeMap*>(malloc(origSize + s_fixEntryNum * sizeof(s_fixEntry[0])));
\r
336 if (fixMap == NULL) {
\r
341 memcpy_s(fixMap, origSize + s_fixEntryNum, origMap, origSize);
\r
346 fixSize = sizeof(ScancodeMap);
\r
347 fixMap = reinterpret_cast<ScancodeMap*>(malloc(sizeof(ScancodeMap) + s_fixEntryNum * sizeof(s_fixEntry[0])));
\r
348 if (fixMap == NULL) {
\r
353 fixMap->header1 = 0;
\r
354 fixMap->header2 = 0;
\r
356 fixMap->entry[0] = 0;
\r
359 for (DWORD i = 0; i < s_fixEntryNum; i++) {
\r
363 for (DWORD j = 0; j < origMap->count; j++) {
\r
364 if (HIWORD(s_fixEntry[i]) == HIWORD(origMap->entry[j])) {
\r
371 // s_fixEntry[i] found in original Scancode Map, so don't fix it
\r
375 // add fix entry to fixMap
\r
376 fixMap->entry[fixMap->count - 1] = s_fixEntry[i];
\r
377 fixMap->entry[fixMap->count] = 0;
\r
382 ret = reg.write(_T("Scancode Map"), reinterpret_cast<BYTE*>(fixMap), fixSize);
\r
383 if (ret == false) {
\r
391 ret = reg.write(_T("Scancode Map"), reinterpret_cast<BYTE*>(origMap), origSize);
\r
393 ret = reg.remove(_T("Scancode Map"));
\r
395 if (ret == false) {
\r
410 int FixScancodeMap::restore()
\r
415 const DWORD FixScancodeMap::s_fixEntryNum = 4;
\r
416 const DWORD FixScancodeMap::s_fixEntry[] = {
\r