看雪论坛
发新帖
1

[原创]我写的模拟挂

asrn 2013-5-7 23:32 48679
发出来,一为抛砖引玉,论坛应该也有很多xd想写外挂,可以参考下;二来想出去找份工作,本人年近30岁,而且还没有编码的工作经验,没有信心,希望大家能给点意见。。
驱动最初参考了http://bbs.pediy.com/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_MOUSECALLBACK     My_MouCallback;         //MouseClassServiceCallback函数

}DEVICE_EXTENSION, *PDEVICE_EXTENSION;

下面是查找KeyboardClassServiceCallback的关键函数,鼠标设备查找方法类似,我合成了一个函数
NTSTATUS GetKmclassInfo(PDEVICE_OBJECT DeviceObject, USHORT Index)
{
    NTSTATUS           status;
    UNICODE_STRING     ObjectName;
    PCWSTR             kmhidName, kmclassName, kmName;
    PVOID              kmDriverStart;
    ULONG              kmDriverSize;
    PVOID*             TargetDeviceObject;
    PVOID*             TargetclassCallback;
    PDEVICE_EXTENSION  deviceExtension;
    PDRIVER_OBJECT     kmDriverObject       = NULL;
    PDRIVER_OBJECT     kmclassDriverObject  = 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;                // 位图像素位指针
        int                cBits;                // 位图每行所用字节总数
        int                cxDib;                // 位图水平像素宽度
        int                cyDib;                // 位图垂直像素高度

        void SetcBits() {cBits = ((cxDib * bmih.biBitCount + 31) & ~31) >> 3;}
        void SetcxDib() {cxDib = bmih.biWidth;}
        void SetcyDib() {cyDib = bmih.biHeight;}
....
}

// 通过窗口图像获取位图信息
Cbm::Cbm(HWND hwndScreen)
{
    HDC     hdc, hdcMem, hdcScreen;
    HBITMAP hBitmap;
    RECT    rect;

    if (!hwndScreen)
    {
        memset(&rect, 0, sizeof(RECT));
        rect.right   = GetSystemMetrics(SM_CXSCREEN);
        rect.bottom  = GetSystemMetrics(SM_CYSCREEN);
    }else
        GetClientRect(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);

    //初始化文件头bmfh
    bmfh.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);
        else
            wsprintf(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;
    else
        bmWnd.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++;
                    }
                    else
                        invalidNum++;

                    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);
            else
                retFileName[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);
        else
            retFileName[0] = '\0';
    }

    return bFind;
}

忘记说了,模拟鼠标移动需要关闭 控制面板->鼠标->指针选项->提高指针精确度  这个选项
整个项目是VS2008创建,驱动工程是通过visualddk的向导添加的。
驱动在XP、win7下测试通过
附件有完整项目的代码
上传的附件:
本主题帖已收到 0 次赞赏,累计¥0.00
最新回复 (67)
4
ycmint 2013-5-7 23:43
2
论坛里有个直接从 鼠标/键盘驱动入手 ,完整模拟一份来进行  模拟点击,效果很好~
1
phpskycn 2013-5-8 00:02
3
求贴名或者地址,有介绍底层的USB键鼠模拟么
2
透明色 2013-5-8 11:14
4
找个八十斤女朋友是骨感,
找个100斤的女朋友是性感,
找个120斤的女朋友是肉感,
找个140斤的女朋友是情感 ,
找个180斤的女朋友,那是幽默感。
永驻零一 2013-5-8 11:34
5
再啰嗦一下
360没有任何明显HOOK的地方 内联的也没有
可是它是怎么防毒的呢

那么 小小的一个西游客户端 这么多年没增加什么内容 体积却越来越大
360体积有多大 对比下 想想吧
你做到多少自我保护

其实你我是同志
我只是好纸上谈兵
1
asrn 2013-5-8 11:58
6
你是说你也好这个吗?
Fido 2013-5-8 14:54
7
膜拜呀...支持一下楼主呀..................
Fido 2013-5-8 14:58
8
你们俩是互相在表白么??能不要搞得这么明显么???

