⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver.c

📁 直接IRP操作文件的实现问题
💻 C
📖 第 1 页 / 共 3 页
字号:

	return status;
}

BOOLEAN GetDriveObject(
	IN ULONG DriveNumber,
	OUT PDEVICE_OBJECT *DeviceObject,
	OUT PDEVICE_OBJECT *ReadDevice
	)
{
	WCHAR driveName[] = L"\\DosDevices\\A:\\";
	UNICODE_STRING deviceName;
	HANDLE deviceHandle;
	OBJECT_ATTRIBUTES objectAttributes;
	IO_STATUS_BLOCK	ioStatus;
	PFILE_OBJECT fileObject;
	NTSTATUS status;

	if (DriveNumber >= 'A' && DriveNumber <= 'Z')
	{
		driveName[12] = (CHAR)DriveNumber;
	}
	else if (DriveNumber >= 'a' && DriveNumber <= 'z')
	{
		driveName[12] = (CHAR)DriveNumber - 'a' + 'A';
	}
	else
	{
		return FALSE;
	}

	RtlInitUnicodeString(&deviceName, driveName);

	InitializeObjectAttributes(	&objectAttributes,
								&deviceName,
								OBJ_CASE_INSENSITIVE,
								NULL,
								NULL);

	status = IoCreateFile(	&deviceHandle,
							SYNCHRONIZE | FILE_ANY_ACCESS,
							&objectAttributes,
							&ioStatus,
							NULL,
							0,
							FILE_SHARE_READ | FILE_SHARE_WRITE,
							FILE_OPEN,
							FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE,
							NULL,
							0,
							CreateFileTypeNone,
							NULL,
							0x100);

	if (!NT_SUCCESS(status))
	{
		DbgPrint(("Could not open drive %c: %x\n", DriveNumber, status));
		return FALSE;
	}

	status = ObReferenceObjectByHandle(	deviceHandle,
										FILE_READ_DATA,
										*IoFileObjectType,
										KernelMode,
										&fileObject,
										NULL);

	if (!NT_SUCCESS(status))
	{
		DbgPrint(("Could not get fileobject from handle: %c\n", DriveNumber));
		ZwClose(deviceHandle);
		return FALSE;
	}

	if (fileObject->Vpb == 0 || fileObject->Vpb->RealDevice == NULL)
	{
		ObDereferenceObject(fileObject);
		ZwClose(deviceHandle);
		return FALSE;
	}

	*DeviceObject = fileObject->Vpb->DeviceObject;
	*ReadDevice = fileObject->Vpb->RealDevice;

	ObDereferenceObject(fileObject);
	ZwClose(deviceHandle);

	return TRUE;
}

NTSTATUS
fnCreateFile(
	IN PFILE_REQUEST_CREATE FileRequestCreate,
	IN ULONG InputBufferLength,
	OUT PIO_STATUS_BLOCK IoStatusBlock
	)
{
	PDEVICE_OBJECT deviceObject;
	PDEVICE_OBJECT realDevice;
	PFILE_OBJECT fileObject;
	NTSTATUS status;
	HANDLE newHandle;
	ANSI_STRING fname;
	UNICODE_STRING fileName;

	if (InputBufferLength <= sizeof(FILE_REQUEST_CREATE))
		return STATUS_INVALID_PARAMETER;

	if ((FileRequestCreate->ShareAccess & ~FILE_SHARE_VALID_FLAGS) ||
		(FileRequestCreate->CreateDisposition > FILE_MAXIMUM_DISPOSITION))
		return STATUS_INVALID_PARAMETER;

	fname.Length = (USHORT)InputBufferLength - sizeof(FILE_REQUEST_CREATE);
	fname.Buffer = FileRequestCreate->FileName;
	fname.MaximumLength = fname.Length;

	if (fname.Buffer[fname.Length - 1] == '\0')
		fname.Length--;

	if (fname.Length < 3)
		return STATUS_INVALID_PARAMETER;

	DbgPrint(("Open %s %d\n", fname.Buffer, fname.Length));
	FileRequestCreate->FileHandle = NULL;

	if (fname.Buffer[1] != ':')
		return STATUS_INVALID_PARAMETER;

	if (!GetDriveObject(fname.Buffer[0], &deviceObject, &realDevice))
	{
		return STATUS_UNSUCCESSFUL;
	}

	fname.Buffer += 2;
	fname.MaximumLength -= 2;
	fname.Length -= 2;

	if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(	&fileName,
													&fname,
													TRUE)))
	{
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	__try
	{
		DbgPrint(("deviceObject = %x\n", deviceObject));

		status = IrpFileCreate(	&fileName,
								FileRequestCreate->DesiredAccess,
								FILE_ATTRIBUTE_NORMAL,
								FileRequestCreate->ShareAccess,
								FileRequestCreate->CreateDisposition,
								0,
								deviceObject,
								realDevice,
								&fileObject);

	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		status = GetExceptionCode();
		DbgPrint(("IrpCreate exception! error=%x\n", status));
		RtlFreeUnicodeString(&fileName);
		return status;
	}

	RtlFreeUnicodeString(&fileName);

	if (!NT_SUCCESS(status))
	{
		DbgPrint(("Irp open file failed\n"));
		return status;
	}

	status = ObOpenObjectByPointer(	fileObject,
									0,
									NULL,
									FileRequestCreate->DesiredAccess,
									*IoFileObjectType,
									KernelMode,
									&newHandle);

	ObDereferenceObject(fileObject);

	if (!NT_SUCCESS(status))
	{
		DbgPrint(("ObOpenObjectByPointer failed\n"));
		return status;
	}

	FileRequestCreate->FileHandle = newHandle;
	IoStatusBlock->Information = sizeof(HANDLE);

	return status;
}

