OLD | NEW |
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 bool ReadUnicodeString(HANDLE process, | 61 bool ReadUnicodeString(HANDLE process, |
62 const process_types::UNICODE_STRING<T>& us, | 62 const process_types::UNICODE_STRING<T>& us, |
63 std::wstring* result) { | 63 std::wstring* result) { |
64 if (us.Length == 0) { | 64 if (us.Length == 0) { |
65 result->clear(); | 65 result->clear(); |
66 return true; | 66 return true; |
67 } | 67 } |
68 DCHECK_EQ(us.Length % sizeof(wchar_t), 0u); | 68 DCHECK_EQ(us.Length % sizeof(wchar_t), 0u); |
69 result->resize(us.Length / sizeof(wchar_t)); | 69 result->resize(us.Length / sizeof(wchar_t)); |
70 SIZE_T bytes_read; | 70 SIZE_T bytes_read; |
71 if (!ReadProcessMemory(process, | 71 if (!ReadProcessMemory( |
72 reinterpret_cast<const void*>(us.Buffer), | 72 process, |
73 &result->operator[](0), | 73 reinterpret_cast<const void*>(static_cast<uintptr_t>(us.Buffer)), |
74 us.Length, | 74 &result->operator[](0), |
75 &bytes_read)) { | 75 us.Length, |
| 76 &bytes_read)) { |
76 PLOG(ERROR) << "ReadProcessMemory UNICODE_STRING"; | 77 PLOG(ERROR) << "ReadProcessMemory UNICODE_STRING"; |
77 return false; | 78 return false; |
78 } | 79 } |
79 if (bytes_read != us.Length) { | 80 if (bytes_read != us.Length) { |
80 LOG(ERROR) << "ReadProcessMemory UNICODE_STRING incorrect size"; | 81 LOG(ERROR) << "ReadProcessMemory UNICODE_STRING incorrect size"; |
81 return false; | 82 return false; |
82 } | 83 } |
83 return true; | 84 return true; |
84 } | 85 } |
85 | 86 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 | 192 |
192 process_types::PEB_LDR_DATA<Traits> peb_ldr_data; | 193 process_types::PEB_LDR_DATA<Traits> peb_ldr_data; |
193 if (!ReadStruct(process, peb.Ldr, &peb_ldr_data)) | 194 if (!ReadStruct(process, peb.Ldr, &peb_ldr_data)) |
194 return false; | 195 return false; |
195 | 196 |
196 process_types::LDR_DATA_TABLE_ENTRY<Traits> ldr_data_table_entry; | 197 process_types::LDR_DATA_TABLE_ENTRY<Traits> ldr_data_table_entry; |
197 | 198 |
198 // Include the first module in the memory order list to get our the main | 199 // Include the first module in the memory order list to get our the main |
199 // executable's name, as it's not included in initialization order below. | 200 // executable's name, as it's not included in initialization order below. |
200 if (!ReadStruct(process, | 201 if (!ReadStruct(process, |
201 reinterpret_cast<WinVMAddress>( | 202 static_cast<WinVMAddress>( |
202 reinterpret_cast<const char*>( | 203 peb_ldr_data.InMemoryOrderModuleList.Flink) - |
203 peb_ldr_data.InMemoryOrderModuleList.Flink) - | |
204 offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>, | 204 offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>, |
205 InMemoryOrderLinks)), | 205 InMemoryOrderLinks), |
206 &ldr_data_table_entry)) { | 206 &ldr_data_table_entry)) { |
207 return false; | 207 return false; |
208 } | 208 } |
209 ProcessInfo::Module module; | 209 ProcessInfo::Module module; |
210 if (!ReadUnicodeString( | 210 if (!ReadUnicodeString( |
211 process, ldr_data_table_entry.FullDllName, &module.name)) { | 211 process, ldr_data_table_entry.FullDllName, &module.name)) { |
212 return false; | 212 return false; |
213 } | 213 } |
214 module.dll_base = ldr_data_table_entry.DllBase; | 214 module.dll_base = ldr_data_table_entry.DllBase; |
215 module.size = ldr_data_table_entry.SizeOfImage; | 215 module.size = ldr_data_table_entry.SizeOfImage; |
216 module.timestamp = ldr_data_table_entry.TimeDateStamp; | 216 module.timestamp = ldr_data_table_entry.TimeDateStamp; |
217 process_info->modules_.push_back(module); | 217 process_info->modules_.push_back(module); |
218 | 218 |
219 // Walk the PEB LDR structure (doubly-linked list) to get the list of loaded | 219 // Walk the PEB LDR structure (doubly-linked list) to get the list of loaded |
220 // modules. We use this method rather than EnumProcessModules to get the | 220 // modules. We use this method rather than EnumProcessModules to get the |
221 // modules in initialization order rather than memory order. | 221 // modules in initialization order rather than memory order. |
222 Traits::Pointer last = peb_ldr_data.InInitializationOrderModuleList.Blink; | 222 Traits::Pointer last = peb_ldr_data.InInitializationOrderModuleList.Blink; |
223 for (Traits::Pointer cur = peb_ldr_data.InInitializationOrderModuleList.Flink; | 223 for (Traits::Pointer cur = peb_ldr_data.InInitializationOrderModuleList.Flink; |
224 ; | 224 ; |
225 cur = ldr_data_table_entry.InInitializationOrderLinks.Flink) { | 225 cur = ldr_data_table_entry.InInitializationOrderLinks.Flink) { |
226 // |cur| is the pointer to the LIST_ENTRY embedded in the | 226 // |cur| is the pointer to the LIST_ENTRY embedded in the |
227 // LDR_DATA_TABLE_ENTRY, in the target process's address space. So we need | 227 // LDR_DATA_TABLE_ENTRY, in the target process's address space. So we need |
228 // to read from the target, and also offset back to the beginning of the | 228 // to read from the target, and also offset back to the beginning of the |
229 // structure. | 229 // structure. |
230 if (!ReadStruct(process, | 230 if (!ReadStruct(process, |
231 reinterpret_cast<WinVMAddress>( | 231 static_cast<WinVMAddress>(cur) - |
232 reinterpret_cast<const char*>(cur) - | |
233 offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>, | 232 offsetof(process_types::LDR_DATA_TABLE_ENTRY<Traits>, |
234 InInitializationOrderLinks)), | 233 InInitializationOrderLinks), |
235 &ldr_data_table_entry)) { | 234 &ldr_data_table_entry)) { |
236 break; | 235 break; |
237 } | 236 } |
238 // TODO(scottmg): Capture Checksum, etc. too? | 237 // TODO(scottmg): Capture Checksum, etc. too? |
239 if (!ReadUnicodeString( | 238 if (!ReadUnicodeString( |
240 process, ldr_data_table_entry.FullDllName, &module.name)) { | 239 process, ldr_data_table_entry.FullDllName, &module.name)) { |
241 break; | 240 break; |
242 } | 241 } |
243 module.dll_base = ldr_data_table_entry.DllBase; | 242 module.dll_base = ldr_data_table_entry.DllBase; |
244 module.size = ldr_data_table_entry.SizeOfImage; | 243 module.size = ldr_data_table_entry.SizeOfImage; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 return true; | 346 return true; |
348 } | 347 } |
349 | 348 |
350 bool ProcessInfo::Modules(std::vector<Module>* modules) const { | 349 bool ProcessInfo::Modules(std::vector<Module>* modules) const { |
351 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 350 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
352 *modules = modules_; | 351 *modules = modules_; |
353 return true; | 352 return true; |
354 } | 353 } |
355 | 354 |
356 } // namespace crashpad | 355 } // namespace crashpad |
OLD | NEW |