Пример #1
1
NTSTATUS CreateDllSection(IN IN PUNICODE_STRING pDllName, OUT PHANDLE pSection, OUT PPVOID pBaseAddress)
{
	HANDLE hFile;
	OBJECT_ATTRIBUTES oa = {sizeof oa, 0, pDllName, OBJ_CASE_INSENSITIVE};
	IO_STATUS_BLOCK iosb;
	SIZE_T size=0;
	NTSTATUS status;

	PAGED_CODE();

	ASSERT(pSection&&pBaseAddress);
	*pBaseAddress = NULL;
	status = ZwOpenFile(&hFile, FILE_EXECUTE | SYNCHRONIZE, &oa, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
	if (NT_SUCCESS(status)) {
		oa.ObjectName = 0;
		status = ZwCreateSection(pSection, SECTION_ALL_ACCESS, &oa, 0,PAGE_EXECUTE, SEC_IMAGE, hFile);
		if (NT_SUCCESS(status)) {
			status = ZwMapViewOfSection(*pSection, ZwCurrentProcess(), pBaseAddress, 0, 1000, 0, &size, (SECTION_INHERIT)1, MEM_TOP_DOWN, PAGE_READWRITE);
			if (!NT_SUCCESS(status)) {
				ZwClose(*pSection);
			}
		}
		ZwClose(hFile);
	}
	return status;
}
/**
* 检查文件是否为PE文件
* @param filename 文件路径。
* return 如果文件是PE文件的话否回true,否则返回false。
* 注:现在的方法比较简单,只检查了文件的前两个字节,最好再检查几步。
*/
bool IsPEFile(const PUNICODE_STRING filename)
{
	HANDLE hFile;
	bool bIsPEFile = true;

	OBJECT_ATTRIBUTES oaFile;
	InitializeObjectAttributes(&oaFile, filename, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);

	IO_STATUS_BLOCK ioStatus;
	NTSTATUS status = ZwOpenFile(&hFile, GENERIC_READ, &oaFile, &ioStatus, FILE_SHARE_READ | FILE_SHARE_WRITE, 
		FILE_SYNCHRONOUS_IO_NONALERT);
	if(!NT_SUCCESS(status))
	{
		KdPrint(("IsPEFile: ZwOpenFile: %ws %08x\n", filename->Buffer, status));
		return true;
	}

	USHORT PESig;
	LARGE_INTEGER offset;
	offset.QuadPart = 0;
	ZwReadFile(hFile, NULL, NULL, NULL, &ioStatus, &PESig, 2, &offset, NULL);

	if(PESig != 'ZM')
		bIsPEFile = false;

	ZwClose(hFile);
	return bIsPEFile;
}
Пример #3
0
/*
 * OpenInputDevice
 *
 * Opens input device for asynchronous access
 */
static
NTSTATUS NTAPI
OpenInputDevice(PHANDLE pHandle, PFILE_OBJECT *ppObject, CONST WCHAR *pszDeviceName)
{
    UNICODE_STRING DeviceName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
    IO_STATUS_BLOCK Iosb;

    RtlInitUnicodeString(&DeviceName, pszDeviceName);

    InitializeObjectAttributes(&ObjectAttributes,
                               &DeviceName,
                               0,
                               NULL,
                               NULL);

    Status = ZwOpenFile(pHandle,
                        FILE_ALL_ACCESS,
                        &ObjectAttributes,
                        &Iosb,
                        0,
                        0);
    if (NT_SUCCESS(Status) && ppObject)
    {
        Status = ObReferenceObjectByHandle(*pHandle, SYNCHRONIZE, NULL, KernelMode, (PVOID*)ppObject, NULL);
        ASSERT(NT_SUCCESS(Status));
    }

    return Status;
}
//
//	Reads or writes specified number of sectors from/to the specified buffer.
//
NTSTATUS _stdcall BkSectorIo(
	PUNICODE_STRING	DriveName,		// drive name to read/write sectors from/to
	PCHAR			Buffer,			// bufer to store the data
	ULONG			Length,			// size of the buffer
	ULONGLONG		StartSector,	// starting LBA sector
	ULONG			Count,			// number of sectors to read/write
	ULONG			Flags			// variouse operation flags
	)
{
	HANDLE		hDrive;
	NTSTATUS	ntStatus = STATUS_BUFFER_TOO_SMALL;
	OBJECT_ATTRIBUTES	oa = {0};
	IO_STATUS_BLOCK		IoStatus = {0};
	LARGE_INTEGER		FilePos = {0};
	ULONG	ObjectFlags = OBJ_CASE_INSENSITIVE;

#ifdef _M_AMD64
	if ((ULONG_PTR)&ObjectFlags & 0x8000000000000000)
#else
	if ((ULONG_PTR)&ObjectFlags & 0x80000000)
#endif
		ObjectFlags |= OBJ_KERNEL_HANDLE;

	InitializeObjectAttributes(&oa, DriveName, ObjectFlags, NULL, NULL);

	if ((Count * BIOS_DEFAULT_SECTOR_SIZE) <= Length)
	{
//		ntStatus = ZwCreateFile(&hDrive, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &oa, &IoStatus, NULL, 0, 
//			FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);

		ntStatus = ZwOpenFile(&hDrive, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &oa, &IoStatus,
			FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
	
		if (NT_SUCCESS(ntStatus))
		{
			FilePos.QuadPart = (StartSector * BIOS_DEFAULT_SECTOR_SIZE);

			if (Flags & BK_IO_WRITE)
				ntStatus = ZwWriteFile(hDrive, 0, NULL, NULL, &IoStatus, Buffer, (Count*BIOS_DEFAULT_SECTOR_SIZE), &FilePos, NULL);
			else
				ntStatus = ZwReadFile(hDrive, 0, NULL, NULL, &IoStatus, Buffer, (Count*BIOS_DEFAULT_SECTOR_SIZE), &FilePos, NULL);

			ZwClose(hDrive);
		}	// if (hDrive != INVALID_HANDLE_VALUE)
	}	// 	if ((Count * BIOS_DEFAULT_SECTOR_SIZE) <= Length)
 
   return(ntStatus);
}
Пример #5
0
NTSTATUS
NTAPI
RtlpMapFile(PUNICODE_STRING ImageFileName,
            ULONG Attributes,
            PHANDLE Section)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
    HANDLE hFile = NULL;
    IO_STATUS_BLOCK IoStatusBlock;

    /* Open the Image File */
    InitializeObjectAttributes(&ObjectAttributes,
                               ImageFileName,
                               Attributes & (OBJ_CASE_INSENSITIVE | OBJ_INHERIT),
                               NULL,
                               NULL);
    Status = ZwOpenFile(&hFile,
                        SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_DELETE | FILE_SHARE_READ,
                        FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to read image file from disk, Status = 0x%08X\n", Status);
        return Status;
    }

    /* Now create a section for this image */
    Status = ZwCreateSection(Section,
                             SECTION_ALL_ACCESS,
                             NULL,
                             NULL,
                             PAGE_EXECUTE,
                             SEC_IMAGE,
                             hFile);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to create section for image file, Status = 0x%08X\n", Status);
    }

    ZwClose(hFile);
    return Status;
}
Пример #6
0
NTSTATUS
RtlpOpenImageFile(
    IN PUNICODE_STRING ImagePathName,
    IN ULONG Attributes,
    OUT PHANDLE FileHandle,
    IN BOOLEAN ReportErrors
    )
{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE File;
    IO_STATUS_BLOCK IoStatus;

    *FileHandle = NULL;

    InitializeObjectAttributes( &ObjectAttributes,
                                ImagePathName,
                                Attributes,
                                NULL,
                                NULL
                              );
    Status = ZwOpenFile( &File,
                         SYNCHRONIZE | FILE_EXECUTE,
                         &ObjectAttributes,
                         &IoStatus,
                         FILE_SHARE_READ | FILE_SHARE_DELETE,
                         FILE_NON_DIRECTORY_FILE
                         );

    if (!NT_SUCCESS( Status )) {
#if DBG
        if (ReportErrors) {
            DbgPrint( "NTRTL: RtlpOpenImageFile - NtCreateFile( %wZ ) failed.  Status == %X\n",
                      ImagePathName,
                      Status
                    );
            }
#endif // DBG
        return( Status );
        }

    *FileHandle = File;
    return( STATUS_SUCCESS );
}
Пример #7
0
NTSTATUS getFileIdOA(POBJECT_ATTRIBUTES OA, PLARGE_INTEGER result) {
  WCHAR buf[1024];
  NTSTATUS status;  
  HANDLE hfile;
  IO_STATUS_BLOCK iostatus;

  UNICODE_STRING t1, t2, t3, obj;
  int ok=0;

  if (!getFullPath(buf, sizeof(buf), OA)) {
    uwcscpy(buf, OA->ObjectName);
  }
  debugOutput(L"getFileIdOA object=");
  debugOutput(buf);
  debugOutput(L"\n");

  RtlInitUnicodeString(&obj, buf);
  RtlInitUnicodeString(&t1, L"\\device\\harddisk");
  RtlInitUnicodeString(&t2, L"\\??\\");
  RtlInitUnicodeString(&t3, L"\\device\\lanmanredirector");

  if (RtlPrefixUnicodeString(&t1, &obj, TRUE)) ok = 1;
  else if (RtlPrefixUnicodeString(&t2, &obj, TRUE)) {
    if (obj.Length > 5*sizeof(WCHAR) && obj.Buffer[5]==L':') ok=1;
  }
  else if (RtlPrefixUnicodeString(&t3, &obj, TRUE)) {
    ok=1;
  }
  if (!ok) return STATUS_OBJECT_NAME_INVALID;


  status = ZwOpenFile(&hfile,
		      0,
		      OA,
		      &iostatus,
		      0,
		      0);

  if (status == STATUS_SUCCESS) {
    status = getFileIdHandle(hfile, result);
    ZwClose(hfile);
  }
  return status;
}
Пример #8
0
NTSTATUS CWdfDevice::CreateUserModeHandle(HANDLE RequestorProcess, PHANDLE ObjectHandle)
{
    IO_STATUS_BLOCK IoStatusBlock;
    PCUNICODE_STRING UniName = m_CachedName;

    OBJECT_ATTRIBUTES ObjectAttributes;
    InitializeObjectAttributes(&ObjectAttributes,
                               const_cast<PUNICODE_STRING>(UniName),
                               OBJ_KERNEL_HANDLE,
                               nullptr, nullptr);

    HANDLE KernelHandle;
    auto status = ZwOpenFile(&KernelHandle,
                             GENERIC_READ | GENERIC_WRITE,
                             &ObjectAttributes, &IoStatusBlock, 0,
                             FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS);
    if (!NT_SUCCESS(status))
    {
        return status;
    }

    status = ZwDuplicateObject(ZwCurrentProcess(),
                               KernelHandle,
                               RequestorProcess,
                               ObjectHandle,
                               0,
                               0,
                               DUPLICATE_SAME_ACCESS |
                               DUPLICATE_SAME_ATTRIBUTES |
                               DUPLICATE_CLOSE_SOURCE);

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_WDFDEVICE, "%!FUNC! ZwDuplicateObject failed. %!STATUS!", status);
        ZwClose(KernelHandle);
    }

    return status;
}
Пример #9
0
/*
* @implemented
*/
NTSTATUS
NTAPI
RtlLockBootStatusData(OUT PHANDLE FileHandle)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatusBlock;
    UNICODE_STRING FileName;
    HANDLE LocalFileHandle;
    NTSTATUS Status;

    /* Intialize the file handle */
    *FileHandle = NULL;

    /* Initialize the file name */
    RtlInitUnicodeString(&FileName,
                         L"\\SystemRoot\\bootstat.dat");

    /* Initialize the object attributes */
    InitializeObjectAttributes(&ObjectAttributes,
                               &FileName,
                               0,
                               NULL,
                               NULL);

    /* Open the boot status data file */
    Status = ZwOpenFile(&LocalFileHandle,
                        FILE_ALL_ACCESS,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        0,
                        FILE_SYNCHRONOUS_IO_NONALERT);
    if (NT_SUCCESS(Status))
    {
        /* Return the file handle */
        *FileHandle = LocalFileHandle;
    }

    return Status;
}
Пример #10
0
//
//	Searches for free disk space to allocate FS area there.
//
NTSTATUS FsLibGetFsArea(
	IN OUT	PBK_FS_AREA	pFsArea
	)
{
	PVOID		WorkBuffer = NULL;
	NTSTATUS	ntStatus;
	OBJECT_ATTRIBUTES	oa;
	IO_STATUS_BLOCK		IoStatus;

	pFsArea->pDeviceName = &g_FsVolumeDevice;
	InitializeObjectAttributes(&oa, pFsArea->pDeviceName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
	
	ntStatus = ZwOpenFile(&pFsArea->hDevice, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &oa, &IoStatus, 
		FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);

	if (NT_SUCCESS(ntStatus))
	{
		if (WorkBuffer = MyAllocatePool(PagedPool, PAGE_SIZE))
		{
			// Searching for FS area.
			ntStatus = BkAllocateFsArea(pFsArea, WorkBuffer);
			MyFreePool(WorkBuffer);
		}	// if (WorkBuffer = MyAllocatePool(PagedPool, PAGE_SIZE)) 
		else
			ntStatus = STATUS_INSUFFICIENT_RESOURCES;

		ZwClose(pFsArea->hDevice);
	}	// if (NT_SUCCESS(ntStatus))

	if (!NT_SUCCESS(ntStatus))
	{
		KdPrint(("VFS: Unable to allocate FS area, status 0x%x\n", ntStatus));
	}

	return(ntStatus);
}
Пример #11
0
/*! \brief Loads a symbol file.
 *
 * \param FileName    Filename of the symbol file to load.
 * \param RosSymInfo  Pointer to a ROSSYM_INFO which gets filled.
 *
 * \sa KdbpSymUnloadModuleSymbols
 */
VOID
KdbpSymLoadModuleSymbols(
    IN PUNICODE_STRING FileName,
    OUT PROSSYM_INFO *RosSymInfo)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE FileHandle;
    NTSTATUS Status;
    IO_STATUS_BLOCK IoStatusBlock;
    PFILE_OBJECT FileObject;
    PROSSYM_KM_OWN_CONTEXT FileContext;

    /* Allow KDB to break on module load */
    KdbModuleLoaded(FileName);

    if (!LoadSymbols)
    {
        *RosSymInfo = NULL;
        return;
    }

    /*  Try to find cached (already loaded) symbol file  */
    *RosSymInfo = KdbpSymFindCachedFile(FileName);
    if (*RosSymInfo)
    {
        DPRINT("Found cached symbol file %wZ\n", FileName);
        return;
    }

    /*  Open the file  */
    InitializeObjectAttributes(&ObjectAttributes,
                               FileName,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);

    DPRINT("Attempting to open image: %wZ\n", FileName);

    Status = ZwOpenFile(&FileHandle,
                        FILE_READ_ACCESS | SYNCHRONIZE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Could not open image file(%x): %wZ\n", Status, FileName);
        return;
    }

    DPRINT("Loading symbols from %wZ...\n", FileName);

    Status = ObReferenceObjectByHandle
        (FileHandle,
         FILE_READ_DATA | SYNCHRONIZE,
         NULL,
         KernelMode,
         (PVOID*)&FileObject,
         NULL);

    if (!NT_SUCCESS(Status))
    {
        DPRINT("Could not get the file object\n");
        ZwClose(FileHandle);
        return;
    }

    if ((FileContext = KdbpCaptureFileForSymbols(FileObject)))
    {
        if (RosSymCreateFromFile(FileContext, RosSymInfo))
        {
            /* add file to cache */
            int i;
            UNICODE_STRING TruncatedName = *FileName;
            for (i = (TruncatedName.Length / sizeof(WCHAR)) - 1; i >= 0; i--)
                if (TruncatedName.Buffer[i] == '\\') {
                    TruncatedName.Buffer += i+1;
                    TruncatedName.Length -= (i+1)*sizeof(WCHAR);
                    TruncatedName.MaximumLength -= (i+1)*sizeof(WCHAR);
                    break;
                }
            KdbpSymAddCachedFile(&TruncatedName, *RosSymInfo);
            DPRINT("Installed symbols: %wZ %p\n", &TruncatedName, *RosSymInfo);
        }
        KdbpReleaseFileForSymbols(FileContext);
    }

    ObDereferenceObject(FileObject);
    ZwClose(FileHandle);
}
Пример #12
0
NTSTATUS
MuInitializeUserModeHelper (
    PMU_GLOBAL_DATA GlobalData
)
{
    NTSTATUS status;
    HANDLE file, proc, dllsec;
    SIZE_T imgsize = 0;
    PVOID secobj, dllbase = NULL;
    LARGE_INTEGER secofs;
    UNICODE_STRING fp;
    IO_STATUS_BLOCK iosb;
    OBJECT_ATTRIBUTES oa;
    WCHAR path[MAX_PATH];
    
    wcscpy(path, MU_ROOTDIR_SYSTEM32);
    wcscat(path, MU_FILENAME_HELPER_DLL);
    
    RtlInitUnicodeString(&fp, path);
    
    InitializeObjectAttributes(&oa,
                               &fp,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);
    
    status = ZwOpenFile(&file,
                        GENERIC_READ,
                        &oa,
                        &iosb,
                        FILE_SHARE_READ,
                        FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    
    if (NT_SUCCESS(status))
    {
        status = ZwCreateSection(&dllsec,
                                 SECTION_ALL_ACCESS,
                                 NULL,
                                 NULL,
                                 PAGE_EXECUTE_READWRITE,
                                 SEC_IMAGE,
                                 file);
        
        ZwClose(file);
        
        if (!NT_SUCCESS(status))
            return status;
            
        status = ObReferenceObjectByHandle(dllsec,
                                           SECTION_ALL_ACCESS,
                                           *MmSectionObjectType,
                                           KernelMode,
                                           &secobj,
                                           NULL);
        
        ZwClose(dllsec);
        
        if (NT_SUCCESS(status))
        {
            secofs.QuadPart = 0;
            
            status = MmMapViewOfSection(secobj,
                                        PsGetCurrentProcess(),
                                        &dllbase,
                                        0,
                                        0,
                                        &secofs,
                                        &imgsize,
                                        ViewShare,
                                        0,
                                        PAGE_EXECUTE_READWRITE);
            
            if (NT_SUCCESS(status))
            {
                status = MuLinkDll(GlobalData, dllbase);
                
                MmUnmapViewOfSection(PsGetCurrentProcess(), dllbase);
            }
            
            if (!NT_SUCCESS(status))
            {
                ObDereferenceObject(secobj);
                
                secobj = NULL;
            }
            
            GlobalData->DllSection   = secobj;
            GlobalData->DllImageSize = imgsize;
            GlobalData->DllImageBase = dllbase;
        }
    }
    
    return status;
}
Пример #13
0
static NTSTATUS
RtlpSysVolTakeOwnership(IN PUNICODE_STRING DirectoryPath,
                        IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
    TOKEN_PRIVILEGES TokenPrivileges;
    OBJECT_ATTRIBUTES ObjectAttributes;
    SECURITY_DESCRIPTOR AbsSD;
    PSID AdminSid = NULL;
    IO_STATUS_BLOCK IoStatusBlock;
    BOOLEAN TokenEnabled = FALSE;
    HANDLE hToken = NULL;
    HANDLE hDirectory = NULL;
    NTSTATUS Status;
    ULONG ReturnLength;

    Status = ZwOpenProcessToken(NtCurrentProcess(),
                                TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
                                &hToken);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* attempt to enable the SE_TAKE_OWNERSHIP_PRIVILEGE privilege */
    TokenPrivileges.PrivilegeCount = 1;
    TokenPrivileges.Privileges[0].Luid.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE;
    TokenPrivileges.Privileges[0].Luid.HighPart = 0;
    TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    Status = ZwAdjustPrivilegesToken(hToken,
                                     FALSE,
                                     &TokenPrivileges,
                                     sizeof(TokenPrivileges),
                                     &TokenPrivileges,
                                     &ReturnLength);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }
    TokenEnabled = (TokenPrivileges.PrivilegeCount != 0);

    /* open the directory */
    InitializeObjectAttributes(&ObjectAttributes,
                               DirectoryPath,
                               0,
                               NULL,
                               SecurityDescriptor);

    Status = ZwOpenFile(&hDirectory,
                        SYNCHRONIZE | WRITE_OWNER,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* create the Administrators SID */
    Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
                                         2,
                                         SECURITY_BUILTIN_DOMAIN_RID,
                                         DOMAIN_ALIAS_RID_ADMINS,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         0,
                                         &AdminSid);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* create the security descriptor */
    Status = RtlCreateSecurityDescriptor(&AbsSD,
                                         SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = RtlSetOwnerSecurityDescriptor(&AbsSD,
                                           AdminSid,
                                           FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* attempt to take ownership */
    Status = ZwSetSecurityObject(hDirectory,
                                 OWNER_SECURITY_INFORMATION,
                                 &AbsSD);

Cleanup:
    if (TokenEnabled)
    {
        ZwAdjustPrivilegesToken(hToken,
                                FALSE,
                                &TokenPrivileges,
                                0,
                                NULL,
                                NULL);
    }

    if (AdminSid != NULL)
    {
        RtlFreeSid(AdminSid);
    }

    if (hDirectory != NULL)
    {
        ZwClose(hDirectory);
    }

    if (hToken != NULL)
    {
        ZwClose(hToken);
    }

    return Status;
}
Пример #14
0
NTSTATUS
GetNextReparseVolumePath(
    IN  HANDLE          Handle,
    OUT PUNICODE_STRING Path
    )

/*++

Routine Description:

    This routine queries the reparse index for the next volume mount point.

Arguments:

    Handle  - Supplies the handle.

    Path    - Returns the path.


Return Value:

    NTSTATUS

--*/

{
    NTSTATUS                        status;
    IO_STATUS_BLOCK                 ioStatus;
    FILE_REPARSE_POINT_INFORMATION  reparseInfo;
    UNICODE_STRING                  fileId;
    OBJECT_ATTRIBUTES               oa;
    HANDLE                          h;
    PREPARSE_DATA_BUFFER            reparse;
    UNICODE_STRING                  volumeName;
    ULONG                           nameInfoSize;
    PFILE_NAME_INFORMATION          nameInfo;

    for (;;) {

        status = ZwQueryDirectoryFile(Handle, NULL, NULL, NULL, &ioStatus,
                                      &reparseInfo, sizeof(reparseInfo),
                                      FileReparsePointInformation, TRUE, NULL,
                                      FALSE);
        if (!NT_SUCCESS(status)) {
            return status;
        }

        if (reparseInfo.Tag != IO_REPARSE_TAG_MOUNT_POINT) {
            continue;
        }

        fileId.Length = sizeof(reparseInfo.FileReference);
        fileId.MaximumLength = fileId.Length;
        fileId.Buffer = (PWSTR) &reparseInfo.FileReference;

        InitializeObjectAttributes(&oa, &fileId, 0, Handle, NULL);

        status = ZwOpenFile(&h, SYNCHRONIZE | FILE_GENERIC_READ, &oa,
                            &ioStatus, FILE_SHARE_READ | FILE_SHARE_WRITE,
                            FILE_OPEN_BY_FILE_ID | FILE_OPEN_REPARSE_POINT |
                            FILE_SYNCHRONOUS_IO_ALERT);
        if (!NT_SUCCESS(status)) {
            continue;
        }

        reparse = ExAllocatePool(PagedPool, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
        if (!reparse) {
            ZwClose(h);
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        status = ZwFsControlFile(h, NULL, NULL, NULL, &ioStatus,
                                 FSCTL_GET_REPARSE_POINT, NULL, 0, reparse,
                                 MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
        if (!NT_SUCCESS(status)) {
            ExFreePool(reparse);
            ZwClose(h);
            continue;
        }

        volumeName.Length = reparse->MountPointReparseBuffer.SubstituteNameLength -
                            sizeof(WCHAR);
        volumeName.MaximumLength = volumeName.Length + sizeof(WCHAR);
        volumeName.Buffer = (PWCHAR)
                            ((PCHAR) reparse->MountPointReparseBuffer.PathBuffer +
                            reparse->MountPointReparseBuffer.SubstituteNameOffset);
        volumeName.Buffer[volumeName.Length/sizeof(WCHAR)] = 0;

        if (!IsVolumeName(&volumeName)) {
            ExFreePool(reparse);
            ZwClose(h);
            continue;
        }

        ExFreePool(reparse);

        nameInfoSize = 1024;
        nameInfo = ExAllocatePool(PagedPool, nameInfoSize);
        if (!nameInfo) {
            ZwClose(h);
            continue;
        }

        status = ZwQueryInformationFile(h, &ioStatus, nameInfo, nameInfoSize,
                                        FileNameInformation);
        ZwClose(h);
        if (!NT_SUCCESS(status)) {
            continue;
        }

        Path->Length = (USHORT) nameInfo->FileNameLength;
        Path->MaximumLength = Path->Length + sizeof(WCHAR);
        Path->Buffer = ExAllocatePool(PagedPool, Path->MaximumLength);
        if (!Path->Buffer) {
            ExFreePool(nameInfo);
            continue;
        }

        RtlCopyMemory(Path->Buffer, nameInfo->FileName, Path->Length);
        Path->Buffer[Path->Length/sizeof(WCHAR)] = 0;

        ExFreePool(nameInfo);
        break;
    }

    return status;
}
Пример #15
0
NTSTATUS
OpenDeviceReparseIndex(
    IN  PUNICODE_STRING DeviceName,
    OUT PHANDLE         Handle
    )

/*++

Routine Description:

    This routine opens the reparse index on the given device.

Arguments:

    DeviceName  - Supplies the device name.

    Handle      - Returns the handle.

Return Value:

    NTSTATUS

--*/

{
    NTSTATUS            status;
    PFILE_OBJECT        fileObject;
    PDEVICE_OBJECT      deviceObject;
    UNICODE_STRING      reparseSuffix, reparseName;
    OBJECT_ATTRIBUTES   oa;
    IO_STATUS_BLOCK     ioStatus;

    status = IoGetDeviceObjectPointer(DeviceName, FILE_READ_ATTRIBUTES,
                                      &fileObject, &deviceObject);
    if (!NT_SUCCESS(status)) {
        return status;
    }
    deviceObject = fileObject->DeviceObject;

    if (!deviceObject->Vpb || !(deviceObject->Vpb->Flags&VPB_MOUNTED)) {
        ObDereferenceObject(fileObject);
        return STATUS_UNSUCCESSFUL;
    }

    ObDereferenceObject(fileObject);

    RtlInitUnicodeString(&reparseSuffix,
                         L"\\$Extend\\$Reparse:$R:$INDEX_ALLOCATION");
    reparseName.Length = DeviceName->Length + reparseSuffix.Length;
    reparseName.MaximumLength = reparseName.Length + sizeof(WCHAR);
    reparseName.Buffer = ExAllocatePool(PagedPool, reparseName.MaximumLength);
    if (!reparseName.Buffer) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlCopyMemory(reparseName.Buffer, DeviceName->Buffer, DeviceName->Length);
    RtlCopyMemory((PCHAR) reparseName.Buffer + DeviceName->Length,
                  reparseSuffix.Buffer, reparseSuffix.Length);
    reparseName.Buffer[reparseName.Length/sizeof(WCHAR)] = 0;

    InitializeObjectAttributes(&oa, &reparseName, OBJ_CASE_INSENSITIVE, 0, 0);
    status = ZwOpenFile(Handle, SYNCHRONIZE | FILE_LIST_DIRECTORY, &oa,
                        &ioStatus, FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT |
                        FILE_OPEN_FOR_BACKUP_INTENT);

    ExFreePool(reparseName.Buffer);

    return status;
}
Пример #16
0
NTSTATUS
QueryDeviceNameForPath(
    IN  PUNICODE_STRING Path,
    OUT PUNICODE_STRING DeviceName
    )

/*++

Routine Description:

    This routine returns the device name for the given path.  It first checks
    to see if the path is a symbolic link and then checks to see if it is a
    volume reparse point.

Arguments:

    Path        - Supplies the path.

    DeviceName  - Returns the device name.

Return Value:

    NTSTATUS

--*/

{
    NTSTATUS                status;
    OBJECT_ATTRIBUTES       oa;
    HANDLE                  h;
    IO_STATUS_BLOCK         ioStatus;
    PREPARSE_DATA_BUFFER    reparse;
    UNICODE_STRING          volumeName;

    status = QuerySymbolicLink(Path, DeviceName);
    if (NT_SUCCESS(status)) {
        return status;
    }

    InitializeObjectAttributes(&oa, Path, OBJ_CASE_INSENSITIVE, 0, 0);
    status = ZwOpenFile(&h, SYNCHRONIZE | FILE_GENERIC_READ, &oa, &ioStatus,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_ALERT);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    reparse = ExAllocatePool(PagedPool, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
    if (!reparse) {
        ZwClose(h);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = ZwFsControlFile(h, NULL, NULL, NULL, &ioStatus,
                             FSCTL_GET_REPARSE_POINT, NULL, 0, reparse,
                             MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
    ZwClose(h);
    if (!NT_SUCCESS(status)) {
        ExFreePool(reparse);
        return status;
    }

    volumeName.Length = reparse->MountPointReparseBuffer.SubstituteNameLength -
                        sizeof(WCHAR);
    volumeName.MaximumLength = volumeName.Length + sizeof(WCHAR);
    volumeName.Buffer = (PWCHAR)
                        ((PCHAR) reparse->MountPointReparseBuffer.PathBuffer +
                        reparse->MountPointReparseBuffer.SubstituteNameOffset);
    volumeName.Buffer[volumeName.Length/sizeof(WCHAR)] = 0;

    status = QuerySymbolicLink(&volumeName, DeviceName);
    ExFreePool(reparse);

    return status;
}
Пример #17
0
NTSTATUS Log_Rotate()
{
	NTSTATUS Status = STATUS_SUCCESS;
	HANDLE hFile = NULL;
	OBJECT_ATTRIBUTES fAttrs;
	UNICODE_STRING FileName;
	IO_STATUS_BLOCK StatusBlock = { 0 };
	ULONG RotateIndex = 0;
	FILE_RENAME_INFORMATION *RenameBuffer = NULL;
	LPCWSTR BaseFileName = LogFileName;
	ULONG BaseFileNameLength = 0;

	if (!LogFileName || !LogFile)
		return STATUS_INVALID_DEVICE_STATE;

	LPWSTR End1 = wcsrchr(LogFileName, L'\\'), End2 = wcsrchr(LogFileName, L'/');
	if ((SIZE_T)End1 > (SIZE_T)End2 > 0)
		BaseFileName = End1 ? End1 + 1 : LogFileName;
	else
		BaseFileName = End2 ? End2 + 1 : LogFileName;
	BaseFileNameLength = (ULONG)(wcslen(BaseFileName) + 4) * sizeof(WCHAR);

	ULONG FileNameLength = (ULONG)(wcslen(LogFileName) + 5) * sizeof(WCHAR);
	RenameBuffer = ExAllocatePoolWithTag(PagedPool, FileNameLength + FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName),
		LogAllocationTag);
	if (!RenameBuffer) {
		Status = STATUS_INSUFFICIENT_RESOURCES;
		goto Cleanup;
	}
	RenameBuffer->FileNameLength = BaseFileNameLength;
	RenameBuffer->ReplaceIfExists = FALSE;
	RenameBuffer->RootDirectory = NULL;

	// Rename already rotated files first
	Status = StringCbPrintf(RenameBuffer->FileName, FileNameLength, L"%ws.%03d", LogFileName, LogSettings.MaxKeptRotatedFiles);
	if (!SUCCEEDED(Status))
		goto Cleanup;
	RtlInitUnicodeString(&FileName, RenameBuffer->FileName);
	InitializeObjectAttributes(&fAttrs, &FileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
	ZwDeleteFile(&fAttrs);

	for (RotateIndex = LogSettings.MaxKeptRotatedFiles - 1; RotateIndex > 0; RotateIndex--)
	{
		Status = StringCbPrintf(RenameBuffer->FileName, FileNameLength, L"%ws.%03d", LogFileName, RotateIndex);
		if (!SUCCEEDED(Status))
			goto Cleanup;
		RtlInitUnicodeString(&FileName, RenameBuffer->FileName);
		InitializeObjectAttributes(&fAttrs, &FileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
		Status = ZwOpenFile(&hFile, DELETE, &fAttrs, &StatusBlock, 0, 0);
		if (!NT_SUCCESS(Status))
			continue;

		Status = StringCbPrintf(RenameBuffer->FileName, FileNameLength, L"%ws.%03d", BaseFileName, RotateIndex + 1);
		if (!SUCCEEDED(Status))
			goto Cleanup;
		Status = ZwSetInformationFile(hFile, &StatusBlock, RenameBuffer, FileNameLength + FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName),
			FileRenameInformation);
		if (!NT_SUCCESS(Status))
			goto Cleanup;

		ZwClose(hFile);
		hFile = NULL;
	}

	// Rename it
	Status = StringCbPrintf(RenameBuffer->FileName, FileNameLength, L"%ws.%03d", BaseFileName, 1);
	if (!SUCCEEDED(Status))
		goto Cleanup;

	// Compress
	Status = Log_CompressFile(LogFile);

	Status = ZwSetInformationFile(LogFile, &StatusBlock, RenameBuffer, FileNameLength + FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName),
		FileRenameInformation);
	if (!NT_SUCCESS(Status))
		goto Cleanup;

	// And start logging into the new file
	ZwClose(LogFile);
	LogFile = NULL;
	Status = Log_StartFileLogging(LogFileName);

Cleanup:
	if (hFile)
		ZwClose(hFile);
	if (RenameBuffer)
		ExFreePoolWithTag(RenameBuffer, LogAllocationTag);
	
	return Status;
}
Пример #18
0
PPROVIDER_DEF
ReplLookupProvider(
    ULONG ProviderId
) {
    NTSTATUS Status;
    PPROVIDER_DEF pProv;
    HANDLE   hProvider = NULL;
    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK ioStatusBlock;
    OBJECT_HANDLE_INFORMATION handleInformation;
    PFILE_OBJECT    fileObject;
    int i;

    DfsDbgTrace(+1, Dbg, "ReplLookupProvider Entered: id = %x\n", ProviderId);

    for (pProv = DfsData.pProvider, i=0; i<DfsData.cProvider; pProv++, i++) {

        if (ProviderId == pProv->eProviderId) {

            if (pProv->FileObject == NULL) {

                DfsDbgTrace(0, Dbg, "Provider device not been referenced yet\n", 0);

                //
                // We haven't opened a handle to the provider yet - so
                // lets try to.
                //

                if (pProv->DeviceName.Buffer) {

                    //
                    // Get a handle to the provider.
                    //

                    DfsDbgTrace(0, Dbg, "About to open %wZ\n", &pProv->DeviceName);

                    InitializeObjectAttributes(
                        &objectAttributes,
                        &pProv->DeviceName,
                        OBJ_CASE_INSENSITIVE,    // Attributes
                        0,                       // Root Directory
                        NULL                     // Security
                        );

                    Status = ZwOpenFile(
                                &hProvider,
                                FILE_TRAVERSE,
                                &objectAttributes,
                                &ioStatusBlock,
                                FILE_SHARE_READ | FILE_SHARE_WRITE,
                                FILE_DIRECTORY_FILE
                                );

                    if ( NT_SUCCESS( Status ) ) {
                        Status = ioStatusBlock.Status;
                    }

                    DfsDbgTrace(0, Dbg, "Open returned %08lx\n", Status);

                    if ( NT_SUCCESS( Status ) ) {

                        //
                        // Increment ref count on objects
                        //

                        Status = ObReferenceObjectByHandle(
                                    hProvider,
                                    0,
                                    NULL,
                                    KernelMode,
                                    (PVOID *)&fileObject,
                                    &handleInformation
                             );

                        //
                        // We have to do this because the pProv structure is in paged
                        // pool, and ObReferenceObjectByHandle requires the fileObject
                        // argument in NonPaged memory. So, we pass in a stack variable
                        // to ObReferenceObjectByHandle, then copy it to pProv->FileObject
                        //

                        pProv->FileObject = fileObject;

                        ASSERT( NT_SUCCESS( Status ) );

                        pProv->DeviceObject = IoGetRelatedDeviceObject(
                                                        pProv->FileObject
                                                        );
                        Status = ObReferenceObjectByPointer(
                                    pProv->DeviceObject,
                                    0,
                                    NULL,
                                    KernelMode
                             );


                        ASSERT( pProv->DeviceObject->StackSize < 6 );   // see dsinit.c

                        ZwClose(hProvider);

                        DfsDbgTrace(-1, Dbg, "ReplLookupProvider Exited: "
                                    "Provider Def @ %08lx\n", pProv);
                        return pProv;

                    } else {

                        return NULL;

                    }

                }

            } else {

                DfsDbgTrace(-1, Dbg, "ReplLookupProvider Exited: "
                           "Provider Def @ %08lx\n", pProv);
                return pProv;

            } // If pProv->FileObject == NULL

        } // If ProviderId == pProv->eProviderId

    } // For all provider defs

    DfsDbgTrace(-1, Dbg, "ReplLookupProvider Exited: Failed!", 0);

    return NULL;
}
/**
* 先检测黑名单,如果在黑名单内,直接拒,否则放行。
   如果不在黑名单,则检查白名单,在白名单内,无操作。
     如果不在白名单内,则将文件全路径及hash值传递到上层
* @param filename 文件全路径。
* return 如果文件安全则返回true,否则返回false。
*/
bool CheckIsFileHashSecure(const PUNICODE_STRING filename)
{
	/////////////////////////////////////////////

	// 比较已经过滤的文件名
	if(IsInBlackCache(filename) == true)
		return false;
	///////////////////////////////////////

	HANDLE hFile;
	OBJECT_ATTRIBUTES oaFile;
	InitializeObjectAttributes(&oaFile, filename, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);

	// 读权限打开文件,如果失败则认为文件不安全,返回false。
	IO_STATUS_BLOCK ioStatus;
	NTSTATUS status = ZwOpenFile(&hFile, GENERIC_READ, &oaFile, &ioStatus, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
	if(!NT_SUCCESS(status))
	{
		KdPrint(("VerifyModule: ZwOpenFile: %ws %08x\n", filename->Buffer, status));
		return false;
	}

	unsigned char* fileBuf = (unsigned char*)ExAllocatePoolWithTag(PagedPool, FILE_BUFFER_SIZE, 'knab');
	if(fileBuf == NULL)
	{
		ZwClose(hFile);
		return false;
	}

	// 获取文件hash。
	MD5_CTX md5;
	MD5Init(&md5);
	ULONG sizeAll=0;
	
	FILE_STANDARD_INFORMATION fsi;
	ZwQueryInformationFile(hFile,&ioStatus,&fsi,sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation);


	while(1)
	{
		NTSTATUS status = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatus, fileBuf, 
			FILE_BUFFER_SIZE, NULL, NULL);
		if(!NT_SUCCESS(status))
			break;
		if(ioStatus.Information == 0)
			break;

		sizeAll += ioStatus.Information;
		MD5Update(&md5, fileBuf, ioStatus.Information);
	}
	ExFreePoolWithTag(fileBuf, 'knab');

	unsigned char final[16];
	MD5Final(final, &md5);

	ZwClose(hFile);

	//黑白名单校验
 	bool bOK = IsHashBlack(final);

	if( bOK )
	{
		if(!IsInBlackCache(filename))
		{
			WriteSysLog(LOG_TYPE_DEBUG,L" Fileter Module :%s", filename->Buffer);
			AddBlackCache(filename);
		}
		return false;
	}
	else if( !IsHashSecure(final) )//传递到上层 
	{
		if( setData(filename->Buffer,filename->Length,final,16) )
			setSigned();
	}	
	//
	return true;
}
Пример #20
0
static
VOID
TestAllInformation(VOID)
{
    NTSTATUS Status;
    UNICODE_STRING FileName = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntoskrnl.exe");
    UNICODE_STRING Ntoskrnl = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE FileHandle;
    IO_STATUS_BLOCK IoStatus;
    PFILE_ALL_INFORMATION FileAllInfo;
    SIZE_T Length;
    ULONG NameLength;
    PWCHAR Name = NULL;
    UNICODE_STRING NamePart;

    InitializeObjectAttributes(&ObjectAttributes,
                               &FileName,
                               OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = ZwOpenFile(&FileHandle,
                        SYNCHRONIZE | FILE_READ_ATTRIBUTES,
                        &ObjectAttributes,
                        &IoStatus,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        FILE_NON_DIRECTORY_FILE);
    if (Status == STATUS_PENDING)
    {
        Status = ZwWaitForSingleObject(FileHandle, FALSE, NULL);
        ok_eq_hex(Status, STATUS_SUCCESS);
        Status = IoStatus.Status;
    }
    ok_eq_hex(Status, STATUS_SUCCESS);
    if (skip(NT_SUCCESS(Status), "No file handle, %lx\n", Status))
        return;

    /* NtQueryInformationFile doesn't do length checks for kernel callers in a free build */
    if (KmtIsCheckedBuild)
    {
    /* Zero length */
    Length = 0;
    Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation);
    ok_eq_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
    ok_eq_size(Length, (ULONG_PTR)0x5555555555555555);
    if (FileAllInfo)
        KmtFreeGuarded(FileAllInfo);

    /* One less than the minimum */
    Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) - 1;
    Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation);
    ok_eq_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
    ok_eq_size(Length, (ULONG_PTR)0x5555555555555555);
    if (FileAllInfo)
        KmtFreeGuarded(FileAllInfo);
    }

    /* The minimum allowed */
    Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName);
    Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation);
    ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW);
    ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName));
    if (FileAllInfo)
        KmtFreeGuarded(FileAllInfo);

    /* Plenty of space -- determine NameLength and copy the name */
    Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + MAX_PATH * sizeof(WCHAR);
    Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    if (!skip(NT_SUCCESS(Status) && FileAllInfo != NULL, "No info\n"))
    {
        NameLength = FileAllInfo->NameInformation.FileNameLength;
        ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength);
        Name = ExAllocatePoolWithTag(PagedPool, NameLength + sizeof(UNICODE_NULL), 'sFmK');
        if (!skip(Name != NULL, "Could not allocate %lu bytes\n", NameLength + (ULONG)sizeof(UNICODE_NULL)))
        {
            RtlCopyMemory(Name,
                          FileAllInfo->NameInformation.FileName,
                          NameLength);
            Name[NameLength / sizeof(WCHAR)] = UNICODE_NULL;
            ok(Name[0] == L'\\', "Name is %ls, expected first char to be \\\n", Name);
            ok(NameLength >= Ntoskrnl.Length + sizeof(WCHAR), "NameLength %lu too short\n", NameLength);
            if (NameLength >= Ntoskrnl.Length)
            {
                NamePart.Buffer = Name + (NameLength - Ntoskrnl.Length) / sizeof(WCHAR);
                NamePart.Length = Ntoskrnl.Length;
                NamePart.MaximumLength = NamePart.Length;
                ok(RtlEqualUnicodeString(&NamePart, &Ntoskrnl, TRUE),
                   "Name ends in '%wZ', expected %wZ\n", &NamePart, &Ntoskrnl);
            }
        }
        ok(FileAllInfo->NameInformation.FileName[NameLength / sizeof(WCHAR)] == 0xdddd,
           "Char past FileName is %x\n",
           FileAllInfo->NameInformation.FileName[NameLength / sizeof(WCHAR)]);
    }
    if (FileAllInfo)
        KmtFreeGuarded(FileAllInfo);

    /* One char less than needed */
    Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - sizeof(WCHAR);
    Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation);
    ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW);
    ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - sizeof(WCHAR));
    if (FileAllInfo)
        KmtFreeGuarded(FileAllInfo);

    /* One byte less than needed */
    Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - 1;
    Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation);
    ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW);
    ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - 1);
    if (FileAllInfo)
        KmtFreeGuarded(FileAllInfo);

    /* Exactly the required size */
    Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength;
    Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength);
    if (FileAllInfo)
        KmtFreeGuarded(FileAllInfo);

    /* One byte more than needed */
    Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength + 1;
    Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength);
    if (FileAllInfo)
        KmtFreeGuarded(FileAllInfo);

    /* One char more than needed */
    Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength + sizeof(WCHAR);
    Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength);
    if (FileAllInfo)
        KmtFreeGuarded(FileAllInfo);

    ExFreePoolWithTag(Name, 'sFmK');

    Status = ObCloseHandle(FileHandle, KernelMode);
    ok_eq_hex(Status, STATUS_SUCCESS);
}
Пример #21
0
NTSTATUS
AFSInitializeRedirector( IN AFSRedirectorInitInfo *RedirInitInfo)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    LARGE_INTEGER cacheSizeBytes;
    AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
    OBJECT_ATTRIBUTES   stObjectAttribs;
    IO_STATUS_BLOCK stIoStatus;
    UNICODE_STRING uniServiceName;

    __Enter
    {

        //
        // First this is to load the library
        //

        RtlInitUnicodeString( &uniServiceName,
                              AFS_REDIR_LIBRARY_SERVICE_ENTRY);

        ntStatus = AFSLoadLibrary( 0,
                                   &uniServiceName);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSInitializeRedirector AFSLoadLibrary failure %08lX\n",
                          ntStatus));

            try_return( ntStatus);
        }

        //
        // Save off the cache file information
        //

        pDevExt->Specific.RDR.CacheBlockSize = RedirInitInfo->CacheBlockSize;

        pDevExt->Specific.RDR.CacheBlockCount = RedirInitInfo->ExtentCount;

        pDevExt->Specific.RDR.MaximumRPCLength = RedirInitInfo->MaximumChunkLength;

        cacheSizeBytes = RedirInitInfo->ExtentCount;
        cacheSizeBytes.QuadPart *= RedirInitInfo->CacheBlockSize;

        AFSDumpFileLocation.Length = 0;

        AFSDumpFileLocation.MaximumLength = (USHORT)RedirInitInfo->DumpFileLocationLength + (4 * sizeof( WCHAR));

        AFSDumpFileLocation.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
                                                                        AFSDumpFileLocation.MaximumLength,
                                                                        AFS_GENERIC_MEMORY_23_TAG);

        if( AFSDumpFileLocation.Buffer == NULL)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSInitializeRedirector AFS_GENERIC_MEMORY_23_TAG allocation error\n"));

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        RtlCopyMemory( AFSDumpFileLocation.Buffer,
                       L"\\??\\",
                       4 * sizeof( WCHAR));

        AFSDumpFileLocation.Length = 4 * sizeof( WCHAR);

        RtlCopyMemory( &AFSDumpFileLocation.Buffer[ AFSDumpFileLocation.Length/sizeof( WCHAR)],
                       (void *)((char *)RedirInitInfo + RedirInitInfo->DumpFileLocationOffset),
                       RedirInitInfo->DumpFileLocationLength);

        AFSDumpFileLocation.Length += (USHORT)RedirInitInfo->DumpFileLocationLength;

        //
        // Be sure the shutdown flag is not set
        //

        ClearFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN);

        //
        // Set up the Throttles.
        //
        // Max IO is 10% of the cache, or the value in the registry,
        // with a minimum of 5Mb (and a maximum of 50% cache size)
        //
        if( AFSMaxDirectIo)
        {
            //
            // collect what the user
            //
            pDevExt->Specific.RDR.MaxIo.QuadPart = AFSMaxDirectIo;
            pDevExt->Specific.RDR.MaxIo.QuadPart *= (1024 * 1024);

        }
        else
        {

            pDevExt->Specific.RDR.MaxIo.QuadPart = cacheSizeBytes.QuadPart / 2;
        }

        if (pDevExt->Specific.RDR.MaxIo.QuadPart < (5 * 1024 * 1204))
        {

            pDevExt->Specific.RDR.MaxIo.QuadPart = 5 * 1024 * 1204;

        }

        //
        // For small cache configurations ...
        //

        if (pDevExt->Specific.RDR.MaxIo.QuadPart > cacheSizeBytes.QuadPart / 2)
        {

            pDevExt->Specific.RDR.MaxIo.QuadPart  = cacheSizeBytes.QuadPart / 2;
        }

        //
        // Maximum Dirty is 50% of the cache, or the value in the
        // registry.  No minimum, maximum of 90% of cache size.
        //
        if (AFSMaxDirtyFile)
        {

            pDevExt->Specific.RDR.MaxDirty.QuadPart = AFSMaxDirtyFile;
            pDevExt->Specific.RDR.MaxDirty.QuadPart *= (1024 * 1024);

        }
        else
        {

            pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart/2;

        }

        cacheSizeBytes.QuadPart *= 9;
        cacheSizeBytes.QuadPart  = cacheSizeBytes.QuadPart / 10;

        if (pDevExt->Specific.RDR.MaxDirty.QuadPart > cacheSizeBytes.QuadPart)
        {
            pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart;
        }

        //
        // Store off any flags for the file system
        //

        if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_HIDE_DOT_FILES))
        {

            //
            // Hide files which begin with .
            //

            SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES);
        }

        if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_DISABLE_SHORTNAMES))
        {

            //
            // Hide files which begin with .
            //

            SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES);
        }

        //
	// Global Reparse Point Policy
	//

	pDevExt->Specific.RDR.ReparsePointPolicy = RedirInitInfo->GlobalReparsePointPolicy;

	//
        // Are we performing direct to service IO?
        //

        if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_PERFORM_SERVICE_IO))
        {

            //
            // Send IO requests directly to service
            //

            SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO);
        }
        else
        {

            if( RedirInitInfo->MemoryCacheOffset.QuadPart != 0 &&
                RedirInitInfo->MemoryCacheLength.QuadPart != 0)
            {

                ntStatus = STATUS_INSUFFICIENT_RESOURCES;

#ifdef AMD64
                pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
                                                              (void *)RedirInitInfo->MemoryCacheOffset.QuadPart,
                                                              RedirInitInfo->MemoryCacheLength.QuadPart);
#else
                pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
                                                              (void *)RedirInitInfo->MemoryCacheOffset.LowPart,
                                                              RedirInitInfo->MemoryCacheLength.LowPart);
