5

I'm trying to make a key logger for Mac OS for one of my research projects. I have a C code which will grab keystroke and write them to a text file. (The following code I have taken out some not important stuff)

What I need to do now is just like PyHook, instead of write the data to a text file, to pass a Python callback function to the C code and make it passes back the key input to Python, so I can do necessary analysis with Python.

I have look for how to do it, but honestly I have no idea how to approach this, as I am not used to C programming or Python extensions. Any help would be greatly appreciated.

#include <Carbon/Carbon.h>
#include <ApplicationServices/ApplicationServices.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>

#define NUM_RECORDING_EVENT_TYPES 5
#define RECORD 0
#define MOUSEACTION 0
#define KEYSTROKE 1
// maximum expected line length, for fgets
#define LINE_LENGTH 80
#define kShowMouse TRUE

OSStatus RUIRecordingEventOccurred(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData);

void prepareToRecord(); // install the event handler, wait for record signal

// note that keyboard character codes are found in Figure C2 of the document
// Inside Macintosh: Text available from http://developer.apple.com
char * keyStringForKeyCode(int keyCode); // get the representation of the Mac keycode

// Global Variables
int dieNow = 0;    // should the program terminate
int ifexit = 0;       // Exit state 
char *filename = NULL;  // Log file name
FILE *fd = NULL;   // Log file descriptor

int typecount = 0;          // count keystroke to periodically save to a txt file

struct timeval thetime;  // for gettimeofday
long currenttime;   // the current time in milliseconds

int main()
{
    filename = "test.txt";
    fd = fopen(filename, "a");

    // Get RUI ready to record or play, based off of mode
    prepareToRecord();

 return EXIT_SUCCESS;
}

// event handler for RUI recorder
OSStatus RUIRecordingEventOccurred(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData)
{
 // Determine class and kind of event
    int eventClass = GetEventClass(theEvent);
    int eventKind = GetEventKind(theEvent);

    /* Handle Keyboard Events */
    if((eventClass == kEventClassKeyboard) && (eventKind == kEventRawKeyDown)) /* key release implied */ {
        int keyCode, modifiers;  // what did the user press? any modifier keys down?

  // gather keystroke information
        GetEventParameter(theEvent, kEventParamKeyCode, typeInteger, NULL, sizeof(keyCode), NULL, &keyCode);
        GetEventParameter(theEvent, kEventParamKeyModifiers, typeInteger, NULL, sizeof(modifiers), NULL, &modifiers);

        // What time is it?
        gettimeofday(&thetime, NULL);
        currenttime =(((thetime.tv_sec*1000000) + (thetime.tv_usec)));

  fprintf(fd, "%s\n", keyStringForKeyCode(keyCode));

    } 

    return EXIT_SUCCESS;
}


void prepareToRecord()
{
 EventRecord event;  // holds an event for examination

    // Types of events to listen for
    EventTypeSpec eventTypes[NUM_RECORDING_EVENT_TYPES] = {{kEventClassKeyboard, kEventRawKeyDown}};

 // Install the event handler
    InstallEventHandler(GetEventMonitorTarget(), NewEventHandlerUPP(RUIRecordingEventOccurred), NUM_RECORDING_EVENT_TYPES, eventTypes, nil, nil);

    // event loop - get events until die command
 do {
        WaitNextEvent((everyEvent),&event,GetCaretTime(),nil);
 } while (dieNow == 0);
}


char * keyStringForKeyCode(int keyCode)
{
 // return key char
 switch (keyCode) {
  case 0: return("a");
 default: return("Empty"); // Unknown key, Return "Empty"
 }
}
1
  • Also, keeping in line with the tradition in SO. Please vote the answer & mark whatever answer most helpful to you as the "CORRECT" answer for your question. This helps the forum & the people using it. Commented Sep 30, 2010 at 4:59

1 Answer 1

4

It's easy - Just Follow the instructions - Calling Python Functions from C (Update March 2022: for Python3, see the corresponding chapter in Extending and Embedding the Python Interpreter).

Alternatively if you are trying to call C/C++ functions from Python you can use SWIG or one of Python's module CTypes

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! It seems I can use SWIG to compile the C code to .so file, and then use it in Python with CTypes, if I understood it correctly. Hope I could figure it out!
@joon the tutorials are very comprehensive along with code examples. You should have little trouble. All the best...
"Just Follow the instructions" is promising more than the linked instructions hold: They do not provide a complete working example, but refer to "the METH_VARARGS flag" in other sections of the Python documentation.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.