Theoretical Paper
- Computer Organization
- Data Structure
- Digital Electronics
- Object Oriented Programming
- Discrete Mathematics
- Graph Theory
- Operating Systems
- Software Engineering
- Computer Graphics
- Database Management System
- Operation Research
- Computer Networking
- Image Processing
- Internet Technologies
- Micro Processor
- E-Commerce & ERP
Practical Paper
Industrial Training
Viruses Like Activities
TSR's - terminate but stay resident programs - from their name appear to be strangers belonging to strange lands. In fact Microsoft wanted them to be so treated because officially it never accepted that TSR's were possible. For quite some time TSR's was indeed a closely guarded secret . But it was only Microsoft who blew it up...by developing a DOS utility called PRINT.COM. This utility helps carrying out the printing in the background whereas you do some other work in the foreground.
And once hackers burnt their midnight oil to get to the root of the PRINT.COM, Microsoft's secret became public knowledge. And overnight, number of TSR's were born. The more popular amongst the herd were Sidekick and Prokey. But even today most of the programmers hold an awe for TSR's. Through a series of programs I intend to bring TSR's down to earth. Let us understand the basis of TSR's first.
When we work with any program like say dBASE, it is loaded into memory on top of COMMAND.COM and when we quit from dBASE it is erased from the memory so that the next program may be loaded on top of COMMAND.COM. With TSR the rules are slightly different. Once loaded in memory it remains on top of COMMAND.COM. And now if we load say Wordstar it will be loaded on top of TSR and not on top of COMMAND.COM. So both TSR and Wordstar coexist. Now all that needs to be done is to activate the TSR through some trigger. This trigger is usually the hot-keys. For example the hot-keys for Sidekick are Ctrl and Alt. From this it is clear that while writing a TSR care should be exercised to make it resident in memory. Turbo C allows you to do this through a function called keep( ). Look at the following program :
#include "dos.h"
main( )
{
printf ( "Before calling keep\n" ) ;
keep ( 0 , 500 ) ;
printf ( "After calling keep" ) ;
}
Once executed you will find that only the first message is displayed. keep( ) makes your program TSR i.e. keeps it in memory and terminates its execution. That is the reason why the output of the second printf( ) doesn't go to the screen. The arguments of keep( ) helps DOS in finding out how much memory to set aside for storing your program in memory.
Although we can now make our program resident in memory, there is no way that it will ever become active. If it is to be activated it is necessary to capture interrupts. But how? Well, at the low end of memory there exists an Interrupt Vector Table ( IVT ). It contains addresses of routines stored in ROM-BIOS... routines which carry out important tasks like reading from disk or keyboard, writing to screen, etc. When we hit a key, an interrupt occurs and then the address of the routine corresponding to this interrupt is picked up from IVT and the control is passed to this routine. While capturing interrupts we have to change the address in IVT so that it contains the address of our TSR. After doing this whenever an interrupt occurs then from IVT address of our TSR is picked up and the control reaches our TSR. Once the control reaches the TSR, we can do something on the screen or on the printer or at any other place and finally handover the control to the ROM-BIOS routine. Turbo C provides functions getvect( ) and setvect( ) to facilitate capturing of interrupts. An important thing that one has to remember is the interrupt numbers associated with various devices. For example, interrupt number 8 is associated with timer, 9 with keyboard, 19 with disk, 23 with printer and so on. Once these details are mastered C makes available raw power at your fingertips
Dancing Dolls
This program displays an activity similar to that of a virus called Dancing Dolls. Whenever you press a key all the characters on the screen which are in uppercase get converted to lower case and that those in lower case turn to upper case. Compile the program given below to create an EXE file and then quit out of Turbo C and execute this program. After that load Wordstar or dbase or even Turbo C and watch the dance !
#include "dos.h"
void interrupt newroutine( ) ;
void interrupt ( *oldroutine )( ) ;
char far *s = ( char far * ) 0xB8000000 ; int i ;
main( )
{
oldroutine = getvect ( 9 ) ;
setvect ( 9, newroutine ) ;
keep ( 0 , 1000 ) ;
}
void interrupt newroutine( )
{
for ( i = 0 ; i <= 3999 ; i+= 2 )
{
if ( *( s + i ) >= 65 && *( s + i ) <= 90 )
* ( s + i ) += 32 ;
else
if ( *( s + i ) >= 97 && *( s + i ) <= 122 )
* ( s + i ) -= 32 ;
}
( *oldroutine )( ) ;
}
When our( )gets called from main( ), first time through the for loop all capitals on the screen are changed to small case and vice versa. The indefinite while loop ensures that this effect is immediately reversed thereby making characters small case one moment and capitals the next. This change takes place so fast that it gives an illusion of the characters dancing on the screen (to your tune).
Caps Locked
How about a TSR which will permanently keep the Caps Lock on? For this we will have to steal interrupt number 9, and then have a routine called which puts on the Caps Lock after the normal keyboard ROM-BIOS routine has done its job. Here is the program.
#include "dos.h"
void interrupt ( *prev )( ) ;
void interrupt our( ) ;
char far *kb = ( char far * ) 0x417 ;
main( )
{
prev = getvect ( 9 ) ;
setvect ( 9, our ) ;
keep ( 0, 500 ) ;
}
void interrupt our( )
{
( *prev )( ) ;
*kb = *kb | 64 ;
}
To understand our( ), note down the following points.
-
The status of Caps Lock is stored in the sixth bit of byte 417h. A 1 in the sixth bit indicates that the Caps Lock is on and a 0 indicates that it is off.
-
The interrupt number 9 is generated once when we hit a key and once when we release it.
-
When the Caps Lock key is pressed the ROM-BIOS routine toggles the sixth bit in 417h, whereas when the Caps Lock key is released the bit remains unchanged. The function our( ) uses this knowledge to ensure that the Caps Lock remains permanently on. Whenever we press a key, instead of the keyboard routine in ROM-BIOS being executed, the our( ) function is executed. This so happens because in the IVT we have substituted the address of this new function for the address of the actual routine. The our( ) function first hands over the control to the ROM-BIOS routine. When the control comes back from this routine the statement *kb = *kb | 64 turns the sixthbit on. The bitwise OR operator | has been used to ensure that the other bits in 417h remain unchanged.
Let us now imagine how our( ) would work in three situations.
-
When any key other than Caps Lock is pressed: The ROM-BIOS routine (called through ( *prev )( )) will not make any change in the Caps Lock bit whereas *kb = *kb | 64 will set the Caps Lock bit to 1.
-
When Caps Lock is on and Caps Lock key is pressed: The ROM-BIOS routine will turn the Caps Lock bit off and *kb = *kb | 64 will immediately set the Caps Lock bit once again to 1.
-
When Caps Lock is off and Caps Lock key is pressed: The ROM-BIOS routine will turn the Caps Lock bit on and *kb = *kb | 64 will ensure that the Caps Lock bit remains 1.
What do you think would happen if the sequence of statements in our( ) is changed? Would the Caps Lock still remain permanently on? Yes, because when the Caps Lock key is pressed the ROM-BIOS routine toggles the sixth bit in 417h, whereas when the Caps Lock key is released the bit remains unchanged. To make absolutely sure that the Caps Lock does remain on you can examine how our( ) works in the three situations given above. The way sixth bit of memory location 417h controls the status of Caps Lock key, bits 2 and 3 contain the status of Ctrl and Alt keys respectively.