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, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #include "util/win/process_info.h" | 15 #include "util/win/process_info.h" |
16 | 16 |
17 #include <winternl.h> | 17 #include <winternl.h> |
18 | 18 |
19 #include <algorithm> | 19 #include <algorithm> |
20 #include <limits> | 20 #include <limits> |
21 | 21 |
22 #include "base/logging.h" | 22 #include "base/logging.h" |
23 #include "base/memory/scoped_ptr.h" | 23 #include "base/memory/scoped_ptr.h" |
24 #include "base/strings/stringprintf.h" | 24 #include "base/strings/stringprintf.h" |
25 #include "base/template_util.h" | 25 #include "base/template_util.h" |
26 #include "build/build_config.h" | 26 #include "build/build_config.h" |
27 #include "util/numeric/safe_assignment.h" | 27 #include "util/numeric/safe_assignment.h" |
28 #include "util/win/get_function.h" | 28 #include "util/win/get_function.h" |
| 29 #include "util/win/handle.h" |
29 #include "util/win/nt_internals.h" | 30 #include "util/win/nt_internals.h" |
30 #include "util/win/ntstatus_logging.h" | 31 #include "util/win/ntstatus_logging.h" |
31 #include "util/win/process_structs.h" | 32 #include "util/win/process_structs.h" |
32 #include "util/win/scoped_handle.h" | 33 #include "util/win/scoped_handle.h" |
33 | 34 |
34 namespace crashpad { | 35 namespace crashpad { |
35 | 36 |
36 namespace { | 37 namespace { |
37 | 38 |
38 NTSTATUS NtQueryInformationProcess(HANDLE process_handle, | 39 NTSTATUS NtQueryInformationProcess(HANDLE process_handle, |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 &bytes_returned); | 175 &bytes_returned); |
175 if (!NT_SUCCESS(status)) { | 176 if (!NT_SUCCESS(status)) { |
176 NTSTATUS_LOG(ERROR, status) << "NtQueryInformationProcess"; | 177 NTSTATUS_LOG(ERROR, status) << "NtQueryInformationProcess"; |
177 return false; | 178 return false; |
178 } | 179 } |
179 if (bytes_returned != sizeof(process_basic_information)) { | 180 if (bytes_returned != sizeof(process_basic_information)) { |
180 LOG(ERROR) << "NtQueryInformationProcess incorrect size"; | 181 LOG(ERROR) << "NtQueryInformationProcess incorrect size"; |
181 return false; | 182 return false; |
182 } | 183 } |
183 | 184 |
184 // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203 on | 185 // API functions (e.g. OpenProcess) take only a DWORD, so there's no sense in |
185 // 32 bit being the correct size for HANDLEs for proceses, even on Windows | 186 // maintaining the top bits. |
186 // x64. API functions (e.g. OpenProcess) take only a DWORD, so there's no | |
187 // sense in maintaining the top bits. | |
188 process_info->process_id_ = | 187 process_info->process_id_ = |
189 static_cast<DWORD>(process_basic_information.UniqueProcessId); | 188 static_cast<DWORD>(process_basic_information.UniqueProcessId); |
190 process_info->inherited_from_process_id_ = static_cast<DWORD>( | 189 process_info->inherited_from_process_id_ = static_cast<DWORD>( |
191 process_basic_information.InheritedFromUniqueProcessId); | 190 process_basic_information.InheritedFromUniqueProcessId); |
192 | 191 |
193 // We now want to read the PEB to gather the rest of our information. The | 192 // We now want to read the PEB to gather the rest of our information. The |
194 // PebBaseAddress as returned above is what we want for 64-on-64 and 32-on-32, | 193 // PebBaseAddress as returned above is what we want for 64-on-64 and 32-on-32, |
195 // but for Wow64, we want to read the 32 bit PEB (a Wow64 process has both). | 194 // but for Wow64, we want to read the 32 bit PEB (a Wow64 process has both). |
196 // The address of this is found by a second call to NtQueryInformationProcess. | 195 // The address of this is found by a second call to NtQueryInformationProcess. |
197 if (!is_wow64) { | 196 if (!is_wow64) { |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 returned_length); | 382 returned_length); |
384 | 383 |
385 std::vector<Handle> handles; | 384 std::vector<Handle> handles; |
386 | 385 |
387 for (size_t i = 0; i < system_handle_information_ex.NumberOfHandles; ++i) { | 386 for (size_t i = 0; i < system_handle_information_ex.NumberOfHandles; ++i) { |
388 const auto& handle = system_handle_information_ex.Handles[i]; | 387 const auto& handle = system_handle_information_ex.Handles[i]; |
389 if (handle.UniqueProcessId != process_id_) | 388 if (handle.UniqueProcessId != process_id_) |
390 continue; | 389 continue; |
391 | 390 |
392 Handle result_handle; | 391 Handle result_handle; |
393 result_handle.handle = | 392 result_handle.handle = HandleToInt(handle.HandleValue); |
394 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(handle.HandleValue)); | |
395 result_handle.attributes = handle.HandleAttributes; | 393 result_handle.attributes = handle.HandleAttributes; |
396 result_handle.granted_access = handle.GrantedAccess; | 394 result_handle.granted_access = handle.GrantedAccess; |
397 | 395 |
398 // TODO(scottmg): Could special case for self. | 396 // TODO(scottmg): Could special case for self. |
399 HANDLE dup_handle; | 397 HANDLE dup_handle; |
400 if (DuplicateHandle(process, | 398 if (DuplicateHandle(process, |
401 reinterpret_cast<HANDLE>(handle.HandleValue), | 399 handle.HandleValue, |
402 GetCurrentProcess(), | 400 GetCurrentProcess(), |
403 &dup_handle, | 401 &dup_handle, |
404 0, | 402 0, |
405 false, | 403 false, |
406 DUPLICATE_SAME_ACCESS)) { | 404 DUPLICATE_SAME_ACCESS)) { |
407 // Some handles cannot be duplicated, for example, handles of type | 405 // Some handles cannot be duplicated, for example, handles of type |
408 // EtwRegistration. If we fail to duplicate, then we can't gather any more | 406 // EtwRegistration. If we fail to duplicate, then we can't gather any more |
409 // information, but include the information that we do have already. | 407 // information, but include the information that we do have already. |
410 ScopedKernelHANDLE scoped_dup_handle(dup_handle); | 408 ScopedKernelHANDLE scoped_dup_handle(dup_handle); |
411 | 409 |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 } else { | 681 } else { |
684 result.push_back(as_ranges[i]); | 682 result.push_back(as_ranges[i]); |
685 } | 683 } |
686 DCHECK(result.back().IsValid()); | 684 DCHECK(result.back().IsValid()); |
687 } | 685 } |
688 | 686 |
689 return result; | 687 return result; |
690 } | 688 } |
691 | 689 |
692 } // namespace crashpad | 690 } // namespace crashpad |
OLD | NEW |