From: buhr@umanitoba.ca (Kevin Andrew Buhr)
Newsgroups: alt.hackers
Subject: Re: Why so simple?
Date: 16 Dec 92 16:12:06 GMT
	<1992Dec10.112237.14659@neptune.inf.ethz.ch>
Organization: University of Manitoba, Canada

Ahhh....  This thread reminds me of a generic "gaming hack".  I've
used it to cheat at Ultima 6 and debug an interesting real-time
process or two.  (I used it in that big Telemate terminal emulation
hack I posted a few months ago, too.)  Basically, it hooks the "Print
Screen" function deep within the keyboard handler, pops a
BIOS-dependent number of bytes off the stack, and generates an "INT 3"
followed by an "IRET" to the point in the code where the interrupt
occurred.

Typical use:

	<C:\WHEREVER> getdebug
	GETDEBUG v 1.0 by Kevin Buhr

	<C:\WHEREVER> debug ultima6.exe
	-g

Then, when I Shift-PrtScrn, up pops a register dump pointing at the
"INT 3".  Hopping past it, I can execute the far return and get back
into the code that was executing.  It's great for scanning for "secret
codes" and for bypassing irritating installation routines when you
want to hack something in the "middle" of a program.

Here's some generic assembler code for it, for all who are interested.
Keep in mind, unless your BIOS happens to have the same stack frame
mine does and stores all the registers in the same order mine does,
you'll have to hack through your own BIOS and then modify it to get it
to work.

	;getdebug.8

	;This program waits patiently for a SHIFT-PRTSC.  When
	;received, the program restores all the variables from the
	;program that was interrupted and sends interrupt 03 just
	;before its IRET.
	
	DOS                     equ 021h
	TSR                     equ 027h
	SetInterruptVector      equ 025h
	PrintScreenInterrupt    equ 05h
	PrintString             equ 09h
	
	FirstByte:      jmp MAIN
	
	;This is the code called on interrupt
	
	NewInterrupt:   add sp,6        ;Dump 6 bytes to return to
					;PRTSC interrupt
	                pop si
	                pop cx
	                pop bx
	                pop ds          ;es still holds keyboard
					;routine dataseg in MY BIOS
	                pop ax
	                add sp,6        ;Add 6 byte return to
					;keyboard interrupt
	                mov bp,sp
	                es: mov bp,[bp]
	                es: mov ss,[bp+4];Restore caller's SS
	                es: mov sp,[bp+2];Restore caller's SP
	                es: mov byte [bp+0],0
	                mov es,0070     ;Keyboard routine code segment
	                es: mov [19fh],bp ;Store the keyboard's BP
	                pop es          ;Recover caller's ES
	                pop bp
	                pop ax
	
	                int 3           ;invoke debug just before...
	                iret            ;returning to original caller
	
	LastByte:
	;This is our code to change the interrupt
	
	MAIN:           mov dx,IntroText
	                mov ah,PrintString
	                int DOS
	
	                cli
	
	                mov al,PrintScreenInterrupt
	                mov ah,SetInterruptVector
	                mov dx,NewInterrupt
	                int DOS
	
	                sti
	
	                mov dx,LastByte                 ;Last Byte plus 1
	                int TSR
	
	IntroText:    db 'GETDEBUG v 1.0 by Kevin Buhr',0d,0a,0a,'$'


Enjoy!

Kevin <buhr@ccu.UManitoba.CA>
Newsgroups: alt.hackers