Пример #1
1
VOID
GRAPHICS_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer)
{
    PGRAPHICS_SCREEN_BUFFER Buff = (PGRAPHICS_SCREEN_BUFFER)Buffer;

    /*
     * IMPORTANT !! Reinitialize the type so that we don't enter a recursive
     * infinite loop when calling CONSOLE_SCREEN_BUFFER_Destroy.
     */
    Buffer->Header.Type = SCREEN_BUFFER;

    /*
     * Uninitialize the graphics screen buffer
     * in the reverse way we initialized it.
     */
    NtUnmapViewOfSection(Buff->ClientProcess, Buff->ClientBitMap);
    NtUnmapViewOfSection(NtCurrentProcess(), Buff->BitMap);
    NtClose(Buff->hSection);
    NtDuplicateObject(Buff->ClientProcess, Buff->ClientMutex,
                      NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
    NtClose(Buff->Mutex);
    ConsoleFreeHeap(Buff->BitMapInfo);

    CONSOLE_SCREEN_BUFFER_Destroy(Buffer);
}
Пример #2
0
/*
 * @implemented
 */
BOOL
NTAPI
UnmapViewOfFile(LPCVOID lpBaseAddress)
{
    NTSTATUS Status;

    /* Unmap the section */
    Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)lpBaseAddress);
    if (!NT_SUCCESS(Status))
    {
        /* Check if the pages were protected */
        if (Status == STATUS_INVALID_PAGE_PROTECTION)
        {
            /* Flush the region if it was a "secure memory cache" */
            if (RtlFlushSecureMemoryCache((PVOID)lpBaseAddress, 0))
            {
                /* Now try to unmap again */
                Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)lpBaseAddress);
                if (NT_SUCCESS(Status)) return TRUE;
            }
        }

        /* We failed */
        BaseSetLastNTError(Status);
        return FALSE;
    }

    /* Otherwise, return sucess */
    return TRUE;
}
Пример #3
0
VOID WepCloseServerObjects(
    VOID
    )
{
    if (WeServerSharedSection)
    {
        NtClose(WeServerSharedSection);
        WeServerSharedSection = NULL;
    }

    if (WeServerSharedData)
    {
        NtUnmapViewOfSection(NtCurrentProcess(), WeServerSharedData);
        WeServerSharedData = NULL;
    }

    if (WeServerSharedSectionLock)
    {
        NtClose(WeServerSharedSectionLock);
        WeServerSharedSectionLock = NULL;
    }

    if (WeServerSharedSectionEvent)
    {
        NtClose(WeServerSharedSectionEvent);
        WeServerSharedSectionEvent = NULL;
    }
}
Пример #4
0
/*
 * @implemented
 */
BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
{
    NTSTATUS Status;
    PIMAGE_NT_HEADERS NtHeaders;

    if (LDR_IS_DATAFILE(hLibModule))
    {
        // FIXME: This SEH should go inside RtlImageNtHeader instead
        _SEH2_TRY
        {
            /* This is a LOAD_LIBRARY_AS_DATAFILE module, check if it's a valid one */
            NtHeaders = RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1));
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            NtHeaders = NULL;
        } _SEH2_END

        if (NtHeaders)
        {
            /* Unmap view */
            Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)((ULONG_PTR)hLibModule & ~1));

            /* Unload alternate resource module */
            LdrUnloadAlternateResourceModule(hLibModule);
        }
        else
            Status = STATUS_INVALID_IMAGE_FORMAT;
    }
    else
    {
Пример #5
0
NTSTATUS PhLoadMappedImage(
    _In_opt_ PWSTR FileName,
    _In_opt_ HANDLE FileHandle,
    _In_ BOOLEAN ReadOnly,
    _Out_ PPH_MAPPED_IMAGE MappedImage
    )
{
    NTSTATUS status;

    status = PhMapViewOfEntireFile(
        FileName,
        FileHandle,
        ReadOnly,
        &MappedImage->ViewBase,
        &MappedImage->Size
        );

    if (NT_SUCCESS(status))
    {
        status = PhInitializeMappedImage(
            MappedImage,
            MappedImage->ViewBase,
            MappedImage->Size
            );

        if (!NT_SUCCESS(status))
        {
            NtUnmapViewOfSection(NtCurrentProcess(), MappedImage->ViewBase);
        }
    }

    return status;
}
Пример #6
0
static int OnUnmapViewClick(HWND hDlg)
{
    TFileTestData * pData = GetDialogData(hDlg);
    NTSTATUS Status;

    // Get the base address where it is mapped
    if(SaveDialog2(hDlg) == ERROR_SUCCESS)
    {
        // Unmap the view from the base address
        Status = NtUnmapViewOfSection(NtCurrentProcess(), pData->pvSectionMappedView);

        // Clear the base address, so the next click on "MapView" will succeed
        Hex2DlgTextPtr(hDlg, IDC_BASE_ADDRESS, NULL);
        pData->pvSectionMappedView = NULL;

        // Clear the view size, so the next click on "MapView" will succeed
        Hex2DlgTextPtr(hDlg, IDC_VIEW_SIZE, 0);
        pData->cbSectViewSize = 0;

        // Show the result
        SetResultInfo(hDlg, Status, pData->hSection);
        UpdateDialog(hDlg, pData);
    }
    return TRUE;
}
Пример #7
0
NTSTATUS PhUnloadMappedImage(
    _Inout_ PPH_MAPPED_IMAGE MappedImage
    )
{
    return NtUnmapViewOfSection(
        NtCurrentProcess(),
        MappedImage->ViewBase
        );
}
Пример #8
0
NTSTATUS PhUnloadMappedArchive(
    _Inout_ PPH_MAPPED_ARCHIVE MappedArchive
    )
{
    return NtUnmapViewOfSection(
        NtCurrentProcess(),
        MappedArchive->ViewBase
        );
}
Пример #9
0
// UnmapPhysicalMemory
// Maps a view of a section.
//
VOID UnmapPhysicalMemory( DWORD Address )
{
	NTSTATUS		status;

	status = NtUnmapViewOfSection( (HANDLE) -1, (PVOID) Address );
	if( !NT_SUCCESS(status)) {

//		PrintError("Unable to unmap view", status );
	}
}
Пример #10
0
/***********************************************************************
 *           exit_thread
 */
void exit_thread( int status )
{
    static void *prev_teb;
    shmlocal_t *shmlocal;
    sigset_t sigset;
    TEB *teb;

    if (status)  /* send the exit code to the server (0 is already the default) */
    {
        SERVER_START_REQ( terminate_thread )
        {
            req->handle    = wine_server_obj_handle( GetCurrentThread() );
            req->exit_code = status;
            wine_server_call( req );
        }
        SERVER_END_REQ;
    }

    if (interlocked_xchg_add( &nb_threads, 0 ) <= 1)
    {
        LdrShutdownProcess();
        exit( status );
    }

    LdrShutdownThread();
    RtlFreeThreadActivationContextStack();

    shmlocal = interlocked_xchg_ptr( &NtCurrentTeb()->Reserved5[2], NULL );
    if (shmlocal) NtUnmapViewOfSection( NtCurrentProcess(), shmlocal );

    pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );

    if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() )))
    {
        struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;

        if (thread_data->pthread_id)
        {
            pthread_join( thread_data->pthread_id, NULL );
            signal_free_thread( teb );
        }
    }

    sigemptyset( &sigset );
    sigaddset( &sigset, SIGQUIT );
    pthread_sigmask( SIG_BLOCK, &sigset, NULL );
    if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) _exit( status );

    close( ntdll_get_thread_data()->wait_fd[0] );
    close( ntdll_get_thread_data()->wait_fd[1] );
    close( ntdll_get_thread_data()->reply_fd );
    close( ntdll_get_thread_data()->request_fd );
    pthread_exit( UIntToPtr(status) );
}
Пример #11
0
static void devmem_unmap(DWORD addr)
{
	NTSTATUS	r;

	r = NtUnmapViewOfSection((HANDLE) -1, (PVOID)addr);

	if(!NT_SUCCESS(r))
	{
		logerr(0, "NtUnmapViewOfSection failed");
		errno = unix_err(RtlNtStatusToDosError(r));
	}
}
Пример #12
0
/*
 * FUNCTION: Closes the current cabinet
 * RETURNS:
 *     Status of operation
 */
static ULONG
CloseCabinet(VOID)
{
    if (FileBuffer)
    {
        NtUnmapViewOfSection(NtCurrentProcess(), FileBuffer);
        NtClose(FileSectionHandle);
        NtClose(FileHandle);
        FileBuffer = NULL;
    }

    return 0;
}
Пример #13
0
/*
 * @implemented
 */
BOOL
WINAPI
Process32FirstW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe)
{
  PTH32SNAPSHOT Snapshot;
  LARGE_INTEGER SOffset;
  SIZE_T ViewSize;
  NTSTATUS Status;

  CHECK_PARAM_SIZE(lppe, sizeof(PROCESSENTRY32W));

  SOffset.QuadPart = 0;
  ViewSize = 0;
  Snapshot = NULL;

  Status = NtMapViewOfSection(hSnapshot,
                              NtCurrentProcess(),
                              (PVOID*)&Snapshot,
                              0,
                              0,
                              &SOffset,
                              &ViewSize,
                              ViewShare,
                              0,
                              PAGE_READWRITE);
  if(NT_SUCCESS(Status))
  {
    BOOL Ret;

    if(Snapshot->ProcessListCount > 0)
    {
      LPPROCESSENTRY32W Entries = (LPPROCESSENTRY32W)OffsetToPtr(Snapshot, Snapshot->ProcessListOffset);

      Snapshot->ProcessListIndex = 1;
      RtlCopyMemory(lppe, &Entries[0], sizeof(PROCESSENTRY32W));
      Ret = TRUE;
    }
    else
    {

      SetLastError(ERROR_NO_MORE_FILES);
      Ret = FALSE;
    }

    NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
    return Ret;
  }

  BaseSetLastNTError(Status);
  return FALSE;
}
Пример #14
0
/*
 * @implemented
 */
BOOL
WINAPI
Heap32ListNext(HANDLE hSnapshot, LPHEAPLIST32 lphl)
{
  PTH32SNAPSHOT Snapshot;
  LARGE_INTEGER SOffset;
  SIZE_T ViewSize;
  NTSTATUS Status;

  CHECK_PARAM_SIZE(lphl, sizeof(HEAPLIST32));

  SOffset.QuadPart = 0;
  ViewSize = 0;
  Snapshot = NULL;

  Status = NtMapViewOfSection(hSnapshot,
                              NtCurrentProcess(),
                              (PVOID*)&Snapshot,
                              0,
                              0,
                              &SOffset,
                              &ViewSize,
                              ViewShare,
                              0,
                              PAGE_READWRITE);
  if(NT_SUCCESS(Status))
  {
    BOOL Ret;

    if(Snapshot->HeapListCount > 0 &&
       Snapshot->HeapListIndex < Snapshot->HeapListCount)
    {
      LPHEAPLIST32 Entries = (LPHEAPLIST32)OffsetToPtr(Snapshot, Snapshot->HeapListOffset);
      RtlCopyMemory(lphl, &Entries[Snapshot->HeapListIndex++], sizeof(HEAPLIST32));
      Ret = TRUE;
    }
    else
    {
      SetLastError(ERROR_NO_MORE_FILES);
      Ret = FALSE;
    }

    NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);
    return Ret;
  }

  BaseSetLastNTError(Status);
  return FALSE;
}
Пример #15
0
/*
 * @implemented
 */
