此文原发
http://blog.csdn.net/power_YQ/archive/2011/04/28/6369580.aspx
此博客属于本人的,应该还算原创吧?
以下是win7 驱动写扇区的相关代码,win7用户模式不能直接读写部分扇区,内核模式下就没有此限制了
/*用户模式 函数
参数1 磁盘号 physicaldriveXX
参数2 扇区索引
参数3 写入字节,因为扇区是512字节,所以写入字节必须为512整数倍
*/
DWORD WINAPI WriteSection(DWORD dwDiskIndex,DWORD dwSectionIndex,IN PBYTE buffer,DWORD dwCount)//dwCount字节数,必须为512整数倍
{
if (dwCount%512!=0)
{
return 0;
}
DWORD dwRet=0;
BOOL bRet=FALSE;
bRet=DeviceIoControl(gHandle,IOCTL_OLS_SET_DISK_INDEX,&dwDiskIndex,sizeof(DWORD),NULL,0,&dwRet,NULL);
if (bRet==FALSE)
{
return 0;
}
bRet=DeviceIoControl(gHandle,IOCTL_OLS_SET_SECTION,&dwSectionIndex,sizeof(DWORD),NULL,0,&dwRet,NULL);
if (bRet==FALSE)
{
//MessageBoxA(NULL,"IOCTL_OLS_SET_SECTION","IOCTL_OLS_SET_SECTION",MB_OK);
return 0;
}
bRet=WriteFile(gHandle,buffer,dwCount,&dwRet,NULL);
if (bRet==FALSE || dwRet==0)
{
//MessageBoxA(NULL,"IOCTL_OLS_SET_SECTION","IOCTL_OLS_SET_SECTION",MB_OK);
return 0;
}
return dwRet;
}
以下是驱动部分的相关代码
NTSTATUS OlsWriteSection(
IN PDEVICE_OBJECT pDO,
IN PIRP pIrp
)
{
PIO_STACK_LOCATION pIrpSp;
PDEVICE_OBJECT pDev_Obj_PhyDrv=NULL;
PFILE_OBJECT pFile_Obj=NULL;
UNICODE_STRING uniNameString;
PIO_STACK_LOCATION pIrpStack;
NTSTATUS status=STATUS_SUCCESS;
ULONG ul_mdl_length=0;
ULONG ul_WriteLength=0;
PVOID pAdd=NULL;
ULONGLONG ull_Temp=0;
WCHAR wsz_temp[64]={0};
pIrp->IoStatus.Information = 0;
if (g_dwWriteType!=OLS_READ_WRTIE_SECTION)
{
return STATUS_UNSUCCESSFUL;
}
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
ul_mdl_length=MmGetMdlByteCount(pIrp->MdlAddress);
ul_WriteLength=pIrpStack->Parameters.Write.Length;
if (ul_mdl_length!=ul_WriteLength)
{
KdPrint(("ul_mdl_length!=ul_WriteLength"));
status=STATUS_UNSUCCESSFUL;
}
else
{
KdPrint(("%s",pAdd));
g_dwWriteType=OLS_WRITE_UNKNOWN;
RtlStringCchPrintfW(wsz_temp,64,L"\\??\\PhysicalDrive%d",g_ulDiskIndex);//打开相关磁盘设备
RtlInitUnicodeString(&uniNameString, wsz_temp);
status=IoGetDeviceObjectPointer(&uniNameString,FILE_ALL_ACCESS,&pFile_Obj,&pDev_Obj_PhyDrv);
if (status==STATUS_SUCCESS)
{
//__asm int 3;
pIrpSp=IoGetCurrentIrpStackLocation(pIrp);
//写入的扇区对应字节的偏移号,Sections_To_Byte是自定义函数,将扇区转为字节,比如1扇区,那就是512个字节偏移开始写入
//Length就是写入字节的长度
//如果读的话就是pIrpSp->Parameters.Read
pIrpSp->Parameters.Write.ByteOffset=Sections_To_Byte(g_dwSectionIndex);
status=fastFsdRequest(pFile_Obj->DeviceObject,IRP_MJ_WRITE,pIrp,TRUE);
ObReferenceObject(pFile_Obj);
}
else
{
pIrp->IoStatus.Status=STATUS_UNSUCCESSFUL;
pIrp->IoStatus.Information=0;
}
}
//__asm int 3;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
NTSTATUS
fastFsdRequest(
IN PDEVICE_OBJECT DeviceObject,
ULONG majorFunction,
PIRP pIrp,
IN BOOLEAN Wait
)
{
PIRP irp;
KEVENT event;
NTSTATUS status;
PIO_STACK_LOCATION pIrpSp=NULL;
PIO_STACK_LOCATION pIrpSpCur=NULL;
pIrpSpCur=IoGetCurrentIrpStackLocation(pIrp);
irp=IoAllocateIrp(DeviceObject->StackSize,FALSE );//创建写扇区IRP
if (!irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
irp->UserIosb=&pIrp->IoStatus;
pIrpSp=IoGetNextIrpStackLocation(irp);
pIrpSp->MajorFunction=majorFunction;
pIrpSp->MinorFunction=IRP_MN_NORMAL;
pIrpSp->DeviceObject =DeviceObject;
irp->MdlAddress=pIrp->MdlAddress;
pIrpSp->Parameters= pIrpSpCur->Parameters;
//irp->Flags =irp->Flags|SL_OVERRIDE_VERIFY_VOLUME;
// win7 对直接磁盘写入进行了保护, 驱动操作需要在IRP的FLAGS加上SL_FORCE_DIRECT_WRITE标志
if (IRP_MJ_WRITE == majorFunction)
{
pIrpSp->Flags |= SL_FORCE_DIRECT_WRITE; //这是写关键
}
if (Wait) {
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
&event, TRUE, TRUE, TRUE);
status = IoCallDriver(DeviceObject,irp);
if (STATUS_PENDING == status) {
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = irp->IoStatus.Status;
}
} else {
IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion,
NULL, TRUE, TRUE, TRUE);
irp->UserIosb = NULL;
status = IoCallDriver(DeviceObject, irp);
}
if (!NT_SUCCESS(status))
{
KdPrint(("IoCallDriver 0x%x fail 0x%x\n", majorFunction, status));
}
return status;
}
//完成例程
NTSTATUS
FltReadWriteSectorsCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
A completion routine for use when calling the lower device objects to
which our filter deviceobject is attached.
Arguments:
DeviceObject - Pointer to deviceobject
Irp - Pointer to a PnP Irp.
Context - NULL or PKEVENT
Return Value:
NT Status is returned.
--*/
{
PMDL mdl;
UNREFERENCED_PARAMETER(DeviceObject);
if (Irp->IoStatus.Status)
{
DbgPrint("!!!!!!!!!!Read Or Write HD Error Code====0x%x\n", Irp->IoStatus.Status);
}
if (Irp->MdlAddress)
{
Irp->MdlAddress=NULL;
}
if (Irp->PendingReturned && (Context != NULL)) {
*Irp->UserIosb = Irp->IoStatus ;
KeSetEvent((PKEVENT) Context, IO_DISK_INCREMENT, FALSE);
}
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)