none
IOCTL_KEYBOARD_INSERT_DATA over PDO RRS feed

  • Question

  • HI,

    I'm trying to send keystrokes from the keyboard.
    I'm using the kbfiltr sample.

    in  the   kbfiltr_EvtIoDeviceControlForRawPdo callback function,

    I am using the following code:

        WDFDEVICE          DeviceFDO = WdfPdoGetParent(parent);
        WDFIOTARGET      wdfIOTarget = WdfDeviceGetIoTarget(DeviceFDO);

     TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! --> Entered  ");

     USHORT MakeCode = 33;  //key F
     USHORT Flags = KEY_MAKE; //Pressed
     ///---------------------------------->>>>
     KEYBOARD_INPUT_DATA INPUT_DATA;
     WDF_MEMORY_DESCRIPTOR  InputDescriptor;
     NTSTATUS status = STATUS_SUCCESS;


     TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   -4-  OK ");


     //The key was pressed
     INPUT_DATA.UnitId = 0;
     INPUT_DATA.Flags = Flags;   //Pressed
     INPUT_DATA.MakeCode = MakeCode;  //key F
     
     TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   -5 -   ");
     WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&InputDescriptor, (PVOID)&INPUT_DATA, sizeof(KEYBOARD_INPUT_DATA));
     status = WdfIoTargetSendInternalIoctlSynchronously(
            wdfIOTarget,
            WDF_NO_HANDLE,
            IOCTL_KEYBOARD_INSERT_DATA,
            &InputDescriptor,
            NULL,
            NULL,
            NULL);

     TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   - 6 -   %!STATUS!  ", status);


     // The key was released.
     INPUT_DATA.Flags = KEY_BREAK;

     status = WdfIoTargetSendInternalIoctlSynchronously(
            wdfIOTarget,
            WDF_NO_HANDLE,
            IOCTL_KEYBOARD_INSERT_DATA,
            &InputDescriptor,
            NULL,
            NULL,
            NULL);
     TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   - 7 -   %!STATUS!  ", status);

    But returns Error 0xC0000010 STATUS_INVALID_DEVICE_REQUEST. i Tryed with IOCTL_KEYBOARD_SET_INDICATORS and Works fine.

    Thanks in advance...

     

    Tuesday, July 15, 2014 2:05 AM

Answers

  • while defined, IOCTL_KEYBOARD_INSERT_DATA is not implemented in the stack. you need to invoke the service callback yourself.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Tuesday, July 15, 2014 6:12 AM

