/**********************************************************************/ /* Code to check for, and remove, the Lamer Revenge Virus */ /* This code by Dan James */ /**********************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "virusx.i" #define ROOT 880L #define HASHCHAIN 124 #define OK 0 #define WRITE_PROTECTED 1 #define NO_DISK 2 UBYTE *diskdata = 0; UBYTE invisible[] = "DF0:\240\240\240\240\240"; UBYTE newfile[] = "DF0:DANGERVIRUS"; unsigned long CheckSum(unsigned long block[]); extern char TDName[]; extern struct IOStdReq *diskreq; /* trackdisk's IOStdReq */ extern struct Window *Window; void CheckDiskForRLamer(int num) { char buf[255]; int i; long *buff, Virus = 0, block, link = 0, before = 0, after = 0; unsigned long lock; char drive[5]; if(OpenDevice(TDName,(long)num,diskreq,0L)) return; /** Check for No Disk **/ invisible[2] = newfile[2] = 0x30 + num; if((lock = Lock(invisible,ACCESS_READ)) == DOSFALSE) return; UnLock(lock); strncpy(drive,invisible,4); drive[4] = 0; strcpy(buf, "CAUTION!|RLamer Virus found on Drive DF0:|Disk is Write Protected."); buf[39] = num + '0'; while (ProtStatus() == TRUE) if (SimpleRequest(buf, "Retry|Cancel", Window, 0) == 1) return; if(Rename(invisible,newfile) == DOSFALSE) { strcat(buf, "Attempt to rename virus Failed.|Your disk has an invisible file on it,|which contains this virus."); SimpleRequest(buf, "Thanks for the Warning", Window, 0); return; } else { strcat(buf, "The virus has been renamed to the root directory|of that disk, as 'DANGERVIRUS'.|Please Delete this file, and edit your|Startup-Sequence to remove the invisible filename|found on the first line."); SimpleRequest(buf, "Will Do", Window, 0); } /* virus is present */ ReadBlock(ROOT); buff = (long *)diskdata; Virus = buff[ 15 ]; for(i = 14; i > 6; i--) if(before = buff[ i ]) break; if(before == 0) return; for(i = 16; i < 81; i++) if(after = buff[ i ]) break; if(after == 0) return; block = before; do { ReadBlock(block); link = buff[ HASHCHAIN ]; if(link == after) { buff[ HASHCHAIN ] = buff[ 5 ] = 0; buff[ 5 ] = CheckSum(buff); WriteBlock(block); break; } } while(block = link); CloseDevice(diskreq); } unsigned long CheckSum(unsigned long block[]) { int cnt; unsigned long sum = 0; for(cnt = 0; cnt < 128; cnt++) sum += block[ cnt ]; return (~sum + 1); } /**********************************************************************/ /* This code will detect one varient of the Lamer virus in memory */ /* and deactivate it. Currently no borrowed vectors are restored. */ /* A reboot would fix that though */ /**********************************************************************/ #define LAMER_ID "clist 33.80" void CheckRamForLamer(void) { struct ExecBase **ExecBase = (struct ExecBase **)4; APTR *KTagPtr = (APTR *)(*ExecBase)->KickTagPtr; APTR Lamer, TestKTag(); while(*KTagPtr) { while((ULONG)*KTagPtr & 0x80000000) KTagPtr = (APTR *)((ULONG)*KTagPtr & 0x7FFFFFFF); if(Lamer = TestKTag( *KTagPtr )) { SimpleRequest("The Lamer Revenge Virus was found in RAM,|and is now disabled.", " Thanks ", Window, 0); if(KillLamer(Lamer)) *KTagPtr = (APTR)((ULONG)(KTagPtr+1) | 0x80000000); return; } KTagPtr++; } } int KillLamer(APTR addr) { #define RTS 0x70014E75 /* moveq.l #1,d0 rts */ int i; APTR ptr; /* I think that the Lamer is in memory. I'm going to test several locations within the virus body to be sure that it is the exact virus I'm familiar with. The test array has memory offsets from addr and the contents I expect to see there. */ static APTR test[] = { (APTR)0x0A6, (APTR)0x2F3A0EEC, /* SumKick routine */ (APTR)0x166, (APTR)0x2F3A0E3C, /* DoIO routine */ (APTR)0x246, (APTR)0x2F3A0D64, /* TDRead routine */ (APTR)0x2B8, (APTR)0x287A0D0C, /* Trigger point */ (APTR)0x5AE, (APTR)0x2C780004 /* Disk Trasher */ }; /* I'm going to pull the vipers fangs by placing RTS instructions in key areas. One area is his Resident Initialization vector - that'll stop him from living through a re-boot (provided he's not on the boot disk that is) */ static APTR rts[] = { (APTR)0, /* Keep from initializing on reset */ (APTR)0x2B8, /* disable one trigger point */ (APTR)0x5AE, /* stop the disk trasher */ (APTR)0x6D8, /* stop the alerts */ (APTR)0x73C /* his ReBoot exit */ }; for(i = 0; i < sizeof(test)/sizeof(ULONG); i+= 2) { ptr = (long)addr+(long)test[ i ]; if( (long)*ptr != (long)test[ i+1 ] ) return 0; } for(i = 0; i < sizeof(rts)/sizeof(ULONG); i++) { ptr = (long)addr+(long)rts[ i ]; *ptr = (APTR)RTS; } return 1; } /* Test the Resident structure ID string to see if it matches the one the Lamer uses. Return the structures Init vector if true, NULL if not */ APTR TestKTag( struct Resident *res ) { char str[12]; strncpy(str,res->rt_IdString,11); str[11] = 0; if(strcmp(LAMER_ID,str) == 0) return res->rt_Init; return (APTR)NULL; }