BOOL
NTAPI
UnmapViewOfFile(LPCVOID lpBaseAddress)
{
    NTSTATUS Status;

    /* Unmap the section */
    Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)lpBaseAddress);
    if (!NT_SUCCESS(Status))
    {
        /* We failed */
        BaseSetLastNTError(Status);
        return FALSE;
    }

    /* Otherwise, return sucess */
    return TRUE;
}
Пример #16
0
/***********************************************************************
 *             UnmapViewOfFile   (KERNEL32.@)
 *
 * Unmaps a mapped view of a file.
 *
 * PARAMS
 *  addr [I] Address where mapped view begins.
 *
 * RETURNS
 *	Success: TRUE.
 *	Failure: FALSE.
 *
 */
BOOL WINAPI UnmapViewOfFile( LPCVOID addr )
{
    NTSTATUS status;

    if (GetVersion() & 0x80000000)
    {
        MEMORY_BASIC_INFORMATION info;
        if (!VirtualQuery( addr, &info, sizeof(info) ) || info.AllocationBase != addr)
        {
            SetLastError( ERROR_INVALID_ADDRESS );
            return FALSE;
        }
    }

    status = NtUnmapViewOfSection( GetCurrentProcess(), (void *)addr );
    if (status) SetLastError( RtlNtStatusToDosError(status) );
    return !status;
}
Пример #17
0
BOOL
APIENTRY
UnmapViewOfFile(
    LPCVOID lpBaseAddress
    )

/*++

Routine Description:

    A previously mapped view of a file may be unmapped from the callers
    address space using UnmapViewOfFile.

Arguments:

    lpBaseAddress - Supplies the base address of a previously mapped
        view of a file that is to be unmapped.  This value must be
        identical to the value returned by a previous call to
        MapViewOfFile.

Return Value:

    TRUE - The operation was successful.  All dirty pages within the
        specified range are stored in the on-disk representation of the
        mapped file.

    FALSE - The operation failed. Extended error status is available
        using GetLastError.

--*/

{
    NTSTATUS Status;

    Status = NtUnmapViewOfSection(NtCurrentProcess(),(PVOID)lpBaseAddress);

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

    return TRUE;
}
Пример #18
0
VOID PhShowMemoryEditorDialog(
    _In_ HANDLE ProcessId,
    _In_ PVOID BaseAddress,
    _In_ SIZE_T RegionSize,
    _In_ ULONG SelectOffset,
    _In_ ULONG SelectLength,
    _In_opt_ PPH_STRING Title,
    _In_ ULONG Flags
    )
{
    PMEMORY_EDITOR_CONTEXT context;
    MEMORY_EDITOR_CONTEXT lookupContext;
    PPH_AVL_LINKS links;

    lookupContext.ProcessId = ProcessId;
    lookupContext.BaseAddress = BaseAddress;
    lookupContext.RegionSize = RegionSize;

    links = PhFindElementAvlTree(&PhMemoryEditorSet, &lookupContext.Links);

    if (!links)
    {
        context = PhAllocate(sizeof(MEMORY_EDITOR_CONTEXT));
        memset(context, 0, sizeof(MEMORY_EDITOR_CONTEXT));

        context->ProcessId = ProcessId;
        context->BaseAddress = BaseAddress;
        context->RegionSize = RegionSize;
        context->SelectOffset = SelectOffset;
        PhSwapReference(&context->Title, Title);
        context->Flags = Flags;

        context->WindowHandle = CreateDialogParam(
            PhInstanceHandle,
            MAKEINTRESOURCE(IDD_MEMEDIT),
            NULL,
            PhpMemoryEditorDlgProc,
            (LPARAM)context
            );

        if (!context->LoadCompleted)
        {
            DestroyWindow(context->WindowHandle);
            return;
        }

        if (SelectOffset != -1)
            PostMessage(context->WindowHandle, WM_PH_SELECT_OFFSET, SelectOffset, SelectLength);

        PhRegisterDialog(context->WindowHandle);
        PhAddElementAvlTree(&PhMemoryEditorSet, &context->Links);

        ShowWindow(context->WindowHandle, SW_SHOW);
    }
    else
    {
        context = CONTAINING_RECORD(links, MEMORY_EDITOR_CONTEXT, Links);

        if (IsIconic(context->WindowHandle))
            ShowWindow(context->WindowHandle, SW_RESTORE);
        else
            SetForegroundWindow(context->WindowHandle);

        if (SelectOffset != -1)
            PostMessage(context->WindowHandle, WM_PH_SELECT_OFFSET, SelectOffset, SelectLength);

        // Just in case.
        if ((Flags & PH_MEMORY_EDITOR_UNMAP_VIEW_OF_SECTION) && ProcessId == NtCurrentProcessId())
            NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
    }
}
Пример #19
0
/*
 * FUNCTION: Extracts a file from the cabinet
 * ARGUMENTS:
 *     Search = Pointer to PCAB_SEARCH structure used to locate the file
 * RETURNS
 *     Status of operation
 */
ULONG
CabinetExtractFile(PCAB_SEARCH Search)
{
    ULONG Size;                 // remaining file bytes to decompress
    ULONG CurrentOffset;        // current uncompressed offset within the folder
    PUCHAR CurrentBuffer;       // current pointer to compressed data in the block
    LONG RemainingBlock;        // remaining comp data in the block
    HANDLE DestFile;
    HANDLE DestFileSection;
    PVOID DestFileBuffer;       // mapped view of dest file
    PVOID CurrentDestBuffer;    // pointer to the current position in the dest view
    PCFDATA CFData;             // current data block
    ULONG Status;
    FILETIME FileTime;
    WCHAR DestName[MAX_PATH];
    NTSTATUS NtStatus;
    UNICODE_STRING UnicodeString;
    ANSI_STRING AnsiString;
    IO_STATUS_BLOCK IoStatusBlock;
    OBJECT_ATTRIBUTES ObjectAttributes;
    FILE_BASIC_INFORMATION FileBasic;
    PCFFOLDER CurrentFolder;
    LARGE_INTEGER MaxDestFileSize;
    LONG InputLength, OutputLength;
    char Junk[512];

    if (wcscmp(Search->Cabinet, CabinetName) != 0)
    {
        /* the file is not in the current cabinet */
        DPRINT("File is not in this cabinet (%S != %S)\n",
               Search->Cabinet, CabinetName);
        return CAB_STATUS_NOFILE;
    }

    /* look up the folder that the file specifies */
    if (Search->File->FolderIndex == 0xFFFD ||
        Search->File->FolderIndex == 0xFFFF)
    {
        /* folder is continued from previous cabinet,
           that shouldn't happen here */
        return CAB_STATUS_NOFILE;
    }
    else if (Search->File->FolderIndex == 0xFFFE)
    {
        /* folder is the last in this cabinet and continues into next */
        CurrentFolder = &CabinetFolders[PCABHeader->FolderCount - 1];
    }
    else
    {
        /* folder is completely contained within this cabinet */
        CurrentFolder = &CabinetFolders[Search->File->FolderIndex];
    }

    switch (CurrentFolder->CompressionType & CAB_COMP_MASK)
    {
        case CAB_COMP_NONE:
            CabinetSelectCodec(CAB_CODEC_RAW);
            break;
        case CAB_COMP_MSZIP:
            CabinetSelectCodec(CAB_CODEC_MSZIP);
            break;
        default:
            return CAB_STATUS_UNSUPPCOMP;
    }

    DPRINT("Extracting file at uncompressed offset (0x%X) Size (%d bytes)\n",
           (UINT)Search->File->FileOffset, (UINT)Search->File->FileSize);

    RtlInitAnsiString(&AnsiString, Search->File->FileName);
    wcscpy(DestName, DestPath);
    UnicodeString.MaximumLength = sizeof(DestName) - wcslen(DestName) * sizeof(WCHAR);
    UnicodeString.Buffer = DestName + wcslen(DestName);
    UnicodeString.Length = 0;
    RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);

    /* Create destination file, fail if it already exists */
    RtlInitUnicodeString(&UnicodeString, DestName);

    InitializeObjectAttributes(&ObjectAttributes,
                               &UnicodeString,
                               OBJ_CASE_INSENSITIVE,
                               NULL, NULL);

    NtStatus = NtCreateFile(&DestFile,
                            GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
                            &ObjectAttributes,
                            &IoStatusBlock,
                            NULL,
                            FILE_ATTRIBUTE_NORMAL,
                            0,
                            FILE_CREATE,
                            FILE_SYNCHRONOUS_IO_NONALERT,
                            NULL, 0);

    if (!NT_SUCCESS(NtStatus))
    {
        DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);

        /* If file exists, ask to overwrite file */
        if (OverwriteHandler == NULL || OverwriteHandler(Search->File, DestName))
        {
            /* Create destination file, overwrite if it already exists */
            NtStatus = NtCreateFile(&DestFile,
                                    GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
                                    &ObjectAttributes,
                                    &IoStatusBlock,
                                    NULL,
                                    FILE_ATTRIBUTE_NORMAL,
                                    0,
                                    FILE_OVERWRITE,
                                    FILE_SYNCHRONOUS_IO_ALERT,
                                    NULL, 0);

            if (!NT_SUCCESS(NtStatus))
            {
                DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus);
                return CAB_STATUS_CANNOT_CREATE;
            }
        }
        else
        {
            DPRINT("File (%S) exists\n", DestName);
            return CAB_STATUS_FILE_EXISTS;
        }
    }

    MaxDestFileSize.QuadPart = Search->File->FileSize;
    NtStatus = NtCreateSection(&DestFileSection,
                               SECTION_ALL_ACCESS,
                               0,
                               &MaxDestFileSize,
                               PAGE_READWRITE,
                               SEC_COMMIT,
                               DestFile);

    if (!NT_SUCCESS(NtStatus))
    {
        DPRINT("NtCreateSection failed: %x\n", NtStatus);
        Status = CAB_STATUS_NOMEMORY;
        goto CloseDestFile;
    }

    DestFileBuffer = 0;
    DestFileSize = 0;
    NtStatus = NtMapViewOfSection(DestFileSection,
                                  NtCurrentProcess(),
                                  &DestFileBuffer,
                                  0, 0, 0,
                                  &DestFileSize,
                                  ViewUnmap,
                                  0,
                                  PAGE_READWRITE);

    if (!NT_SUCCESS(NtStatus))
    {
        DPRINT("NtMapViewOfSection failed: %x\n", NtStatus);
        Status = CAB_STATUS_NOMEMORY;
        goto CloseDestFileSection;
    }

    CurrentDestBuffer = DestFileBuffer;
    if (!ConvertDosDateTimeToFileTime(Search->File->FileDate,
                                      Search->File->FileTime,
                                      &FileTime))
    {
        DPRINT("DosDateTimeToFileTime() failed\n");
        Status = CAB_STATUS_CANNOT_WRITE;
        goto UnmapDestFile;
    }

    NtStatus = NtQueryInformationFile(DestFile,
                                      &IoStatusBlock,
                                      &FileBasic,
                                      sizeof(FILE_BASIC_INFORMATION),
                                      FileBasicInformation);
    if (!NT_SUCCESS(NtStatus))
    {
        DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus);
    }
    else
    {
        memcpy(&FileBasic.LastAccessTime, &FileTime, sizeof(FILETIME));

        NtStatus = NtSetInformationFile(DestFile,
                                        &IoStatusBlock,
                                        &FileBasic,
                                        sizeof(FILE_BASIC_INFORMATION),
                                        FileBasicInformation);
        if (!NT_SUCCESS(NtStatus))
        {
            DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus);
        }
    }

    SetAttributesOnFile(Search->File, DestFile);

    /* Call extract event handler */
    if (ExtractHandler != NULL)
    {
        ExtractHandler(Search->File, DestName);
    }

    /* find the starting block of the file
       start with the first data block of the folder */
    CFData = (PCFDATA)(CabinetFolders[Search->File->FolderIndex].DataOffset + FileBuffer);
    CurrentOffset = 0;
    while (CurrentOffset + CFData->UncompSize <= Search->File->FileOffset)
    {
        /* walk the data blocks until we reach
           the one containing the start of the file */
        CurrentOffset += CFData->UncompSize;
        CFData = (PCFDATA)((char *)(CFData + 1) + DataReserved + CFData->CompSize);
    }

    /* now decompress and discard any data in
       the block before the start of the file */

    /* start of comp data */
    CurrentBuffer = ((unsigned char *)(CFData + 1)) + DataReserved;
    RemainingBlock = CFData->CompSize;
    InputLength = RemainingBlock;

    while (CurrentOffset < Search->File->FileOffset)
    {
        /* compute remaining uncomp bytes to start
           of file, bounded by sizeof junk */
        OutputLength = Search->File->FileOffset - CurrentOffset;
        if (OutputLength > (LONG)sizeof(Junk))
            OutputLength = sizeof (Junk);

        /* negate to signal NOT end of block */
        OutputLength = -OutputLength;
        CodecUncompress(Junk, CurrentBuffer, &InputLength, &OutputLength);
        /* add the uncomp bytes extracted to current folder offset */
        CurrentOffset += OutputLength;
        /* add comp bytes consumed to CurrentBuffer */
        CurrentBuffer += InputLength;
        /* subtract bytes consumed from bytes remaining in block */
        RemainingBlock -= InputLength;
        /* neg for resume decompression of the same block */
        InputLength = -RemainingBlock;
    }

    /* now CurrentBuffer points to the first comp byte
       of the file, so we can begin decompressing */

    /* Size = remaining uncomp bytes of the file to decompress */
    Size = Search->File->FileSize;
    while (Size > 0)
    {
        OutputLength = Size;
        DPRINT("Decompressing block at %x with RemainingBlock = %d, Size = %d\n",
               CurrentBuffer, RemainingBlock, Size);

        Status = CodecUncompress(CurrentDestBuffer,
                                 CurrentBuffer,
                                 &InputLength,
                                 &OutputLength);

        if (Status != CS_SUCCESS)
        {
            DPRINT("Cannot uncompress block\n");
            if (Status == CS_NOMEMORY)
                Status = CAB_STATUS_NOMEMORY;
            Status = CAB_STATUS_INVALID_CAB;
            goto UnmapDestFile;
        }

        /* advance dest buffer by bytes produced */
        CurrentDestBuffer = (PVOID)((ULONG_PTR)CurrentDestBuffer + OutputLength);
        /* advance src buffer by bytes consumed */
        CurrentBuffer += InputLength;
        /* reduce remaining file bytes by bytes produced */
        Size -= OutputLength;
        /* reduce remaining block size by bytes consumed */
        RemainingBlock -= InputLength;
        if (RemainingBlock == 0)
        {
            /* used up this block, move on to the next */
            DPRINT("Out of block data\n");
            CFData = (PCFDATA)CurrentBuffer;
            RemainingBlock = CFData->CompSize;
            CurrentBuffer = (unsigned char *)(CFData + 1) + DataReserved;
            InputLength = RemainingBlock;
        }
    }

    Status = CAB_STATUS_SUCCESS;

