首页
社区
课程
招聘
[求助]Inline hook KeyboardClassServiceCallback的问题
发表于: 2009-2-9 15:24 10446

[求助]Inline hook KeyboardClassServiceCallback的问题

2009-2-9 15:24
10446
最近学一下hook ,初试hook KeyboardClassServiceCallback ,但是遇到点问题.调试一下午,不知道怎么弄?
下面贴上部分源代码:
__declspec(naked)
VOID
Froxy_KeyboardClassServiceCallback(
                                                                   PDEVICE_OBJECT pDeviceObject,
                                                                   PKEYBOARD_INPUT_DATA InputDataStart,
                                                                   PKEYBOARD_INPUT_DATA InputDataEnd,
                                                                   PULONG InputDataConsumed
                                                                   )
{
        _asm
        {
                _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90 //填充Jmp
                        _emit 0x90   
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90 //因为是长转移,所以必须是0x0080
        }
}

void
fake_KeyboardClassServiceCallback(IN  PDEVICE_OBJECT      pDeviceObject,
                                                                  IN PKEYBOARD_INPUT_DATA InputDataStart,
                                                                  IN PKEYBOARD_INPUT_DATA InputDataEnd,
                                                                  IN OUT PULONG InputDataConsumed
                                                                  )
{
        PShareMemory Scan = (PShareMemory)g_ShareMem;
        /*
        if(g_pReadReady == NULL || g_pReadFinish == NULL)
                goto _x_;
                */
        if(InputDataStart->Flags == KEY_MAKE || InputDataStart->Flags == KEY_E0)
        {
                RtlCopyMemory(Scan->Code,&InputDataStart->MakeCode,1);
                dprintf("ScanCode is %d\n",Scan->Code[0]);
        }
        _asm
        {
                jmp Froxy_KeyboardClassServiceCallback
        }
}

void
InlineHookkbClassServiceCallback()
{
        KIRQL Irql;
        BYTE JmpCodes[7] ={0xEA,0,0,0,0,0x08,0x00},InlineCodes[5] = {0xe9,0x00,0x00,0x00,0x00};
        dprintf("==>进入 InlineHookkbClassServiceCallback 例程\n");
    RtlCopyMemory(g_OrigCodes,(BYTE *)OldKbClassServiceCallbackAddr,5);
        *((ULONG *)(InlineCodes+1)) = (ULONG)fake_KeyboardClassServiceCallback - (ULONG)OldKbClassServiceCallbackAddr - 5;
   
        //关闭保护模式
        _asm
        {
                cli
                        mov eax,cr0
                        and eax,not 10000h
                        mov cr0,eax
        }

        //提升Iqrl到Dpc
        Irql = KeRaiseIrqlToDpcLevel();
        RtlCopyMemory((BYTE *)OldKbClassServiceCallbackAddr,InlineCodes,5);
        *((ULONG *)(JmpCodes + 1)) = (ULONG)((BYTE *)OldKbClassServiceCallbackAddr+5);

        RtlCopyMemory((BYTE *)Froxy_KeyboardClassServiceCallback, g_OrigCodes, 5);
        RtlCopyMemory((BYTE *)Froxy_KeyboardClassServiceCallback+5 , JmpCodes, 7);

        //将Irql置成原来的Level
        KeLowerIrql(Irql);

        //开启保护模式
        _asm
        {
                mov eax,cr0
                        or eax,10000h
                        mov cr0,eax
                        sti
        }
        dprintf("<==退出 InlineHookkbClassServiceCallback 例程\n");
}

调试发现,获取的扫描码是正确的,但是jmp到Froxy_KeyboardClassServiceCallback里,再jmp到原函数(KeyboardClassServiceCallback)的时候出错了.
出错位置为:KeyboardClassDequeueRead + 0x14

