Sunday 20 November 2011

Can you disable warm boots (Ctrl-Alt-Delete)?in C programming

Can you disable warm boots (Ctrl-Alt-Delete)?

Yes. Disabling warm boots is not particularly easy to figure out, but it is not difficult to actually code. To trap a Ctrl-Alt-Delete key sequence, you must trap the keyboard’s interrupt service routine (ISR). From a highlevel perspective, it works like this: You monitor (trap) all keystrokes, waiting for the dreaded Ctrl-Alt-Delete combination. If the keystroke is not Ctrl-Alt-Delete, you pass the keystroke on to the “computer” (remember, I’m speaking in high-level terms). When you see the Ctrl-Alt-Delete combination, you can swallow it (remove it from the keyboard’s character buffer) or change it to some other keystroke (one that your program might be expecting to mean that the user just tried to reboot the machine). When your program is finished, it stops monitoring the keystrokes and resumes normal operation. This is how TSRs work—they chain themselves to the keyboard and other interrupts so that they can know when to pop up and do that voodoo that they do so well.

“So how do you do this?” you might ask. With a C program, of course. The next example shows a simplified form of trapping all Ctrl-Alt-Delete keystrokes and doing “nothing” when that combination is pressed:

#include <stdlib.h>
#include <dos.h>
/* function prototypes */
void (_interrupt _far _cdecl KbIntProc)(
unsigned short es, unsigned short ds, unsigned short di,
unsigned short si, unsigned short bp, unsigned short sp,
unsigned short bx, unsigned short dx, unsigned short cx,
unsigned short ax, unsigned short ip, unsigned short cs,
unsigned short flags);
void (_interrupt _far _cdecl * OldKbIntProc)(void);
unsigned char far * kbFlags; /* pointer to keyboard flags */
int key_char, junk; /* miscellaneous variables */
/* keyboard scancode values */
#define ALT 0x8
#define CTRL 0x4
#define KEY_MASK 0x0F
#define DELETE 0x53
void
main(int argc, char ** argv)
{
int i, idx;
/* Save old interrupt vectors */
OldKbIntProc = _dos_getvect(0x9);
/* Set pointer to keyboard flags */
FP_SEG(kbFlags) = 0;
FP_OFF(kbFlags) = 0x417;
/* Add my ISR to the chain */
_dos_setvect(0x9, KbIntProc);
/* Print something while user presses keys... */
/* Until ESCAPE is pressed, then leave */
while(getch() != 27){
printf(“Disallowing Ctrl-Alt-Delete...\n”);
}
/* Remove myself from the chain */
_dos_setvect(0x9, OldKbIntProc);
}
void _interrupt _far _cdecl KbIntProc(
unsigned short es, unsigned short ds, unsigned short di,
unsigned short si, unsigned short bp, unsigned short sp,
unsigned short bx, unsigned short dx, unsigned short cx,
unsigned short ax, unsigned short ip, unsigned short cs,
unsigned short flags)
{
/* Get keystroke input from keyboard port */
key_char = inp(0x60);
if( ((*kbFlags & KEY_MASK) == (CTRL | ALT))
&& (key_char == DELETE) ){
/* Reset the keyboard */
junk = inp(0x61);
outp(0x61, (junk | 0x80));
outp(0x61, junk);
outp(0x60, (key_char | 0x80));
outp(0x60, 0x9C);

}
/* Reset the interrupt counter */
outp(0x20, 0x20);
/* Now call the next ISR in line */
(*OldKbIntProc)();
}

There are only two sections to this program: the main() body and the keyboard interrupt service routine KbIntProc(). The main() uses _dos_getvect() to retrieve the address of the function (ISR) that is currently servicing keystrokes from the keyboard. Next, it uses _dos_setvect() to replace the keyboard servicing function with your own—KbIntProc(). A while loop that constantly gets keystrokes prints the same message repeatedly until the Escape key (decimal 27) is pressed. When that event occurs, the program calls _dos_setvect() to restore the original keyboard servicing program into place.

However, KbIntProc() is where all the fun takes place. When installed (by the _dos_setvect() call described
previously), it gets to look at all keystrokes before anyone else. Therefore, it has the first crack at manipulating or entirely removing the keystroke that came in. When a keystroke arrives, the keyboard is checked to see whether the Ctrl and Alt keys are down. Also, the keystroke itself is checked to see whether it is the Delete key (hex 53). If both cases are true, the Delete key is removed by resetting the keyboard. Regardless of whether the keystroke was ignored, manipulated, or removed by you, the ISR always calls the original keyboard interrupt service routine (OldKbIntProc()). Otherwise, the machine immediately grinds to a halt.
 
When this example program is executed, it prints “Disallowing Ctrl-Alt-Delete...” each time you press any key. When you do press Ctrl-Alt-Delete, nothing happens, because the keystroke is removed and the computer has no idea you are pressing those three keys. Exiting the program restores the state of the machine
to normal operation.
 
If you think about it, you will realize that this program can trap any keystroke or key combination, including Ctrl-C and Ctrl-Break. You therefore could legitimately consider this method for trapping the Ctrl-Break key sequence. I should point out that this method is quite intrusive—the tiniest of bugs can quickly halt the machine. But don’t let that stop you from learning or having fun.

Cross Reference:

XX.16: How do you disable Ctrl-Break?

No comments:

Post a Comment