#endif

                if( pDevExt->Specific.RDR.CacheMdl != NULL)
                {

                    __try
                    {

                        MmProbeAndLockPages( pDevExt->Specific.RDR.CacheMdl,
                                             KernelMode,
                                             IoModifyAccess);

                        pDevExt->Specific.RDR.CacheBaseAddress = MmGetSystemAddressForMdlSafe( pDevExt->Specific.RDR.CacheMdl,
                                                                                               NormalPagePriority);
                    }
                    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
                    {

                        AFSDumpTraceFilesFnc();

                        IoFreeMdl( pDevExt->Specific.RDR.CacheMdl);
                        pDevExt->Specific.RDR.CacheMdl = NULL;
                    }

                    if( pDevExt->Specific.RDR.CacheMdl != NULL)
                    {
                        pDevExt->Specific.RDR.CacheLength = RedirInitInfo->MemoryCacheLength;
                        ntStatus = STATUS_SUCCESS;
                    }

                }
            }

            if( !NT_SUCCESS( ntStatus) &&
                RedirInitInfo->CacheFileNameLength == 0)
            {

                AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                              AFS_TRACE_LEVEL_ERROR,
                              "AFSInitializeRedirector Unable to initialize cache file %08lX\n",
                              ntStatus));

                try_return( ntStatus);
            }

            if( pDevExt->Specific.RDR.CacheMdl == NULL)
            {

                if( RedirInitInfo->CacheFileNameLength == 0)
                {

                    AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                                  AFS_TRACE_LEVEL_ERROR,
                                  "AFSInitializeRedirector CacheMdl == NULL\n"));

                    try_return( ntStatus = STATUS_INVALID_PARAMETER);
                }

                //
                // Go open the cache file
                //

                pDevExt->Specific.RDR.CacheFile.Length = 0;
                pDevExt->Specific.RDR.CacheFile.MaximumLength = (USHORT)RedirInitInfo->CacheFileNameLength + (4 * sizeof( WCHAR));

                pDevExt->Specific.RDR.CacheFile.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
                                                                                            pDevExt->Specific.RDR.CacheFile.MaximumLength,
                                                                                            AFS_GENERIC_MEMORY_24_TAG);

                if( pDevExt->Specific.RDR.CacheFile.Buffer == NULL)
                {

                    AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                                  AFS_TRACE_LEVEL_ERROR,
                                  "AFSInitializeRedirector AFS_GENERIC_MEMORY_24_TAG allocation failure\n"));

                    try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
                }

                RtlCopyMemory( pDevExt->Specific.RDR.CacheFile.Buffer,
                               L"\\??\\",
                               4 * sizeof( WCHAR));

                pDevExt->Specific.RDR.CacheFile.Length = 4 * sizeof( WCHAR);

                RtlCopyMemory( &pDevExt->Specific.RDR.CacheFile.Buffer[ pDevExt->Specific.RDR.CacheFile.Length/sizeof( WCHAR)],
                               RedirInitInfo->CacheFileName,
                               RedirInitInfo->CacheFileNameLength);

                pDevExt->Specific.RDR.CacheFile.Length += (USHORT)RedirInitInfo->CacheFileNameLength;

                InitializeObjectAttributes( &stObjectAttribs,
                                            &pDevExt->Specific.RDR.CacheFile,
                                            OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                            NULL,
                                            NULL);

                ntStatus = ZwOpenFile( &pDevExt->Specific.RDR.CacheFileHandle,
                                       GENERIC_READ | GENERIC_WRITE,
                                       &stObjectAttribs,
                                       &stIoStatus,
                                       FILE_SHARE_READ | FILE_SHARE_WRITE,
                                       FILE_WRITE_THROUGH | FILE_RANDOM_ACCESS);

                if( !NT_SUCCESS( ntStatus))
                {

                    AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                                  AFS_TRACE_LEVEL_ERROR,
                                  "AFSInitializeRedirector ZwOpenFile failure %08lX\n",
                                  ntStatus));

                    try_return( ntStatus);
                }

                //
                // Map to the fileobject
                //

                ntStatus = ObReferenceObjectByHandle( pDevExt->Specific.RDR.CacheFileHandle,
                                                      SYNCHRONIZE,
                                                      NULL,
                                                      KernelMode,
                                                      (void **)&pDevExt->Specific.RDR.CacheFileObject,
                                                      NULL);

                if( !NT_SUCCESS( ntStatus))
                {

                    AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                                  AFS_TRACE_LEVEL_ERROR,
                                  "AFSInitializeRedirector ObReferenceObjectByHandle failure %08lX\n",
                                  ntStatus));

                    try_return( ntStatus);
                }
            }
        }
