/*



	    Gaara virus disinfector type 1
	--------------------------------------
	by Piotr Bania <bania.piotr@gmail.com>
	http://www.piotrbania.com
	
	
	Details:

	Firs of all, the disinfector checks if the GAARA is already resident
	if so you may want to clear the RAM memory. And this seems to be 
	the best way of disinfection but you will loose all your RAM programs
	unless they are archived. Anyway i made an another approach.
	Which i hope can teach you how to clear the virus.

	This little file, is going prevent Gaara virus from execution.
	It simply checks all variables (files) for the marker occurency
	then if it is found, we are searching for the const bytes of gaara
	body within the virus execution starts. Then we patch those bytes
	with orginal bytes from the host. Due to that fact, Gaara will not
	get executed, and the execution flow returns to the orginal program.
	Finally the GAARA marker is erased from the orginal file. Well
	i could also re-design the heap memory and change the size but i
	was too lazy to do so. Nothing more like few minutes code.

*/



#include <tigcclib.h>

#define get_romb(x)					({(long)x = *(long*)0xC8;}) 
#define LOW_GAARA_SIZE			400



/* signatures */
unsigned char 	sig_gaara_mark[]	= {'G','A','A','R','A','X'};
unsigned char 	sig_gaara_start[] = {0x4E, 0x71, 0x4E, 0x71, 0x48, 0xE7, 0xFF, 0xFE};


/* repair */
unsigned char 	repair_bytes[]		=	{0x4E, 0x5E, 0x4E, 0x75};

unsigned short	gaara_m_offset 		= 0;
int							d_files						= 0;


void is_infected(void)
{
	unsigned long a;
	get_romb(a);
		
	if (!(a & 0xE00000))
	{
		printf("Disg: Seems the ROMCALL-JUMP-TABLE is redirected\n");
		printf("Disg: Please reset RAM to make it clean.\n");

		/* well i should rewrite the ROMCALL-JUMP-TABLE ptr here by hand
		but i guess it would be a cool job for you :)*/

		ngetchx();		
		return;
	}
	
	printf("Disg: Seems the RAM is clean\n");	
}


unsigned short get_sig_off(void *mem, unsigned short size, unsigned char *sig, int sig_s)
{
	
	int i,ii, found;
	for (i = 0; i < (size-3); i++)
	{	
		found = 1;
		for (ii = 0; ii < sig_s; ii++)
		{
			if (*(unsigned char*)(mem+i+ii) != sig[ii])
			{
				found = 0;
				goto next;				
			}
		}		

next:		
		if (found == 1)
		{
			if (*(char*)(mem+i+ii) == 'X')
				return 0;			// to avoid fail on itself
			return i;		
		}
			
	}	
	
	return 0;
}


int is_gaara(void *mem, unsigned short size)
{
	int i;
	unsigned long offset;
	
	printf("Disg: Scaning for the infection mark\n");

	gaara_m_offset = get_sig_off(mem,size,&sig_gaara_mark,sizeof(sig_gaara_mark)-1);
	if (gaara_m_offset != 0)
	{
					printf("Disg: File is infected with Gaara, trying to repair\n");
					return 1;			
	}

	printf("Disg: File is clean\n");
	return 0;	
}


void disinfection_one(void *mem, unsigned short size)
{
	void *where;
	unsigned short offset;
		
	offset = get_sig_off(mem,size,&sig_gaara_start,7);
	
	if (!offset)
	{
		printf("Disg: Disinfection failed, cannot find second signature\n");
		return;		
	}

	where = (void*)(mem + offset);
	printf("Disg: Gaara entry found at 0x%lx\n",where);
	
	/* lets set orginal bytes just after the virus entry point, so
	the body will not be executed, and the execution flow will return to the host at start*/
	
	memcpy((void*)(where+4),(void*)&repair_bytes,sizeof(repair_bytes));
	
	
	/* and now destroy the Gaara marker, pad it with 0 */
	memset((void*)(mem + gaara_m_offset),0,5);
	
	printf("Disg: File is repaired\n");
	d_files++;
	return;
}




void in_infected_file(SYM_ENTRY *se)
{
	unsigned short size;
	void *mem = HeapDeref(se->handle);
	
	printf("Disg: Checking %s\n",se->name);
	
	if (!mem)
	{
		printf("Disg: Error, cannot HeapDeref();\n");
		return;		
	}
	
	size = *(unsigned short*)mem;
	
	printf("Disg: Variable size is %d bytes \n",size);
	
	if (size < LOW_GAARA_SIZE)
	{
		printf("Disg: The file is not infected (size is too low)\n");
		return;		
	}
		
	if (!is_gaara(mem,size))
		return;
				
	disinfection_one(mem,size);
	
}




void dis_loop(void)
{

	SYM_ENTRY *se;

	if (!FolderOp(NULL, FOP_LOCK | FOP_ALL_FOLDERS))
	{
		printf("Disg: Locking folder table failed\n");
		return;		
	}
		
	se = SymFindFirst(NULL, FO_RECURSE | FO_SKIP_TEMPS);
	
	while (se)
	{
			in_infected_file(se);			
			se = SymFindNext();		
	}
		
	FolderOp(NULL,FOP_UNLOCK | FOP_ALL_FOLDERS);
	
}


// Main Function
void _main(void)
{
	clrscr();
	printf("*** DISG - Gaara virus file disinfector ready.\n");
	printf("*** by Piotr Bania - http://www.piotrbania.com\n");

	is_infected();
	dis_loop();
	
	
	printf("Disg: Disinfection ended, %d file were disinfected\n",d_files);
	ngetchx();
}
