diff --git a/handler/win/crashy_test_program.cc b/handler/win/crashy_test_program.cc index b6e044c8..58afa47f 100644 --- a/handler/win/crashy_test_program.cc +++ b/handler/win/crashy_test_program.cc @@ -201,8 +201,8 @@ int CrashyMain(int argc, wchar_t* argv[]) { AllocateExtraUnsavedMemory(extra_ranges); // Load and unload some uncommonly used modules so we can see them in the list - // reported by `lm`. At least two so that we confirm we got the size of - // RTL_UNLOAD_EVENT_TRACE right. + // reported by `lm`. At least two so that we confirm we got the element size + // advancement of RTL_UNLOAD_EVENT_TRACE correct. CHECK(GetModuleHandle(L"lz32.dll") == nullptr); CHECK(GetModuleHandle(L"wmerror.dll") == nullptr); HMODULE lz32 = LoadLibrary(L"lz32.dll"); diff --git a/snapshot/win/process_snapshot_win.cc b/snapshot/win/process_snapshot_win.cc index 63543c76..11e83145 100644 --- a/snapshot/win/process_snapshot_win.cc +++ b/snapshot/win/process_snapshot_win.cc @@ -281,21 +281,43 @@ void ProcessSnapshotWin::InitializeUnloadedModules() { #error port #endif - RTL_UNLOAD_EVENT_TRACE* unload_event_trace_address = - RtlGetUnloadEventTrace(); - WinVMAddress address_in_target_process = - reinterpret_cast(unload_event_trace_address); + ULONG* element_size; + ULONG* element_count; + void* event_trace_address; + RtlGetUnloadEventTraceEx(&element_size, &element_count, &event_trace_address); - std::vector> events( - RTL_UNLOAD_EVENT_TRACE_NUMBER); - if (!process_reader_.ReadMemory(address_in_target_process, - events.size() * sizeof(events[0]), - &events[0])) { + if (*element_size < sizeof(RTL_UNLOAD_EVENT_TRACE)) { + LOG(ERROR) << "unexpected unloaded module list element size"; return; } - for (const RTL_UNLOAD_EVENT_TRACE& uet : events) { - if (uet.ImageName[0]) { + const WinVMAddress address_in_target_process = + reinterpret_cast(event_trace_address); + + Traits::Pointer pointer_to_array; + if (!process_reader_.ReadMemory(address_in_target_process, + sizeof(pointer_to_array), + &pointer_to_array)) { + LOG(ERROR) << "failed to read target address"; + return; + } + + // No unloaded modules. + if (pointer_to_array == 0) + return; + + const size_t data_size = *element_size * *element_count; + std::vector data(data_size); + if (!process_reader_.ReadMemory(pointer_to_array, data_size, &data[0])) { + LOG(ERROR) << "failed to read unloaded module data"; + return; + } + + for (ULONG i = 0; i < *element_count; ++i) { + const uint8_t* base_address = &data[i * *element_size]; + const auto& uet = + *reinterpret_cast*>(base_address); + if (uet.ImageName[0] != 0) { unloaded_modules_.push_back(UnloadedModuleSnapshot( uet.BaseAddress, uet.SizeOfImage, diff --git a/util/win/nt_internals.cc b/util/win/nt_internals.cc index 12201620..97eba68b 100644 --- a/util/win/nt_internals.cc +++ b/util/win/nt_internals.cc @@ -42,7 +42,9 @@ NTSTATUS NTAPI NtSuspendProcess(HANDLE); NTSTATUS NTAPI NtResumeProcess(HANDLE); -void* NTAPI RtlGetUnloadEventTrace(); +VOID NTAPI RtlGetUnloadEventTraceEx(PULONG* ElementSize, + PULONG* ElementCount, + PVOID* EventTrace); namespace crashpad { @@ -145,12 +147,12 @@ NTSTATUS NtResumeProcess(HANDLE handle) { return nt_resume_process(handle); } -template -RTL_UNLOAD_EVENT_TRACE* RtlGetUnloadEventTrace() { - static const auto rtl_get_unload_event_trace = - GET_FUNCTION_REQUIRED(L"ntdll.dll", ::RtlGetUnloadEventTrace); - return reinterpret_cast*>( - rtl_get_unload_event_trace()); +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 @@ -169,10 +171,4 @@ template NTSTATUS NtOpenThread( const process_types::CLIENT_ID* client_id); -template RTL_UNLOAD_EVENT_TRACE* -RtlGetUnloadEventTrace(); - -template RTL_UNLOAD_EVENT_TRACE* -RtlGetUnloadEventTrace(); - } // namespace crashpad diff --git a/util/win/nt_internals.h b/util/win/nt_internals.h index 0a80fd53..41e5fa44 100644 --- a/util/win/nt_internals.h +++ b/util/win/nt_internals.h @@ -75,10 +75,7 @@ NTSTATUS NtSuspendProcess(HANDLE handle); NTSTATUS NtResumeProcess(HANDLE handle); -// From https://msdn.microsoft.com/en-us/library/bb432428(VS.85).aspx and -// http://processhacker.sourceforge.net/doc/struct___r_t_l___u_n_l_o_a_d___e_v_e_n_t___t_r_a_c_e.html -#define RTL_UNLOAD_EVENT_TRACE_NUMBER 64 - +// From https://msdn.microsoft.com/en-us/library/cc678403(v=vs.85).aspx. template struct RTL_UNLOAD_EVENT_TRACE { typename Traits::Pointer BaseAddress; @@ -87,14 +84,10 @@ struct RTL_UNLOAD_EVENT_TRACE { ULONG TimeDateStamp; ULONG CheckSum; WCHAR ImageName[32]; - ULONG Version0; - union { - ULONG Version1; - typename Traits::Pad alignment_for_x64; - }; }; -template -RTL_UNLOAD_EVENT_TRACE* RtlGetUnloadEventTrace(); +void RtlGetUnloadEventTraceEx(ULONG** element_size, + ULONG** element_count, + void** event_trace); } // namespace crashpad