Пример #22
0
NTSTATUS
PsLocateSystemDll (
    VOID
    )

/*++

Routine Description:

    This function locates the system dll and creates a section for the
    DLL and maps it into the system process.

Arguments:

    None.

Return Value:

    TRUE - Initialization was successful.

    FALSE - Initialization Failed.

--*/

{

    HANDLE File;
    HANDLE Section;
    NTSTATUS st;
    UNICODE_STRING DllPathName;
    WCHAR PathBuffer[DOS_MAX_PATH_LENGTH];
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatus;

    //
    // Initialize the system DLL
    //

    DllPathName.Length = 0;
    DllPathName.Buffer = PathBuffer;
    DllPathName.MaximumLength = 256;
    RtlInitUnicodeString(&DllPathName,L"\\SystemRoot\\System32\\ntdll.dll");
    InitializeObjectAttributes(
        &ObjectAttributes,
        &DllPathName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL
        );

    st = ZwOpenFile(
            &File,
            SYNCHRONIZE | FILE_EXECUTE,
            &ObjectAttributes,
            &IoStatus,
            FILE_SHARE_READ,
            0
            );

    if (!NT_SUCCESS(st)) {

#if DBG
        DbgPrint("PS: PsLocateSystemDll - NtOpenFile( NTDLL.DLL ) failed.  Status == %lx\n",
            st
            );
#endif
        KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,2,0,0);
        return st;
    }

    st = MmCheckSystemImage(File);
    if ( st == STATUS_IMAGE_CHECKSUM_MISMATCH ) {
        ULONG ErrorParameters;
        ULONG ErrorResponse;

        //
        // Hard error time. A driver is corrupt.
        //

	ErrorParameters = (ULONG)&DllPathName;

        NtRaiseHardError(
            st,
            1,
            1,
            &ErrorParameters,
            OptionOk,
            &ErrorResponse
            );
        return st;
        }


    PsNtDllPathName.MaximumLength = DllPathName.Length + sizeof( WCHAR );
    PsNtDllPathName.Length = 0;
    PsNtDllPathName.Buffer = RtlAllocateStringRoutine( PsNtDllPathName.MaximumLength );
    RtlCopyUnicodeString( &PsNtDllPathName, &DllPathName );

    st = ZwCreateSection(
            &Section,
            SECTION_ALL_ACCESS,
            NULL,
            0,
            PAGE_EXECUTE,
            SEC_IMAGE,
            File
            );
    ZwClose( File );

    if (!NT_SUCCESS(st)) {
#if DBG
        DbgPrint("PS: PsLocateSystemDll: NtCreateSection Status == %lx\n",st);
#endif
        KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,3,0,0);
        return st;
    }

    //
    // Now that we have the section, reference it, store its address in the
    // PspSystemDll and then close handle to the section.
    //

    st = ObReferenceObjectByHandle(
            Section,
            SECTION_ALL_ACCESS,
            MmSectionObjectType,
            KernelMode,
            &PspSystemDll.Section,
            NULL
            );

    ZwClose(Section);

    if ( !NT_SUCCESS(st) ) {
        KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,4,0,0);
        return st;
    }

    //
    // Map the system dll into the user part of the address space
    //

    st = PspMapSystemDll(PsGetCurrentProcess(),&PspSystemDll.DllBase);
    PsSystemDllDllBase = PspSystemDll.DllBase;

    if ( !NT_SUCCESS(st) ) {
        KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED,st,5,0,0);
        return st;
    }
    PsSystemDllBase = PspSystemDll.DllBase;

    return STATUS_SUCCESS;
}
Пример #23
0
NTSTATUS 
ForceDelete(
			wchar_t *path
			)
{

	HANDLE fileHandle;
	NTSTATUS result;
	IO_STATUS_BLOCK ioBlock;
	DEVICE_OBJECT *device_object;
	void* object = NULL;
	OBJECT_ATTRIBUTES fileObject;
	wchar_t deviceName[14];
	UNICODE_STRING uDeviceName;
	UNICODE_STRING uPath;

	
	EPROCESS *eproc = IoGetCurrentProcess();
	//switch context to UserMode
	KeAttachProcess(eproc);
	
	//initialize file to delete variable
	g_fileToDelete = path;
	g_fileToDelete += 6; //take from \??\C:\example only \example
	

	//e.g "\??\C:\"
	memset(deviceName,0,sizeof(deviceName));
	wcsncpy(deviceName,path,7);
	uDeviceName.Buffer = deviceName;
	uDeviceName.Length = 14;
	//file path to unicode string
	RtlInitUnicodeString(&uPath,path);
	
	InitializeObjectAttributes(&fileObject,
								&uDeviceName,
								OBJ_CASE_INSENSITIVE,
								NULL,
								NULL);

	result = ZwOpenFile(&fileHandle,
						SYNCHRONIZE,
						&fileObject,
						&ioBlock,
						FILE_SHARE_READ,
						FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE);

	if(result != STATUS_SUCCESS)
	{
		DbgPrint("Some problems with open file ;[");
		goto _end;
	}

    if ( !ObReferenceObjectByHandle(fileHandle, 0, 0, 0, &object, 0) )
    {

      device_object = IoGetBaseFileSystemDeviceObject(object);
      ObfDereferenceObject(object);
    }
	
    ZwClose(fileHandle);	
	
	InitializeObjectAttributes(&fileObject,
							   &uPath,
							   OBJ_CASE_INSENSITIVE,
							   NULL,
							   NULL);

	result = IoCreateFileSpecifyDeviceObjectHint(
			   &fileHandle,
			   SYNCHRONIZE | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES | FILE_READ_DATA, //0x100181 
			   &fileObject,
			   &ioBlock,
			   0,
			   0,
			   FILE_SHARE_READ | FILE_SHARE_WRITE |FILE_SHARE_DELETE, //FILE_SHARE_VALID_FLAGS,
			   FILE_OPEN,
			   FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,//0x60,
			   0,
			   0,
			   CreateFileTypeNone,
			   0,
			   IO_IGNORE_SHARE_ACCESS_CHECK,
			   device_object);
	if(result != STATUS_SUCCESS)
	{
		DbgPrint("error in IoCreateFileSpecifyDeviceObjectHint");
		goto _end;
	}

	result = ObReferenceObjectByHandle(fileHandle, 0, 0, 0, &object, 0);

	if(result != STATUS_SUCCESS)
	{
		DbgPrint("error in ObReferenceObjectByHandle");
		ZwClose(fileHandle);
		goto _end;
	}
	/*
		METHOD 1
	*/
	((FILE_OBJECT*)object)->SectionObjectPointer->ImageSectionObject = 0;
	((FILE_OBJECT*)object)->DeleteAccess = 1;	
	 result = ZwDeleteFile(&fileObject);
	
	if(result != STATUS_SUCCESS)
	{
		DbgPrint("\n[+]error in ZwDeleteFile");
	}
	ObDereferenceObject(object);
	ZwClose(fileHandle);
	 
	result = ZwDeleteFile(&fileObject);
	if(result != STATUS_SUCCESS)
	{
		DbgPrint("\n[+]error in ZwDeleteFile");
		/*
			METHOD 2
		*/		
		r0_fileToDelete(path);
		
		/*
			METHOD 3
			If simple solutions did not help, try this one.
		*/
		hook_it(device_object)
	}
Пример #24
0
static
_Check_return_
NTSTATUS
LcOpenFile (
    _In_  PUNICODE_STRING SourceFile,
    _In_  PUNICODE_STRING TargetFile,
    _Out_ PHANDLE         Handle
    )
/*++

Summary:

    This function tries to open the 'FilePath' given.

    If open operation fails in the current context, it asks for the user-mode service
    to open that file.

Arguments:

    SourceFile - Path to the file to open.

    TargetFile - Path to the file the content should be stored to.

    Handle     - Receives handle to the opened file.

Return Value:

    The return value is the status of the operation.

--*/
{
    NTSTATUS          status           = STATUS_SUCCESS;
    IO_STATUS_BLOCK   statusBlock      = { 0 };
    OBJECT_ATTRIBUTES objectAttributes = { 0 };
    HANDLE            fileHandle       = NULL;

    PAGED_CODE();

    FLT_ASSERT(SourceFile != NULL);
    FLT_ASSERT(TargetFile != NULL);
    FLT_ASSERT(Handle     != NULL);

    EventWriteFile_Open_Start(NULL, SourceFile->Buffer);

    __try
    {
        // The current minifilter instance may not be attached to the target volume,
        // so the ZwOpenFile/ZwReadFile functions should be used here instead of the FltCreateFile/FltReadFile.
        InitializeObjectAttributes(&objectAttributes, SourceFile, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);

        // Open file for asynchronous reads.
        status = ZwOpenFile(
            &fileHandle,
            GENERIC_READ,
            &objectAttributes,
            &statusBlock,
            FILE_SHARE_READ,
            FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY);

        // Open operation may fail, if a remote file is opened by a system, which does not have access to the remote share.
        // If this happens, we want the user-mode client to open it for us.
        if (!NT_SUCCESS(status) && status == STATUS_ACCESS_DENIED)
        {
            NTSTATUS notificationStatus = STATUS_SUCCESS;

            LOG((DPFLTR_IHVDRIVER_ID, DPFLTR_WARNING_LEVEL, "[LazyCopy] '%wZ' cannot be accessed by the system, trying to use user-mode service instead.\n", FilePath));

            notificationStatus = LcOpenFileInUserMode(SourceFile, TargetFile, &fileHandle);

            // Return original status, if error occurred while sending notification to the user-mode client.
            status = notificationStatus == STATUS_PORT_DISCONNECTED || notificationStatus == STATUS_TIMEOUT
                     ? status
                     : notificationStatus;
        }
    }
    __finally
    {
        if (NT_SUCCESS(status))
        {
            *Handle = fileHandle;

            // Make sure it's not closed by the code below.
            fileHandle = NULL;
        }

        if (fileHandle != NULL)
        {
            ZwClose(fileHandle);
        }
    }

    EventWriteFile_Open_Stop(NULL);

    return status;
}
Пример #25
0
//
// Initializes the NRER subsystem by creating a file-backed section that is
// pointed at the NRER user-mode DLL on disk.  This section is used for
// randomization purposes.
//
NTSTATUS InitializeNreSubsystem()
{
	OBJECT_ATTRIBUTES Attributes;
	IO_STATUS_BLOCK   IoStatus;
	UNICODE_STRING    FilePath;
	NTSTATUS          Status = STATUS_SUCCESS;
	HANDLE            FileHandle;
	HANDLE            SectionHandle;

	do
	{
		//
		// Get a file handle to the user-mode DLL
		//
		RtlInitUnicodeString(
				&FilePath,
				NRER_USER_MODE_DLL_PATH);

		InitializeObjectAttributes(
				&Attributes,
				&FilePath,
				OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
				NULL,
				NULL);

		if (!NT_SUCCESS(Status = ZwOpenFile(
				&FileHandle,
				GENERIC_READ | GENERIC_EXECUTE,
				&Attributes,
				&IoStatus,
				FILE_SHARE_READ | FILE_SHARE_WRITE,
				0)))
		{
			DebugPrint(("InitializeNreSubsystem(): ZwCreateFile(%wZ) failed, %.8x.",
					&FilePath, 
					Status));
			break;
		}

		//
		// Create an image file-backed section that is associated with the DLL
		//
		if (!NT_SUCCESS(Status = ZwCreateSection(
				&SectionHandle,
				SECTION_ALL_ACCESS,
				NULL,
				NULL,
				PAGE_EXECUTE_WRITECOPY,
				SEC_IMAGE,
				FileHandle)))
		{
			DebugPrint(("InitializeNreSubsystem(): ZwCreateSection() failed, %.8x.",
					Status));
			break;
		}

		//
		// Get the section object that's associated with the section handle
		//
		if (!NT_SUCCESS(Status = ObReferenceObjectByHandle(
				SectionHandle,
				0,
				NULL,
				KernelMode,
				(PVOID *)&NrerUserModeDllSectionObject,
				NULL)))
		{
			DebugPrint(("InitializeNreSubsystem(): ObReferenceObjectByHandle() failed, %.8x.",
					Status));
			break;
		}

		DebugPrint(("InitializeNreSubsystem(): NRER user-mode DLL section at: %p.",
				NrerUserModeDllSectionObject));

		NrerInitialized = TRUE;

	} while (0);

	//
	// Close the handles that were opened
	//
	if (FileHandle)
		ZwClose(
				FileHandle);
	if (SectionHandle)
		ZwClose(
				SectionHandle);

	return Status;
}
Пример #26
0
//static
VOID
NTAPI
UserModeTest(VOID)
{
    NTSTATUS Status;
    IO_STATUS_BLOCK IoStatusBlock;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE ParentHandle, SystemRootHandle;

    ok(ExGetPreviousMode() == UserMode, "KernelMode returned!\n");

    /* Attempt direct target open */
    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRootRegedit,
                               OBJ_CASE_INSENSITIVE,
                               NULL, NULL);
    Status = IoCreateFile(&ParentHandle,
                          GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          0,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          FILE_OPEN,
                          FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0,
                          CreateFileTypeNone,
                          NULL,
                          IO_OPEN_TARGET_DIRECTORY);
    ok_eq_hex(Status, STATUS_ACCESS_VIOLATION);
    ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
    if (Status == STATUS_SUCCESS)
    {
        ObCloseHandle(ParentHandle, UserMode);
    }

    /* Attempt relative target open */
    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRoot,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = ZwOpenFile(&SystemRootHandle,
                        GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        IoStatusBlock.Status = 0xFFFFFFFF;
        IoStatusBlock.Information = 0xFFFFFFFF;
        InitializeObjectAttributes(&ObjectAttributes,
                                   &Regedit,
                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                   SystemRootHandle,
                                   NULL);
        Status = IoCreateFile(&ParentHandle,
                              GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                              &ObjectAttributes,
                              &IoStatusBlock,
                              NULL,
                              0,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              FILE_OPEN,
                              FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                              NULL,
                              0,
                              CreateFileTypeNone,
                              NULL,
                              IO_OPEN_TARGET_DIRECTORY);
        ok_eq_hex(Status, STATUS_ACCESS_VIOLATION);
        ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
        if (Status == STATUS_SUCCESS)
        {
            ObCloseHandle(ParentHandle, KernelMode);
        }
        ObCloseHandle(SystemRootHandle, KernelMode);
    }
}
Пример #27
0
static
VOID
NTAPI
TestSymlinks(VOID)
{
    HANDLE ReparseHandle;
    NTSTATUS Status;
    IO_STATUS_BLOCK IoStatusBlock;
    OBJECT_ATTRIBUTES ObjectAttributes;
    PREPARSE_DATA_BUFFER Reparse;
    FILE_DISPOSITION_INFORMATION ToDelete;
    PFILE_OBJECT FileObject;
    UNICODE_STRING SysDir, Foobar, Regedit;
    ULONG Size;

    /* Get Windows/ReactOS directory */
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRoot,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = ZwOpenFile(&ReparseHandle,
                        FILE_READ_DATA,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        FILE_DIRECTORY_FILE);
    if (skip(NT_SUCCESS(Status), "Opening \\SystemRoot failed: %lx\n", Status))
    {
        return;
    }

    Status = ObReferenceObjectByHandle(ReparseHandle,
                                       FILE_READ_DATA,
                                       *IoFileObjectType,
                                       UserMode,
                                       (PVOID *)&FileObject,
                                       NULL);
    if (skip(NT_SUCCESS(Status), "Querying name failed: %lx\n", Status))
    {
        ZwClose(ReparseHandle);
        return;
    }

    SysDir.Buffer = ExAllocatePool(NonPagedPool, FileObject->FileName.Length + sizeof(L"\\??\\C:"));
    if (skip(SysDir.Buffer != NULL, "Allocating memory failed\n"))
    {
        ObDereferenceObject(FileObject);
        ZwClose(ReparseHandle);
        return;
    }

    SysDir.Length = sizeof(L"\\??\\C:") - sizeof(UNICODE_NULL);
    SysDir.MaximumLength = FileObject->FileName.Length + sizeof(L"\\??\\C:");
    RtlCopyMemory(SysDir.Buffer, L"\\??\\C:", sizeof(L"\\??\\C:") - sizeof(UNICODE_NULL));
    RtlAppendUnicodeStringToString(&SysDir, &FileObject->FileName);

    Foobar.Buffer = ExAllocatePool(NonPagedPool, FileObject->FileName.Length + sizeof(L"\\foobar.exe"));
    if (skip(Foobar.Buffer != NULL, "Allocating memory failed\n"))
    {
        ExFreePool(SysDir.Buffer);
        ObDereferenceObject(FileObject);
        ZwClose(ReparseHandle);
        return;
    }

    Foobar.Length = 0;
    Foobar.MaximumLength = FileObject->FileName.Length + sizeof(L"\\foobar.exe");
    RtlCopyUnicodeString(&Foobar, &FileObject->FileName);
    RtlCopyMemory(&Foobar.Buffer[Foobar.Length / sizeof(WCHAR)], L"\\foobar.exe", sizeof(L"\\foobar.exe") - sizeof(UNICODE_NULL));
    Foobar.Length += (sizeof(L"\\foobar.exe") - sizeof(UNICODE_NULL));

    Regedit.Buffer = ExAllocatePool(NonPagedPool, FileObject->FileName.Length + sizeof(L"\\regedit.exe"));
    if (skip(Regedit.Buffer != NULL, "Allocating memory failed\n"))
    {
        ExFreePool(Foobar.Buffer);
        ExFreePool(SysDir.Buffer);
        ObDereferenceObject(FileObject);
        ZwClose(ReparseHandle);
        return;
    }

    Regedit.Length = 0;
    Regedit.MaximumLength = FileObject->FileName.Length + sizeof(L"\\regedit.exe");
    RtlCopyUnicodeString(&Regedit, &FileObject->FileName);
    RtlCopyMemory(&Regedit.Buffer[Regedit.Length / sizeof(WCHAR)], L"\\regedit.exe", sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL));
    Regedit.Length += (sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL));

    ObDereferenceObject(FileObject);
    ZwClose(ReparseHandle);

    ToDelete.DeleteFile = TRUE;
    Size = FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + SysDir.Length * 2 + sizeof(L"\\regedit.exe") * 2 - sizeof(L"\\??\\") - sizeof(UNICODE_NULL);

    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRootFoobar,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = ZwCreateFile(&ReparseHandle,
                          GENERIC_READ | GENERIC_WRITE | DELETE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                          FILE_SUPERSEDE,
                          FILE_NON_DIRECTORY_FILE,
                          NULL,
                          0);
    ok_eq_hex(Status, STATUS_SUCCESS);
    if (skip(NT_SUCCESS(Status), "Creating file failed: %lx\n", Status))
    {
        ExFreePool(Regedit.Buffer);
        ExFreePool(Foobar.Buffer);
        ExFreePool(SysDir.Buffer);
        return;
    }

    Reparse = ExAllocatePool(NonPagedPool, Size);
    RtlZeroMemory(Reparse, Size);
    Reparse->ReparseTag = IO_REPARSE_TAG_SYMLINK;
    Reparse->ReparseDataLength = 12 + SysDir.Length * 2 + sizeof(L"\\regedit.exe") * 2 - sizeof(L"\\??\\") - sizeof(UNICODE_NULL);
    Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength = SysDir.Length + sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL);
    Reparse->SymbolicLinkReparseBuffer.PrintNameLength = SysDir.Length + sizeof(L"\\regedit.exe") - sizeof(L"\\??\\");
    Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset = Reparse->SymbolicLinkReparseBuffer.PrintNameLength;
    RtlCopyMemory(Reparse->SymbolicLinkReparseBuffer.PathBuffer,
                  (WCHAR *)((ULONG_PTR)SysDir.Buffer + sizeof(L"\\??\\") - sizeof(UNICODE_NULL)),
                  SysDir.Length - sizeof(L"\\??\\") + sizeof(UNICODE_NULL));
    RtlCopyMemory((WCHAR *)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + SysDir.Length - sizeof(L"\\??\\") + sizeof(UNICODE_NULL)),
                  L"\\regedit.exe", sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL));
    RtlCopyMemory((WCHAR *)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset),
                  SysDir.Buffer, SysDir.Length);
    RtlCopyMemory((WCHAR *)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset + SysDir.Length),
                  L"\\regedit.exe", sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL));

    Status = ZwFsControlFile(ReparseHandle,
                             NULL,
                             NULL,
                             NULL,
                             &IoStatusBlock,
                             FSCTL_SET_REPARSE_POINT,
                             Reparse,
                             Size,
                             NULL,
                             0);
    ok_eq_hex(Status, STATUS_SUCCESS);
    if (!NT_SUCCESS(Status))
    {
        ZwClose(ReparseHandle);

        Status = ZwCreateFile(&ReparseHandle,
                              FILE_WRITE_ATTRIBUTES | DELETE | SYNCHRONIZE,
                              &ObjectAttributes,
                              &IoStatusBlock,
                              NULL,
                              FILE_ATTRIBUTE_NORMAL,
                              0,
                              FILE_SUPERSEDE,
                              FILE_NON_DIRECTORY_FILE  | FILE_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT,
                              NULL,
                              0);
        if (skip(NT_SUCCESS(Status), "Creating symlink failed: %lx\n", Status))
        {
            Status = ZwOpenFile(&ReparseHandle,
                                DELETE,
                                &ObjectAttributes,
                                &IoStatusBlock,
                                FILE_SHARE_DELETE,
                                FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE);
            ok_eq_hex(Status, STATUS_SUCCESS);
            ZwClose(ReparseHandle);
            ExFreePool(Regedit.Buffer);
            ExFreePool(Foobar.Buffer);
            ExFreePool(SysDir.Buffer);
            ExFreePool(Reparse);
            return;
        }

        Status = ZwFsControlFile(ReparseHandle,
                                 NULL,
                                 NULL,
                                 NULL,
                                 &IoStatusBlock,
                                 FSCTL_SET_REPARSE_POINT,
                                 Reparse,
                                 Size,
                                 NULL,
                                 0);
    }

    if (skip(NT_SUCCESS(Status), "Creating symlink failed: %lx\n", Status))
    {
        ZwSetInformationFile(ReparseHandle,
                             &IoStatusBlock,
                             &ToDelete,
                             sizeof(ToDelete),
                             FileDispositionInformation);
        ZwClose(ReparseHandle);
        ExFreePool(Regedit.Buffer);
        ExFreePool(Foobar.Buffer);
        ExFreePool(SysDir.Buffer);
        ExFreePool(Reparse);
        return;
    }

    ZwClose(ReparseHandle);

    Status = ZwCreateFile(&ReparseHandle,
                          GENERIC_READ,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                          FILE_OPEN,
                          FILE_NON_DIRECTORY_FILE,
                          NULL,
                          0);
    ok(Status == STATUS_SUCCESS || /* Windows Vista+ */
       Status == STATUS_IO_REPARSE_TAG_NOT_HANDLED, /* Windows 2003 (SP1, SP2) */
        "ZwCreateFile returned unexpected status: %lx\n", Status);
    if (NT_SUCCESS(Status))
    {
        Status = ObReferenceObjectByHandle(ReparseHandle,
                                           FILE_READ_DATA,
                                           *IoFileObjectType,
                                           UserMode,
                                           (PVOID *)&FileObject,
                                           NULL);
        ok_eq_hex(Status, STATUS_SUCCESS);
        if (NT_SUCCESS(Status))
        {
            ok(RtlCompareUnicodeString(&Regedit, &FileObject->FileName, TRUE) == 0,
               "Expected: %wZ. Opened: %wZ\n", &Regedit, &FileObject->FileName);
            ObDereferenceObject(FileObject);
        }

        ZwClose(ReparseHandle);
    }

    ExFreePool(Regedit.Buffer);

    Status = IoCreateFile(&ReparseHandle,
                          GENERIC_READ,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                          FILE_OPEN,
                          FILE_NON_DIRECTORY_FILE,
                          NULL,
                          0,
                          CreateFileTypeNone,
                          NULL,
                          IO_NO_PARAMETER_CHECKING | IO_STOP_ON_SYMLINK);
    ok(Status == STATUS_STOPPED_ON_SYMLINK || /* Windows Vista+ */
       Status == STATUS_IO_REPARSE_TAG_NOT_HANDLED, /* Windows 2003 (SP1, SP2) */
        "ZwCreateFile returned unexpected status: %lx\n", Status);
    if (NT_SUCCESS(Status))
    {
        ZwClose(ReparseHandle);
    }

    Status = ZwCreateFile(&ReparseHandle,
                          GENERIC_READ | GENERIC_WRITE | DELETE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                          FILE_OPEN,
                          FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT | FILE_OPEN_FOR_BACKUP_INTENT,
                          NULL,
                          0);
    if (skip(NT_SUCCESS(Status), "Creating opening reparse point: %lx\n", Status))
    {
        Status = ZwOpenFile(&ReparseHandle,
                            DELETE,
                            &ObjectAttributes,
                            &IoStatusBlock,
                            FILE_SHARE_DELETE,
                            FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE);
        ok_eq_hex(Status, STATUS_SUCCESS);
        ZwClose(ReparseHandle);
        ExFreePool(Foobar.Buffer);
        ExFreePool(SysDir.Buffer);
        ExFreePool(Reparse);
        return;
    }

    Status = ObReferenceObjectByHandle(ReparseHandle,
                                       FILE_READ_DATA,
                                       *IoFileObjectType,
                                       UserMode,
                                       (PVOID *)&FileObject,
                                       NULL);
    ok_eq_hex(Status, STATUS_SUCCESS);
    if (NT_SUCCESS(Status))
    {
        ok(RtlCompareUnicodeString(&Foobar, &FileObject->FileName, TRUE) == 0,
           "Expected: %wZ. Opened: %wZ\n", &Foobar, &FileObject->FileName);
        ObDereferenceObject(FileObject);
    }

    ExFreePool(Foobar.Buffer);

    RtlZeroMemory(Reparse, Size);
    Status = ZwFsControlFile(ReparseHandle,
                             NULL,
                             NULL,
                             NULL,
                             &IoStatusBlock,
                             FSCTL_GET_REPARSE_POINT,
                             NULL,
                             0,
                             Reparse,
                             Size);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Information, Size);
    if (NT_SUCCESS(Status))
    {
        PWSTR Buffer;
        UNICODE_STRING ReparsePath, FullPath;

        ok_eq_hex(Reparse->ReparseTag, IO_REPARSE_TAG_SYMLINK);
        ok_eq_hex(Reparse->ReparseDataLength, 12 + SysDir.Length * 2 + sizeof(L"\\regedit.exe") * 2 - sizeof(L"\\??\\") - sizeof(UNICODE_NULL));
        ok_eq_hex(Reparse->SymbolicLinkReparseBuffer.Flags, 0);

        FullPath.Length = 0;
        FullPath.MaximumLength = SysDir.Length + sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL);
        Buffer = FullPath.Buffer = ExAllocatePool(NonPagedPool, FullPath.MaximumLength);
        if (!skip(Buffer != NULL, "Memory allocation failed!\n"))
        {
            RtlCopyUnicodeString(&FullPath, &SysDir);
            RtlCopyMemory(&FullPath.Buffer[FullPath.Length / sizeof(WCHAR)], L"\\regedit.exe", sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL));
            FullPath.Length += (sizeof(L"\\regedit.exe") - sizeof(UNICODE_NULL));
            ReparsePath.Buffer = (PWSTR)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset);
            ReparsePath.Length = ReparsePath.MaximumLength = Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength;
            ok(RtlCompareUnicodeString(&ReparsePath, &FullPath, TRUE) == 0, "Expected: %wZ. Got: %wZ\n", &ReparsePath, &FullPath);

            FullPath.Length -= (sizeof(L"\\??\\") - sizeof(UNICODE_NULL));
            FullPath.MaximumLength -= (sizeof(L"\\??\\") - sizeof(UNICODE_NULL));
            FullPath.Buffer = (PWSTR)((ULONG_PTR)Buffer + sizeof(L"\\??\\") - sizeof(UNICODE_NULL));
            ReparsePath.Buffer = (PWSTR)((ULONG_PTR)Reparse->SymbolicLinkReparseBuffer.PathBuffer + Reparse->SymbolicLinkReparseBuffer.PrintNameOffset);
            ReparsePath.Length = ReparsePath.MaximumLength = Reparse->SymbolicLinkReparseBuffer.PrintNameLength;
            ok(RtlCompareUnicodeString(&ReparsePath, &FullPath, TRUE) == 0, "Expected: %wZ. Got: %wZ\n", &ReparsePath, &FullPath);

            ExFreePool(Buffer);
        }
    }

    ExFreePool(SysDir.Buffer);
    ExFreePool(Reparse);

    ZwSetInformationFile(ReparseHandle,
                         &IoStatusBlock,
                         &ToDelete,
                         sizeof(ToDelete),
                         FileDispositionInformation);
    ZwClose(ReparseHandle);
}
Пример #28
0
static
VOID
NTAPI
KernelModeTest(IN PVOID Context)
{
    NTSTATUS Status;
    IO_STATUS_BLOCK IoStatusBlock;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE ParentHandle, SystemRootHandle, TargetHandle;
    PFILE_OBJECT ParentFileObject, TargetFileObject, SystemRootFileObject;

    UNREFERENCED_PARAMETER(Context);

    /* Kernelmode mandatory for IoCreateFile */
    ok(ExGetPreviousMode() == KernelMode, "UserMode returned!\n");

    /* First of all, open \\SystemRoot
     * We're interested in 3 pieces of information about it:
     * -> Its target (it's a symlink): \Windows or \ReactOS
     * -> Its associated File Object
     * -> Its associated FCB
     */
    TargetFileObject = NULL;
    IoStatusBlock.Status = 0xFFFFFFFF;
    TargetHandle = INVALID_HANDLE_VALUE;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRoot,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = ZwOpenFile(&TargetHandle,
                        GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        Status = ObReferenceObjectByHandle(TargetHandle,
                                           FILE_READ_DATA,
                                           *IoFileObjectType,
                                           KernelMode,
                                           (PVOID *)&TargetFileObject,
                                           NULL);
        ok_eq_hex(Status, STATUS_SUCCESS);
    }

    ok(TargetFileObject != NULL, "Not target to continue!\n");
    if (TargetFileObject == NULL)
    {
        if (TargetHandle != INVALID_HANDLE_VALUE)
        {
            ObCloseHandle(TargetHandle, KernelMode);
        }
        return;
    }

    /* Open target directory of \SystemRoot\Regedit.exe
     * This must lead to \SystemRoot opening
     */
    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRootRegedit,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = IoCreateFile(&ParentHandle,
                          GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          0,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          FILE_OPEN,
                          FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0,
                          CreateFileTypeNone,
                          NULL,
                          IO_OPEN_TARGET_DIRECTORY);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        Status = ObReferenceObjectByHandle(ParentHandle,
                                           FILE_READ_DATA,
                                           *IoFileObjectType,
                                           KernelMode,
                                           (PVOID *)&ParentFileObject,
                                           NULL);
        ok_eq_hex(Status, STATUS_SUCCESS);
        if (Status == STATUS_SUCCESS)
        {
            /* At that point, file object must point to \SystemRoot
             * But must not be the same FO than target (diverted file object)
             * This means FCB & FileName are equal
             * But CCB & FO are different
             * CCB must be != NULL, otherwise it means open failed
             */
            ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n");
            ok_eq_pointer(ParentFileObject->RelatedFileObject, NULL);
            ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext);
            ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n");
            ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n");
            ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0);
            ObDereferenceObject(ParentFileObject);
        }
        /* Because target exists FSD must signal it */
        ok_eq_long(IoStatusBlock.Information, FILE_EXISTS);
        ObCloseHandle(ParentHandle, KernelMode);
    }

    /* Do the same with relative open */
    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRoot,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = ZwOpenFile(&SystemRootHandle,
                        GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        IoStatusBlock.Status = 0xFFFFFFFF;
        IoStatusBlock.Information = 0xFFFFFFFF;
        InitializeObjectAttributes(&ObjectAttributes,
                                   &Regedit,
                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                   SystemRootHandle,
                                   NULL);
        Status = IoCreateFile(&ParentHandle,
                              GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                              &ObjectAttributes,
                              &IoStatusBlock,
                              NULL,
                              0,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              FILE_OPEN,
                              FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                              NULL,
                              0,
                              CreateFileTypeNone,
                              NULL,
                              IO_OPEN_TARGET_DIRECTORY);
        ok_eq_hex(Status, STATUS_SUCCESS);
        ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
        if (Status == STATUS_SUCCESS)
        {
            Status = ObReferenceObjectByHandle(ParentHandle,
                                               FILE_READ_DATA,
                                               *IoFileObjectType,
                                               KernelMode,
                                               (PVOID *)&ParentFileObject,
                                               NULL);
            ok_eq_hex(Status, STATUS_SUCCESS);
            if (Status == STATUS_SUCCESS)
            {
                ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n");
                ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext);
                ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n");
                ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n");
                ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0);
                Status = ObReferenceObjectByHandle(SystemRootHandle,
                                                   FILE_READ_DATA,
                                                   *IoFileObjectType,
                                                   KernelMode,
                                                   (PVOID *)&SystemRootFileObject,
                                                   NULL);
                ok_eq_hex(Status, STATUS_SUCCESS);
                if (Status == STATUS_SUCCESS)
                {
                    ok_eq_pointer(ParentFileObject->RelatedFileObject, SystemRootFileObject);
                    ok(ParentFileObject->RelatedFileObject != TargetFileObject, "File objects must be different\n");
                    ok(SystemRootFileObject != TargetFileObject, "File objects must be different\n");
                    ObDereferenceObject(SystemRootFileObject);
                }
                ObDereferenceObject(ParentFileObject);
            }
            ok_eq_long(IoStatusBlock.Information, FILE_EXISTS);
            ObCloseHandle(ParentHandle, KernelMode);
        }
        ObCloseHandle(SystemRootHandle, KernelMode);
    }

    /* *** */

    /* Now redo the same scheme, but using a target that doesn't exist
     * The difference will be in IoStatusBlock.Information, the FSD will
     * inform that the target doesn't exist.
     * Clear for rename :-)
     */
    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRootFoobar,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = IoCreateFile(&ParentHandle,
                          GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          0,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          FILE_OPEN,
                          FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0,
                          CreateFileTypeNone,
                          NULL,
                          IO_OPEN_TARGET_DIRECTORY);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        Status = ObReferenceObjectByHandle(ParentHandle,
                                           FILE_READ_DATA,
                                           *IoFileObjectType,
                                           KernelMode,
                                           (PVOID *)&ParentFileObject,
                                           NULL);
        ok_eq_hex(Status, STATUS_SUCCESS);
        if (Status == STATUS_SUCCESS)
        {
            ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n");
            ok_eq_pointer(ParentFileObject->RelatedFileObject, NULL);
            ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext);
            ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n");
            ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n");
            ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0);
            ObDereferenceObject(ParentFileObject);
        }
        ok_eq_long(IoStatusBlock.Information, FILE_DOES_NOT_EXIST);
        ObCloseHandle(ParentHandle, KernelMode);
    }

    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRoot,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = ZwOpenFile(&SystemRootHandle,
                        GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        IoStatusBlock.Status = 0xFFFFFFFF;
        IoStatusBlock.Information = 0xFFFFFFFF;
        InitializeObjectAttributes(&ObjectAttributes,
                                   &Foobar,
                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                   SystemRootHandle,
                                   NULL);
        Status = IoCreateFile(&ParentHandle,
                              GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                              &ObjectAttributes,
                              &IoStatusBlock,
                              NULL,
                              0,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              FILE_OPEN,
                              FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                              NULL,
                              0,
                              CreateFileTypeNone,
                              NULL,
                              IO_OPEN_TARGET_DIRECTORY);
        ok_eq_hex(Status, STATUS_SUCCESS);
        ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
        if (Status == STATUS_SUCCESS)
        {
            Status = ObReferenceObjectByHandle(ParentHandle,
                                               FILE_READ_DATA,
                                               *IoFileObjectType,
                                               KernelMode,
                                               (PVOID *)&ParentFileObject,
                                               NULL);
            ok_eq_hex(Status, STATUS_SUCCESS);
            if (Status == STATUS_SUCCESS)
            {
                ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n");
                ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext);
                ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n");
                ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n");
                ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0);
                Status = ObReferenceObjectByHandle(SystemRootHandle,
                                                   FILE_READ_DATA,
                                                   *IoFileObjectType,
                                                   KernelMode,
                                                   (PVOID *)&SystemRootFileObject,
                                                   NULL);
                ok_eq_hex(Status, STATUS_SUCCESS);
                if (Status == STATUS_SUCCESS)
                {
                    ok_eq_pointer(ParentFileObject->RelatedFileObject, SystemRootFileObject);
                    ok(ParentFileObject->RelatedFileObject != TargetFileObject, "File objects must be different\n");
                    ok(SystemRootFileObject != TargetFileObject, "File objects must be different\n");
                    ObDereferenceObject(SystemRootFileObject);
                }
                ObDereferenceObject(ParentFileObject);
            }
            ok_eq_long(IoStatusBlock.Information, FILE_DOES_NOT_EXIST);
            ObCloseHandle(ParentHandle, KernelMode);
        }
        ObCloseHandle(SystemRootHandle, KernelMode);
    }

    ObDereferenceObject(TargetFileObject);
    ObCloseHandle(TargetHandle, KernelMode);

    /* *** */

    /* Direct target open of something that doesn't exist */
    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRootFoobarFoobar,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = IoCreateFile(&ParentHandle,
                          GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          0,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          FILE_OPEN,
                          FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0,
                          CreateFileTypeNone,
                          NULL,
                          IO_OPEN_TARGET_DIRECTORY);
    ok_eq_hex(Status, STATUS_OBJECT_PATH_NOT_FOUND);
    ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
    if (Status == STATUS_SUCCESS)
    {
        ObCloseHandle(ParentHandle, KernelMode);
    }

    /* Relative target open of something that doesn't exist */
    IoStatusBlock.Status = 0xFFFFFFFF;
    IoStatusBlock.Information = 0xFFFFFFFF;
    InitializeObjectAttributes(&ObjectAttributes,
                               &SystemRoot,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL, NULL);
    Status = ZwOpenFile(&SystemRootHandle,
                        GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    ok_eq_hex(Status, STATUS_SUCCESS);
    ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS);
    if (Status == STATUS_SUCCESS)
    {
        IoStatusBlock.Status = 0xFFFFFFFF;
        IoStatusBlock.Information = 0xFFFFFFFF;
        InitializeObjectAttributes(&ObjectAttributes,
                                   &FoobarFoobar,
                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                   SystemRootHandle,
                                   NULL);
        Status = IoCreateFile(&ParentHandle,
                              GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE,
                              &ObjectAttributes,
                              &IoStatusBlock,
                              NULL,
                              0,
                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                              FILE_OPEN,
                              FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                              NULL,
                              0,
                              CreateFileTypeNone,
                              NULL,
                              IO_OPEN_TARGET_DIRECTORY);
        ok_eq_hex(Status, STATUS_OBJECT_PATH_NOT_FOUND);
        ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF);
        if (Status == STATUS_SUCCESS)
        {
            ObCloseHandle(ParentHandle, KernelMode);
        }
        ObCloseHandle(SystemRootHandle, KernelMode);
    }
}
/**
* 先检测黑名单,如果在黑名单内,直接拒,否则放行。
   如果不在黑名单,则检查白名单,在白名单内,无操作。
     如果不在白名单内,则将文件全路径及hash值传递到上层
* @param filename 文件全路径。
* return 如果文件安全则返回true,否则返回false。
*/
bool CheckIsFileHashSecure(const PUNICODE_STRING filename)
{	
	/////////////////////////////////////////////比较已经过滤的文件名
	if(IsInBlackCache(filename) == true)
		return false;

	if( MODULE_FILTERED == GetModuleFilter((ULONG)PsGetCurrentProcessId(),filename) )		
		return true;
	///////////////////////////////////////

	HANDLE hFile;
	OBJECT_ATTRIBUTES oaFile;
	InitializeObjectAttributes(&oaFile, filename, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);

	// 读权限打开文件,如果失败则认为文件不安全,返回false。
	IO_STATUS_BLOCK ioStatus;
	NTSTATUS status = ZwOpenFile(&hFile, GENERIC_READ, &oaFile, &ioStatus, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
	if(!NT_SUCCESS(status))
	{
		KdPrint(("VerifyModule: ZwOpenFile: %ws %08x\n", filename->Buffer, status));
		return false;
	}

	unsigned char* fileBuf = (unsigned char*)ExAllocatePoolWithTag(PagedPool, FILE_BUFFER_SIZE, 'knab');
	if(fileBuf == NULL)
	{
		ZwClose(hFile);
		return false;
	}

	// 获取文件hash。
	MD5_CTX md5;
	MD5Init(&md5);
	ULONG sizeAll=0;
	
	FILE_STANDARD_INFORMATION fsi;
	ZwQueryInformationFile(hFile,&ioStatus,&fsi,sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation);


	while(1)
	{
		NTSTATUS status = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatus, fileBuf, 
			FILE_BUFFER_SIZE, NULL, NULL);
		if(!NT_SUCCESS(status))
			break;
		if(ioStatus.Information == 0)
			break;

		sizeAll += ioStatus.Information;
		MD5Update(&md5, fileBuf, ioStatus.Information);
	}
	ExFreePoolWithTag(fileBuf, 'knab');

	unsigned char final[16];
	MD5Final(final, &md5);

	ZwClose(hFile);

	//黑白名单校验
//  	bool bOK = IsHashBlack(final);
// 
// 	if( bOK )
// 	{
// 		if(!IsInBlackCache(filename))
// 		{
// 			WriteSysLog(LOG_TYPE_DEBUG,L" Fileter Module :%s", filename->Buffer);
// 			AddBlackCache(filename);
// 		}
// 		return false;
// 	}
// 	else if( !IsHashSecure(final) )//传递到上层 
// 	{
// 		if( setData(filename->Buffer,filename->Length,final,16) )
// 			setSigned();
// 	}	
	bool bOK = IsHashBlack(final);
	bool bReturn = true;

	if( bOK )
	{
		if(!IsInBlackCache(filename))
		{
			WriteSysLog(LOG_TYPE_INFO,L" Fileter Module :%s", filename->Buffer);
			AddBlackCache(filename);
		}
		bReturn = false;
	}
	else if( !IsHashSecure(final) )//传递到上层 
	{
		if( !IsInstall() )
		{
			if( setData(filename->Buffer,filename->Length,final,16) )
				setSigned();

			LARGE_INTEGER  lWaitTimeOuts;
			lWaitTimeOuts.QuadPart = -10 * 1000 * 1000;

			//DbgPrint("###kernel wait event!");
WriteSysLog(LOG_TYPE_INFO,L" kernel is waitint for event signal!");
			if( STATUS_TIMEOUT == KeWaitForSingleObject(g_pEventFilterGo, Executive, KernelMode, FALSE, &lWaitTimeOuts) )
			{
				IsInstall(true);
				if( GetPIDNumber() > 2)
					bReturn = false;
				else
					bReturn = true;
			}
			else
				bReturn = g_bPassFilter;
			//DbgPrint("###kernel continue: file path : %ws is %ws \n", filename->Buffer, bReturn? L"pass":L"noPass");
WriteSysLog(LOG_TYPE_INFO,L" kernel continue: file path : %ws is %ws", filename->Buffer, bReturn? L"pass":L"noPass");
			if( bReturn )
				if( MODULE_FILTERED != GetModuleFilter((ULONG)PsGetCurrentProcessId(),filename) && (GetPIDNumber() > 2) )
					SetModuleFilter((ULONG)PsGetCurrentProcessId(), filename, true);
		}
	}	
	//
	return bReturn;
}
Пример #30
-2
EXTERN_C NTSTATUS EnumDirectory( char *lpDirName )
{
	NTSTATUS status, fStatus; 
	ULONG dwBytesReturned; 
	OBJECT_ATTRIBUTES objectAttributes; 
	PDEVICE_OBJECT lpDeviceObject;
	IO_STACK_LOCATION iost; 
	PIO_STACK_LOCATION lpsp; 
	IO_STATUS_BLOCK IoStatus; 
	HANDLE hFile = NULL;
	PFILE_DIRECTORY_INFORMATION lpInformation; 
	PDIRECTORY_INFO lpDirInfo = NULL, lpPreDirInfo = NULL; 
	PFILE_OBJECT lpFileObject = NULL;
	UNICODE_STRING unFileName;
	ANSI_STRING anFileName;
	HANDLE  eventHandle = NULL;
	CHAR buffer[1024]; 
	PUCHAR lpNext;

	dwBytesReturned = 0; 
	status = STATUS_UNSUCCESSFUL; 
	RtlZeroMemory(buffer,1024); 
	strcpy(buffer,"\\DosDevices\\"); 
	strcat(buffer,lpDirName); 
	RtlInitAnsiString(&anFileName,buffer); 
	RtlAnsiStringToUnicodeString(&unFileName,&anFileName,TRUE); 
	InitializeObjectAttributes(&objectAttributes,&unFileName,OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,NULL,NULL);

	__try
	{
		//打开文件
		fStatus = ZwOpenFile(&hFile,\
			FILE_LIST_DIRECTORY | SYNCHRONIZE | FILE_ANY_ACCESS,\
			&objectAttributes,\
			&IoStatus,\
			FILE_SHARE_READ | FILE_SHARE_WRITE| FILE_SHARE_DELETE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);

		ObReferenceObjectByHandle(hFile, FILE_LIST_DIRECTORY | SYNCHRONIZE, 0, KernelMode, (PVOID *)&lpFileObject, NULL); 

		status = ZwCreateEvent(&eventHandle, GENERIC_ALL, 0, NotificationEvent,
			FALSE);

		lpInformation = (PFILE_DIRECTORY_INFORMATION)ExAllocatePool(PagedPool, 655350); 
		status = ZwQueryDirectoryFile(hFile, eventHandle,0, 0, &IoStatus,
			lpInformation, 655350,
			FileDirectoryInformation, FALSE, NULL,
			FALSE );

		if (!NT_SUCCESS(status) && status != STATUS_PENDING)
		{
			goto LeaveBefore;
		}
		if (status == STATUS_PENDING)
		{
			KeWaitForSingleObject(eventHandle, Executive, KernelMode, TRUE, 0);
		}

		FreePagedLookasideListForDirectory();
		g_pPageListDirectory = (PPAGED_LOOKASIDE_LIST)ExAllocatePool(PagedPool, sizeof(PAGED_LOOKASIDE_LIST));
		ExInitializePagedLookasideList(g_pPageListDirectory, NULL, NULL, 0, sizeof(DIRECTORY_INFO), NULL, 0);

		while(1) 
		{
			lpDirInfo = (PDIRECTORY_INFO)ExAllocateFromPagedLookasideList(g_pPageListDirectory);
			RtlZeroMemory(lpDirInfo, sizeof(DIRECTORY_INFO));

			RtlCopyMemory(lpDirInfo->FileName, lpInformation->FileName, lpInformation->FileNameLength);
			lpDirInfo->AllocationSize = lpInformation->AllocationSize;
			lpDirInfo->FileAttributes = lpInformation->FileAttributes;
			RtlTimeToTimeFields(&(lpInformation->CreationTime), &(lpDirInfo->CreationTime)); 
			RtlTimeToTimeFields(&(lpInformation->LastAccessTime), &(lpDirInfo->LastAccessTime));  
			RtlTimeToTimeFields(&(lpInformation->LastWriteTime), &(lpDirInfo->LastWriteTime));  
			RtlTimeToTimeFields(&(lpInformation->ChangeTime), &(lpDirInfo->ChangeTime));
			lpDirInfo->next = NULL;

			if (NULL == g_pDirectoryInfo)
			{
				g_pDirectoryInfo = lpDirInfo;
				lpPreDirInfo = lpDirInfo;
			}
			else
			{
				lpPreDirInfo->next = lpDirInfo;
				lpPreDirInfo = lpDirInfo;
			}

			if(!lpInformation->NextEntryOffset)
			{
				break;
			}

			lpInformation = (PFILE_DIRECTORY_INFORMATION)((PUCHAR)lpInformation + lpInformation->NextEntryOffset);

		} 
LeaveBefore:
		;
	}
	__finally
	{
		if (NT_SUCCESS(fStatus))
		{
			ZwClose(hFile);
		}
		if (NULL != lpFileObject)
		{
			ObDereferenceObject(lpFileObject);
			lpFileObject = NULL;
		}
		if (NULL != eventHandle)
		{
			ZwClose(eventHandle);
			eventHandle = NULL;
		}

	}

	return status;               
}