UnmapDestFile:
    NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer);

CloseDestFileSection:
    NtClose(DestFileSection);

CloseDestFile:
    NtClose(DestFile);

    return Status;
}
Пример #20
0
NTSTATUS
SetupCopyFile(
    PWCHAR SourceFileName,
    PWCHAR DestinationFileName)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE FileHandleSource;
    HANDLE FileHandleDest;
    static IO_STATUS_BLOCK IoStatusBlock;
    FILE_STANDARD_INFORMATION FileStandard;
    FILE_BASIC_INFORMATION FileBasic;
    ULONG RegionSize;
    UNICODE_STRING FileName;
    NTSTATUS Status;
    PVOID SourceFileMap = 0;
    HANDLE SourceFileSection;
    SIZE_T SourceSectionSize = 0;
    LARGE_INTEGER ByteOffset;

#ifdef __REACTOS__
    RtlInitUnicodeString(&FileName,
                         SourceFileName);

    InitializeObjectAttributes(&ObjectAttributes,
                               &FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtOpenFile(&FileHandleSource,
                        GENERIC_READ,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ,
                        FILE_SEQUENTIAL_ONLY);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtOpenFile failed: %x, %wZ\n", Status, &FileName);
        goto done;
    }
#else
    FileHandleSource = CreateFileW(SourceFileName,
                                   GENERIC_READ,
                                   FILE_SHARE_READ,
                                   NULL,
                                   OPEN_EXISTING,
                                   0,
                                   NULL);
    if (FileHandleSource == INVALID_HANDLE_VALUE)
    {
        Status = STATUS_UNSUCCESSFUL;
        goto done;
    }
#endif

    Status = NtQueryInformationFile(FileHandleSource,
                                    &IoStatusBlock,
                                    &FileStandard,
                                    sizeof(FILE_STANDARD_INFORMATION),
                                    FileStandardInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtQueryInformationFile failed: %x\n", Status);
        goto closesrc;
    }

    Status = NtQueryInformationFile(FileHandleSource,
                                    &IoStatusBlock,&FileBasic,
                                    sizeof(FILE_BASIC_INFORMATION),
                                    FileBasicInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtQueryInformationFile failed: %x\n", Status);
        goto closesrc;
    }

    Status = NtCreateSection(&SourceFileSection,
                             SECTION_MAP_READ,
                             NULL,
                             NULL,
                             PAGE_READONLY,
                             SEC_COMMIT,
                             FileHandleSource);
    if (!NT_SUCCESS(Status))
    {
      DPRINT1("NtCreateSection failed: %x, %S\n", Status, SourceFileName);
      goto closesrc;
    }

    Status = NtMapViewOfSection(SourceFileSection,
                                NtCurrentProcess(),
                                &SourceFileMap,
                                0,
                                0,
                                NULL,
                                &SourceSectionSize,
                                ViewUnmap,
                                0,
                                PAGE_READONLY );
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtMapViewOfSection failed: %x, %S\n", Status, SourceFileName);
        goto closesrcsec;
    }

    RtlInitUnicodeString(&FileName,
                         DestinationFileName);

    InitializeObjectAttributes(&ObjectAttributes,
                               &FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtCreateFile(&FileHandleDest,
                          GENERIC_WRITE | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          0,
                          FILE_OVERWRITE_IF,
                          FILE_NO_INTERMEDIATE_BUFFERING |
                          FILE_SEQUENTIAL_ONLY |
                          FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateFile failed: %x\n", Status);
        goto unmapsrcsec;
    }

    RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart);
    IoStatusBlock.Status = 0;
    ByteOffset.QuadPart = 0;
    Status = NtWriteFile(FileHandleDest,
                         NULL,
                         NULL,
                         NULL,
                         &IoStatusBlock,
                         SourceFileMap,
                         RegionSize,
                         &ByteOffset,
                         NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n", Status, IoStatusBlock.Status, &IoStatusBlock, SourceFileMap, RegionSize);
        goto closedest;
    }

    /* Copy file date/time from source file */
    Status = NtSetInformationFile(FileHandleDest,
                                  &IoStatusBlock,
                                  &FileBasic,
                                  sizeof(FILE_BASIC_INFORMATION),
                                  FileBasicInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetInformationFile failed: %x\n", Status);
        goto closedest;
    }

    /* shorten the file back to it's real size after completing the write */
    Status = NtSetInformationFile(FileHandleDest,
                                  &IoStatusBlock,
                                  &FileStandard.EndOfFile,
                                  sizeof(FILE_END_OF_FILE_INFORMATION),
                                  FileEndOfFileInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetInformationFile failed: %x\n", Status);
    }

closedest:
    NtClose(FileHandleDest);

unmapsrcsec:
    NtUnmapViewOfSection(NtCurrentProcess(), SourceFileMap);

closesrcsec:
    NtClose(SourceFileSection);

closesrc:
    NtClose(FileHandleSource);

