1 : // Copyright 2015 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (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
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/common/process_utils.h"
16 :
17 : #include <psapi.h>
18 :
19 : #include "base/logging.h"
20 : #include "base/win/pe_image.h"
21 : #include "syzygy/common/com_utils.h"
22 : #include "syzygy/common/path_util.h"
23 :
24 : namespace common {
25 :
26 E : bool GetCurrentProcessModules(ModuleVector* modules) {
27 E : return GetProcessModules(::GetCurrentProcess(), modules);
28 E : }
29 :
30 E : bool GetProcessModules(HANDLE process, ModuleVector* modules) {
31 E : DCHECK(modules != NULL);
32 :
33 E : modules->resize(128);
34 E : while (true) {
35 E : DWORD bytes_required = 0;
36 : // EnumProcessModules returns 'success' even if the buffer size is too
37 : // small.
38 : if (!::EnumProcessModules(process, &(*modules)[0],
39 : modules->size() * sizeof(modules->at(0)),
40 E : &bytes_required)) {
41 i : DPLOG(ERROR) << "::EnumProcessModules";
42 i : modules->clear();
43 i : return false;
44 : }
45 E : DCHECK_EQ(0u, bytes_required % sizeof(modules->at(0)));
46 E : size_t num_modules = bytes_required / sizeof(modules->at(0));
47 E : if (num_modules <= modules->size()) {
48 : // Buffer size was too big, presumably because a module was unloaded.
49 E : modules->resize(num_modules);
50 E : return true;
51 i : } else if (num_modules == 0) {
52 i : DLOG(ERROR) << "Can't determine the module list size.";
53 i : modules->clear();
54 i : return false;
55 i : } else {
56 : // Buffer size was too small. Try again with a larger buffer.
57 i : modules->resize(num_modules + 4, NULL);
58 : }
59 i : }
60 E : }
61 :
62 : } // namespace common
|