NTSTATUS
fnReadFile(
	IN PFILE_REQUEST_READ FileRequestRead,
	IN ULONG InputBufferLength,
	OUT PIO_STATUS_BLOCK IoStatusBlock
	)
{
	NTSTATUS status;
	PFILE_OBJECT fileObject;
	IO_STATUS_BLOCK ioStatus;

	if (InputBufferLength < sizeof(FILE_REQUEST_READ))
		return STATUS_INVALID_PARAMETER;

	if (InputBufferLength < sizeof(FILE_REQUEST_READ) + FileRequestRead->Length)
		return STATUS_INVALID_PARAMETER;

	DbgPrint(("read file\n"));

	status = ObReferenceObjectByHandle(	FileRequestRead->FileHandle,
										GENERIC_READ,
										*IoFileObjectType,
										KernelMode,
										&fileObject,
										NULL);

	if (!NT_SUCCESS(status))
		return status;

	__try
	{
		status = IrpFileRead(	fileObject,
								NULL,
								FileRequestRead->Length,
								FileRequestRead->Buffer,
								&ioStatus);

		status = ioStatus.Status;
		FileRequestRead->ReadLength = sizeof(FILE_REQUEST_READ) + ioStatus.Information;
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		status = GetExceptionCode();
		DbgPrint(("IrpRead exception! error=%x\n", status));
	}

	ObDereferenceObject(fileObject);

	return status;
}

NTSTATUS
fnDeleteFile(
	IN HANDLE FileHandle
	)
{
	NTSTATUS status;
	PFILE_OBJECT fileObject;
	PDEVICE_OBJECT deviceObject;
	FILE_DISPOSITION_INFORMATION fdi;

	status = ObReferenceObjectByHandle(	FileHandle,
										0,
										*IoFileObjectType,
										KernelMode,
										&fileObject,
										NULL);

	if (!NT_SUCCESS(status))
	{
		return status;
	}

	deviceObject = IoGetRelatedDeviceObject(fileObject);

	//fnCloseFile(deviceObject, fileObject);
	fdi.DeleteFile = TRUE;

	status = IoSetInformation(	fileObject,
								FileDispositionInformation,
								sizeof(FILE_DISPOSITION_INFORMATION),
								&fdi);

	ObDereferenceObject(fileObject);

	return status;
}

