Why does this keyboard not intercept the kernel extension?

my fellow developers! I really hope that at least some of you will not be scared by the amount of text contained in this question (I just did my best to describe it as humane). :)

For those who think I asked this question, write malware or something else. I want to write an application that will allow users to select the applications that will be launched after the OS shuts down. The whole idea is to allow the user to select these applications before the OS finishes launching by pressing hot keys previously bound to the applications. For example, a user switches to their Mac, dials SMTV and leaves when the system finishes launching my application, restores input and launches Safari, Mail, Tweetie and Vuze. I am new to SO, but I am doing my best to help others by answering their questions. I think I can expect the same in return. Check my profile and my activity and after that start screaming about malware.

This question is a continuation of the question Can I restore keyboard input that was made during Mac OS startup? .

Guided by Pekka 's advice , I came across an article on Keyboard Event Capture from Christian Starkjohann, which describes how he and the goal development team managed to reassign the iBook CDROM eject key from F12 to Shift + F12. The main part is that they actually intercept keyboard events, and that is what I need. In the end, Christian wrote this article specifically for developers like me to use the idea of ​​iJect as a prototype of similar functionality.

To get started, I decided to create a simple kernel extension to simply register user keyboard input in /var/log/kernel.log. I started a new universal kernel extension project in Xcode following the Hello Kernel instructions : Creating a kernel extension using Xcode . Mac Dev Center core extension concepts to create a Hello World project and then populate it with code taken from iJect sources. Here are the results:

TestKEXT.c

#include <sys/systm.h>
#include <mach/mach_types.h>


extern int HidHackLoad(void);
extern int HidHackUnload(void);


kern_return_t MacOSSCKEXT_start (kmod_info_t * ki, void * d) {
    return HidHackLoad() == 0 ? KERN_SUCCESS : KERN_FAILURE;
}


kern_return_t MacOSSCKEXT_stop (kmod_info_t * ki, void * d) {
    return HidHackUnload() == 0 ? KERN_SUCCESS : KERN_FAILURE;
}

HIDHack.h

#ifdef __cplusplus
extern "C" {
#endif

#include <mach/mach_types.h>
#include <sys/systm.h>

 extern int HidHackLoad(void);
 extern int HidHackUnload(void);

#ifdef __cplusplus
}
#endif

#include <IOKit/system.h>
#include <IOKit/assert.h>
#include <IOKit/hidsystem/IOHIDSystem.h>


class HIDHack : public IOHIDSystem {
public:
 virtual void keyboardEvent(unsigned   eventType,
          /* flags */            unsigned   flags,
          /* keyCode */          unsigned   key,
          /* charCode */         unsigned   charCode,
          /* charSet */          unsigned   charSet,
          /* originalCharCode */ unsigned   origCharCode,
          /* originalCharSet */  unsigned   origCharSet,
          /* keyboardType */     unsigned   keyboardType,
          /* repeat */           bool       repeat,
          /* atTime */           AbsoluteTime ts);

 virtual void keyboardSpecialEvent(unsigned   eventType,
           /* flags */        unsigned   flags,
           /* keyCode  */     unsigned   key,
           /* specialty */    unsigned   flavor,
           /* guid */         UInt64     guid,
           /* repeat */       bool       repeat,
           /* atTime */       AbsoluteTime ts);
};

HIDHack.cpp

#include "HIDHack.h"


static void *oldVtable = NULL;
static void *myVtable = NULL;


int HidHackLoad(void) {
 IOHIDSystem *p;
 HIDHack *sub;

 if (oldVtable != NULL) {
  printf("###0 KEXT is already loaded\n");
  return 1;
 }
 if (myVtable == NULL) {
  sub = new HIDHack();
  myVtable = *(void **)sub;
  sub->free();
 }
    p = IOHIDSystem::instance();
    oldVtable = *(void **)p;
    *(void **)p = myVtable;

 printf("###1 KEXT has been successfully loaded\n");

    return 0;
}

int HidHackUnload(void) {
 IOHIDSystem *p;

    if (oldVtable != NULL) {
        p = IOHIDSystem::instance();
  if (*(void **)p != myVtable) {
   printf("###2 KEXT is not loaded\n");

   return 1;
  }
        *(void **)p = oldVtable;
        oldVtable = NULL;
    }

 printf("###3 KEXT has been successfully unloaded\n");

 return 0;
}

void HIDHack::keyboardEvent(unsigned   eventType, unsigned   flags, unsigned   key, unsigned   charCode, unsigned   charSet, unsigned   origCharCode, unsigned   origCharSet, unsigned   keyboardType, bool repeat,
       AbsoluteTime ts) {
 printf("###4 hid event type %d flags 0x%x key %d kbdType %d\n", eventType, flags, key, keyboardType);

    IOHIDSystem::keyboardEvent(eventType, flags, key, charCode, charSet, origCharCode, origCharSet, keyboardType, repeat, ts);
}

void HIDHack::keyboardSpecialEvent(   unsigned   eventType,
          /* flags */        unsigned   flags,
          /* keyCode  */     unsigned   key,
          /* specialty */    unsigned   flavor,
          /* guid */         UInt64     guid,
          /* repeat */       bool       repeat,
          /* atTime */       AbsoluteTime ts) {
 printf("###5 special event type %d flags 0x%x key %d flavor %d\n", eventType, flags, key, flavor);

 IOHIDSystem::keyboardSpecialEvent(eventType, flags, key, flavor, guid, repeat, ts);
}

The resulting kernel extension is successfully loaded / unloaded using the kextload / kextunload programs, but does not actually intercept any of the keyboard events. I tried to do many things to make it work, but without any errors or other problems with it, since I can’t do anything useful to Google and ask you to help.

+5
1

, IOHIDSystem. .

, IOHIKeyboard IOHIDS . IOHIDSystem, _keyboardEvent:

    success = ((IOHIKeyboard*)source)->open(this, kIOServiceSeize,0,
                (KeyboardEventCallback)        _keyboardEvent, 
                (KeyboardSpecialEventCallback) _keyboardSpecialEvent,
                (UpdateEventFlagsCallback)     _updateEventFlags);

keyboardEvent IOHIDSystem:

    self->keyboardEvent(eventType, flags, key, charCode, charSet,
                            origCharCode, origCharSet, keyboardType, repeat, ts, sender);

, ( ). , , 11. , 11 , , vtable.

+2

All Articles