1 #include "fixscancodemap.h"
\r
3 #include "windowstool.h"
\r
5 #include <tlhelp32.h>
\r
7 #pragma runtime_checks( "", off )
\r
8 static DWORD invokeFunc(InjectInfo *info)
\r
13 FpImpersonateLoggedOnUser pImpersonateLoggedOnUser;
\r
14 FpRevertToSelf pRevertToSelf;
\r
15 FpOpenProcessToken pOpenProcessToken;
\r
17 hAdvapi32 = info->pGetModuleHandle(info->advapi32_);
\r
19 pImpersonateLoggedOnUser = (FpImpersonateLoggedOnUser)info->pGetProcAddress(hAdvapi32, info->impersonateLoggedOnUser_);
\r
20 pRevertToSelf = (FpRevertToSelf)info->pGetProcAddress(hAdvapi32, info->revertToSelf_);
\r
21 pOpenProcessToken = (FpOpenProcessToken)info->pGetProcAddress(hAdvapi32, info->openProcessToken_);
\r
23 HANDLE hProcess = info->pOpenProcess(PROCESS_QUERY_INFORMATION, FALSE, info->pid_);
\r
24 if (hProcess == NULL) {
\r
28 ret = pOpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_DUPLICATE , &hToken);
\r
33 ret = pImpersonateLoggedOnUser(hToken);
\r
38 info->pUpdate(0, 1);
\r
40 ret = pRevertToSelf();
\r
45 info->pCloseHandle(hToken);
\r
46 info->pCloseHandle(hProcess);
\r
49 static int afterFunc(int arg)
\r
52 // if this function empty, optimizer unify this with other empty functions.
\r
53 // following code avoid it.
\r
54 arg *= 710810; // non-sense operation
\r
57 #pragma runtime_checks( "", restore )
\r
59 const DWORD FixScancodeMap::s_fixEntryNum = 4;
\r
60 const DWORD FixScancodeMap::s_fixEntry[] = {
\r
67 int FixScancodeMap::acquirePrivileges()
\r
70 HANDLE hToken = NULL;
\r
72 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
\r
78 if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
\r
83 TOKEN_PRIVILEGES tk_priv;
\r
84 tk_priv.PrivilegeCount = 1;
\r
85 tk_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
\r
86 tk_priv.Privileges[0].Luid = luid;
\r
88 if (!AdjustTokenPrivileges(hToken, FALSE, &tk_priv, 0, NULL, NULL)) {
\r
94 if (hToken != NULL) {
\r
95 CloseHandle(hToken);
\r
101 DWORD FixScancodeMap::getWinLogonPid()
\r
104 DWORD mySessionId = 0;
\r
106 if (ProcessIdToSessionId(GetCurrentProcessId(), &mySessionId) == FALSE) {
\r
110 HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
\r
111 if (hSnap == INVALID_HANDLE_VALUE) {
\r
116 pe.dwSize = sizeof(pe);
\r
118 BOOL bResult = Process32First(hSnap, &pe);
\r
120 if (!_tcscmp(pe.szExeFile, _T("winlogon.exe"))) {
\r
123 if (ProcessIdToSessionId(pe.th32ProcessID, &sessionId) != FALSE) {
\r
124 if (sessionId == mySessionId) {
\r
125 pid = pe.th32ProcessID;
\r
130 bResult = Process32Next(hSnap, &pe);
\r
133 CloseHandle(hSnap);
\r
138 int FixScancodeMap::clean()
\r
142 if (WaitForSingleObject(m_hThread, 5000) == WAIT_TIMEOUT) {
\r
147 GetExitCodeThread(m_hThread, &result);
\r
149 CloseHandle(m_hThread);
\r
152 if (m_remoteMem != NULL && m_hProcess != NULL) {
\r
153 VirtualFreeEx(m_hProcess, m_remoteMem, 0, MEM_RELEASE);
\r
154 m_remoteMem = NULL;
\r
157 if (m_remoteInfo != NULL && m_hProcess != NULL) {
\r
158 VirtualFreeEx(m_hProcess, m_remoteInfo, 0, MEM_RELEASE);
\r
159 m_remoteInfo = NULL;
\r
162 if (m_hProcess != NULL) {
\r
163 CloseHandle(m_hProcess);
\r
172 int FixScancodeMap::injectThread(DWORD dwPID)
\r
178 DWORD invokeFuncAddr = (DWORD)invokeFunc;
\r
179 DWORD afterFuncAddr = (DWORD)afterFunc;
\r
180 DWORD memSize = afterFuncAddr - invokeFuncAddr;
\r
182 if (m_hThread != NULL) {
\r
189 if ((m_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) == NULL) {
\r
194 m_remoteMem = VirtualAllocEx(m_hProcess, NULL, memSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
\r
195 if (m_remoteMem == NULL) {
\r
197 err = GetLastError();
\r
201 wFlag = WriteProcessMemory(m_hProcess, m_remoteMem, (char*)invokeFunc, memSize, (SIZE_T*)0);
\r
202 if (wFlag == FALSE) {
\r
207 m_remoteInfo = VirtualAllocEx(m_hProcess, NULL, sizeof(m_info), MEM_COMMIT, PAGE_READWRITE);
\r
208 if (m_remoteInfo == NULL) {
\r
210 err = GetLastError();
\r
214 wFlag = WriteProcessMemory(m_hProcess, m_remoteInfo, (char*)&m_info, sizeof(m_info), (SIZE_T*)0);
\r
215 if (wFlag == FALSE) {
\r
223 _stprintf_s(buf, sizeof(buf)/sizeof(buf[0]),
\r
224 _T("execute UpdatePerUserSystemParameters(), inject code to winlogon.exe?\r\n")
\r
225 _T("invokeFunc=0x%p\r\n")
\r
226 _T("afterFunc=0x%p\r\n")
\r
227 _T("afterFunc - invokeFunc=%d\r\n")
\r
228 _T("remoteMem=0x%p\r\n")
\r
229 _T("remoteInfo=0x%p(size: %d)\r\n"),
\r
230 invokeFunc, afterFunc, memSize, m_remoteMem, m_remoteInfo, sizeof(m_info));
\r
231 if (MessageBox((HWND)NULL, buf, _T("upusp"), MB_OKCANCEL | MB_ICONSTOP) == IDCANCEL) {
\r
232 (m_info.pUpdate)(0, 1);
\r
237 m_hThread = CreateRemoteThread(m_hProcess, NULL, 0,
\r
238 (LPTHREAD_START_ROUTINE)m_remoteMem, m_remoteInfo, 0, NULL);
\r
239 if (m_hThread == NULL) {
\r
244 if (WaitForSingleObject(m_hThread, 5000) == WAIT_TIMEOUT) {
\r
249 GetExitCodeThread(m_hThread, &result);
\r
251 CloseHandle(m_hThread);
\r
255 if (m_remoteMem != NULL && m_hProcess != NULL) {
\r
256 VirtualFreeEx(m_hProcess, m_remoteMem, 0, MEM_RELEASE);
\r
257 m_remoteMem = NULL;
\r
260 if (m_remoteInfo != NULL && m_hProcess != NULL) {
\r
261 VirtualFreeEx(m_hProcess, m_remoteInfo, 0, MEM_RELEASE);
\r
262 m_remoteInfo = NULL;
\r
265 if (m_hProcess != NULL) {
\r
266 CloseHandle(m_hProcess);
\r
274 int FixScancodeMap::update()
\r
276 MINIMIZEDMETRICS mm;
\r
279 result = acquirePrivileges();
\r
285 if ((dwPID = getWinLogonPid()) == 0) {
\r
290 memset(&mm, 0, sizeof(mm));
\r
291 mm.cbSize = sizeof(mm);
\r
292 SystemParametersInfo(SPI_GETMINIMIZEDMETRICS, sizeof(mm), &mm, 0);
\r
294 result = injectThread(dwPID);
\r
295 if (result && m_hThread == NULL) {
\r
299 SystemParametersInfo(SPI_SETMINIMIZEDMETRICS, sizeof(mm), &mm, 0);
\r
305 int FixScancodeMap::fix()
\r
307 ScancodeMap *origMap, *fixMap;
\r
308 DWORD origSize, fixSize;
\r
312 // save original Scancode Map
\r
313 ret = m_pReg->read(_T("Scancode Map"), NULL, &origSize, NULL, 0);
\r
315 origMap = reinterpret_cast<ScancodeMap*>(malloc(origSize));
\r
316 if (origMap == NULL) {
\r
321 ret = m_pReg->read(_T("Scancode Map"), reinterpret_cast<BYTE*>(origMap), &origSize, NULL, 0);
\r
322 if (ret == false) {
\r
327 fixSize = origSize;
\r
328 fixMap = reinterpret_cast<ScancodeMap*>(malloc(origSize + s_fixEntryNum * sizeof(s_fixEntry[0])));
\r
329 if (fixMap == NULL) {
\r
334 memcpy_s(fixMap, origSize + s_fixEntryNum, origMap, origSize);
\r
339 fixSize = sizeof(ScancodeMap);
\r
340 fixMap = reinterpret_cast<ScancodeMap*>(malloc(sizeof(ScancodeMap) + s_fixEntryNum * sizeof(s_fixEntry[0])));
\r
341 if (fixMap == NULL) {
\r
346 fixMap->header1 = 0;
\r
347 fixMap->header2 = 0;
\r
349 fixMap->entry[0] = 0;
\r
352 for (DWORD i = 0; i < s_fixEntryNum; i++) {
\r
356 for (DWORD j = 0; j < origMap->count; j++) {
\r
357 if (HIWORD(s_fixEntry[i]) == HIWORD(origMap->entry[j])) {
\r
364 // s_fixEntry[i] found in original Scancode Map, so don't fix it
\r
368 // add fix entry to fixMap
\r
369 fixMap->entry[fixMap->count - 1] = s_fixEntry[i];
\r
370 fixMap->entry[fixMap->count] = 0;
\r
375 ret = m_pReg->write(_T("Scancode Map"), reinterpret_cast<BYTE*>(fixMap), fixSize);
\r
376 if (ret == false) {
\r
384 ret = m_pReg->write(_T("Scancode Map"), reinterpret_cast<BYTE*>(origMap), origSize);
\r
386 ret = m_pReg->remove(_T("Scancode Map"));
\r
388 if (ret == false) {
\r
403 int FixScancodeMap::restore()
\r
408 FixScancodeMap::FixScancodeMap() :
\r
411 m_remoteInfo(NULL),
\r
413 m_regHKCU(HKEY_CURRENT_USER, _T("Keyboard Layout")),
\r
414 m_regHKLM(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout")),
\r
419 m_info.pid_ = GetCurrentProcessId();
\r
421 memcpy(&m_info.advapi32_, _T("advapi32.dll"), sizeof(m_info.advapi32_));
\r
422 memcpy(&m_info.impersonateLoggedOnUser_, "ImpersonateLoggedOnUser", sizeof(m_info.impersonateLoggedOnUser_));
\r
423 memcpy(&m_info.revertToSelf_, "RevertToSelf", sizeof(m_info.revertToSelf_));
\r
424 memcpy(&m_info.openProcessToken_, "OpenProcessToken", sizeof(m_info.openProcessToken_));
\r
426 hMod = GetModuleHandle(_T("user32.dll"));
\r
427 if (hMod != NULL) {
\r
428 m_info.pUpdate = (FpUpdatePerUserSystemParameters)GetProcAddress(hMod, "UpdatePerUserSystemParameters");
\r
429 if (m_info.pUpdate == NULL) {
\r
434 hMod = GetModuleHandle(_T("kernel32.dll"));
\r
435 if (hMod != NULL) {
\r
436 m_info.pGetModuleHandle = (FpGetModuleHandleW)GetProcAddress(hMod, "GetModuleHandleW");
\r
437 if (m_info.pGetModuleHandle == NULL) {
\r
441 m_info.pGetProcAddress = (FpGetProcAddress)GetProcAddress(hMod, "GetProcAddress");
\r
442 if (m_info.pGetProcAddress == NULL) {
\r
446 m_info.pOpenProcess = (FpOpenProcess)GetProcAddress(hMod, "OpenProcess");
\r
447 if (m_info.pOpenProcess == NULL) {
\r
451 m_info.pCloseHandle = (FpCloseHandle)GetProcAddress(hMod, "CloseHandle");
\r
452 if (m_info.pCloseHandle == NULL) {
\r
457 // Windows7 RC not support Scancode Map on HKCU?
\r
458 if (checkWindowsVersion(6, 1) == FALSE) {
\r
459 m_pReg = &m_regHKCU; // Vista or earlier
\r
461 m_pReg = &m_regHKLM; // Windows7 or later
\r
465 FixScancodeMap::~FixScancodeMap()
\r