All replies

  • while defined, IOCTL_KEYBOARD_INSERT_DATA is not implemented in the stack. you need to invoke the service callback yourself.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Tuesday, July 15, 2014 6:12 AM
  • Hi Doron:

              Thanks for you support,  I trying to invoke the service callback,  with this code doesnt Works.

              Can you help me with yours comments.

    Thanks again...

    VOID  kbfiltr_EvtIoDeviceControlForRawPdo(IN WDFQUEUE Queue,IN WDFREQUEST Request,IN size_t  OutputBufferLength, IN size_t InputBufferLength,IN ULONG IoControlCode)
    {
    ....
     //
     WDFIOTARGET  wdfIOTarget;
     WDFDEVICE DeviceFDO = WdfPdoGetParent(parent);
     wdfIOTarget = WdfDeviceGetIoTarget(DeviceFDO); //
     TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   -3-  OK ");
     if (wdfIOTarget == NULL)
     {
      TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   -7-  wdfIOTarget is NULL");
     }
     else
     {
      SendKeyBoard(DeviceFDO, 0x21);
      SendKeyBoard(DeviceFDO, 0x22);
      SendKeyBoard(DeviceFDO, 0x23);
     }


    ....
    }

     


    VOID SendKeyBoard(WDFDEVICE pDevice, USHORT pMakeCode)
    {
      UNREFERENCED_PARAMETER(pDevice);


      TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! --> Entered  %d", pMakeCode);
      if (pDevice == NULL)
      {
       TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC!     pDevice == NULL");
       return;
      }


      devExt = FilterGetData(pDevice);
      if (devExt == NULL)
      {
       TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC!     devExt == NULL");
       return;
      }

     

     


      PKEYBOARD_INPUT_DATA InputDataStart[1];//, InputDataEnd = { 0 };
      TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   -4-  OK ");
      ULONG InputDataConsumed = 0;

      InputDataStart[0] = (PKEYBOARD_INPUT_DATA)ExAllocatePool(NonPagedPool, sizeof(PKEYBOARD_INPUT_DATA));
      InputDataStart[1] = (PKEYBOARD_INPUT_DATA)ExAllocatePool(NonPagedPool, sizeof(PKEYBOARD_INPUT_DATA));
      TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   -5-  OK ");

      
      //The key was pressed
      InputDataStart[0]->Reserved = 0;
      InputDataStart[0]->UnitId = 0;
      InputDataStart[0]->ExtraInformation = 0;
      InputDataStart[0]->Flags = KEY_MAKE;   //Pressed
      InputDataStart[0]->MakeCode = pMakeCode;  //key F 0x021

     

      InputDataStart[1] = InputDataStart[0];
      InputDataStart[1]->Flags = KEY_BREAK;   //Released

      InputDataConsumed = 0;// (InputDataEnd - InputDataStart);
      TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   -6 -   ");

     

     

      (*(PSERVICE_CALLBACK_ROUTINE)(ULONG_PTR)devExt->UpperConnectData.ClassService)(
       devExt->UpperConnectData.ClassDeviceObject,
       InputDataStart,
       InputDataStart + 1, //InputDataEnd
       &InputDataConsumed);


      TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   ------------------------  ok %d ", InputDataConsumed);
     }


    Wednesday, July 16, 2014 1:50 AM
  • a few things are wrong

    1) you are referencing [0] and [1] indexes but only allocate memory for one KEYBOARD_INPUT_DATA.

    2) you are allocating an array of pointers, not structures themselves

    3) you don't need to allocate the array at all. all you have to do is

       KEYBOARD_INPUT_DATA InputDataStart[2] = { 0 };

       TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   -4-  OK ");
       ULONG InputDataConsumed = 0;

       TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   -5-  OK ");

     
       //The key was pressed
       InputDataStart[0].Reserved = 0;
       InputDataStart[0].UnitId = 0;
       InputDataStart[0].ExtraInformation = 0;
       InputDataStart[0].Flags = KEY_MAKE;   //Pressed
       InputDataStart[0].MakeCode = pMakeCode;  //key F 0x021

       InputDataStart[1] = InputDataStart[0];
       InputDataStart[1].Flags = KEY_BREAK;   //Released

       InputDataConsumed = 0;// (InputDataEnd - InputDataStart);
     
       TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   -6 -   ");

      (*(PSERVICE_CALLBACK_ROUTINE)(ULONG_PTR)devExt.UpperConnectData.ClassService)(
        devExt.UpperConnectData.ClassDeviceObject,
        InputDataStart,
        InputDataStart + 2, //InputDataEnd
        &InputDataConsumed);


    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, July 16, 2014 4:20 AM
  • Hi Doron:

                 I did the the changes indicated for you. 
                 The program runs fine, (not exists errors) but dont make the keystrokes. 

                 The variable InputDataConsumed returns 2.

                 I dont know if  require other thing..

           

    Thanks for your support.

    VOID SendKeyBoard(WDFDEVICE pDevice, USHORT pMakeCode)
    {
      UNREFERENCED_PARAMETER(pDevice);
      PDEVICE_EXTENSION   devExt;
      
      TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! --> Entered  %d", pMakeCode);
      if (pDevice == NULL)
      {
       TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC!     pDevice == NULL");
       return;
      }

      devExt = FilterGetData(pDevice);
      if (devExt == NULL)
      {
       TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC!     devExt == NULL");
       return;
      }

      KEYBOARD_INPUT_DATA InputDataStart[2] = { 0 };
      ULONG InputDataConsumed = 0;
      
      //The key was pressed
      InputDataStart[0].Reserved = 0;
      InputDataStart[0].UnitId = 0;
      InputDataStart[0].ExtraInformation = 0;
      InputDataStart[0].Flags = KEY_MAKE;   //Pressed
      InputDataStart[0].MakeCode = pMakeCode;  

      //The key was released
      InputDataStart[1] = InputDataStart[0];
      InputDataStart[1].Flags = KEY_BREAK;  //Released
      
      InputDataConsumed = 0;
      
      (*(PSERVICE_CALLBACK_ROUTINE)(ULONG_PTR)devExt->UpperConnectData.ClassService)(
       devExt->UpperConnectData.ClassDeviceObject,
       InputDataStart,
       InputDataStart + 2,
       &InputDataConsumed);

      TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC!   ------------------------  InputDataConsumed: %d ", InputDataConsumed);
    }


    Thursday, July 17, 2014 1:02 AM
  • try sending the make and break inputs separately and with some time between them. Perhaps sending the make and break in the same message causes them to cancel each other out. If sending separately and with a pause still doesn't insert the keystrokes, the formatting could be wrong or your test isn't working and it isn't the in focus window so you are not seeing the keystrokes.


    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Thursday, July 17, 2014 1:13 AM
  • Hi Doron, i did separete make and break with a delay and works Fine, thanks for your support. although it works well, no icover my goal. I need detect a Hardware keylogger,my idea was send keystrokes and measure the response time. Do you have any suggestions on how to detect a HKL.?
    Thursday, July 17, 2014 5:01 AM
  • We are looking for several paths, we dont have clear a idea.

    to detect it:
    - we are trying send a lot of keystrokes and measure the response time. if time we detect delay on the response, may be are there a hkl.

    To Prevent:
    - We are thinking obfuscate sensitive information since keyboard driver, and the application has the algorithm to get these information.
    - Send a lot of keystrokes to full keylogger with fake data.

    I did believed with the filter driver could be possible develop this points.

    any suggestion will be the great support for me.

    Thursday, July 17, 2014 9:25 PM