// Copyright 2015 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/win/process_info.h"

#include <stddef.h>
#include <winternl.h>

#include <algorithm>
#include <limits>
#include <memory>
#include <new>
#include <type_traits>

#include "base/check_op.h"
#include "base/containers/heap_array.h"
#include "base/logging.h"
#include "base/memory/free_deleter.h"
#include "base/process/memory.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "util/misc/from_pointer_cast.h"
#include "util/numeric/safe_assignment.h"
#include "util/win/get_function.h"
#include "util/win/handle.h"
#include "util/win/nt_internals.h"
#include "util/win/ntstatus_logging.h"
#include "util/win/process_structs.h"
#include "util/win/scoped_handle.h"

namespace crashpad {

namespace {

using UniqueMallocPtr = std::unique_ptr<uint8_t[], base::FreeDeleter>;

UniqueMallocPtr UncheckedAllocate(size_t size) {
  void* raw_ptr = nullptr;
  if (!base::UncheckedMalloc(size, &raw_ptr))
    return UniqueMallocPtr();

  return UniqueMallocPtr(new (raw_ptr) uint8_t[size]);
}

NTSTATUS NtQueryInformationProcess(HANDLE process_handle,
                                   PROCESSINFOCLASS process_information_class,
                                   PVOID process_information,
                                   ULONG process_information_length,
                                   PULONG return_length) {
  static const auto nt_query_information_process =
      GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtQueryInformationProcess);
  return nt_query_information_process(process_handle,
                                      process_information_class,
                                      process_information,
                                      process_information_length,
                                      return_length);
}

bool IsProcessWow64(HANDLE process_handle) {
  static const auto is_wow64_process =
      GET_FUNCTION(L"kernel32.dll", ::IsWow64Process);
  if (!is_wow64_process)
    return false;
  BOOL is_wow64;
  if (!is_wow64_process(process_handle, &is_wow64)) {
    PLOG(ERROR) << "IsWow64Process";
    return false;
  }
  return !!is_wow64;
}

template <class T>
bool ReadUnicodeString(HANDLE process,
                       const process_types::UNICODE_STRING<T>& us,
                       std::wstring* result) {
  if (us.Length == 0) {
    result->clear();
    return true;
  }
  DCHECK_EQ(us.Length % sizeof(wchar_t), 0u);
  result->resize(us.Length / sizeof(wchar_t));
  SIZE_T bytes_read;
  if (!ReadProcessMemory(
          process,
          reinterpret_cast<const void*>(static_cast<uintptr_t>(us.Buffer)),
          &result->operator[](0),
          us.Length,
          &bytes_read)) {
    PLOG(ERROR) << "ReadProcessMemory UNICODE_STRING";
    return false;
  }
  if (bytes_read != us.Length) {
    LOG(ERROR) << "ReadProcessMemory UNICODE_STRING incorrect size";
    return false;
  }
  return true;
}

template <class T>
bool ReadStruct(HANDLE process, WinVMAddress at, T* into) {
  SIZE_T bytes_read;
  if (!ReadProcessMemory(process,
                         reinterpret_cast<const void*>(at),
                         into,
                         sizeof(T),
                         &bytes_read)) {
    // We don't have a name for the type we're reading, so include the signature
    // to get the type of T.
    PLOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__;
    return false;
  }
  if (bytes_read != sizeof(T)) {
    LOG(ERROR) << "ReadProcessMemory " << __FUNCSIG__ << " incorrect size";
    return false;
  }
  return true;
}

bool RegionIsAccessible(const MEMORY_BASIC_INFORMATION64& memory_info) {
  return memory_info.State == MEM_COMMIT &&
         (memory_info.Protect & PAGE_NOACCESS) == 0 &&
         (memory_info.Protect & PAGE_GUARD) == 0;
}

MEMORY_BASIC_INFORMATION64 MemoryBasicInformationToMemoryBasicInformation64(
    const MEMORY_BASIC_INFORMATION& mbi) {
  MEMORY_BASIC_INFORMATION64 mbi64 = {0};
  mbi64.BaseAddress = FromPointerCast<ULONGLONG>(mbi.BaseAddress);
  mbi64.AllocationBase = reinterpret_cast<ULONGLONG>(mbi.AllocationBase);
  mbi64.AllocationProtect = mbi.AllocationProtect;
  mbi64.RegionSize = mbi.RegionSize;
  mbi64.State = mbi.State;
  mbi64.Protect = mbi.Protect;
  mbi64.Type = mbi.Type;
  return mbi64;
}

// NtQueryObject with a retry for size mismatch as well as a minimum size to
// retrieve (and expect).
base::HeapArray<uint8_t> QueryObject(
    HANDLE handle,
    OBJECT_INFORMATION_CLASS object_information_class,
    ULONG minimum_size) {
  ULONG return_length;
  auto buffer = base::HeapArray<uint8_t>::Uninit(minimum_size);
  NTSTATUS status = crashpad::NtQueryObject(handle,
                                            object_information_class,
                                            buffer.data(),
                                            (ULONG)buffer.size(),
                                            &return_length);
  if (status == STATUS_INFO_LENGTH_MISMATCH) {
    DCHECK_GT(return_length, buffer.size());

    buffer = base::HeapArray<uint8_t>::Uninit(return_length);
    status = crashpad::NtQueryObject(handle,
                                     object_information_class,
                                     buffer.data(),
                                     (ULONG)buffer.size(),
                                     &return_length);
  }

  if (!NT_SUCCESS(status)) {
    NTSTATUS_LOG(ERROR, status) << "NtQueryObject";
    return base::HeapArray<uint8_t>();
  }

  DCHECK_LE(return_length, buffer.size());
  DCHECK_GE(return_length, minimum_size);
  return buffer;
}

}  // namespace

template <class Traits>
bool GetProcessBasicInformation(HANDLE process,
                                bool is_wow64,
                                ProcessInfo* process_info,
                                WinVMAddress* peb_address,
                                WinVMSize* peb_size) {
  ULONG bytes_returned;
  process_types::PROCESS_BASIC_INFORMATION<Traits> process_basic_information;
  NTSTATUS status =
      crashpad::NtQueryInformationProcess(process,
                                          ProcessBasicInformation,
                                          &process_basic_information,
                                          sizeof(process_basic_information),
                                          &bytes_returned);
  if (!NT_SUCCESS(status)) {
    NTSTATUS_LOG(ERROR, status) << "NtQueryInformationProcess";
    return false;
  }
  if (bytes_returned != sizeof(process_basic_information)) {
    LOG(ERROR) << "NtQueryInformationProcess incorrect size";
    return false;
  }

  // API functions (e.g. OpenProcess) take only a DWORD, so there's no sense in
  // maintaining the top bits.
  process_info->process_id_ =
      static_cast<DWORD>(process_basic_information.UniqueProcessId);
  process_info->inherited_from_process_id_ = static_cast<DWORD>(
      process_basic_information.InheritedFromUniqueProcessId);

  // We now want to read the PEB to gather the rest of our information. The
  // PebBaseAddress as returned above is what we want for 64-on-64 and 32-on-32,
  // but for Wow64, we want to read the 32 bit PEB (a Wow64 process has both).
  // The address of this is found by a second call to NtQueryInformationProcess.
  if (!is_wow64) {
    *peb_address = process_basic_information.PebBaseAddress;
    *peb_size = sizeof(process_types::PEB<Traits>);
  } else {
    ULONG_PTR wow64_peb_address;
    status = crashpad::NtQueryInformationProcess(process,
                                                 ProcessWow64Information,
                                                 &wow64_peb_address,
                                                 sizeof(wow64_peb_address),
                                                 &bytes_returned);
    if (!NT_SUCCESS(status)) {
      NTSTATUS_LOG(ERROR, status) << "NtQueryInformationProcess";
      return false;
    }
    if (bytes_returned != sizeof(wow64_peb_address)) {
      LOG(ERROR) << "NtQueryInformationProcess incorrect size";
      return false;
    }
    *peb_address = wow64_peb_address;
    *peb_size = sizeof(process_types::PEB<process_types::internal::Traits32>);
  }

  return true;
}

template <class Traits>
bool ReadProcessData(HANDLE process,
                     WinVMAddress peb_address_vmaddr,
                     ProcessInfo* process_info) {
  typename Traits::Pointer peb_address;
  if (!AssignIfInRange(&peb_address, peb_address_vmaddr)) {
    LOG(ERROR) << base::StringPrintf("peb address 0x%llx out of range",
                                     peb_address_vmaddr);
    return false;
  }

  // Try to read the process environment block.
  process_types::PEB<Traits> peb;
  if (!ReadStruct(process, peb_address, &peb))
    return false;

  process_types::RTL_USER_PROCESS_PARAMETERS<Traits> process_parameters;
  if (!ReadStruct(process, peb.ProcessParameters, &process_parameters))
    return false;

  if (!ReadUnicodeString(process,
                         process_parameters.CommandLine,
                         &process_info->command_line_)) {
    return false;
  }

  process_types::PEB_LDR_DATA<Traits> peb_ldr_data;
  if (!ReadStruct(process, peb.Ldr, &peb_ldr_data))
    return false;

  process_types::LDR_DATA_TABLE_ENTRY<Traits> ldr_data_table_entry;
  ProcessInfo::Module module;

  // Walk the PEB LDR structure (doubly-linked list) to get the list of loaded
  // modules. We use this method rather than EnumProcessModules to get the
  // modules in load order rather than memory order. Notably, this includes the
  // main executable as the first element.
  typename Traits::Pointer last = peb_ldr_data.InLoadOrderModuleList.Blink;
  for (typename Traits::Pointer cur = peb_ldr_data.InLoadOrderModuleList.Flink;;
       cur = ldr_data_table_entry.InLoadOrderLinks.Flink) {
    // |cur| is the pointer to the LIST_ENTRY embedded in the
    // LDR_DATA_TABLE_ENTRY, in the target process's address space. So we need
    // to read from the target, and also offset back to the beginning of the
    // structure.
    if (!ReadStruct(process,
                    static_cast<WinVMAddress>(cur) -
                        offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>,
                                 InLoadOrderLinks),
                    &ldr_data_table_entry)) {
      break;
    }
    // TODO(scottmg): Capture Checksum, etc. too?
    if (!ReadUnicodeString(
            process, ldr_data_table_entry.FullDllName, &module.name)) {
      module.name = L"???";
    }
    module.dll_base = ldr_data_table_entry.DllBase;
    module.size = ldr_data_table_entry.SizeOfImage;
    module.timestamp = ldr_data_table_entry.TimeDateStamp;
    process_info->modules_.push_back(module);
    if (cur == last)
      break;
  }

  return true;
}

bool ReadMemoryInfo(HANDLE process, bool is_64_bit, ProcessInfo* process_info) {
  DCHECK(process_info->memory_info_.empty());

  constexpr WinVMAddress min_address = 0;
  // We can't use GetSystemInfo() to get the address space range for another
  // process. VirtualQueryEx() will fail with ERROR_INVALID_PARAMETER if the
  // address is above the highest memory address accessible to the process, so
  // we just probe the entire potential range (2^32 for x86, or 2^64 for x64).
  const WinVMAddress max_address = is_64_bit
                                       ? std::numeric_limits<uint64_t>::max()
                                       : std::numeric_limits<uint32_t>::max();
  MEMORY_BASIC_INFORMATION memory_basic_information;
  for (WinVMAddress address = min_address; address <= max_address;
       address += memory_basic_information.RegionSize) {
    size_t result = VirtualQueryEx(process,
                                   reinterpret_cast<void*>(address),
                                   &memory_basic_information,
                                   sizeof(memory_basic_information));
    if (result == 0) {
      if (GetLastError() == ERROR_INVALID_PARAMETER)
        break;
      PLOG(ERROR) << "VirtualQueryEx";
      return false;
    }

    process_info->memory_info_.push_back(
        MemoryBasicInformationToMemoryBasicInformation64(
            memory_basic_information));

    if (memory_basic_information.RegionSize == 0) {
      LOG(ERROR) << "RegionSize == 0";
      return false;
    }
  }

  return true;
}

std::vector<ProcessInfo::Handle> ProcessInfo::BuildHandleVector(
    HANDLE process) const {
  ULONG buffer_size = 2 * 1024 * 1024;
  // Typically if the buffer were too small, STATUS_INFO_LENGTH_MISMATCH would
  // return the correct size in the final argument, but it does not for
  // SystemExtendedHandleInformation, so we loop and attempt larger sizes.
  NTSTATUS status;
  ULONG returned_length;
  UniqueMallocPtr buffer;
  for (int tries = 0; tries < 5; ++tries) {
    buffer.reset();
    buffer = UncheckedAllocate(buffer_size);
    if (!buffer) {
      LOG(ERROR) << "UncheckedAllocate";
      return std::vector<Handle>();
    }

    status = crashpad::NtQuerySystemInformation(
        static_cast<SYSTEM_INFORMATION_CLASS>(SystemExtendedHandleInformation),
        buffer.get(),
        buffer_size,
        &returned_length);
    if (NT_SUCCESS(status) || status != STATUS_INFO_LENGTH_MISMATCH)
      break;

    buffer_size *= 2;
  }

  if (!NT_SUCCESS(status)) {
    NTSTATUS_LOG(ERROR, status)
        << "NtQuerySystemInformation SystemExtendedHandleInformation";
    return std::vector<Handle>();
  }

  const auto& system_handle_information_ex =
      *reinterpret_cast<process_types::SYSTEM_HANDLE_INFORMATION_EX*>(
          buffer.get());

  DCHECK_LE(offsetof(process_types::SYSTEM_HANDLE_INFORMATION_EX, Handles) +
                system_handle_information_ex.NumberOfHandles *
                    sizeof(system_handle_information_ex.Handles[0]),
            returned_length);

  std::vector<Handle> handles;

  for (size_t i = 0; i < system_handle_information_ex.NumberOfHandles; ++i) {
    const auto& handle = system_handle_information_ex.Handles[i];
    if (handle.UniqueProcessId != process_id_)
      continue;

    Handle result_handle;
    result_handle.handle = HandleToInt(handle.HandleValue);
    result_handle.attributes = handle.HandleAttributes;
    result_handle.granted_access = handle.GrantedAccess;

    // TODO(scottmg): Could special case for self.
    HANDLE dup_handle;
    if (DuplicateHandle(process,
                        handle.HandleValue,
                        GetCurrentProcess(),
                        &dup_handle,
                        0,
                        false,
                        DUPLICATE_SAME_ACCESS)) {
      // Some handles cannot be duplicated, for example, handles of type
      // EtwRegistration. If we fail to duplicate, then we can't gather any more
      // information, but include the information that we do have already.
      ScopedKernelHANDLE scoped_dup_handle(dup_handle);

      auto object_basic_information_buffer =
          QueryObject(dup_handle,
                      ObjectBasicInformation,
                      sizeof(PUBLIC_OBJECT_BASIC_INFORMATION));
      if (!object_basic_information_buffer.empty()) {
        PUBLIC_OBJECT_BASIC_INFORMATION* object_basic_information =
            reinterpret_cast<PUBLIC_OBJECT_BASIC_INFORMATION*>(
                object_basic_information_buffer.data());
        // The Attributes and GrantedAccess sometimes differ slightly between
        // the data retrieved in SYSTEM_HANDLE_INFORMATION_EX and
        // PUBLIC_OBJECT_TYPE_INFORMATION. We prefer the values in
        // SYSTEM_HANDLE_INFORMATION_EX because they were retrieved from the
        // target process, rather than on the duplicated handle, so don't use
        // them here.

        // Subtract one to account for our DuplicateHandle() and another for
        // NtQueryObject() while the query was being executed.
        DCHECK_GT(object_basic_information->PointerCount, 2u);
        result_handle.pointer_count =
            object_basic_information->PointerCount - 2;

        // Subtract one to account for our DuplicateHandle().
        DCHECK_GT(object_basic_information->HandleCount, 1u);
        result_handle.handle_count = object_basic_information->HandleCount - 1;
      }

      auto object_type_information_buffer =
          QueryObject(dup_handle,
                      ObjectTypeInformation,
                      sizeof(PUBLIC_OBJECT_TYPE_INFORMATION));
      if (!object_type_information_buffer.empty()) {
        PUBLIC_OBJECT_TYPE_INFORMATION* object_type_information =
            reinterpret_cast<PUBLIC_OBJECT_TYPE_INFORMATION*>(
                object_type_information_buffer.data());

        DCHECK_EQ(object_type_information->TypeName.Length %
                      sizeof(result_handle.type_name[0]),
                  0u);
        result_handle.type_name =
            std::wstring(object_type_information->TypeName.Buffer,
                         object_type_information->TypeName.Length /
                             sizeof(result_handle.type_name[0]));
      }
    }

    handles.push_back(result_handle);
  }
  return handles;
}

ProcessInfo::Module::Module() : name(), dll_base(0), size(0), timestamp() {
}

ProcessInfo::Module::~Module() {
}

ProcessInfo::Handle::Handle()
    : type_name(),
      handle(0),
      attributes(0),
      granted_access(0),
      pointer_count(0),
      handle_count(0) {
}

ProcessInfo::Handle::~Handle() {
}

ProcessInfo::ProcessInfo()
    : process_id_(),
      inherited_from_process_id_(),
      process_(),
      command_line_(),
      peb_address_(0),
      peb_size_(0),
      modules_(),
      memory_info_(),
      handles_(),
      is_64_bit_(false),
      is_wow64_(false),
      initialized_() {
}

ProcessInfo::~ProcessInfo() {
}

bool ProcessInfo::Initialize(HANDLE process) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);

  process_ = process;

  is_wow64_ = IsProcessWow64(process);

  if (is_wow64_) {
    // If it's WoW64, then it's 32-on-64.
    is_64_bit_ = false;
  } else {
    // Otherwise, it's either 32 on 32, or 64 on 64. Use GetSystemInfo() to
    // distinguish between these two cases.
    SYSTEM_INFO system_info;
    GetSystemInfo(&system_info);

#if defined(ARCH_CPU_X86_FAMILY)
    constexpr uint16_t kNative64BitArchitecture = PROCESSOR_ARCHITECTURE_AMD64;
#elif defined(ARCH_CPU_ARM_FAMILY)
    constexpr uint16_t kNative64BitArchitecture = PROCESSOR_ARCHITECTURE_ARM64;
#endif

    is_64_bit_ = system_info.wProcessorArchitecture == kNative64BitArchitecture;
  }

#if defined(ARCH_CPU_32_BITS)
  if (is_64_bit_) {
    LOG(ERROR) << "Reading x64 process from x86 process not supported";
    return false;
  }
#endif  // ARCH_CPU_32_BITS

#if defined(ARCH_CPU_64_BITS)
  bool result = GetProcessBasicInformation<process_types::internal::Traits64>(
      process, is_wow64_, this, &peb_address_, &peb_size_);
#else
  bool result = GetProcessBasicInformation<process_types::internal::Traits32>(
      process, false, this, &peb_address_, &peb_size_);
#endif  // ARCH_CPU_64_BITS

  if (!result) {
    LOG(ERROR) << "GetProcessBasicInformation failed";
    return false;
  }

  result = is_64_bit_ ? ReadProcessData<process_types::internal::Traits64>(
                            process, peb_address_, this)
                      : ReadProcessData<process_types::internal::Traits32>(
                            process, peb_address_, this);
  if (!result) {
    LOG(ERROR) << "ReadProcessData failed";
    return false;
  }

  if (!ReadMemoryInfo(process, is_64_bit_, this)) {
    LOG(ERROR) << "ReadMemoryInfo failed";
    return false;
  }

  INITIALIZATION_STATE_SET_VALID(initialized_);
  return true;
}

bool ProcessInfo::Is64Bit() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return is_64_bit_;
}

bool ProcessInfo::IsWow64() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return is_wow64_;
}

crashpad::ProcessID ProcessInfo::ProcessID() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return process_id_;
}

crashpad::ProcessID ProcessInfo::ParentProcessID() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return inherited_from_process_id_;
}

bool ProcessInfo::CommandLine(std::wstring* command_line) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  *command_line = command_line_;
  return true;
}

void ProcessInfo::Peb(WinVMAddress* peb_address, WinVMSize* peb_size) const {
  *peb_address = peb_address_;
  *peb_size = peb_size_;
}

bool ProcessInfo::Modules(std::vector<Module>* modules) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  *modules = modules_;
  return true;
}

const ProcessInfo::MemoryBasicInformation64Vector& ProcessInfo::MemoryInfo()
    const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  return memory_info_;
}

std::vector<CheckedRange<WinVMAddress, WinVMSize>>
ProcessInfo::GetReadableRanges(
    const CheckedRange<WinVMAddress, WinVMSize>& range) const {
  return GetReadableRangesOfMemoryMap(range, MemoryInfo());
}

bool ProcessInfo::LoggingRangeIsFullyReadable(
    const CheckedRange<WinVMAddress, WinVMSize>& range) const {
  const auto ranges = GetReadableRanges(range);
  if (ranges.empty()) {
    LOG(ERROR) << base::StringPrintf(
        "range at 0x%llx, size 0x%llx fully unreadable",
        range.base(),
        range.size());
    return false;
  }

  if (ranges.size() != 1 ||
      ranges[0].base() != range.base() || ranges[0].size() != range.size()) {
    LOG(ERROR) << base::StringPrintf(
        "range at 0x%llx, size 0x%llx partially unreadable",
        range.base(),
        range.size());
    return false;
  }

  return true;
}

const std::vector<ProcessInfo::Handle>& ProcessInfo::Handles() const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
  if (handles_.empty())
    handles_ = BuildHandleVector(process_);
  return handles_;
}

std::vector<CheckedRange<WinVMAddress, WinVMSize>> GetReadableRangesOfMemoryMap(
    const CheckedRange<WinVMAddress, WinVMSize>& range,
    const ProcessInfo::MemoryBasicInformation64Vector& memory_info) {
  using Range = CheckedRange<WinVMAddress, WinVMSize>;

  // Constructing Ranges and using OverlapsRange() is very, very slow in Debug
  // builds, so do a manual check in this loop. The ranges are still validated
  // by a CheckedRange before being returned.
  WinVMAddress range_base = range.base();
  WinVMAddress range_end = range.end();

  // Find all the ranges that overlap the target range, maintaining their order.
  ProcessInfo::MemoryBasicInformation64Vector overlapping;
  const size_t size = memory_info.size();

  // This loop is written in an ugly fashion to make Debug performance
  // reasonable.
  const MEMORY_BASIC_INFORMATION64* begin = &memory_info[0];
  for (size_t i = 0; i < size; ++i) {
    const MEMORY_BASIC_INFORMATION64& mi = *(begin + i);
    static_assert(std::is_same<decltype(mi.BaseAddress), WinVMAddress>::value,
                  "expected range address to be WinVMAddress");
    static_assert(std::is_same<decltype(mi.RegionSize), WinVMSize>::value,
                  "expected range size to be WinVMSize");
    WinVMAddress mi_end = mi.BaseAddress + mi.RegionSize;
    if (range_base < mi_end && mi.BaseAddress < range_end)
      overlapping.push_back(mi);
  }
  if (overlapping.empty())
    return std::vector<Range>();

  // For the first and last, trim to the boundary of the incoming range.
  MEMORY_BASIC_INFORMATION64& front = overlapping.front();
  WinVMAddress original_front_base_address = front.BaseAddress;
  front.BaseAddress = std::max(front.BaseAddress, range.base());
  front.RegionSize =
      (original_front_base_address + front.RegionSize) - front.BaseAddress;

  MEMORY_BASIC_INFORMATION64& back = overlapping.back();
  WinVMAddress back_end = back.BaseAddress + back.RegionSize;
  back.RegionSize = std::min(range.end(), back_end) - back.BaseAddress;

  // Discard all non-accessible.
  overlapping.erase(std::remove_if(overlapping.begin(),
                                   overlapping.end(),
                                   [](const MEMORY_BASIC_INFORMATION64& mbi) {
                                     return !RegionIsAccessible(mbi);
                                   }),
                    overlapping.end());
  if (overlapping.empty())
    return std::vector<Range>();

  // Convert to return type.
  std::vector<Range> as_ranges;
  for (const auto& mi : overlapping) {
    as_ranges.push_back(Range(mi.BaseAddress, mi.RegionSize));
    DCHECK(as_ranges.back().IsValid());
  }

  // Coalesce remaining regions.
  std::vector<Range> result;
  result.push_back(as_ranges[0]);
  for (size_t i = 1; i < as_ranges.size(); ++i) {
    if (result.back().end() == as_ranges[i].base()) {
      result.back().SetRange(result.back().base(),
                             result.back().size() + as_ranges[i].size());
    } else {
      result.push_back(as_ranges[i]);
    }
    DCHECK(result.back().IsValid());
  }

  return result;
}

}  // namespace crashpad
