900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > [转] 驱动模拟键盘鼠标

[转] 驱动模拟键盘鼠标

时间:2021-06-13 20:12:48

相关推荐

[转] 驱动模拟键盘鼠标

标 题: 【原创】我写的模拟挂作 者: asrn时 间: -05-07,23:32:09链 接: /showthread.php?t=171203发出来,一为抛砖引玉,论坛应该也有很多xd想写外挂,可以参考下;二来想出去找份工作,本人年近30岁,而且还没有编码的工作经验,没有信心,希望大家能给点意见。。驱动最初参考了/showthread.php?t=101653中的代码,因为是根据特征码搜索,不爽,后面又根据寒江独钓中的代码作了修改(这里要澄清下,不是为寒江独钓打广告,反而我觉得那书写得不清不楚的)。原理:通过直接调用Kbdclass的回调函数KeyboardClassServiceCallback直接给上层发送键盘驱动,就可以实现模拟键盘操作,鼠标类似。通过windbg查看类设备下面的端口设备(i8042prt)或usb设备(kbdhid),其设备对象中的DeviceExtension里面保存了设备对象与KeyboardClassServiceCallback回调函数,设备对象保存在回调函数前面一个地址中。这个是驱动扩展结构,用来保存查找到的设备对象和回调函数,避免直接使用全局变量typedef struct _DEVICE_EXTENSION {PDEVICE_OBJECT kbdDeviceObject; //键盘类设备对象PDEVICE_OBJECT mouDeviceObject; //鼠标类设备对象MY_KEYBOARDCALLBACK My_KbdCallback; //KeyboardClassServiceCallback函数 MY_MOUSECALLBACKMy_MouCallback; //MouseClassServiceCallback函数}DEVICE_EXTENSION, *PDEVICE_EXTENSION;下面是查找KeyboardClassServiceCallback的关键函数,鼠标设备查找方法类似,我合成了一个函数NTSTATUS GetKmclassInfo(PDEVICE_OBJECT DeviceObject, USHORT Index){NTSTATUS status;UNICODE_STRINGObjectName;PCWSTR kmhidName, kmclassName, kmName;PVOID kmDriverStart;ULONG kmDriverSize;PVOID* TargetDeviceObject;PVOID* TargetclassCallback;PDEVICE_EXTENSION deviceExtension;PDRIVER_OBJECTkmDriverObject = NULL;PDRIVER_OBJECTkmclassDriverObject = NULL;deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;switch(Index){case KEYBOARD_DEVICE:kmName = L"kbd";kmhidName = L"\\Driver\\kbdhid";kmclassName = L"\\Driver\\kbdclass";TargetDeviceObject = (PVOID*)&(deviceExtension->kbdDeviceObject);TargetclassCallback = (PVOID*)&(deviceExtension->My_KbdCallback);break;case MOUSE_DEVICE:kmName = L"mou";kmhidName = L"\\Driver\\mouhid";kmclassName = L"\\Driver\\mouclass";TargetDeviceObject = (PVOID*)&(deviceExtension->mouDeviceObject);TargetclassCallback = (PVOID*)&(deviceExtension->My_MouCallback);break;default:return STATUS_INVALID_PARAMETER;}// 通过USB类设备获取驱动对象RtlInitUnicodeString(&ObjectName, kmhidName);status = ObReferenceObjectByName(&ObjectName,OBJ_CASE_INSENSITIVE,NULL,FILE_READ_ACCESS,*IoDriverObjectType,KernelMode,NULL,(PVOID*)&kmDriverObject);if(!NT_SUCCESS(status)){// 通过i8042prt获取驱动对象RtlInitUnicodeString(&ObjectName, L"\\Driver\\i8042prt");status = ObReferenceObjectByName(&ObjectName,OBJ_CASE_INSENSITIVE,NULL, FILE_READ_ACCESS,*IoDriverObjectType,KernelMode,NULL,(PVOID*)&kmDriverObject);if(!NT_SUCCESS(status)){KdPrint(("Couldn't Get the i8042prt Driver Object\n"));return status;}}// 通过kmclass获取键盘鼠标类驱动对象RtlInitUnicodeString(&ObjectName, kmclassName);status = ObReferenceObjectByName(&ObjectName,OBJ_CASE_INSENSITIVE,NULL,FILE_READ_ACCESS,*IoDriverObjectType,KernelMode,NULL,(PVOID*)&kmclassDriverObject);if(!NT_SUCCESS(status)){KdPrint(("Couldn't Get the kmclass Driver Object\n"));return status;}else{kmDriverStart = kmclassDriverObject->DriverStart;kmDriverSize = kmclassDriverObject->DriverSize;}ULONG DeviceExtensionSize;PULONG kmDeviceExtension;PDEVICE_OBJECT kmTempDeviceObject;PDEVICE_OBJECT kmclassDeviceObject;PDEVICE_OBJECT kmDeviceObject = kmDriverObject->DeviceObject;while (kmDeviceObject){kmTempDeviceObject = kmDeviceObject;while (kmTempDeviceObject){kmDeviceExtension = (PULONG)kmTempDeviceObject->DeviceExtension;kmclassDeviceObject = kmclassDriverObject->DeviceObject;DeviceExtensionSize = ((ULONG)kmTempDeviceObject->DeviceObjectExtension - (ULONG)kmTempDeviceObject->DeviceExtension) / 4;while (kmclassDeviceObject){for (ULONG i = 0; i < DeviceExtensionSize; i++){if (kmDeviceExtension[i] == (ULONG)kmclassDeviceObject &&kmDeviceExtension[i + 1] > (ULONG)kmDriverStart &&kmDeviceExtension[i + 1] < (ULONG)kmDriverStart + kmDriverSize){// 将获取到的设备对象保存到自定义扩展设备结构*TargetDeviceObject = (PVOID)kmDeviceExtension[i];*TargetclassCallback = (PVOID)kmDeviceExtension[i + 1];KdPrint(("%SDeviceObject == 0x%x\n", kmName, kmDeviceExtension[i]));KdPrint(("%SClassServiceCallback == 0x%x\n", kmName, kmDeviceExtension[i + 1]));return STATUS_SUCCESS;}}kmclassDeviceObject = kmclassDeviceObject->NextDevice;}kmTempDeviceObject = kmTempDeviceObject->AttachedDevice;}kmDeviceObject = kmDeviceObject->NextDevice;}return STATUS_UNSUCCESSFUL;}应用层模拟键盘操作函数BOOL KeyboardButton(USHORT VirtualKey, USHORT Flags){KEYBOARD_INPUT_DATA kid ;DWORD dwOutput;HANDLE hDevice = CreateFile(KEYMOUSE_WIN32_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hDevice == INVALID_HANDLE_VALUE)return FALSE;memset(&kid, 0, sizeof(KEYBOARD_INPUT_DATA));kid.Flags = Flags;kid.MakeCode = (USHORT)MapVirtualKey(VirtualKey, 0);BOOL bRet = DeviceIoControl(hDevice, IOCTL_KEYBOARD, &kid, sizeof(KEYBOARD_INPUT_DATA), NULL, 0, &dwOutput, NULL);if (!bRet)TRACE(_T("Error! please open the simulate kmclass driver!\n"));CloseHandle(hDevice);return bRet;}模拟鼠标的函数BOOL MouseMove(LONG dx, LONG dy, USHORT Flags){MOUSE_INPUT_DATA mid ;DWORD dwOutput;HANDLE hDevice = CreateFile(KEYMOUSE_WIN32_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hDevice == INVALID_HANDLE_VALUE)return FALSE;memset(&mid, 0, sizeof(MOUSE_INPUT_DATA));mid.Flags = Flags;switch (mid.Flags){case MOUSE_MOVE_RELATIVE:mid.LastX = dx;mid.LastY = dy;break;case MOUSE_MOVE_ABSOLUTE:mid.LastX = dx * 0xffff / GetSystemMetrics(SM_CXSCREEN);mid.LastY = dy * 0xffff / GetSystemMetrics(SM_CYSCREEN);break;default:TRACE(_T("Flags: Parameter error!\n"));return FALSE;}BOOL bRet = DeviceIoControl(hDevice, IOCTL_MOUSE, &mid, sizeof(MOUSE_INPUT_DATA), NULL, 0, &dwOutput, NULL);if (!bRet)TRACE(_T("Error! please start the kmclass driver!\n"));CloseHandle(hDevice);return bRet;}另外一个是前台窗口找图的实现bmp类定义class Cbm {private:BITMAPFILEHEADER bmfh; // 位图文件头BITMAPINFOHEADER bmih; // 位图信息头PBYTE pBits;// 位图像素位指针intcBits;// 位图每行所用字节总数intcxDib;// 位图水平像素宽度intcyDib;// 位图垂直像素高度void SetcBits() {cBits = ((cxDib * bmih.biBitCount + 31) & ~31) >> 3;}void SetcxDib() {cxDib = bmih.biWidth;}void SetcyDib() {cyDib = bmih.biHeight;}....}// 通过窗口图像获取位图信息Cbm::Cbm(HWND hwndScreen){HDChdc, hdcMem, hdcScreen;HBITMAP hBitmap;RECT rect;if (!hwndScreen){memset(&rect, 0, sizeof(RECT));rect.right = GetSystemMetrics(SM_CXSCREEN);rect.bottom = GetSystemMetrics(SM_CYSCREEN);}elseGetClientRect(hwndScreen, &rect); //获得截图窗口的范围大小hdc= GetDC(NULL);hdcMem = CreateCompatibleDC(hdc);hBitmap = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top);SelectObject(hdcMem, hBitmap);hdcScreen = GetDC(hwndScreen);BitBlt(hdcMem, 0, 0, rect.right - rect.left, rect.bottom - rect.top, hdcScreen, 0, 0, SRCCOPY);DeleteDC(hdcMem);ReleaseDC(hwndScreen, hdcScreen);//初始化信息头bmi结构memset(&bmih, 0, sizeof(BITMAPINFOHEADER));bmih.biSize = sizeof(BITMAPINFOHEADER);bmih.biWidth = rect.right - rect.left;bmih.biHeight= rect.bottom - rect.top;bmih.biBitCount = 24;bmih.biCompression = BI_RGB;bmih.biPlanes= 1;SetcxDib();SetcyDib();SetcBits();//获取pBits的值pBits = new BYTE [cBits * cyDib];GetDIBits(hdc, hBitmap, 0, cyDib, pBits, (LPBITMAPINFO)&bmih, DIB_RGB_COLORS);//初始化文件头bmfhbmfh.bfType= 0x4D42;bmfh.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + cBits * cyDib;bmfh.bfReserved1 = 0;bmfh.bfReserved2 = 0;bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);ReleaseDC(NULL, hdc);DeleteObject(hBitmap);}// 通过加载文件获取位图信息Cbm::Cbm(PCTSTR FilePath){HANDLE hFile = CreateFile(FilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);if (hFile == INVALID_HANDLE_VALUE){pBits = NULL;TRACE(_T("read file failed. FileName: %s\n"), FilePath);return;}DWORD dwBytesRead;if ( !(ReadFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL) &&ReadFile(hFile, &bmih, sizeof(BITMAPINFOHEADER), &dwBytesRead, NULL) &&bmfh.bfType == 0x4D42) ){pBits = NULL;TRACE(_T("read file failed. FileName: %s\n"), FilePath);CloseHandle(hFile);return;}SetcxDib();SetcyDib();SetcBits();pBits = new BYTE [cBits * cyDib];if (!ReadFile(hFile, pBits, cBits * cyDib, &dwBytesRead, NULL)){delete [] pBits;pBits = NULL;TRACE(_T("read file failed. FileName: %s\n"), FilePath);}CloseHandle(hFile);}// 保存位图到文件BOOL Cbm::SaveBitmapToFile(PCTSTR FileName, LPCRECT pRect) const{ASSERT(pBits);TCHAR FilePath[MAX_PATH], DefaultFileName[MAX_PATH];//创建以系统时间命名的bmp文件 SYSTEMTIME time;GetLocalTime(&time);wsprintf(DefaultFileName, _T("%04u%02u%02u%02u%02u%02u%03u.bmp"),time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds);//修正保存路径,默认保存至当前程序目录Screen文件夹if (!FileName)wsprintf(FilePath, _T("%s\\%s"), _T("screen"), DefaultFileName);else{if (FileName[1] == ':')_tcscpy_s(FilePath, FileName);elsewsprintf(FilePath, _T("%s\\%s"), _T("screen"), FileName);if (FileName[lstrlen(FileName) - 1] == '\\' || FileName[lstrlen(FileName) - 1] == '/')_tcscat_s(FilePath, MAX_PATH, DefaultFileName);}// 判断文件路径是否有效,无效则创建路径中没有的文件夹if (!PathIsDirectory(FilePath))CreateFolder(FilePath);//保存数据HANDLE hFile = CreateFile(FilePath, GENERIC_WRITE, 0 ,NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INVALID_HANDLE_VALUE)return FALSE;DWORD dwBytesWritten;Cbm bmFile(*this, pRect);BOOL bSuccess = WriteFile(hFile, &bmFile.bmfh, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL) &&WriteFile(hFile, &bmFile.bmih, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL) &&WriteFile(hFile, bmFile.pBits, bmFile.cBits * bmFile.cyDib, &dwBytesWritten, NULL);CloseHandle(hFile);if (!bSuccess)DeleteFile(FilePath);return bSuccess;}找图函数BOOL FindPic(const Cbm & bmWnd, const Cbm & bmFile, LPCRECT rectTarget, OUT PRECT retRect, int resemble, COLORREF rgb){if (!(bmFile.pBits && bmWnd.pBits) || bmFile.cxDib > bmWnd.cxDib || bmFile.cyDib > bmWnd.cyDib)return FALSE;resemble = max(resemble, 0);resemble = min(resemble, 100);BYTE r = GetRValue(rgb);BYTE g = GetGValue(rgb);BYTE b = GetBValue(rgb);// 实际范围 RECT rectDefault;if (rectTarget && bmWnd.IsInRect(*rectTarget))rectDefault = *rectTarget;elsebmWnd.GetBitmapRect(rectDefault);// bmFile图像坐标(x, y), bmWnd图像坐标(x + xOffset, y + yOffset)int yTotal = rectDefault.bottom - bmFile.cyDib;int xTotal = rectDefault.right - bmFile.cxDib;int invalidTotal = (100 - resemble) * (bmFile.cxDib * bmFile.cyDib);int validTotal = resemble * (bmFile.cxDib * bmFile.cyDib);// ignoreNum忽略值, validNum有效值,invalidNum无效值int invalidNum = 0, validNum = 0, ignoreNum = 0;for (int yOffset = rectDefault.top; yOffset <= yTotal; yOffset++)for (int xOffset = rectDefault.left; xOffset <= xTotal; xOffset++){for (int y = 0, bflag = TRUE; bflag && (y < bmFile.cyDib); y++)for (int x = 0; x < bmFile.cxDib; x++){int FileIndex = (bmFile.cyDib - 1 - y) * bmFile.cBits + 3 * x;int WndIndex = (bmWnd.cyDib - 1 - yOffset - y) * bmWnd.cBits + 3 * (xOffset + x);if (r == bmFile.pBits[FileIndex + 2] &&g == bmFile.pBits[FileIndex + 1] &&b == bmFile.pBits[FileIndex]&&0xF8 != bmWnd.pBits[WndIndex + 2] &&0xFC != bmWnd.pBits[WndIndex + 1] &&0xF8 != bmWnd.pBits[WndIndex]) {ignoreNum++;} else if (bmFile.pBits[FileIndex + 2] == bmWnd.pBits[WndIndex + 2] &&bmFile.pBits[FileIndex + 1] == bmWnd.pBits[WndIndex + 1] &&bmFile.pBits[FileIndex] == bmWnd.pBits[WndIndex]) {validNum++;}elseinvalidNum++;if (100 * invalidNum > invalidTotal){invalidNum = validNum = ignoreNum = 0;bflag = FALSE;break;}if (100 * (validNum + ignoreNum) >= validTotal){if (retRect){retRect->left = xOffset;retRect->top = yOffset;retRect->right = xOffset + bmFile.cxDib;retRect->bottom = yOffset + bmFile.cyDib;}return TRUE;}}}return FALSE;}多图查找函数BOOL FindSomePic(const Cbm & bmWnd, PCTSTR FileName, LPCRECT rectTarget, PRECT retRect, PTSTR retFileName, int resemble, COLORREF rgb){WIN32_FIND_DATA fData;BOOL bFind = FALSE;TCHAR FilePath[MAX_PATH];TCHAR FileDir[MAX_PATH];_tcscpy_s(FilePath, MAX_PATH, FileName);_tcscpy_s(FileDir, MAX_PATH, FileName);if (FileName[lstrlen(FileName) - 1] == '\\')_tcscat_s(FilePath, MAX_PATH, _T("*.bmp"));else if (_tcschr(FileName, '*'))_tcsrchr(FileDir, '\\')[1] = '\0';else{bFind = FindPic(bmWnd, FileName, rectTarget, retRect, resemble, rgb);if (retFileName){if (bFind)_tcscpy_s(retFileName, MAX_PATH, FileName);elseretFileName[0] = '\0';}return bFind;}HANDLE hFile = FindFirstFile(FilePath, &fData);if (hFile == INVALID_HANDLE_VALUE){TRACE(_T("FindSomePic --- read file failed.\n"));return FALSE;}do{wsprintf(FilePath, _T("%s%s"), FileDir, fData.cFileName);bFind = FindPic(bmWnd, FilePath, rectTarget, retRect, resemble, rgb);}while (!bFind && FindNextFile(hFile, &fData));FindClose(hFile);if (retFileName){if (bFind)_tcscpy_s(retFileName, MAX_PATH, fData.cFileName);elseretFileName[0] = '\0';}return bFind;}忘记说了,模拟鼠标移动需要关闭 控制面板->鼠标->指针选项->提高指针精确度 这个选项整个项目是VS创建,驱动工程是通过visualddk的向导添加的。驱动在XP、win7下测试通过附件有完整项目的代码

/showthread.php?t=171203

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。