NTSTATUS
QueryHandleInfo(
	IN PQUERY_HANDLE_INFO QueryHandleInfo,
	OUT PVOID OutputBuffer,
	IN ULONG OutputBufferLength
	)
{
	NTSTATUS status;
	HANDLE processHandle, objectHandle;
	PEPROCESS process;
	PVOID object;
	OBJECT_ATTRIBUTES objectAttributes;
	CLIENT_ID clientID;
	POBJECT_NAME_INFORMATION objectName;
	ANSI_STRING objectNameA;
	ULONG returnLength;

	__try
	{
		if (QueryHandleInfo->Pid < 8)
		{
			PsLookupProcessByProcessId(	(HANDLE)QueryHandleInfo->Pid,
										&process);

			KeAttachProcess(process);

			status = ObReferenceObjectByHandle(	(HANDLE)QueryHandleInfo->Handle,
												GENERIC_READ,
												NULL,
												KernelMode,
												&object,
												NULL);

			KeDetachProcess();

			if (!NT_SUCCESS(status))
			{
				return status;
			}
		}
		else
		{
			InitializeObjectAttributes(	&objectAttributes,
										NULL,
										0,
										NULL,
										NULL);

			clientID.UniqueProcess = (HANDLE)QueryHandleInfo->Pid;
			clientID.UniqueThread = 0;

			status = ZwOpenProcess(	&processHandle,
									PROCESS_DUP_HANDLE,
									&objectAttributes,
									&clientID);

			if (!NT_SUCCESS(status))
			{
				return status;
			}

			status = ZwDuplicateObject(	processHandle,
										(HANDLE)QueryHandleInfo->Handle,
										NtCurrentProcess(),
										&objectHandle,
										0,
										FALSE,
										DUPLICATE_SAME_ACCESS);

			ZwClose(processHandle);

			if (!NT_SUCCESS(status))
			{
				return status;
			}

			status = ObReferenceObjectByHandle(	objectHandle,
												GENERIC_READ,
												NULL,
												KernelMode,
												&object,
												NULL);

			ZwClose(objectHandle);

			if (!NT_SUCCESS(status))
			{
				return status;
			}
		}

		if (object != (PVOID)QueryHandleInfo->Object)
		{
			ObDereferenceObject(object);
			return STATUS_OBJECT_TYPE_MISMATCH;
		}

		if (*(PULONG)object == 0x700005)
		{
			DbgPrint(("0x700005, link?\n"));
			return STATUS_SUCCESS;
		}

		objectName = ExAllocatePool(NonPagedPool, 0x400);

		if (objectName == NULL)
		{
			ObDereferenceObject(object);
			return STATUS_INSUFFICIENT_RESOURCES;
		}

		status = ObQueryNameString(	object,
									objectName,
									0x400,
									&returnLength);

		ObDereferenceObject(object);

		if (!NT_SUCCESS(status))
		{
			ExFreePool(objectName);
			return status;
		}

		status = RtlUnicodeStringToAnsiString(	&objectNameA,
												&objectName->Name,
												TRUE);

		ExFreePool(objectName);

		if (!NT_SUCCESS(status))
		{
			return status;
		}

		if (objectNameA.Length >= OutputBufferLength)
		{
			RtlFreeAnsiString(&objectNameA);
			return STATUS_BUFFER_TOO_SMALL;
		}

		strcpy(OutputBuffer, objectNameA.Buffer);
		RtlFreeAnsiString(&objectNameA);
		return STATUS_SUCCESS;
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		return STATUS_ACCESS_VIOLATION;
	}
}

VOID
PsExitSpecialApc(
	IN PKAPC Apc,
	IN PKNORMAL_ROUTINE *NormalRoutine,
	IN PVOID *NormalContext,
	IN PVOID *SystemArgument1,
	IN PVOID *SystemArgument2
	)
{
	NTSTATUS status;
	NTSTATUS ExitStatus;
	PKTHREAD KThread;
	CHAR ch;

	ExitStatus = (NTSTATUS)((LONG_PTR)Apc->NormalContext);
	ExFreePool(Apc);
	status = PsTerminateSystemThread(ExitStatus);

	if (status == STATUS_INVALID_PARAMETER)
	{
		KThread = KeGetCurrentThread();

		if (*NtBuildNumber == 2195)
		{
			ch = *((PCHAR)KThread + 0x1fc);
			*((PCHAR)KThread + 0x1fc) = '\0';
			//NtTerminateThread((HANDLE)-1, ExitStatus);
			*((PCHAR)KThread + 0x1fc) = ch;
		}
	}
}

NTSTATUS
KillThread(
    IN PVOID ThreadId,
    IN NTSTATUS ExitStatus
	)
{
	NTSTATUS status;
	PETHREAD Thread;
	PKAPC ExitApc;

	status = PsLookupThreadByThreadId(ThreadId, &Thread);

	if (!NT_SUCCESS(status))
		return STATUS_UNSUCCESSFUL;

	status = ObReferenceObjectByPointer(	Thread,
											0x1f03ff,
											*PsThreadType,
											KernelMode);

	if (!NT_SUCCESS(status))
		return STATUS_UNSUCCESSFUL;

	if (Thread == PsGetCurrentThread())
	{
		ObDereferenceObject(Thread);
		PsTerminateSystemThread(ExitStatus);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -