Exemple #1
0
static NTSTATUS FASTCALL
BuildWindowStationNameList(
    ULONG dwSize,
    PVOID lpBuffer,
    PULONG pRequiredSize)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
    HANDLE DirectoryHandle;
    char InitialBuffer[256], *Buffer;
    ULONG Context, ReturnLength, BufferSize;
    DWORD EntryCount;
    POBJECT_DIRECTORY_INFORMATION DirEntry;
    WCHAR NullWchar;

    /*
     * Try to open the directory.
     */
    InitializeObjectAttributes(&ObjectAttributes,
                               &gustrWindowStationsDir,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);

    Status = ZwOpenDirectoryObject(&DirectoryHandle,
                                   DIRECTORY_QUERY,
                                   &ObjectAttributes);

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

    /* First try to query the directory using a fixed-size buffer */
    Context = 0;
    Buffer = NULL;
    Status = ZwQueryDirectoryObject(DirectoryHandle,
                                    InitialBuffer,
                                    sizeof(InitialBuffer),
                                    FALSE,
                                    TRUE,
                                    &Context,
                                    &ReturnLength);
    if (NT_SUCCESS(Status))
    {
        if (STATUS_NO_MORE_ENTRIES == ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
                                                             FALSE, &Context, NULL))
        {
            /* Our fixed-size buffer is large enough */
            Buffer = InitialBuffer;
        }
    }

    if (NULL == Buffer)
    {
        /* Need a larger buffer, check how large exactly */
        Status = ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, TRUE, &Context,
                                        &ReturnLength);
        if (!NT_SUCCESS(Status))
        {
            ERR("ZwQueryDirectoryObject failed\n");
            ZwClose(DirectoryHandle);
            return Status;
        }

        BufferSize = ReturnLength;
        Buffer = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_WINSTA);
        if (NULL == Buffer)
        {
            ZwClose(DirectoryHandle);
            return STATUS_NO_MEMORY;
        }

        /* We should have a sufficiently large buffer now */
        Context = 0;
        Status = ZwQueryDirectoryObject(DirectoryHandle, Buffer, BufferSize,
                                        FALSE, TRUE, &Context, &ReturnLength);
        if (! NT_SUCCESS(Status) ||
              STATUS_NO_MORE_ENTRIES != ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
                                                               FALSE, &Context, NULL))
        {
            /* Something went wrong, maybe someone added a directory entry? Just give up. */
            ExFreePoolWithTag(Buffer, TAG_WINSTA);
            ZwClose(DirectoryHandle);
            return NT_SUCCESS(Status) ? STATUS_INTERNAL_ERROR : Status;
        }
    }

    ZwClose(DirectoryHandle);

    /*
     * Count the required size of buffer.
     */
    ReturnLength = sizeof(DWORD);
    EntryCount = 0;
    for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer;
         0 != DirEntry->Name.Length;
         DirEntry++)
    {
        ReturnLength += DirEntry->Name.Length + sizeof(WCHAR);
        EntryCount++;
    }
    TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
    if (NULL != pRequiredSize)
    {
        Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
        if (! NT_SUCCESS(Status))
        {
            if (Buffer != InitialBuffer)
            {
                ExFreePoolWithTag(Buffer, TAG_WINSTA);
            }
            return STATUS_BUFFER_TOO_SMALL;
        }
    }

    /*
     * Check if the supplied buffer is large enough.
     */
    if (dwSize < ReturnLength)
    {
        if (Buffer != InitialBuffer)
        {
            ExFreePoolWithTag(Buffer, TAG_WINSTA);
        }
        return STATUS_BUFFER_TOO_SMALL;
    }

    /*
     * Generate the resulting buffer contents.
     */
    Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
    if (! NT_SUCCESS(Status))
    {
        if (Buffer != InitialBuffer)
        {
            ExFreePoolWithTag(Buffer, TAG_WINSTA);
        }
        return Status;
    }
    lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));

    NullWchar = L'\0';
    for (DirEntry = (POBJECT_DIRECTORY_INFORMATION) Buffer;
         0 != DirEntry->Name.Length;
         DirEntry++)
    {
        Status = MmCopyToCaller(lpBuffer, DirEntry->Name.Buffer, DirEntry->Name.Length);
        if (! NT_SUCCESS(Status))
        {
            if (Buffer != InitialBuffer)
            {
                ExFreePoolWithTag(Buffer, TAG_WINSTA);
            }
            return Status;
        }
        lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->Name.Length);
        Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
        if (! NT_SUCCESS(Status))
        {
            if (Buffer != InitialBuffer)
            {
                ExFreePoolWithTag(Buffer, TAG_WINSTA);
            }
            return Status;
        }
        lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
    }

    /*
     * Clean up
     */
    if (Buffer != InitialBuffer)
    {
        ExFreePoolWithTag(Buffer, TAG_WINSTA);
    }

    return STATUS_SUCCESS;
}
Exemple #2
0
void STDCALL look_for_vols(PDRIVER_OBJECT DriverObject, LIST_ENTRY* volumes) {
    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT mountmgr;
    OBJECT_ATTRIBUTES attr;
    UNICODE_STRING mmdevpath, us;
    HANDLE h;
    OBJECT_DIRECTORY_INFORMATION* odi;
    ULONG odisize;
    ULONG context;
    BOOL restart;
    NTSTATUS Status;
    LIST_ENTRY* le;
    
    static const WCHAR directory[] = L"Directory";
    static const WCHAR harddisk[] = L"Harddisk";
    
    RtlInitUnicodeString(&mmdevpath, MOUNTMGR_DEVICE_NAME);
    Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &FileObject, &mountmgr);
    if (!NT_SUCCESS(Status)) {
        ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
        return;
    }
    
    RtlInitUnicodeString(&us, devpath);
    
    attr.Length = sizeof(attr);
    attr.RootDirectory = 0;
    attr.Attributes = OBJ_CASE_INSENSITIVE;
    attr.ObjectName = &us;
    attr.SecurityDescriptor = NULL;
    attr.SecurityQualityOfService = NULL;

    Status = ZwOpenDirectoryObject(&h, DIRECTORY_TRAVERSE, &attr);

    if (!NT_SUCCESS(Status)) {
        ERR("ZwOpenDirectoryObject returned %08x\n", Status);
        return;
    }
    
    odisize = sizeof(OBJECT_DIRECTORY_INFORMATION) * 16;
    odi = ExAllocatePoolWithTag(PagedPool, odisize, ALLOC_TAG);
    if (!odi) {
        ERR("out of memory\n");
        ZwClose(h);
        return;
    }
    
    restart = TRUE;
    do {
        Status = ZwQueryDirectoryObject(h, odi, odisize, FALSE, restart, &context, NULL/*&retlen*/);
        restart = FALSE;
        
        if (!NT_SUCCESS(Status)) {
            if (Status != STATUS_NO_MORE_ENTRIES)
                ERR("ZwQueryDirectoryObject returned %08x\n", Status);
        } else {
            OBJECT_DIRECTORY_INFORMATION* odi2 = odi;
            
            while (odi2->Name.Buffer) {
                if (odi2->TypeName.Length == wcslen(directory) * sizeof(WCHAR) &&
                    RtlCompareMemory(odi2->TypeName.Buffer, directory, odi2->TypeName.Length) == odi2->TypeName.Length &&
                    odi2->Name.Length > wcslen(harddisk) * sizeof(WCHAR) &&
                    RtlCompareMemory(odi2->Name.Buffer, harddisk, wcslen(harddisk) * sizeof(WCHAR)) == wcslen(harddisk) * sizeof(WCHAR)) {
                        look_in_harddisk_dir(DriverObject, mountmgr, &odi2->Name, volumes);
                }
                
                odi2 = &odi2[1];
            }
        }
    } while (NT_SUCCESS(Status));
    
    ExFreePool(odi);
    ZwClose(h);
    
    le = volumes->Flink;
    while (le != volumes) {
        volume* v = CONTAINING_RECORD(le, volume, list_entry);
        
        if (!v->processed) {
            LIST_ENTRY* le2 = le;
            volume* mountvol = v;
            
            while (le2 != volumes) {
                volume* v2 = CONTAINING_RECORD(le2, volume, list_entry);
                
                if (RtlCompareMemory(&v2->fsuuid, &v->fsuuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
                    v2->processed = TRUE;
                    
                    if (v2->devnum < mountvol->devnum) {
                        remove_drive_letter(mountmgr, mountvol);
                        mountvol = v2;
                    } else if (v2->devnum > mountvol->devnum)
                        remove_drive_letter(mountmgr, v2);
                }
                
                le2 = le2->Flink;
            }
            
            add_volume(mountmgr, &mountvol->devpath);
        }
        
        le = le->Flink;
    }
    
    ObDereferenceObject(FileObject);
}
Exemple #3
0
NTSTATUS Mouse_Hook(IN PDRIVER_OBJECT driverObject)
{
	ULONG i;
	int found = 1;
	NTSTATUS status = STATUS_SUCCESS;
	PIO_STACK_LOCATION stack;
	UNICODE_STRING uniMouseDeviceName;
	PFILE_OBJECT mouseFileObject;
	PDEVICE_OBJECT MouseDeviceObject;
	ULONG counter;
	HANDLE hDir;
	OBJECT_ATTRIBUTES oa;
	UNICODE_STRING uniOa;
	PVOID pBuffer;
	PVOID pContext;
	ULONG RetLen;
	PDIRECTORY_BASIC_INFORMATION pDirBasicInfo;
	UNICODE_STRING uniMouseDrv;
	char* mouseclsNum;
	char arMouseCls[0x10];
	WCHAR tmpNameBuffer[512];

	DbgPrint("Running Mouse_Create.");


	RtlInitUnicodeString(&uniOa, L"\\Device");

	InitializeObjectAttributes(	&oa,&uniOa,	OBJ_CASE_INSENSITIVE,NULL,NULL);

	status = ZwOpenDirectoryObject(	&hDir,DIRECTORY_ALL_ACCESS,&oa);
	if(!NT_SUCCESS(status)) return status;

	pBuffer = ExAllocatePool(PagedPool, ALLOC_SIZE);
	pContext = ExAllocatePool(PagedPool, ALLOC_SIZE);
// 		pBuffer = ExAllocatePoolWithTag(PagedPool, ALLOC_SIZE, Tag);
// 		pContext = ExAllocatePoolWithTag(PagedPool, ALLOC_SIZE, Tag);
	memset(pBuffer, 0, ALLOC_SIZE);
	memset(pContext, 0, ALLOC_SIZE);
	memset(arMouseCls, 0, 0x10);
	counter = 0;
	g_Mouseclsnum = 0;

	while(TRUE)	{
		status = ZwQueryDirectoryObject(hDir,pBuffer,ALLOC_SIZE,TRUE,FALSE,pContext,&RetLen);
		if(!NT_SUCCESS(status)) break;

		pDirBasicInfo =	(PDIRECTORY_BASIC_INFORMATION)pBuffer;
		pDirBasicInfo->ObjectName.Length -= 2;

		RtlInitUnicodeString(&uniMouseDrv, L"PointerClass");

		if(RtlCompareUnicodeString(	&pDirBasicInfo->ObjectName, &uniMouseDrv,FALSE) == 0){
			mouId = (ULONG)(*(char *)(pDirBasicInfo->ObjectName.Buffer+pDirBasicInfo->ObjectName.Length));
			mouId -= 0x30;
			pDirBasicInfo->ObjectName.Length += 2;
			RtlInitUnicodeString(&uniMouseDeviceName, pDirBasicInfo->ObjectName.Buffer);

			found = 1;
			break;
		}
		pDirBasicInfo->ObjectName.Length += 2;
	}
	ExFreePool(pBuffer);
	ExFreePool(pContext);
	ZwClose(hDir);

	if( found == 0 ) return status;
	DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_INFO_LEVEL,"Mouse_Hook ----> mouId[%d].\n", mouId);
				
	swprintf(tmpNameBuffer, L"\\Device\\%s", uniMouseDeviceName.Buffer);
	RtlInitUnicodeString(&uniMouseDeviceName, tmpNameBuffer);

	status = My_IoGetDeviceObjectPointer(&uniMouseDeviceName, FILE_ALL_ACCESS, &mouseFileObject,&MouseDeviceObject);

	if(NT_SUCCESS(status)) {
		g_MouseDeviceObject = MouseDeviceObject;
		ObDereferenceObject(mouseFileObject);
		g_OldReadFunction = g_MouseDeviceObject->DriverObject->MajorFunction[IRP_MJ_READ];
		g_MouseDeviceObject->DriverObject->MajorFunction[IRP_MJ_READ] = Mouse_HookProc;
		g_OldInternalDeviceFunction = g_MouseDeviceObject->DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL];
		g_MouseDeviceObject->DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = Mouse_IO_InternalIoctl;

		DbgPrintEx( DPFLTR_IHVDRIVER_ID,  DPFLTR_INFO_LEVEL,"Mouse_Create ----> Mouse_HookProc success.\n");
	}
	return status;
}
Exemple #4
0
static NTSTATUS look_in_harddisk_dir(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT mountmgr, PUNICODE_STRING name, LIST_ENTRY* volumes) {
    UNICODE_STRING path;
    OBJECT_ATTRIBUTES attr;
    NTSTATUS Status;
    HANDLE h;
    OBJECT_DIRECTORY_INFORMATION* odi;
    ULONG odisize, context;
    BOOL restart, has_part0 = FALSE, has_parts = FALSE;
    
    static const WCHAR partition[] = L"Partition";
    static WCHAR partition0[] = L"Partition0";
    
    path.Buffer = ExAllocatePoolWithTag(PagedPool, ((wcslen(devpath) + 1) * sizeof(WCHAR)) + name->Length, ALLOC_TAG);
    if (!path.Buffer) {
        ERR("out of memory\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    
    RtlCopyMemory(path.Buffer, devpath, wcslen(devpath) * sizeof(WCHAR));
    path.Buffer[wcslen(devpath)] = '\\';
    RtlCopyMemory(&path.Buffer[wcslen(devpath) + 1], name->Buffer, name->Length);
    path.Length = path.MaximumLength = ((wcslen(devpath) + 1) * sizeof(WCHAR)) + name->Length;

    attr.Length = sizeof(attr);
    attr.RootDirectory = 0;
    attr.Attributes = OBJ_CASE_INSENSITIVE;
    attr.ObjectName = &path;
    attr.SecurityDescriptor = NULL;
    attr.SecurityQualityOfService = NULL;
    
    Status = ZwOpenDirectoryObject(&h, DIRECTORY_TRAVERSE, &attr);

    if (!NT_SUCCESS(Status)) {
        ERR("ZwOpenDirectoryObject returned %08x\n", Status);
        goto end;
    }
    
    odisize = sizeof(OBJECT_DIRECTORY_INFORMATION) * 16;
    odi = ExAllocatePoolWithTag(PagedPool, odisize, ALLOC_TAG);
    if (!odi) {
        ERR("out of memory\n");
        Status = STATUS_INSUFFICIENT_RESOURCES;
        ZwClose(h);
        goto end;
    }
    
    restart = TRUE;
    do {
        Status = ZwQueryDirectoryObject(h, odi, odisize, FALSE, restart, &context, NULL/*&retlen*/);
        restart = FALSE;
        
        if (!NT_SUCCESS(Status)) {
            if (Status != STATUS_NO_MORE_ENTRIES)
                ERR("ZwQueryDirectoryObject returned %08x\n", Status);
        } else {
            OBJECT_DIRECTORY_INFORMATION* odi2 = odi;
            
            while (odi2->Name.Buffer) {
                TRACE("%.*S, %.*S\n", odi2->TypeName.Length / sizeof(WCHAR), odi2->TypeName.Buffer, odi2->Name.Length / sizeof(WCHAR), odi2->Name.Buffer);
                
                if (odi2->Name.Length > wcslen(partition) * sizeof(WCHAR) &&
                    RtlCompareMemory(odi2->Name.Buffer, partition, wcslen(partition) * sizeof(WCHAR)) == wcslen(partition) * sizeof(WCHAR)) {
                    
                    if (odi2->Name.Length == (wcslen(partition) + 1) * sizeof(WCHAR) && odi2->Name.Buffer[(odi2->Name.Length / sizeof(WCHAR)) - 1] == '0') {
                        // Partition0 refers to the whole disk
                        has_part0 = TRUE;
                    } else {
                        has_parts = TRUE;
                        
                        test_vol(DriverObject, mountmgr, &path, &odi2->Name, FALSE, volumes);
                    }
                }
                
                odi2 = &odi2[1];
            }
        }
    } while (NT_SUCCESS(Status));
    
    // If disk had no partitions, test the whole disk
    if (!has_parts && has_part0) {
        UNICODE_STRING part0us;
        
        part0us.Buffer = partition0;
        part0us.Length = part0us.MaximumLength = wcslen(partition0) * sizeof(WCHAR);
        
        test_vol(DriverObject, mountmgr, &path, &part0us, TRUE, volumes);
    }
    
    ZwClose(h);
    
    ExFreePool(odi);
    
    Status = STATUS_SUCCESS;
    
end:
    ExFreePool(path.Buffer);
    
    return Status;
}