部分kbdclass.c源码
VOID
KeyboardClassServiceCallback(
    IN PDEVICE_OBJECT DeviceObject,
    IN PKEYBOARD_INPUT_DATA InputDataStart,
    IN PKEYBOARD_INPUT_DATA InputDataEnd,
    IN OUT PULONG InputDataConsumed
    )
{
    PDEVICE_EXTENSION deviceExtension;
    PIO_STACK_LOCATION irpSp;
    LIST_ENTRY listHead;
    PIRP  irp;
    ULONG bytesInQueue;
    ULONG bytesToMove;
    ULONG moveSize;
    ULONG dumpData[2];
    BOOLEAN logOverflow;

    KbdPrint((2,"KBDCLASS-KeyboardClassServiceCallback: enter\n"));

    deviceExtension = DeviceObject->DeviceExtension;
    bytesInQueue = (ULONG)((PCHAR) InputDataEnd - (PCHAR) InputDataStart);
    moveSize = 0;
    *InputDataConsumed = 0;

    logOverflow = FALSE;

    //
    // Notify system that human input has occured
    //

    PoSetSystemState (ES_USER_PRESENT);

    //
    // N.B. We can use KeAcquireSpinLockAtDpcLevel, instead of
    //      KeAcquireSpinLock, because this routine is already running
    //      at DISPATCH_IRQL.
    //

    KeAcquireSpinLockAtDpcLevel (&deviceExtension->SpinLock);

    InitializeListHead (&listHead);
    irp = KeyboardClassDequeueRead (deviceExtension);
    if (irp) {
        //
        // An outstanding read request exists.
        //
        // Copy as much of the input data possible from the port input
        // data queue to the SystemBuffer to satisfy the read.
        //
        irpSp = IoGetCurrentIrpStackLocation (irp);
        bytesToMove = irpSp->Parameters.Read.Length;
        moveSize = (bytesInQueue < bytesToMove) ?
                                   bytesInQueue:bytesToMove;
        *InputDataConsumed += (moveSize / sizeof(KEYBOARD_INPUT_DATA));

KeyboardClassDequeueRead函数部分源码:
PIRP
KeyboardClassDequeueRead(
    IN PDEVICE_EXTENSION DeviceExtension
    )
/*++

Routine Description:
    Dequeues the next available read irp regardless of FileObject

Assumptions:
    DeviceExtension->SpinLock is already held (so no further sync is required).

  --*/
{
    PIRP nextIrp = NULL;
    KIRQL oldIrql;

    while (!nextIrp && !IsListEmpty (&DeviceExtension->ReadQueue)){
        PDRIVER_CANCEL oldCancelRoutine;
        PLIST_ENTRY listEntry = RemoveHeadList (&DeviceExtension->ReadQueue);

        //
        // Get the next IRP off the queue and clear the cancel routine
        //
        nextIrp = CONTAINING_RECORD (listEntry, IRP, Tail.Overlay.ListEntry);
        oldCancelRoutine = IoSetCancelRoutine (nextIrp, NULL);

我初步认为出错在while (!nextIrp && !IsListEmpty (&DeviceExtension->ReadQueue))这句,但是不知道怎么改.
望大牛们,解惑一下,谢谢.

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 364
活跃值: (152)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
2
你的fake_KeyboardClassServiceCallback把堆栈破坏了吧?
2009-2-10 18:17
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
3
人家有好好的object hook你不用,用什么INLINE HOOK~
2009-2-10 18:26
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
也有人在研究,我贴上我的代码吧,我测试已经好了。我的问题就在于模拟键盘部分。。。一直在蓝。代码参考sudami的,希望他出来指导指导。。。

//==========================KbdClassCallBack
int Get_KbdClass_Base()
{
        g_kbdclass_base = (ULONG)GetModlueBaseAdress( "kbdclass.sys",0 );
        DbgPrint("kbdclass.sys: 0x%08lx\n", (PVOID)g_kbdclass_base);

        if ( g_kbdclass_base )
        {
                curAddr = g_kbdclass_base;
                for (icurAddr=curAddr;icurAddr<=curAddr+0x3000;icurAddr++)
                {
                        if (*((ULONG *)icurAddr)==code1_sp2)
                        {
                                if (*((ULONG *)(icurAddr+4))==code2_sp2)
                                {
                                        if (*((ULONG *)(icurAddr+8))==code3_sp2)
                                        {
                                                if (*((ULONG *)(icurAddr+12))==code4_sp2)
                                                {
                                                        KbdClass=icurAddr;
                                                        orig_KeyboardClassServiceCallback = (KEYBOARDCLASSSERVICECALLBACK)(KbdClass);
                                                        DbgPrint("KeyboardClassServiceCallback: 0x%08lx\n", (PVOID)KbdClass);
                                                        return 1;
                                                }
                                        }
                                }
                        }
                }

        }
        else
        {       
                DbgPrint("ERROR: g_kbdclass_base == 0\n");
        }       
        return 0;
};

__declspec (naked)
NTSTATUS
Proxy_KbdClass(
                           PDEVICE_OBJECT  DeviceObject,
                           PKEYBOARD_INPUT_DATA  InputDataStart,
                           PKEYBOARD_INPUT_DATA  InputDataEnd,
                           PULONG  InputDataConsumed)
{
        __asm {  // 共12字节
                _emit 0x8b
                        _emit 0xff
                        _emit 0x55
                        _emit 0x8b
                        _emit 0xec  // 前5字节实现原函数的头5字节功能
                        _emit 0xe9  // 这个填充jmp
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90
                        _emit 0x90  // 这4字节保存原函数+5处的地址
                        _emit 0x90
                        _emit 0x90  // 因为是长转移,所以必须是 0x0080
        }
};

NTSTATUS
My_KbdClass_func(
                                 PDEVICE_OBJECT  DeviceObject,
                                 PKEYBOARD_INPUT_DATA  InputDataStart,
                                 PKEYBOARD_INPUT_DATA  InputDataEnd,
                                 PULONG  InputDataConsumed)
{
        //KEYBOARD_INPUT_DATA
        //UnitId
        //MakeCode
        //Flags
        //Reserved
        //ExtraInformation

        //if(InputDataStart->Flags==KEY_E0&&InputDataStart->Flags==0) //当按下的时候
        //{
        //InputDataStart->MakeCode=0;
        //}

        if(InputDataStart->Flags==KEY_MAKE&& InputDataStart->MakeCode)
        {
                switch (InputDataStart->MakeCode)
                {
                case 0x1:
                        DbgPrint("ESC 键被按下CallBack");
                        break;
                case 0x2:
                        if(XydEnabeldProtect==1)
                        {
                                if(XydPw[XydIdPwFlag]=='@')
                                {
                                        XydPw[XydIdPwFlag]='1';
                                        XydIdPwFlag=XydIdPwFlag+1;
                                        InputDataStart->MakeCode=0x2;
                                }
                                else
                                {
                                        for(i=15;i>=XydIdPwFlag;i--)
                                                XydPw[i]=XydPw[i-1];
                                }
                        }
                        DbgPrint("1 键被按下CallBack");
                        break;

                case 0x3:
                        DbgPrint("2 键被按下CallBack");
                        break;

                case 0x4:
                        DbgPrint("3 键被按下CallBack");
                        break;

                case 0x5:
                        DbgPrint("4 键被按下CallBack");
                        break;

                case 0x6:
                        DbgPrint("5 键被按下CallBack");
                        break;

                case 0x7:
                        DbgPrint("6 键被按下CallBack");
                        break;

                case 0x8:
                        DbgPrint("7 键被按下CallBack");
                        break;

                case 0x9:
                        DbgPrint("8 键被按下CallBack");
                        break;

                case 0xA:
                        DbgPrint("9 键被按下CallBack");
                        break;

                case 0xB:
                        DbgPrint("0 键被按下CallBack");
                        break;

                case 0xC:
                        DbgPrint("- 键被按下CallBack");
                        break;
                case 0xD:
                        DbgPrint("= 键被按下CallBack");
                        break;
                case 0xE:
                        if(XydEnabeldProtect==1)
                        {
                                XydIdPwFlag=XydIdPwFlag-1;
                                XydPw[XydIdPwFlag]='0';
                                //InputDataStart->MakeCode=0x2;
                        }
                        DbgPrint("BACKSPACE 键被按下CallBack");
                        break;
                case 0xF:
                        DbgPrint("TAB 键被按下CallBack");
                        break;
                case 0x10:
                        DbgPrint("Q 键被按下CallBack");
                        break;
                case 0x11:
                        DbgPrint("W 键被按下CallBack");
                        break;
                case 0x12:
                        DbgPrint("E 键被按下CallBack");
                        break;
                case 0x13:
                        DbgPrint("R 键被按下CallBack");
                        break;
                case 0x14:
                        DbgPrint("T 键被按下CallBack");
                        break;
                case 0x15:
                        DbgPrint("Y 键被按下CallBack");
                        break;
                case 0x16:
                        DbgPrint("U 键被按下CallBack");
                        break;
                case 0x17:
                        DbgPrint("I 键被按下CallBack");
                        break;
                case 0x18:
                        DbgPrint("O 键被按下CallBack");
                        break;
                case 0x19:
                        DbgPrint("P 键被按下CallBack");
                        break;
                case 0x1A:
                        DbgPrint("[ 键被按下CallBack");
                        break;
                case 0x1B:
                        DbgPrint("] 键被按下CallBack");
                        break;
                case 0x2B:
                        DbgPrint("\\ 键被按下CallBack");
                        break;
                case 0x1D:
                        DbgPrint("LEFT CTRL 键被按下CallBack");
                        break;
                case 0x1E:
                        DbgPrint("A 键被按下CallBack");
                        break;
                case 0x1F:
                        DbgPrint("S 键被按下CallBack");
                        break;
                case 0x20:
                        DbgPrint("D 键被按下CallBack");
                        break;
                case 0x21:
                        DbgPrint("F 键被按下CallBack");
                        break;
                case 0x22:
                        DbgPrint("G 键被按下CallBack");
                        break;
                case 0x23:
                        DbgPrint("H 键被按下CallBack");
                        break;
                case 0x24:
                        DbgPrint("J 键被按下CallBack");
                        break;
                case 0x25:
                        DbgPrint("K 键被按下CallBack");
                        break;
                case 0x26:
                        DbgPrint("L 键被按下CallBack");
                        break;
                case 0x27:
                        DbgPrint("; 键被按下CallBack");
                        break;
                case 0x28:
                        DbgPrint("' 键被按下CallBack");
                        break;
                case 0x29:
                        DbgPrint("` 键被按下CallBack");
                        break;
                case 0x2A:
                        DbgPrint("LEFT SHIFT 键被按下CallBack");
                        break;
                case 0x1C:
                        DbgPrint("ENTER 键被按下CallBack");
                        break;
                case 0x2C:
                        DbgPrint("Z 键被按下CallBack");
                        break;
                case 0x2D:
                        DbgPrint("X 键被按下CallBack");
                        break;
                case 0x2E:
                        DbgPrint("C 键被按下CallBack");
                        break;
                case 0x2F:
                        DbgPrint("V 键被按下CallBack");
                        break;
                case 0x30:
                        DbgPrint("B 键被按下CallBack");
                        break;
                case 0x31:
                        DbgPrint("N 键被按下CallBack");
                        break;
                case 0x32:
                        DbgPrint("M 键被按下CallBack");
                        break;
                case 0x33:
                        DbgPrint(", 键被按下CallBack");
                        break;
                case 0x34:
                        DbgPrint(". 键被按下CallBack");
                        break;
                case 0x35:
                        DbgPrint("/ 键被按下CallBack");
                        break;
                case 0x36:
                        DbgPrint("RIGHT SHIFT 键被按下CallBack");
                        break;
                case 0x37:
                        DbgPrint("* 键被按下CallBack");
                        break;
                case 0x38:
                        DbgPrint("LEFT ALT 键被按下CallBack");
                        break;
                case 0x39:
                        DbgPrint("SPACE 键被按下CallBack");
                        break;
                case 0x3A:
                        DbgPrint("CAP LOCK 键被按下CallBack");
                        break;
                case 0x3B:
                        DbgPrint("F1 键被按下CallBack");
                        break;
                case 0x3C:
                        DbgPrint("F2 键被按下CallBack");
                        break;
                case 0x3D:
                        DbgPrint("F3 键被按下CallBack");
                        break;
                case 0x3E:
                        DbgPrint("F4 键被按下CallBack");
                        break;
                case 0x3F:
                        DbgPrint("F5 键被按下CallBack");
                        break;
                case 0x40:
                        DbgPrint("F6 键被按下CallBack");
                        break;
                case 0x41:
                        DbgPrint("F7 键被按下CallBack");
                        break;
                case 0x42:
                        DbgPrint("F8 键被按下CallBack");
                        break;
                case 0x43:
                        DbgPrint("F9 键被按下CallBack");
                        break;
                case 0x44:
                        DbgPrint("F10 键被按下CallBack");
                        break;
                case 0x45:
                        DbgPrint("NumLock 键被按下CallBack");
                        break;
                case 0x46:
                        DbgPrint("小键盘 / 键被按下CallBack");
                        break;
                case 0x47:
                        DbgPrint("小键盘 7 键被按下CallBack");
                        break;
                case 0x48:
                        DbgPrint("小键盘 8 键被按下CallBack");
                        break;
                case 0x49:
                        DbgPrint("小键盘 9 键被按下CallBack");
                        break;
                case 0x4A:
                        DbgPrint("小键盘 - 键被按下CallBack");
                        break;
                case 0x4B:
                        DbgPrint("小键盘 4 键被按下CallBack");
                        break;
                case 0x4C:
                        DbgPrint("小键盘 5 键被按下CallBack");
                        break;
                case 0x4D:
                        DbgPrint("小键盘 6 键被按下CallBack");
                        break;
                case 0x4E:
                        DbgPrint("小键盘 + 键被按下CallBack");
                        break;
                case 0x4F:
                        DbgPrint("小键盘 1 键被按下CallBack");
                        break;
                case 0x50:
                        DbgPrint("小键盘 2 键被按下CallBack");
                        break;
                case 0x51:
                        DbgPrint("小键盘 3 键被按下CallBack");
                        break;
                case 0x52:
                        DbgPrint("小键盘 0 键被按下CallBack");
                        break;
                case 0x53:
                        DbgPrint("小键盘 . 键被按下CallBack");
                        break;
                case 0x57:
                        DbgPrint("F11 键被按下CallBack");
                        break;
                case 0x58:
                        DbgPrint("F12 键被按下CallBack");
                        break;

                default:
                        DbgPrint("%X CallBack",InputDataStart->MakeCode);
                        break;
                }
        }
        else if(InputDataStart->Flags==KEY_E0 && InputDataStart->MakeCode)
        {
                switch (InputDataStart->MakeCode)
                {
                case 0x48:
                        DbgPrint("↑ 键被按下CallBack");
                        break;
                case 0x50:
                        DbgPrint("↓ 键被按下CallBack");
                        break;
                case 0x4b:
                        DbgPrint("← 键被按下CallBack");
                        XydIdPwFlag=XydIdPwFlag-1;
                        break;
                case 0x4d:
                        DbgPrint("→ 键被按下CallBack");
                        XydIdPwFlag=XydIdPwFlag+1;
                        break;
                default:
                        DbgPrint("%X  CallBack",InputDataStart->MakeCode);
                        break;
                }
        }

        //DbgPrint(" MakeCode: %08X Flags: %08X   ",InputDataStart->MakeCode,InputDataStart->Flags);
        return Proxy_KbdClass(DeviceObject,InputDataStart,InputDataEnd,InputDataConsumed);
};

void My_Hook_KbdClass_code()
{
        BYTE g_HookCode[5] = { 0xe9, 0x00, 0x00, 0x00, 0x00 };
        BYTE jmp_orig_code[7] = { 0xEA, 0, 0, 0, 0, 0x08, 0x00 };
        BYTE g_OrigCode[5]={0x8b,0xff,0x55,0x8b,0xec};

        Key_CallBack_Flag=1;
        *( (ULONG*)(g_HookCode + 1) ) = (ULONG)My_KbdClass_func - (ULONG)orig_KeyboardClassServiceCallback - 5;
        DbgPrint("My_KbdClass_func address at %x\n",My_KbdClass_func);
        WPOFF();
        KeAcquireSpinLock( &SDTSpinLock, &oldIrql );
        RtlCopyMemory ( (BYTE*)orig_KeyboardClassServiceCallback, g_HookCode, 5 );  //原来的函数跳到我们的函数
        *( (ULONG*)(jmp_orig_code + 1) ) = (ULONG) ( (BYTE*)orig_KeyboardClassServiceCallback + 5 );  //原来的函数地址+5字节后的地址
        RtlCopyMemory ( (BYTE*)Proxy_KbdClass, g_OrigCode, 5);  //执行原来的5字节
        RtlCopyMemory ( (BYTE*)Proxy_KbdClass+ 5, jmp_orig_code, 7);  //我们的函数跳去原来的函数
        KeReleaseSpinLock( &SDTSpinLock, oldIrql );
        WPON();
        DbgPrint("Proxy_KeAttachProcess address at %x\n",KeAttachProcess);
};

void My_UnHook_KbdClass_code()
{
        BYTE g_OrigCode[5] = { 0x8b,  0xff,  0x55,  0x8b,  0xec }; //函数头的5字节老代码
        KIRQL  oldIrql;
        if(Key_CallBack_Flag==1)
        {
                WPOFF();
                KeAcquireSpinLock( &SDTSpinLock, &oldIrql );
                RtlCopyMemory ( (BYTE*)orig_KeyboardClassServiceCallback, g_OrigCode, 5 );
                KeReleaseSpinLock( &SDTSpinLock, oldIrql );
                WPON();
        }
};

void  My_KbdClass_Check()
{
        BYTE Ob_Code[5]={0,0,0,0,0};
        BYTE My_Ob_Code[5]={0xe9,0,0,0,0};

        RtlCopyMemory (Ob_Code, (BYTE *)KbdClass, 5);
        *( (ULONG*)(My_Ob_Code + 1) ) = (ULONG)My_KbdClass_func - (ULONG)KbdClass - 5;
        if(Ob_Code[0]==My_Ob_Code[0])
        {
                if((Ob_Code[1]!=My_Ob_Code[1])||(Ob_Code[2]!=My_Ob_Code[2])||(Ob_Code[3]!=My_Ob_Code[3])||(Ob_Code[4]!=My_Ob_Code[4]))
                        My_Hook_KbdClass_code();
                DbgPrint("KbdClass : %x\n",KbdClass);
        }
        else
                My_Hook_KbdClass_code();
};       

//模拟按键
void PostKey()
{
        KEYBOARD_INPUT_DATA kid;
dwSize = sizeof(KEYBOARD_INPUT_DATA);
        __asm {
                push eax
                        mov        kid.UnitId,0                ; 构造 KEYBOARD_INPUT_DATA
                        mov        eax,0x10/*0x90        ; //Num Lock*/
                mov        kid.MakeCode,ax
                        mov        kid.Flags,KEY_MAKE        ;模拟按下
                        mov        kid.Reserved,0
                        mov        kid.ExtraInformation,0

                        lea        eax,dwRet
                        push        eax
                        lea        eax,kid
                        add        eax,dwSize
                        push        eax
                        lea        eax,kid
                        push        eax
                        push        g_kbDeviceObject
                        call        orig_KeyboardClassServiceCallback        ;利用 KeyboardClassServiceCallback 模拟按键

                        pop eax
        }
}

希望谁来帮 我看下void PostKey()函数啊。。。
2009-2-17 15:38
0
雪    币: 135
活跃值: (76)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不懂,帮顶.
2009-2-17 16:13
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
6
我放过的代码和这个不一样啊. 我的模拟按键没问题啊. 是你自己的inline hook的fake函数处理时,可能破坏了堆栈, 双机一连,源码及调试,还不好解决问题啊???
2009-2-17 18:36
0
雪    币: 71
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
我这个好像没蓝
SendKey(USHORT ScanCode, USHORT UpDown)
/*
//@@ ScanCode 请输入十六进制的扫描码    eg : 0x45;
//     可将扫描码在头文件中定义
//
//@@ UpDown    按下 或弹起的标志         define KEY_MAKE 0
//             KEY_UP   1 KEY_CONTROL   4
//
// 注意 控制键 有的为 3 4
*/
{
DWORD dwRet,dwSize;
PVOID pTmp;

KEYBOARD_INPUT_DATA kid;

kid.UnitId=(USHORT) 0 ; ; //构造 KEYBOARD_INPUT_DATA ; /*VK_M*/
kid.MakeCode=ScanCode;
kid.Flags=UpDown ; //模拟按下
kid.Reserved=(USHORT) 0;
kid.ExtraInformation=(ULONG) 0;//千万别用汇编在这,否则很痛苦!

dwSize = sizeof kid;
__asm {
     push eax
     lea eax,kid
     add eax,dwSize
     mov pTmp,eax
     pop eax
   }

orig_KeyboardClassServiceCallback( g_kbDeviceObject, &kid, pTmp, &dwRet );

}
2009-2-18 09:27
0
雪    币: 255
活跃值: (37)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
好长的 swtich
搞个表吧,运算可以更快
2009-2-18 09:37
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
我模拟按键的时候没有inline... 要不然我也不这么郁闷了。BA5D119A的函数地址,蓝屏说地址BA5D11A8出问题。估计我Y的参数那没处理好,可是直接copy的doking的代码也蓝....再一次郁闷中,得人是真跟跟了
2009-2-18 17:04
0
游客
登录 | 注册 方可回帖
返回
//