문제

내 동료 개발자! 나는이 질문에 포함 된 텍스트의 양에 대해 적어도 일부 사람들이 두려워하지 않기를 바랍니다. :)

내가이 질문을했다고 생각하는 사람들에게 맬웨어 나 무언가를 쓸 수 있습니다. OS가 시작된 후 사용자가 출시 될 응용 프로그램을 선택할 수있는 응용 프로그램을 작성하고 싶습니다. 전체 아이디어는 이전에 핫키를 앱에 눌러 OS를 시작하기 전에 사용자가 이러한 앱을 선택할 수 있도록하는 것입니다. 예를 들어, 사용자는 Mac을 켜고 SMTV를 유형하고 시스템을 시작하면 앱을 시작하면 입력을 복구하고 Safari, Mail, Tweetie 및 Vuze를 시작합니다. 나는 새롭지 만 다른 사람들에게 질문에 대답함으로써 최선을 다합니다. 나는 그 대가로 같은 것을 기대할 수 있다고 생각합니다. 내 프로필과 내 활동을 확인하고 그 후 맬웨어에 대해 비명을 지르기 시작하십시오.

이 질문은 질문에 대한 후속 조치입니다 Mac OS가 시작되는 동안 수행 된 키보드 입력을 복구 할 수 있습니까?.

에게 가이드 받다 Pekka의 조언, 나는 기사를 우연히 발견했다 키보드 이벤트를 가로 채기 그리스도인 Starkjohann에 의해 그와 그와 객관적인 개발 팀 F12에서 Shift+F12로 iBook의 CDROM 배출 키를 재 할당하는 데 성공했습니다. 주요 부분은 실제로 그것들입니다 가로 채기 키보드 이벤트, 이것이 필요한 것입니다. 결국 Christian은 나와 같은 개발자가 ICEJECT의 아이디어를 유사한 기능의 프로토 타입으로 사용하도록이 기사를 정확하게 작성했습니다.

우선, 간단한 커널 확장을 만들기 위해 사용자의 키보드 입력을 단순히 로그인하기로 결정했습니다. /var/log/kernel.log. Xcode에서 새로운 제네릭 커널 확장 프로젝트를 시작했으며 Hello 커널 : Xcode로 커널 확장 기능을 작성합니다 발견 된 튜토리얼 Mac Dev Center의 커널 확장 개념 Hello World 프로젝트를 만들고 iject 소스에서 가져온 코드로 채워 넣었습니다. 결과는 다음과 같습니다.

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);
}

결과 커널 확장은 KextLoad/Kextunload 프로그램에 의해 성공적으로로드/언로드되지만 실제로 키보드 이벤트를 가로 채지는 않습니다. 나는 그것을 작동시키기 위해 많은 일을 시도했지만, 유용한 것을 Google에 할 수없는 방식으로 오류 나 다른 문제없이 도움을 요청하고 도움을 요청합니다.

도움이 되었습니까?

해결책

문제는 기존 ioHidSystem 인스턴스를 재정의하는 방법에 관한 것이 아닙니다. 그것은 잘 작동합니다.

문제는 iohikeyboard가 열리면 이벤트 처리를 위해 콜백 함수가 iohidsystem에 전달된다는 것입니다. 콜백은 _keyboardevent라고하는 ioHidsystem의 정적 개인 기능입니다.

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

그런 다음 콜백은 iohidsystem 인스턴스에서 keadevent function을 호출합니다.

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

가상 (그리고 당신이 우선하고있는 10 개의 매개 변수 1을 호출하지 않습니다. 대신, 불리는 것은 11 매개 변수가 아닌 매개 변수입니다. 따라서 11 매개 변수 1을 무시하려고하더라도 호출이 vtable을 통과하지 않기 때문에 작동하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top