crashpad/util/win/nt_internals.cc
Scott Graham 0567536f86 win: Attempt to fix unloaded modules list by using RtlGetUnloadEventTraceEx
I haven't been able to reproduce this locally, but we see errors in
crash dumps where the unloaded module list consists of a number of
modules with invalid names and implausible addresses. My assumption is
that RTL_UNLOAD_EVENT_TRACE isn't correct for some OS levels. Instead of
trying to finesse and test that, use RtlGetUnloadEventTraceEx() instead
of RtlGetUnloadEventTrace(), which returns an element size. (This
function is Vista+ which is why it wasn't used the first time around.)

R=mark@chromium.org
BUG=chromium:620175

Change-Id: I4d7080a03623276f9c1c038d6e7329af70e4a64c
Reviewed-on: https://chromium-review.googlesource.com/421564
Reviewed-by: Mark Mentovai <mark@chromium.org>
2016-12-16 20:32:25 +00:00

175 lines
6.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2015 The Crashpad Authors. All rights reserved.
//
// 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/nt_internals.h"
#include "base/logging.h"
#include "util/win/get_function.h"
// Declarations that the system headers should provide but dont.
struct CLIENT_ID;
NTSTATUS NTAPI NtCreateThreadEx(PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
PVOID StartRoutine,
PVOID Argument,
ULONG CreateFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
PVOID /*PPS_ATTRIBUTE_LIST*/ AttributeList);
NTSTATUS NTAPI NtOpenThread(HANDLE* ThreadHandle,
ACCESS_MASK DesiredAccess,
OBJECT_ATTRIBUTES* ObjectAttributes,
CLIENT_ID* ClientId);
NTSTATUS NTAPI NtSuspendProcess(HANDLE);
NTSTATUS NTAPI NtResumeProcess(HANDLE);
VOID NTAPI RtlGetUnloadEventTraceEx(PULONG* ElementSize,
PULONG* ElementCount,
PVOID* EventTrace);
namespace crashpad {
NTSTATUS NtClose(HANDLE handle) {
static const auto nt_close = GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtClose);
return nt_close(handle);
}
NTSTATUS
NtCreateThreadEx(PHANDLE thread_handle,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
HANDLE process_handle,
PVOID start_routine,
PVOID argument,
ULONG create_flags,
SIZE_T zero_bits,
SIZE_T stack_size,
SIZE_T maximum_stack_size,
PVOID attribute_list) {
static const auto nt_create_thread_ex =
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtCreateThreadEx);
return nt_create_thread_ex(thread_handle,
desired_access,
object_attributes,
process_handle,
start_routine,
argument,
create_flags,
zero_bits,
stack_size,
maximum_stack_size,
attribute_list);
}
NTSTATUS NtQuerySystemInformation(
SYSTEM_INFORMATION_CLASS system_information_class,
PVOID system_information,
ULONG system_information_length,
PULONG return_length) {
static const auto nt_query_system_information =
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtQuerySystemInformation);
return nt_query_system_information(system_information_class,
system_information,
system_information_length,
return_length);
}
NTSTATUS NtQueryInformationThread(HANDLE thread_handle,
THREADINFOCLASS thread_information_class,
PVOID thread_information,
ULONG thread_information_length,
PULONG return_length) {
static const auto nt_query_information_thread =
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtQueryInformationThread);
return nt_query_information_thread(thread_handle,
thread_information_class,
thread_information,
thread_information_length,
return_length);
}
template <class Traits>
NTSTATUS NtOpenThread(PHANDLE thread_handle,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
const process_types::CLIENT_ID<Traits>* client_id) {
static const auto nt_open_thread =
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtOpenThread);
return nt_open_thread(
thread_handle,
desired_access,
object_attributes,
const_cast<CLIENT_ID*>(reinterpret_cast<const CLIENT_ID*>(client_id)));
}
NTSTATUS NtQueryObject(HANDLE handle,
OBJECT_INFORMATION_CLASS object_information_class,
void* object_information,
ULONG object_information_length,
ULONG* return_length) {
static const auto nt_query_object =
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtQueryObject);
return nt_query_object(handle,
object_information_class,
object_information,
object_information_length,
return_length);
}
NTSTATUS NtSuspendProcess(HANDLE handle) {
static const auto nt_suspend_process =
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtSuspendProcess);
return nt_suspend_process(handle);
}
NTSTATUS NtResumeProcess(HANDLE handle) {
static const auto nt_resume_process =
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtResumeProcess);
return nt_resume_process(handle);
}
void RtlGetUnloadEventTraceEx(ULONG** element_size,
ULONG** element_count,
void** event_trace) {
static const auto rtl_get_unload_event_trace_ex =
GET_FUNCTION_REQUIRED(L"ntdll.dll", ::RtlGetUnloadEventTraceEx);
rtl_get_unload_event_trace_ex(element_size, element_count, event_trace);
}
// Explicit instantiations with the only 2 valid template arguments to avoid
// putting the body of the function in the header.
template NTSTATUS NtOpenThread<process_types::internal::Traits32>(
PHANDLE thread_handle,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
const process_types::CLIENT_ID<process_types::internal::Traits32>*
client_id);
template NTSTATUS NtOpenThread<process_types::internal::Traits64>(
PHANDLE thread_handle,
ACCESS_MASK desired_access,
POBJECT_ATTRIBUTES object_attributes,
const process_types::CLIENT_ID<process_types::internal::Traits64>*
client_id);
} // namespace crashpad