done:
    return Status;
}
Пример #21
0
BOOL GetSetThreadContext_Injection()
{
	TCHAR lpApplicationName[] = _T("C:\\Windows\\System32\\svchost.exe");
	TCHAR lpApplicationName2[] = _T("C:\\masm32\\examples\\dialogs_later\\basic\\basicdlg.exe");
	BOOL bResult;

	STARTUPINFO StartupInfo;
	PROCESS_INFORMATION ProcessInfo;

	SecureZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
	SecureZeroMemory(&ProcessInfo, sizeof(PPROCESS_INFORMATION));

	// Create the hollowed process in suspended mode
	bResult = CreateProcess(lpApplicationName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInfo);
	if (bResult == NULL){
		print_last_error(_T("CreateProcess"));
		return FALSE;
	}

	// Allocate space for context structure
	PCONTEXT pContext;
	LPVOID pTargetImageBase = NULL;
	pContext = PCONTEXT(VirtualAlloc(NULL, sizeof(LPVOID), MEM_COMMIT, PAGE_READWRITE));
	if (pContext == NULL) {
		print_last_error(_T("VirtualAlloc"));
		return FALSE;
	}

	// Get the thread context of target
	pContext->ContextFlags = CONTEXT_FULL;
	bResult = GetThreadContext(ProcessInfo.hThread, pContext);
	if (bResult == NULL) {
		print_last_error(_T("GetThreadContext"));
		return FALSE;
	}

	// Read the image base address of target
	ReadProcessMemory(ProcessInfo.hProcess, LPCVOID(pContext->Ebx + 8), pTargetImageBase, 4, NULL);

	// Opening source image
	HANDLE hFile = CreateFile(lpApplicationName2, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, NULL, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		print_last_error(_T("CreateFile"));
		return FALSE;
	}

	// Reading the file
	DWORD dwSize = GetFileSize(hFile, 0);
	DWORD dwBytesRead;
	PBYTE pBuffer = new BYTE[dwSize];
	ReadFile(hFile, pBuffer, dwSize, &dwBytesRead, 0);
	PIMAGE_SECTION_HEADER pImageSectionHeader;

	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBuffer;
	if (pDosHeader->e_magic == IMAGE_DOS_SIGNATURE)
	{
		PIMAGE_NT_HEADERS32 pNTHeaders = PIMAGE_NT_HEADERS(DWORD(pBuffer) + pDosHeader->e_lfanew);
		if (pNTHeaders->Signature == IMAGE_NT_SIGNATURE)
		{

			if (DWORD(pTargetImageBase) == pNTHeaders->OptionalHeader.ImageBase)
			{
				pNtUnmapViewOfSection NtUnmapViewOfSection;
				NtUnmapViewOfSection = (pNtUnmapViewOfSection)(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection"));
				NtUnmapViewOfSection(ProcessInfo.hProcess, pTargetImageBase);
			}

			LPVOID pImageBase;
			pImageBase = VirtualAllocEx(ProcessInfo.hProcess, LPVOID(pNTHeaders->OptionalHeader.ImageBase), pNTHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
			if (pImageBase == NULL) {
				print_last_error(_T("VirtualAllocEx"));
				return FALSE;
			}

				WriteProcessMemory(ProcessInfo.hProcess, pImageBase, pBuffer, pNTHeaders->OptionalHeader.SizeOfHeaders, NULL);
				for (int Count = 0; Count < pNTHeaders->FileHeader.NumberOfSections; Count++)
				{
					pImageSectionHeader = PIMAGE_SECTION_HEADER(DWORD(pBuffer) + pDosHeader->e_lfanew + 248 + (Count * 40));
					WriteProcessMemory(ProcessInfo.hProcess, LPVOID(DWORD(pImageBase) + pImageSectionHeader->VirtualAddress), LPVOID(DWORD(pBuffer) + pImageSectionHeader->PointerToRawData), pImageSectionHeader->SizeOfRawData, NULL);
				}
				WriteProcessMemory(ProcessInfo.hProcess, LPVOID(pContext->Ebx + 8), LPVOID(&pNTHeaders->OptionalHeader.ImageBase), 4, NULL);
				pContext->Eax = DWORD(pImageBase) + pNTHeaders->OptionalHeader.AddressOfEntryPoint;
				SetThreadContext(ProcessInfo.hThread, LPCONTEXT(pContext));
				ResumeThread(ProcessInfo.hThread);
			
		}
	}

	return TRUE;
}
Пример #22
0
BOOLEAN ZMain(
    IN PVOID DllHandle,
    ULONG Reason,
    IN PCONTEXT Context OPTIONAL)
					
{
    static char szDumpFile[13];
    NTSTATUS Status;
    DllHandle, Context;	// avoid compiler warnings


    // if process is attaching, initialize the dll
    //
    if (Reason == DLL_PROCESS_ATTACH) {
		GdiSetBatchLimit (1);
    	ApfInitDll();
    }
    else if (Reason == DLL_THREAD_ATTACH) {
		GdiSetBatchLimit (1);
    }
    else if (Reason == DLL_PROCESS_DETACH) {
	//
	// Get semaphore
	//
	Status = NtWaitForSingleObject(hDataSem,FALSE,NULL);

#ifdef ERRORDBG
	if (!NT_SUCCESS(Status)) {
	    KdPrint (("WAP: Could not wait for Dsemaphore in ZMain, %lx\n",
		Status));
    }
#endif	

	// Number of processes accessing this dll is contained in
	// ApfData[I_CALIBRATE].cCalls.	Decrement this number, and
	// if this number is then zero, dump the data.
			
	ApfData[I_CALIBRATE].cCalls--;
	if (ApfData[I_CALIBRATE].cCalls == 0) {
	    strcpy (szDumpFile, MODULE_NAME);
	    strcat (szDumpFile, ".end");
	    ApfDumpData ((LPSTR)szDumpFile);
	    //
	    // Unmap and close sections, and close semaphores
	    //
	    Status = NtUnmapViewOfSection(MyProcess,(PVOID)ApfControl);
	    Status = NtClose(ApfDataSectionHandle);

	    // This instance is now "uninitialized"
	    //
	    fInitDone = FALSE;
	}
	//
	// Release semaphore
	//
	Status = NtReleaseSemaphore(hDataSem,1,NULL);
#ifdef ERRORDBG
	if (!NT_SUCCESS(Status)) {
	    KdPrint (("WAP: DSemaphore Not Released in ZMain!! %lx\n",
		Status));
	}
#endif		
    }
    return(TRUE);

} /* ZMain () */
Пример #23
0
VOID
GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
                                BOOL Defaults)
{
    NTSTATUS Status;
    PCONSRV_CONSOLE Console = GuiData->Console;
    PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
    PCONSOLE_PROCESS_DATA ProcessData;
    HANDLE hSection = NULL, hClientSection = NULL;
    LARGE_INTEGER SectionSize;
    ULONG ViewSize = 0;
    SIZE_T Length = 0;
    PCONSOLE_PROPS pSharedInfo = NULL;
    PGUI_CONSOLE_INFO GuiInfo = NULL;

    DPRINT("GuiConsoleShowConsoleProperties entered\n");

    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;

    /*
     * Create a memory section to share with the applet, and map it.
     */
    /* Holds data for console.dll + console info + terminal-specific info */
    SectionSize.QuadPart = sizeof(CONSOLE_PROPS) + sizeof(GUI_CONSOLE_INFO);
    Status = NtCreateSection(&hSection,
                             SECTION_ALL_ACCESS,
                             NULL,
                             &SectionSize,
                             PAGE_READWRITE,
                             SEC_COMMIT,
                             NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to create a shared section, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                (PVOID*)&pSharedInfo,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to map the shared section, Status = 0x%08lx\n", Status);
        goto Quit;
    }


    /*
     * Setup the shared console properties structure.
     */

    /* Header */
    pSharedInfo->hConsoleWindow = GuiData->hWindow;
    pSharedInfo->ShowDefaultParams = Defaults;

    /*
     * We fill-in the fields only if we display
     * our properties, not the default ones.
     */
    if (!Defaults)
    {
        /* Console information */
        pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize;
        pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
        pSharedInfo->ci.HistoryNoDup = Console->HistoryNoDup;
        pSharedInfo->ci.QuickEdit = Console->QuickEdit;
        pSharedInfo->ci.InsertMode = Console->InsertMode;
        /////////////pSharedInfo->ci.InputBufferSize = 0;
        pSharedInfo->ci.ScreenBufferSize = ActiveBuffer->ScreenBufferSize;
        pSharedInfo->ci.ConsoleSize = ActiveBuffer->ViewSize;
        pSharedInfo->ci.CursorBlinkOn;
        pSharedInfo->ci.ForceCursorOff;
        pSharedInfo->ci.CursorSize = ActiveBuffer->CursorInfo.dwSize;
        if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
        {
            PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;

            pSharedInfo->ci.ScreenAttrib = Buffer->ScreenDefaultAttrib;
            pSharedInfo->ci.PopupAttrib  = Buffer->PopupDefaultAttrib;
        }
        else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
        {
            // PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer;
            DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n");

            // FIXME: Gather defaults from the registry ?
            pSharedInfo->ci.ScreenAttrib = DEFAULT_SCREEN_ATTRIB;
            pSharedInfo->ci.PopupAttrib  = DEFAULT_POPUP_ATTRIB ;
        }
        pSharedInfo->ci.CodePage;

        /* GUI Information */
        pSharedInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
        GuiInfo = pSharedInfo->TerminalInfo.TermInfo = (PGUI_CONSOLE_INFO)(pSharedInfo + 1);
        wcsncpy(GuiInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE);
        GuiInfo->FaceName[LF_FACESIZE - 1] = UNICODE_NULL;
        GuiInfo->FontFamily = GuiData->GuiInfo.FontFamily;
        GuiInfo->FontSize   = GuiData->GuiInfo.FontSize;
        GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight;
        GuiInfo->FullScreen = GuiData->GuiInfo.FullScreen;
        GuiInfo->AutoPosition = GuiData->GuiInfo.AutoPosition;
        GuiInfo->WindowOrigin = GuiData->GuiInfo.WindowOrigin;
        /* Offsetize */
        pSharedInfo->TerminalInfo.TermInfo = (PVOID)((ULONG_PTR)GuiInfo - (ULONG_PTR)pSharedInfo);

        /* Palette */
        memcpy(pSharedInfo->ci.Colors, Console->Colors, sizeof(Console->Colors));

        /* Title of the console, original one corresponding to the one set by the console leader */
        Length = min(sizeof(pSharedInfo->ci.ConsoleTitle) / sizeof(pSharedInfo->ci.ConsoleTitle[0]) - 1,
                     Console->OriginalTitle.Length / sizeof(WCHAR));
        wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
    }
    else
    {
        Length = 0;
        // FIXME: Load the default parameters from the registry.
    }

    /* Null-terminate the title */
    pSharedInfo->ci.ConsoleTitle[Length] = L'\0';


    /* Unmap the view */
    NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo);

    /* Get the console leader process, our client */
    ProcessData = ConSrvGetConsoleLeaderProcess(Console);

    /* Duplicate the section handle for the client */
    Status = NtDuplicateObject(NtCurrentProcess(),
                               hSection,
                               ProcessData->Process->ProcessHandle,
                               &hClientSection,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to duplicate section handle for client, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    /* Start the properties dialog */
    if (ProcessData->PropRoutine)
    {
        _SEH2_TRY
        {
            HANDLE Thread = NULL;

            _SEH2_TRY
            {
                Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
                                            ProcessData->PropRoutine,
                                            (PVOID)hClientSection, 0, NULL);
                if (NULL == Thread)
                {
                    DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
                }
                else
                {
                    DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
                           ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
                    /// WaitForSingleObject(Thread, INFINITE);
                }
            }
            _SEH2_FINALLY
            {
                CloseHandle(Thread);
            }
            _SEH2_END;
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            Status = _SEH2_GetExceptionCode();
            DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = 0x%08lx\n", Status);
        }
        _SEH2_END;
    }
Пример #24
0
VOID
PropertiesUpdate(
    IN PCONSOLE_INFORMATION Console,
    IN HANDLE hClientSection
    )

/*++

    Updates the console state from information sent by the properties
    dialog box.

--*/

{
    HANDLE hSection;
    ULONG ulViewSize;
    NTSTATUS Status;
    PCONSOLE_STATE_INFO pStateInfo;
    PCONSOLE_PROCESS_HANDLE ProcessHandleRecord;
    PSCREEN_INFORMATION ScreenInfo;
    ULONG FontIndex;
    WINDOWPLACEMENT wp;
    COORD NewSize;

    /*
     * Map the shared memory block handle into our address space.
     */
    ProcessHandleRecord = CONTAINING_RECORD(Console->ProcessHandleList.Blink,
                                            CONSOLE_PROCESS_HANDLE,
                                            ListLink);
    Status = NtDuplicateObject(ProcessHandleRecord->ProcessHandle,
                               hClientSection,
                               NtCurrentProcess(),
                               &hSection,
                               0,
                               0,
                               DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status)) {
        KdPrint(("CONSRV: error %x mapping client handle\n", Status));
        return;
    }

    /*
     * Get a pointer to the shared memory block.
     */
    pStateInfo = NULL;
    ulViewSize = 0;
    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                &pStateInfo,
                                0,
                                0,
                                NULL,
                                &ulViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READONLY);
    if (!NT_SUCCESS(Status)) {
        KdPrint(("CONSRV: error %x mapping view of file\n", Status));
        NtClose(hSection);
        return;
    }

    /*
     * Verify the size of the shared memory block.
     */
    if (ulViewSize < sizeof(CONSOLE_STATE_INFO)) {
        KdPrint(("CONSRV: sizeof(hSection) < sizeof(CONSOLE_STATE_INFO)\n"));
        NtUnmapViewOfSection(NtCurrentProcess(), pStateInfo);
        NtClose(hSection);
        return;
    }

    /*
     * Update the console state from the supplied values.
     */
    ScreenInfo = Console->CurrentScreenBuffer;
    if (!(Console->Flags & CONSOLE_VDM_REGISTERED) &&
        (pStateInfo->ScreenBufferSize.X != ScreenInfo->ScreenBufferSize.X ||
         pStateInfo->ScreenBufferSize.Y != ScreenInfo->ScreenBufferSize.Y)) {
        ResizeScreenBuffer(ScreenInfo,
                           pStateInfo->ScreenBufferSize,
                           TRUE);
    }
    FontIndex = FindCreateFont(pStateInfo->FontFamily,
                               pStateInfo->FaceName,
                               pStateInfo->FontSize,
                               pStateInfo->FontWeight);
    SetScreenBufferFont(ScreenInfo, FontIndex);
    SetCursorInformation(ScreenInfo,
                         pStateInfo->CursorSize,
                         ScreenInfo->BufferInfo.TextInfo.CursorVisible);

    NewSize.X = min(pStateInfo->WindowSize.X, ScreenInfo->MaximumWindowSize.X);
    NewSize.Y = min(pStateInfo->WindowSize.Y, ScreenInfo->MaximumWindowSize.Y);
    if (NewSize.X != CONSOLE_WINDOW_SIZE_X(ScreenInfo) ||
        NewSize.Y != CONSOLE_WINDOW_SIZE_Y(ScreenInfo)) {
        wp.length = sizeof(wp);
        GetWindowPlacement(Console->hWnd, &wp);
        wp.rcNormalPosition.right += (NewSize.X - CONSOLE_WINDOW_SIZE_X(ScreenInfo)) *
                            SCR_FONTSIZE(ScreenInfo).X;
        wp.rcNormalPosition.bottom += (NewSize.Y - CONSOLE_WINDOW_SIZE_Y(ScreenInfo)) *
                             SCR_FONTSIZE(ScreenInfo).Y;
        SetWindowPlacement(Console->hWnd, &wp);
    }

#ifdef i386
    if (FullScreenInitialized) {
        if (pStateInfo->FullScreen == FALSE) {
            if (Console->FullScreenFlags & CONSOLE_FULLSCREEN) {
                ConvertToWindowed(Console);
                ASSERT(!(Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE));
                Console->FullScreenFlags = 0;

                ChangeDispSettings(Console, Console->hWnd, 0);
            }
        } else {
            if (Console->FullScreenFlags == 0) {
                ConvertToFullScreen(Console);
                Console->FullScreenFlags |= CONSOLE_FULLSCREEN;

                ChangeDispSettings(Console, Console->hWnd, CDS_FULLSCREEN);
            }
        }
    }
#endif
    if (pStateInfo->QuickEdit) {
        Console->Flags |= CONSOLE_QUICK_EDIT_MODE;
    } else {
        Console->Flags &= ~CONSOLE_QUICK_EDIT_MODE;
    }
    if (pStateInfo->AutoPosition) {
        Console->Flags |= CONSOLE_AUTO_POSITION;
    } else {
        Console->Flags &= ~CONSOLE_AUTO_POSITION;
        SetWindowPos(Console->hWnd, NULL,
                        pStateInfo->WindowPosX,
                        pStateInfo->WindowPosY,
                        0, 0, SWP_NOZORDER | SWP_NOSIZE);
    }
    if (Console->InsertMode != pStateInfo->InsertMode) {
        SetCursorMode(ScreenInfo, FALSE);
        Console->InsertMode = pStateInfo->InsertMode;
    }

    RtlCopyMemory(Console->ColorTable,
                  pStateInfo->ColorTable,
                  sizeof(Console->ColorTable));
    SetScreenColors(ScreenInfo,
                    pStateInfo->ScreenAttributes,
                    pStateInfo->PopupAttributes,
                    TRUE);

    Console->CommandHistorySize = pStateInfo->HistoryBufferSize;
    Console->MaxCommandHistories = pStateInfo->NumberOfHistoryBuffers;
    if (pStateInfo->HistoryNoDup) {
        Console->Flags |= CONSOLE_HISTORY_NODUP;
    } else {
        Console->Flags &= ~CONSOLE_HISTORY_NODUP;
    }

    NtUnmapViewOfSection(NtCurrentProcess(), pStateInfo);
    NtClose(hSection);

    return;
}
Пример #25
0
BOOL MapNewExecutableRegionInProcess(
		IN HANDLE TargetProcessHandle,
		IN HANDLE TargetThreadHandle,
		IN LPVOID NewExecutableRawImage)
{
	PROCESS_BASIC_INFORMATION BasicInformation;
	PIMAGE_SECTION_HEADER     SectionHeader;
	PIMAGE_DOS_HEADER         DosHeader;
	PIMAGE_NT_HEADERS         NtHeader;
	PMINI_PEB                 ProcessPeb;
	NTSTATUS                  (NTAPI *NtUnmapViewOfSection)(HANDLE, LPVOID) = NULL;
	NTSTATUS                  (NTAPI *NtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, LPVOID, ULONG, PULONG) = NULL;
	NTSTATUS                  Status;
	CONTEXT                   ThreadContext;
	LPVOID                    OldEntryPoint = NULL;
	LPVOID                    TargetImageBase = NULL;
	ULONG                     SectionIndex = 0;
	ULONG                     SizeOfBasicInformation;
	BOOL                      Success = FALSE;


	//
	// Error checking? Bah.
	//
	DosHeader = (PIMAGE_DOS_HEADER)NewExecutableRawImage;
	NtHeader  = (PIMAGE_NT_HEADERS)((PCHAR)NewExecutableRawImage + DosHeader->e_lfanew);

	do
	{
		//
		// Get the old entry point address by inspecting eax of the current
		// thread (which should be BaseProcessStart).  Eax holds the address
		// of the entry point for the executable when the process is created
		// suspended.
		//
		ZeroMemory(
				&ThreadContext,
				sizeof(ThreadContext));

		ThreadContext.ContextFlags = CONTEXT_INTEGER;

		if (!GetThreadContext(
					TargetThreadHandle,
					&ThreadContext))
		{
			break;
		}

		OldEntryPoint = (LPVOID) NtHeader->OptionalHeader.ImageBase;

		//
		// Unmap the old executable region in the child process to avoid
		// conflicts
		//
		NtUnmapViewOfSection = (NTSTATUS (NTAPI *)(HANDLE, LPVOID))GetProcAddress(
				GetModuleHandle(
					TEXT("NTDLL")),
				"NtUnmapViewOfSection");

		NtUnmapViewOfSection(TargetProcessHandle, OldEntryPoint);

		//
		// Change the entry point address to the new executable's entry point
		//
		ThreadContext.Eax = NtHeader->OptionalHeader.AddressOfEntryPoint +
			NtHeader->OptionalHeader.ImageBase;

		if (!SetThreadContext(
					TargetThreadHandle,
					&ThreadContext))
			break;

		//
		// Allocate storage for the new executable in the child process
		//
		if (!(TargetImageBase = VirtualAllocEx(
						TargetProcessHandle,
						(LPVOID)NtHeader->OptionalHeader.ImageBase,
						NtHeader->OptionalHeader.SizeOfImage,
						MEM_COMMIT | MEM_RESERVE,
						PAGE_EXECUTE_READWRITE)))
			break;

		//
		// Update the executable's image base address in the PEB...
		//
		NtQueryInformationProcess = (NTSTATUS (NTAPI *)(HANDLE, PROCESSINFOCLASS, LPVOID, ULONG, PULONG))GetProcAddress(
				GetModuleHandle(
					TEXT("NTDLL")),
				"NtQueryInformationProcess");

		if (NtQueryInformationProcess(
					TargetProcessHandle,
					ProcessBasicInformation,
					&BasicInformation,
					sizeof(BasicInformation),
					&SizeOfBasicInformation) != ERROR_SUCCESS)
			break;

		ProcessPeb = BasicInformation.PebBaseAddress;

		if (!WriteProcessMemory(
					TargetProcessHandle,
					(LPVOID)&ProcessPeb->ImageBaseAddress,
					(LPVOID)&NtHeader->OptionalHeader.ImageBase,
					sizeof(LPVOID),
					NULL))
			break;

		//
		// Copy the image headers and all of the section contents
		//
		if (!WriteProcessMemory(
					TargetProcessHandle,
					TargetImageBase,
					NewExecutableRawImage,
					NtHeader->OptionalHeader.SizeOfHeaders,
					NULL))
			break;

		Success = TRUE;
		for (SectionIndex = 0,
				SectionHeader = IMAGE_FIRST_SECTION(NtHeader);
				SectionIndex < NtHeader->FileHeader.NumberOfSections;
				SectionIndex++)
		{
			//
			// Skip uninitialized data
			//
			if ((!SectionHeader[SectionIndex].SizeOfRawData) ||
					(SectionHeader[SectionIndex].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA))
				continue;

			if (!WriteProcessMemory(
						TargetProcessHandle,
						(LPVOID)((PCHAR)TargetImageBase +
							SectionHeader[SectionIndex].VirtualAddress),
						(LPVOID)((PCHAR)NewExecutableRawImage +
							SectionHeader[SectionIndex].PointerToRawData),
						SectionHeader[SectionIndex].SizeOfRawData,
						NULL))
			{
				Success = FALSE;
				break;
			}
		}

	} while (0);

	return Success;
}
NTSTATUS LeGlobalData::Initialize()
{
    BOOL            IsLoader;
    PLEPEB          LePeb;
    PLDR_MODULE     Ntdll;
    PPEB_BASE       Peb;
    NTSTATUS        Status;
    NLSTABLEINFO    NlsTableInfo;
    UNICODE_STRING  SystemDirectory, NlsFileName, OemNlsFileName, LangFileName;
    PKEY_VALUE_PARTIAL_INFORMATION IndexValue;

    IsLoader = IsLeLoader();

    Wow64 = Ps::IsWow64Process();
    Ntdll = GetNtdllLdrModule();

    LOOP_ONCE
    {
        LePeb = OpenOrCreateLePeb();
        if (LePeb == nullptr)
        {
            ULONG_PTR       DefaultACPLength, DefaultLCIDLength, DefaultOEMCPLength;
            WCHAR           DefaultACP[0x20], DefaultOEMCP[0x20], DefaultLCID[0x20];
            PVOID           ReloadedNtdll;
            PUNICODE_STRING FullDllName;

            LePeb = GetLePeb();

            InitDefaultLeb(&LePeb->Leb);

            FullDllName = &FindLdrModuleByHandle(&__ImageBase)->FullDllName;
            CopyMemory(LePeb->LeDllFullPath, FullDllName->Buffer, FullDllName->Length + sizeof(WCHAR));

            Status = LoadPeImage(Ntdll->FullDllName.Buffer, &ReloadedNtdll, nullptr, LOAD_PE_IGNORE_RELOC);
            if (NT_SUCCESS(Status))
            {
                PVOID LdrLoadDllAddress;

                LdrLoadDllAddress = LookupExportTable(ReloadedNtdll, NTDLL_LdrLoadDll);
                LePeb->LdrLoadDllAddress = PtrAdd(LdrLoadDllAddress, PtrOffset(Ntdll->DllBase, ReloadedNtdll));
                CopyMemory(LePeb->LdrLoadDllBackup, LdrLoadDllAddress, LDR_LOAD_DLL_BACKUP_SIZE);
                LePeb->LdrLoadDllBackupSize = LDR_LOAD_DLL_BACKUP_SIZE;

                UnloadPeImage(ReloadedNtdll);
            }

            DefaultACPLength    = (swprintf(DefaultACP, L"%d", LePeb->Leb.AnsiCodePage) + 1) * sizeof(WCHAR);
            DefaultOEMCPLength  = (swprintf(DefaultOEMCP, L"%d", LePeb->Leb.OemCodePage) + 1) * sizeof(WCHAR);
            DefaultLCIDLength   = (swprintf(DefaultLCID, L"%d", LePeb->Leb.LocaleID) + 1) * sizeof(WCHAR);

            REGISTRY_REDIRECTION_ENTRY64 *Entry, Entries[] =
            {
                {
                    { (ULONG64)HKEY_LOCAL_MACHINE, USTR64(REGPATH_CODEPAGE), USTR64(REGKEY_ACP), REG_SZ, },
                    { (ULONG64)HKEY_LOCAL_MACHINE, USTR64(REGPATH_CODEPAGE), USTR64(REGKEY_ACP), REG_SZ, DefaultACP, DefaultACPLength },
                },
                {
                    { (ULONG64)HKEY_LOCAL_MACHINE, USTR64(REGPATH_CODEPAGE), USTR64(REGKEY_OEMCP), REG_SZ, },
                    { (ULONG64)HKEY_LOCAL_MACHINE, USTR64(REGPATH_CODEPAGE), USTR64(REGKEY_OEMCP), REG_SZ, DefaultOEMCP, DefaultOEMCPLength },
                },
                {
                    { (ULONG64)HKEY_LOCAL_MACHINE, USTR64(REGPATH_LANGUAGE), USTR64(REGKEY_DEFAULT_LANGUAGE), REG_SZ, },
                    { (ULONG64)HKEY_LOCAL_MACHINE, USTR64(REGPATH_LANGUAGE), USTR64(REGKEY_DEFAULT_LANGUAGE), REG_SZ, DefaultLCID, DefaultLCIDLength },
                },
            };

            Status = this->InitRegistryRedirection(Entries, countof(Entries), nullptr);
        }
        else
        {
            *GetLePeb() = *LePeb;
            Status = this->InitRegistryRedirection(LePeb->Leb.RegistryReplacement, LePeb->Leb.NumberOfRegistryRedirectionEntries, &LePeb->Leb);

            NtClose(LePeb->Section);
            CloseLePeb(LePeb);
        }

        if (IsLoader)
            break;

        Status = this->TextMetricCache.Initialize();
        FAIL_RETURN(Status);

        PVOID           NlsBaseAddress;
        LCID            DefaultLocaleID;
        LARGE_INTEGER   DefaultCasingTableSize;

        Status = NtInitializeNlsFiles(&NlsBaseAddress, &DefaultLocaleID, &DefaultCasingTableSize);
        FAIL_RETURN(Status);

        this->GetLePeb()->OriginalLocaleID = DefaultLocaleID;

        NtUnmapViewOfSection(CurrentProcess, NlsBaseAddress);

        WriteLog(L"init leb %s", GetLePeb()->LeDllFullPath);

        SystemDirectory = Ntdll->FullDllName;
        SystemDirectory.Length -= Ntdll->BaseDllName.Length;

        Status = RtlDuplicateUnicodeString(RTL_DUPSTR_ADD_NULL, &SystemDirectory, &this->SystemDirectory);
        FAIL_RETURN(Status);

        RtlInitEmptyString(&NlsFileName, nullptr, 0);
        RtlInitEmptyString(&OemNlsFileName, nullptr, 0);
        RtlInitEmptyString(&LangFileName, nullptr, 0);

        SCOPE_EXIT
        {
            RtlFreeUnicodeString(&NlsFileName);
            RtlFreeUnicodeString(&OemNlsFileName);
            RtlFreeUnicodeString(&LangFileName);
        }
        SCOPE_EXIT_END;

        Status = GetNlsFile(&NlsFileName, GetLeb()->AnsiCodePage, REGPATH_CODEPAGE);
        FAIL_RETURN(Status);

        Status = GetNlsFile(&OemNlsFileName, GetLeb()->OemCodePage, REGPATH_CODEPAGE);
        FAIL_RETURN(Status);

        Status = GetLangFile(&LangFileName, GetLeb()->LocaleID, REGPATH_LANGUAGE);
        FAIL_RETURN(Status);

        NtFileMemory AnsiFile, OemFile, LangFile;

        Status = ReadFileInSystemDirectory(AnsiFile, &NlsFileName);
        FAIL_RETURN(Status);

        Status = ReadFileInSystemDirectory(OemFile, &OemNlsFileName);
        FAIL_RETURN(Status);

        Status = ReadFileInSystemDirectory(LangFile, &LangFileName);
        FAIL_RETURN(Status);

        AnsiCodePageOffset      = 0;
        OemCodePageOffset       = ROUND_UP(AnsiFile.GetSize32(), 16);
        UnicodeCaseTableOffset  = OemCodePageOffset + ROUND_UP(OemFile.GetSize32(), 16);

        Status = AllocVirtualMemory(&CodePageMapView, UnicodeCaseTableOffset + LangFile.GetSize32(), PAGE_READWRITE, MEM_COMMIT | MEM_TOP_DOWN);
        FAIL_RETURN(Status);

        CopyMemory(PtrAdd(CodePageMapView, AnsiCodePageOffset),     AnsiFile.GetBuffer(),   AnsiFile.GetSize32());
        CopyMemory(PtrAdd(CodePageMapView, OemCodePageOffset),      OemFile.GetBuffer(),    OemFile.GetSize32());
        CopyMemory(PtrAdd(CodePageMapView, UnicodeCaseTableOffset), LangFile.GetBuffer(),   LangFile.GetSize32());

        ProtectVirtualMemory(CodePageMapView, UnicodeCaseTableOffset + LangFile.GetSize32(), PAGE_READONLY);

        RtlInitNlsTables(
            (PUSHORT)PtrAdd(CodePageMapView, AnsiCodePageOffset),
            (PUSHORT)PtrAdd(CodePageMapView, OemCodePageOffset),
            (PUSHORT)PtrAdd(CodePageMapView, UnicodeCaseTableOffset),
            &NlsTableInfo
        );

        RtlResetRtlTranslations(&NlsTableInfo);

        WriteLog(L"reset nls");

        Peb = CurrentPeb();

        Peb->AnsiCodePageData       = (PUSHORT)PtrAdd(CodePageMapView, AnsiCodePageOffset);
        Peb->OemCodePageData        = (PUSHORT)PtrAdd(CodePageMapView, OemCodePageOffset);
        Peb->UnicodeCaseTableData   = (PUSHORT)PtrAdd(CodePageMapView, UnicodeCaseTableOffset);

        // LdrInitShimEngineDynamic(&__ImageBase);

        LdrRegisterDllNotification(0,
            [] (ULONG NotificationReason, PCLDR_DLL_NOTIFICATION_DATA NotificationData, PVOID Context)
            {
                return ((PLeGlobalData)Context)->DllNotification(NotificationReason, NotificationData);
            },
            this,
            &DllNotificationCookie
        );
    }

    Status = InstallHookPort();
    WriteLog(L"inst hp: %08X", Status);
    FAIL_RETURN(Status);

    HookNtdllRoutines(Ntdll->DllBase);

    WriteLog(L"hook ntdll");

    if (IsLoader)
        return Status;

    PLDR_MODULE Kernel32Ldr;

    Kernel32Ldr = GetKernel32Ldr();
    if (Kernel32Ldr != nullptr)
    {
        Kernel32Ldr->EntryPoint = DelayInitDllEntry;
        // HookKernel32Routines(Kernel32Ldr->DllBase);
    }

    WriteLog(L"init %p", Status);

    return Status;
}
Пример #27
0
NTSTATUS
GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
                           IN OUT PCONSOLE Console,
                           IN PGRAPHICS_BUFFER_INFO GraphicsInfo)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PGRAPHICS_SCREEN_BUFFER NewBuffer = NULL;

    LARGE_INTEGER SectionSize;
    ULONG ViewSize = 0;
    HANDLE ProcessHandle;

    if (Buffer == NULL || Console == NULL || GraphicsInfo == NULL)
        return STATUS_INVALID_PARAMETER;

    *Buffer = NULL;

    Status = CONSOLE_SCREEN_BUFFER_Initialize((PCONSOLE_SCREEN_BUFFER*)&NewBuffer,
                                              Console,
                                              sizeof(GRAPHICS_SCREEN_BUFFER));
    if (!NT_SUCCESS(Status)) return Status;
    NewBuffer->Header.Type = GRAPHICS_BUFFER;
    NewBuffer->Vtbl = &GraphicsVtbl;

    /*
     * Remember the handle to the process so that we can close or unmap
     * correctly the allocated resources when the client releases the
     * screen buffer.
     */
    ProcessHandle = CsrGetClientThread()->Process->ProcessHandle;
    NewBuffer->ClientProcess = ProcessHandle;

    /* Get infos from the graphics buffer information structure */
    NewBuffer->BitMapInfoLength = GraphicsInfo->Info.dwBitMapInfoLength;

    NewBuffer->BitMapInfo = ConsoleAllocHeap(HEAP_ZERO_MEMORY, NewBuffer->BitMapInfoLength);
    if (NewBuffer->BitMapInfo == NULL)
    {
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Adjust the bitmap height if needed (bottom-top vs. top-bottom). Use always bottom-up. */
    if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight > 0)
        GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight = -GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight;

    /* We do not use anything else than uncompressed bitmaps */
    if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression != BI_RGB)
    {
        DPRINT1("biCompression == %d != BI_RGB, correct that!\n", GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression);
        GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression = BI_RGB;
    }

    RtlCopyMemory(NewBuffer->BitMapInfo,
                  GraphicsInfo->Info.lpBitMapInfo,
                  GraphicsInfo->Info.dwBitMapInfoLength);

    NewBuffer->BitMapUsage = GraphicsInfo->Info.dwUsage;

    /* Set the screen buffer size. Fight against overflows. */
    if ( GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biWidth  <= 0xFFFF &&
        -GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight <= 0xFFFF )
    {
        /* Be careful about the sign of biHeight */
        NewBuffer->ScreenBufferSize.X =  (SHORT)GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biWidth ;
        NewBuffer->ScreenBufferSize.Y = (SHORT)-GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight;

        NewBuffer->OldViewSize = NewBuffer->ViewSize = 
            NewBuffer->OldScreenBufferSize = NewBuffer->ScreenBufferSize;
    }
    else
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Create a mutex to synchronize bitmap memory access
     * between ourselves and the client.
     */
    Status = NtCreateMutant(&NewBuffer->Mutex, MUTANT_ALL_ACCESS, NULL, FALSE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateMutant() failed: %lu\n", Status);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Duplicate the Mutex for the client. We must keep a trace of it
     * so that we can close it when the client releases the screen buffer.
     */
    Status = NtDuplicateObject(NtCurrentProcess(),
                               NewBuffer->Mutex,
                               ProcessHandle,
                               &NewBuffer->ClientMutex,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
        NtClose(NewBuffer->Mutex);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Create a memory section for the bitmap area, to share with the client.
     */
    SectionSize.QuadPart = NewBuffer->BitMapInfo->bmiHeader.biSizeImage;
    Status = NtCreateSection(&NewBuffer->hSection,
                             SECTION_ALL_ACCESS,
                             NULL,
                             &SectionSize,
                             PAGE_READWRITE,
                             SEC_COMMIT,
                             NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to create a shared section ; Status = %lu\n", Status);
        NtClose(NewBuffer->ClientMutex);
        NtClose(NewBuffer->Mutex);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Create a view for our needs.
     */
    ViewSize = 0;
    NewBuffer->BitMap = NULL;
    Status = NtMapViewOfSection(NewBuffer->hSection,
                                NtCurrentProcess(),
                                (PVOID*)&NewBuffer->BitMap,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status);
        NtClose(NewBuffer->hSection);
        NtClose(NewBuffer->ClientMutex);
        NtClose(NewBuffer->Mutex);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Create a view for the client. We must keep a trace of it so that
     * we can unmap it when the client releases the screen buffer.
     */
    ViewSize = 0;
    NewBuffer->ClientBitMap = NULL;
    Status = NtMapViewOfSection(NewBuffer->hSection,
                                ProcessHandle,
                                (PVOID*)&NewBuffer->ClientBitMap,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status);
        NtUnmapViewOfSection(NtCurrentProcess(), NewBuffer->BitMap);
        NtClose(NewBuffer->hSection);
        NtClose(NewBuffer->ClientMutex);
        NtClose(NewBuffer->Mutex);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    NewBuffer->ViewOrigin.X = NewBuffer->ViewOrigin.Y = 0;
    NewBuffer->VirtualY = 0;

    NewBuffer->CursorBlinkOn  = FALSE;
    NewBuffer->ForceCursorOff = TRUE;
    NewBuffer->CursorInfo.bVisible = FALSE;
    NewBuffer->CursorInfo.dwSize   = 0;
    NewBuffer->CursorPosition.X = NewBuffer->CursorPosition.Y = 0;

    NewBuffer->Mode = 0;

    *Buffer = (PCONSOLE_SCREEN_BUFFER)NewBuffer;
    Status = STATUS_SUCCESS;

Quit:
    return Status;
}
Пример #28
0
INT_PTR CALLBACK PhpMemoryEditorDlgProc(
    _In_ HWND hwndDlg,
    _In_ UINT uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
    )
{
    PMEMORY_EDITOR_CONTEXT context;

    if (uMsg != WM_INITDIALOG)
    {
        context = GetProp(hwndDlg, PhMakeContextAtom());
    }
    else
    {
        context = (PMEMORY_EDITOR_CONTEXT)lParam;
        SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context);
    }

    if (!context)
        return FALSE;

    switch (uMsg)
    {
    case WM_INITDIALOG:
        {
            NTSTATUS status;

            if (context->Title)
            {
                SetWindowText(hwndDlg, context->Title->Buffer);
            }
            else
            {
                PPH_PROCESS_ITEM processItem;

                if (processItem = PhReferenceProcessItem(context->ProcessId))
                {
                    SetWindowText(hwndDlg, PhaFormatString(L"%s (%u) (0x%Ix - 0x%Ix)",
                        processItem->ProcessName->Buffer, HandleToUlong(context->ProcessId),
                        context->BaseAddress, (ULONG_PTR)context->BaseAddress + context->RegionSize)->Buffer);
                    PhDereferenceObject(processItem);
                }
            }

            PhInitializeLayoutManager(&context->LayoutManager, hwndDlg);

            if (context->RegionSize > 1024 * 1024 * 1024) // 1 GB
            {
                PhShowError(NULL, L"Unable to edit the memory region because it is too large.");
                return TRUE;
            }

            if (!NT_SUCCESS(status = PhOpenProcess(
                &context->ProcessHandle,
                PROCESS_VM_READ,
                context->ProcessId
                )))
            {
                PhShowStatus(NULL, L"Unable to open the process", status, 0);
                return TRUE;
            }

            context->Buffer = PhAllocatePage(context->RegionSize, NULL);

            if (!context->Buffer)
            {
                PhShowError(NULL, L"Unable to allocate memory for the buffer.");
                return TRUE;
            }

            if (!NT_SUCCESS(status = PhReadVirtualMemory(
                context->ProcessHandle,
                context->BaseAddress,
                context->Buffer,
                context->RegionSize,
                NULL
                )))
            {
                PhShowStatus(PhMainWndHandle, L"Unable to read memory", status, 0);
                return TRUE;
            }

            PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL,
                PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);
            PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_SAVE), NULL,
                PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM);
            PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_BYTESPERROW), NULL,
                PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
            PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_GOTO), NULL,
                PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
            PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_WRITE), NULL,
                PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);
            PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_REREAD), NULL,
                PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT);

            if (MinimumSize.left == -1)
            {
                RECT rect;

                rect.left = 0;
                rect.top = 0;
                rect.right = 290;
                rect.bottom = 140;
                MapDialogRect(hwndDlg, &rect);
                MinimumSize = rect;
                MinimumSize.left = 0;
            }

            context->HexEditHandle = GetDlgItem(hwndDlg, IDC_MEMORY);
            PhAddLayoutItem(&context->LayoutManager, context->HexEditHandle, NULL, PH_ANCHOR_ALL);
            HexEdit_SetBuffer(context->HexEditHandle, context->Buffer, (ULONG)context->RegionSize);

            {
                PH_RECTANGLE windowRectangle;

                windowRectangle.Position = PhGetIntegerPairSetting(L"MemEditPosition");
                windowRectangle.Size = PhGetScalableIntegerPairSetting(L"MemEditSize", TRUE).Pair;
                PhAdjustRectangleToWorkingArea(NULL, &windowRectangle);

                MoveWindow(hwndDlg, windowRectangle.Left, windowRectangle.Top,
                    windowRectangle.Width, windowRectangle.Height, FALSE);

                // Implement cascading by saving an offsetted rectangle.
                windowRectangle.Left += 20;
                windowRectangle.Top += 20;

                PhSetIntegerPairSetting(L"MemEditPosition", windowRectangle.Position);
                PhSetScalableIntegerPairSetting2(L"MemEditSize", windowRectangle.Size);
            }

            {
                PWSTR bytesPerRowStrings[7];
                ULONG i;
                ULONG bytesPerRow;

                for (i = 0; i < sizeof(bytesPerRowStrings) / sizeof(PWSTR); i++)
                    bytesPerRowStrings[i] = PhaFormatString(L"%u bytes per row", 1 << (2 + i))->Buffer;

                PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_BYTESPERROW),
                    bytesPerRowStrings, sizeof(bytesPerRowStrings) / sizeof(PWSTR));

                bytesPerRow = PhGetIntegerSetting(L"MemEditBytesPerRow");

                if (bytesPerRow >= 4)
                {
                    HexEdit_SetBytesPerRow(context->HexEditHandle, bytesPerRow);
                    PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_BYTESPERROW),
                        PhaFormatString(L"%u bytes per row", bytesPerRow)->Buffer, FALSE);
                }
            }

            context->LoadCompleted = TRUE;
        }
        break;
    case WM_DESTROY:
        {
            if (context->LoadCompleted)
            {
                PhSaveWindowPlacementToSetting(L"MemEditPosition", L"MemEditSize", hwndDlg);
                PhRemoveElementAvlTree(&PhMemoryEditorSet, &context->Links);
                PhUnregisterDialog(hwndDlg);
            }

            RemoveProp(hwndDlg, PhMakeContextAtom());

            PhDeleteLayoutManager(&context->LayoutManager);

            if (context->Buffer) PhFreePage(context->Buffer);
            if (context->ProcessHandle) NtClose(context->ProcessHandle);
            PhClearReference(&context->Title);

            if ((context->Flags & PH_MEMORY_EDITOR_UNMAP_VIEW_OF_SECTION) && context->ProcessId == NtCurrentProcessId())
                NtUnmapViewOfSection(NtCurrentProcess(), context->BaseAddress);

            PhFree(context);
        }
        break;
    case WM_SHOWWINDOW:
        {
            SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)context->HexEditHandle, TRUE);
        }
        break;
    case WM_COMMAND:
        {
            switch (LOWORD(wParam))
            {
            case IDCANCEL:
            case IDOK:
                DestroyWindow(hwndDlg);
                break;
            case IDC_SAVE:
                {
                    static PH_FILETYPE_FILTER filters[] =
                    {
                        { L"Binary files (*.bin)", L"*.bin" },
                        { L"All files (*.*)", L"*.*" }
                    };
                    PVOID fileDialog;
                    PPH_PROCESS_ITEM processItem;

                    fileDialog = PhCreateSaveFileDialog();

                    PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER));

                    if (!context->Title && (processItem = PhReferenceProcessItem(context->ProcessId)))
                    {
                        PhSetFileDialogFileName(fileDialog,
                            PhaFormatString(L"%s_0x%Ix-0x%Ix.bin", processItem->ProcessName->Buffer,
                            context->BaseAddress, context->RegionSize)->Buffer);
                        PhDereferenceObject(processItem);
                    }
                    else
                    {
                        PhSetFileDialogFileName(fileDialog, L"Memory.bin");
                    }

                    if (PhShowFileDialog(hwndDlg, fileDialog))
                    {
                        NTSTATUS status;
                        PPH_STRING fileName;
                        PPH_FILE_STREAM fileStream;

                        fileName = PH_AUTO(PhGetFileDialogFileName(fileDialog));

                        if (NT_SUCCESS(status = PhCreateFileStream(
                            &fileStream,
                            fileName->Buffer,
                            FILE_GENERIC_WRITE,
                            FILE_SHARE_READ,
                            FILE_OVERWRITE_IF,
                            0
                            )))
                        {
                            status = PhWriteFileStream(fileStream, context->Buffer, (ULONG)context->RegionSize);
                            PhDereferenceObject(fileStream);
                        }

                        if (!NT_SUCCESS(status))
                            PhShowStatus(hwndDlg, L"Unable to create the file", status, 0);
                    }

                    PhFreeFileDialog(fileDialog);
                }
                break;
            case IDC_GOTO:
                {
                    PPH_STRING selectedChoice = NULL;

                    while (PhaChoiceDialog(
                        hwndDlg,
                        L"Go to Offset",
                        L"Enter an offset:",
                        NULL,
                        0,
                        NULL,
                        PH_CHOICE_DIALOG_USER_CHOICE,
                        &selectedChoice,
                        NULL,
                        L"MemEditGotoChoices"
                        ))
                    {
                        ULONG64 offset;

                        if (selectedChoice->Length == 0)
                            continue;

                        if (PhStringToInteger64(&selectedChoice->sr, 0, &offset))
                        {
                            if (offset >= context->RegionSize)
                            {
                                PhShowError(hwndDlg, L"The offset is too large.");
                                continue;
                            }

                            SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)context->HexEditHandle, TRUE);
                            HexEdit_SetSel(context->HexEditHandle, (LONG)offset, (LONG)offset);
                            break;
                        }
                    }
                }
                break;
            case IDC_WRITE:
                {
                    NTSTATUS status;

                    if (!context->WriteAccess)
                    {
                        HANDLE processHandle;

                        if (!NT_SUCCESS(status = PhOpenProcess(
                            &processHandle,
                            PROCESS_VM_READ | PROCESS_VM_WRITE,
                            context->ProcessId
                            )))
                        {
                            PhShowStatus(hwndDlg, L"Unable to open the process", status, 0);
                            break;
                        }

                        if (context->ProcessHandle) NtClose(context->ProcessHandle);
                        context->ProcessHandle = processHandle;
                        context->WriteAccess = TRUE;
                    }

                    if (!NT_SUCCESS(status = PhWriteVirtualMemory(
                        context->ProcessHandle,
                        context->BaseAddress,
                        context->Buffer,
                        context->RegionSize,
                        NULL
                        )))
                    {
                        PhShowStatus(hwndDlg, L"Unable to write memory", status, 0);
                    }
                }
                break;
            case IDC_REREAD:
                {
                    NTSTATUS status;

                    if (!NT_SUCCESS(status = PhReadVirtualMemory(
                        context->ProcessHandle,
                        context->BaseAddress,
                        context->Buffer,
                        context->RegionSize,
                        NULL
                        )))
                    {
                        PhShowStatus(hwndDlg, L"Unable to read memory", status, 0);
                    }

                    InvalidateRect(context->HexEditHandle, NULL, TRUE);
                }
                break;
            case IDC_BYTESPERROW:
                if (HIWORD(wParam) == CBN_SELCHANGE)
                {
                    PPH_STRING bytesPerRowString = PhaGetDlgItemText(hwndDlg, IDC_BYTESPERROW);
                    PH_STRINGREF firstPart;
                    PH_STRINGREF secondPart;
                    ULONG64 bytesPerRow64;

                    if (PhSplitStringRefAtChar(&bytesPerRowString->sr, ' ', &firstPart, &secondPart))
                    {
                        if (PhStringToInteger64(&firstPart, 10, &bytesPerRow64))
                        {
                            PhSetIntegerSetting(L"MemEditBytesPerRow", (ULONG)bytesPerRow64);
                            HexEdit_SetBytesPerRow(context->HexEditHandle, (ULONG)bytesPerRow64);
                            SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)context->HexEditHandle, TRUE);
                        }
                    }
                }
                break;
            }
        }
        break;
    case WM_SIZE:
        {
            PhLayoutManagerLayout(&context->LayoutManager);
        }
        break;
    case WM_SIZING:
        {
            PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom);
        }
        break;
    case WM_PH_SELECT_OFFSET:
        {
            HexEdit_SetEditMode(context->HexEditHandle, EDIT_ASCII);
            HexEdit_SetSel(context->HexEditHandle, (ULONG)wParam, (ULONG)wParam + (ULONG)lParam);
        }
        break;
    }

    return FALSE;
}
Пример #29
0
/***********************************************************************
 *             UnmapViewOfFile   (KERNEL32.@)
 *
 * Unmaps a mapped view of a file.
 *
 * PARAMS
 *  addr [I] Address where mapped view begins.
 *
 * RETURNS
 *	Success: TRUE.
 *	Failure: FALSE.
 *
 */
