📄 driver.c
字号:
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 + -