私下联系一下呗...咱聊技术啊..兄弟们啊..
凉风 2013-5-8 15:24
9
都是被某个游戏折磨过的人?
永驻零一 2013-5-8 15:30
10
没错 兄弟们
中午又附加了次DT无双  用工具看不出有明显的H
定时器倒是有7个多
然后下段
就退出了
你能说它没做手脚吗

当年手动双开跑商 不知道是谁他妈玩谁
如今要换回来
不公平
用习总的话说 作为人民 各种不体面 没尊严
永驻零一 2013-5-8 15:32
11
让他们看看
在其淫威下
我们学到了哪些
1
asrn 2013-5-8 15:47
12
那是hook了debugbreakpoint几个函数,这个我知道的
kxzjchen 2013-5-8 16:28
13
楼主牛掰呀
抓到你了,酱油男,咱两也私下聊聊啊
1
asrn 2013-5-8 16:37
14
我是半吊子,发这个主要想请大家帮忙鉴别下,我这编码水平能否找份合适的码农工作?
hemdacker 2013-5-8 16:56
15
在一起~~在一起~~
fiorentina 2013-5-8 17:15
16
纯技术学习啊
2
liuqiangni 2013-5-8 17:18
17
给个连接吧! 需要的童鞋,就看看吧.
http://bbs.pediy.com/showthread.php?t=74327&highlight=winIo
永驻零一 2013-5-8 17:43
18
奴隶们~
复活吧~
We are FREE!
dayang 2013-5-8 19:42
19
如果体重超过220斤的呢?
樊辉 2013-5-8 22:31
20
那将会有恐惧感。。。
troops 2013-5-9 00:21
21
mark。。。。。。。。。。
ebookread 2013-5-9 07:34
22
下了学习一下
foolday 2013-5-10 01:10
23
mark,thx for sharing
boainfall 2013-5-10 19:51
24
驱动级的能最小化窗口不
凉风 2013-5-10 20:25
25
驱动级的只能最前台
zyicai 2013-5-11 09:39
26
正在学习驱动,标记一下
welcomeg 2013-5-11 10:39
27
值得学习!
harrypaul 2013-5-11 23:17
28
果然都是高手!
小龙飞 2013-5-12 20:37
29
mark一下 刚好在做相关方面的研究 感谢楼主分享
sdrjfzg 2013-5-13 00:58
30
果然是极好的。
codeape 2013-5-14 13:46
31
目测:循环太深了啊,容易挨骂
hovey 2013-5-17 17:27
32
学习一下源码
timiil 2013-5-28 17:36
33
在win8下运行PreDemo.exe 提示驱动加载失败
请问是如何?
1
asrn 2013-5-28 19:36
34
不清楚win8的驱动加载要求,可能和win7 64位一样需要微软认证文件签名
timiil 2013-5-31 15:03
35
老兄有没有可能弄一个inf形式的驱动? 我用的确实是win8 64位的系统来测试:)
1
asrn 2013-6-2 11:21
36
与那个没有关系,inf的安装形式一样需要签名验证的。
wwwshast 2013-6-2 16:45
37
不错,下来学习下
最爱小铅 2013-6-4 11:07
38
学习一下,楼主代码风格还不错,能看的进去
tigerwood 2013-6-17 13:49
39
下载了代码,无法编译通过,NTDDK找不到,我用了绝对路径都找不到,求助,汗。。。
汀雨如炎 2013-6-18 21:53
40
如果你装了DDK的话,那就是没设置环境变量。
天地人一 2013-6-27 17:11
41
模拟挂..不错,,有时间我也模拟你一个,呵呵
vincentpra 2013-8-14 00:27
42
你好,对你的模拟鼠标/键盘的文章很感兴趣,我觉得这应该是一个切入驱动学习的很好的例子,我下载了附件后,使用VS2008打开工程以后,可以顺利的编译出kmclass.sys, 然后我找了一个通用的安装驱动的工具安装这个驱动,把这个驱动安装在VMWARE的虚拟机上面,系统是WIN XP SP3,使用debugview观察,发现出现错误:

KEYBOARD_DEVICE ERROR, error = 0xc0000001

我加入打印后发现,是kmclass.cpp文件的第259行的变量kmDeviceObject为NULL导致返回“STATUS_UNSUCCESSFUL”。
在真实的WIN XP SP3的机器上面是完全可以运行的,可以找到鼠标和键盘的地址。
是不是虚拟机里面 有什么不一样的地方?
另外我运行了你的附件里面的Debug和Relase里面的可执行程序在虚拟机里面,发现都不能运行,不知道为什么。
另外我还有一个问题,这个驱动支持WIN 7 64位吗?我还没有来的级测试。据说WIN 7 安装驱动要什么签名,请问用什么工具来安装你这个驱动呢?
由于是初学者,一下问了这么多问题,希望见谅,谢谢!
panti 2013-8-14 08:00
43
这个驱动没用的,慢
vincentpra 2013-8-24 22:29
44
为了让这个驱动支持win7 64位,需要把kmDeviceExtension[i + 1]变成kmDeviceExtension[i + 2]即可,就可以顺利找到键盘和鼠标的回调地址,然后把这个驱动编译成win 7 64位的,运行在虚拟机上面后,使用应用层模拟发送一个键盘按键消息,结果蓝屏,使用windbg调试了半天,百思不得其解,错误如下:
kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

SYSTEM_SERVICE_EXCEPTION (3b)
An exception happened while executing a system service routine.
Arguments:
Arg1: 00000000c0000005, Exception code that caused the bugcheck
Arg2: 0000000005131990, Address of the instruction which caused the bugcheck
Arg3: fffff8800367bf00, Address of the context record for the exception that caused the bugcheck
Arg4: 0000000000000000, zero.

其他的没有贴
我想问下大牛们,是不是WIN 7 64 位不支持直接调用kbdclass的回调函数模拟键盘消息?
谢谢啊
1
asrn 2013-8-25 13:13
45
[QUOTE=vincentpra;1214204]为了让这个驱动支持win7 64位,需要把kmDeviceExtension[i + 1]变成kmDeviceExtension[i + 2]即可,就可以顺利找到键盘和鼠标的回调地址,然后把这个驱动编译成win 7 64位的,运行在虚拟机上面后,使用应用层模拟发送一个键盘按键消息,结果蓝屏,使用wi...[/QUOTE]

没有试过64位系统,XP和win732位没有问题。你要让生成的exe文件直接在虚拟机里面运行,请在vs中选择项目->项目属性->配置属性->常规->MFC的使用中选择静态链接MFC
vincentpra 2013-8-26 12:20
46
嗯,windows XP sp3和win7 32位我测试过没有问题,就是在win 7 64为上面出现了问题。
你附的那个应用程序的控制程序我编译用VC2008编译不通过,出现了一大堆错误,不知道怎么搞的,应该是我环境给的问题吧,我暂时没有管,然后我自己模拟你的源代码写了一个的发送IOCTL的上层调用驱动的程序。
对于64位我还真不知道怎么调试,你可以帮我指导下后续如何调试这个蓝屏呢?
谢谢!
我的QQ:1067739461
chengqiyan 2013-8-27 20:11
47
写的还可以   鼠标模拟可以再优化下 先SetPos 再交给驱动
1
wjshome 2013-8-28 12:40
48
强帖, mark。
fanshulin 2013-8-28 23:54
49
很好,mark搜藏,支持楼主
chilun 2013-9-6 17:55
50
标记一下
返回



©2000-2017 看雪学院 | Based on Xiuno BBS | 微信公众号:ikanxue
Time: 0.016, SQL: 10 / 京ICP备10040895号-17