BOOL WINAPI UnmapViewOfFile( LPCVOID addr )
{
    NTSTATUS status = NtUnmapViewOfSection( GetCurrentProcess(), (void *)addr );
    if (status) SetLastError( RtlNtStatusToDosError(status) );
    return !status;
}
Пример #30
0
static NTSTATUS
TH32CreateSnapshotSectionInitialize(DWORD dwFlags,
                                    DWORD th32ProcessID,
                                    PRTL_DEBUG_INFORMATION HeapDebug,
                                    PRTL_DEBUG_INFORMATION ModuleDebug,
                                    PVOID ProcThrdInfo,
                                    HANDLE *SectionHandle)
{
  PSYSTEM_PROCESS_INFORMATION ProcessInfo;
  LPHEAPLIST32 HeapListEntry;
  LPMODULEENTRY32W ModuleListEntry;
  LPPROCESSENTRY32W ProcessListEntry;
  LPTHREADENTRY32 ThreadListEntry;
  OBJECT_ATTRIBUTES ObjectAttributes;
  LARGE_INTEGER SSize, SOffset;
  HANDLE hSection;
  PTH32SNAPSHOT Snapshot;
  ULONG_PTR DataOffset;
  SIZE_T ViewSize;
  ULONG i, nProcesses = 0, nThreads = 0, nHeaps = 0, nModules = 0;
  ULONG RequiredSnapshotSize = sizeof(TH32SNAPSHOT);
  PRTL_PROCESS_HEAPS hi = NULL;
  PRTL_PROCESS_MODULES mi = NULL;
  NTSTATUS Status = STATUS_SUCCESS;

  /*
   * Determine the required size for the heap snapshot
   */
  if(dwFlags & TH32CS_SNAPHEAPLIST)
  {
    hi = (PRTL_PROCESS_HEAPS)HeapDebug->Heaps;
    nHeaps = hi->NumberOfHeaps;
    RequiredSnapshotSize += nHeaps * sizeof(HEAPLIST32);
  }

  /*
   * Determine the required size for the module snapshot
   */
  if(dwFlags & TH32CS_SNAPMODULE)
  {
    mi = (PRTL_PROCESS_MODULES)ModuleDebug->Modules;
    nModules = mi->NumberOfModules;
    RequiredSnapshotSize += nModules * sizeof(MODULEENTRY32W);
  }

  /*
   * Determine the required size for the processes and threads snapshot
   */
  if(dwFlags & (TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD))
  {
    ULONG ProcOffset = 0;

    ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo;
    do
    {
      ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset);
      nProcesses++;
      nThreads += ProcessInfo->NumberOfThreads;
      ProcOffset = ProcessInfo->NextEntryOffset;
    } while(ProcOffset != 0);

    if(dwFlags & TH32CS_SNAPPROCESS)
    {
      RequiredSnapshotSize += nProcesses * sizeof(PROCESSENTRY32W);
    }
    if(dwFlags & TH32CS_SNAPTHREAD)
    {
      RequiredSnapshotSize += nThreads * sizeof(THREADENTRY32);
    }
  }

  /*
   * Create and map the section
   */

  SSize.QuadPart = RequiredSnapshotSize;

  InitializeObjectAttributes(&ObjectAttributes,
                             NULL,
                             ((dwFlags & TH32CS_INHERIT) ? OBJ_INHERIT : 0),
			     NULL,
			     NULL);

  Status = NtCreateSection(&hSection,
                           SECTION_ALL_ACCESS,
                           &ObjectAttributes,
                           &SSize,
                           PAGE_READWRITE,
                           SEC_COMMIT,
                           NULL);
  if(!NT_SUCCESS(Status))
  {
    return Status;
  }

  SOffset.QuadPart = 0;
  ViewSize = 0;
  Snapshot = NULL;

  Status = NtMapViewOfSection(hSection,
                              NtCurrentProcess(),
                              (PVOID*)&Snapshot,
                              0,
                              0,
                              &SOffset,
                              &ViewSize,
                              ViewShare,
                              0,
                              PAGE_READWRITE);
  if(!NT_SUCCESS(Status))
  {
    NtClose(hSection);
    return Status;
  }

  RtlZeroMemory(Snapshot, sizeof(TH32SNAPSHOT));
  DataOffset = 0;

  /*
   * Initialize the section data and fill it with all the data we collected
   */

  /* initialize the heap list */
  if(dwFlags & TH32CS_SNAPHEAPLIST)
  {
    Snapshot->HeapListCount = nHeaps;
    Snapshot->HeapListOffset = DataOffset;
    HeapListEntry = (LPHEAPLIST32)OffsetToPtr(Snapshot, DataOffset);
    for(i = 0; i < nHeaps; i++)
    {
      HeapListEntry->dwSize = sizeof(HEAPLIST32);
      HeapListEntry->th32ProcessID = th32ProcessID;
      HeapListEntry->th32HeapID = (ULONG_PTR)hi->Heaps[i].BaseAddress;
      HeapListEntry->dwFlags = hi->Heaps[i].Flags;

      HeapListEntry++;
    }

    DataOffset += hi->NumberOfHeaps * sizeof(HEAPLIST32);
  }

  /* initialize the module list */
  if(dwFlags & TH32CS_SNAPMODULE)
  {
    Snapshot->ModuleListCount = nModules;
    Snapshot->ModuleListOffset = DataOffset;
    ModuleListEntry = (LPMODULEENTRY32W)OffsetToPtr(Snapshot, DataOffset);
    for(i = 0; i < nModules; i++)
    {
      ModuleListEntry->dwSize = sizeof(MODULEENTRY32W);
      ModuleListEntry->th32ModuleID = 1; /* no longer used, always set to one! */
      ModuleListEntry->th32ProcessID = th32ProcessID;
      ModuleListEntry->GlblcntUsage = mi->Modules[i].LoadCount;
      ModuleListEntry->ProccntUsage = mi->Modules[i].LoadCount;
      ModuleListEntry->modBaseAddr = (BYTE*)mi->Modules[i].ImageBase;
      ModuleListEntry->modBaseSize = mi->Modules[i].ImageSize;
      ModuleListEntry->hModule = (HMODULE)mi->Modules[i].ImageBase;

      MultiByteToWideChar(CP_ACP,
                          0,
                          &mi->Modules[i].FullPathName[mi->Modules[i].OffsetToFileName],
                          -1,
                          ModuleListEntry->szModule,
                          sizeof(ModuleListEntry->szModule) / sizeof(ModuleListEntry->szModule[0]));

      MultiByteToWideChar(CP_ACP,
                          0,
                          mi->Modules[i].FullPathName,
                          -1,
                          ModuleListEntry->szExePath,
                          sizeof(ModuleListEntry->szExePath) / sizeof(ModuleListEntry->szExePath[0]));

      ModuleListEntry++;
    }

    DataOffset += mi->NumberOfModules * sizeof(MODULEENTRY32W);
  }

  /* initialize the process list */
  if(dwFlags & TH32CS_SNAPPROCESS)
  {
    ULONG ProcOffset = 0;

    Snapshot->ProcessListCount = nProcesses;
    Snapshot->ProcessListOffset = DataOffset;
    ProcessListEntry = (LPPROCESSENTRY32W)OffsetToPtr(Snapshot, DataOffset);
    ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo;
    do
    {
      ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset);

      ProcessListEntry->dwSize = sizeof(PROCESSENTRY32W);
      ProcessListEntry->cntUsage = 0; /* no longer used */
      ProcessListEntry->th32ProcessID = (ULONG_PTR)ProcessInfo->UniqueProcessId;
      ProcessListEntry->th32DefaultHeapID = 0; /* no longer used */
      ProcessListEntry->th32ModuleID = 0; /* no longer used */
      ProcessListEntry->cntThreads = ProcessInfo->NumberOfThreads;
      ProcessListEntry->th32ParentProcessID = (ULONG_PTR)ProcessInfo->InheritedFromUniqueProcessId;
      ProcessListEntry->pcPriClassBase = ProcessInfo->BasePriority;
      ProcessListEntry->dwFlags = 0; /* no longer used */
      if(ProcessInfo->ImageName.Buffer != NULL)
      {
        lstrcpynW(ProcessListEntry->szExeFile,
                  ProcessInfo->ImageName.Buffer,
                  min(ProcessInfo->ImageName.Length / sizeof(WCHAR), sizeof(ProcessListEntry->szExeFile) / sizeof(ProcessListEntry->szExeFile[0])));
      }
      else
      {
        lstrcpyW(ProcessListEntry->szExeFile, L"[System Process]");
      }

      ProcessListEntry++;

      ProcOffset = ProcessInfo->NextEntryOffset;
    } while(ProcOffset != 0);

    DataOffset += nProcesses * sizeof(PROCESSENTRY32W);
  }

  /* initialize the thread list */
  if(dwFlags & TH32CS_SNAPTHREAD)
  {
    ULONG ProcOffset = 0;

    Snapshot->ThreadListCount = nThreads;
    Snapshot->ThreadListOffset = DataOffset;
    ThreadListEntry = (LPTHREADENTRY32)OffsetToPtr(Snapshot, DataOffset);
    ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo;
    do
    {
      PSYSTEM_THREAD_INFORMATION ThreadInfo;
      ULONG n;

      ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset);
      ThreadInfo = (PSYSTEM_THREAD_INFORMATION)(ProcessInfo + 1);

      for(n = 0; n < ProcessInfo->NumberOfThreads; n++)
      {
        ThreadListEntry->dwSize = sizeof(THREADENTRY32);
        ThreadListEntry->cntUsage = 0; /* no longer used */
        ThreadListEntry->th32ThreadID = (ULONG_PTR)ThreadInfo->ClientId.UniqueThread;
        ThreadListEntry->th32OwnerProcessID = (ULONG_PTR)ThreadInfo->ClientId.UniqueProcess;
        ThreadListEntry->tpBasePri = ThreadInfo->BasePriority;
        ThreadListEntry->tpDeltaPri = 0; /* no longer used */
        ThreadListEntry->dwFlags = 0; /* no longer used */

        ThreadInfo++;
        ThreadListEntry++;
      }

      ProcOffset = ProcessInfo->NextEntryOffset;
    } while(ProcOffset != 0);
  }

  /*
   * We're done, unmap the view and return the section handle
   */

  Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)Snapshot);

  if(NT_SUCCESS(Status))
  {
    *SectionHandle = hSection;
  }
  else
  {
    NtClose(hSection);
  }

  return Status;
}