Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(432)

Side by Side Diff: syzygy/refinery/analyzers/type_propagator_analyzer.cc

Issue 1475083002: [Refinery] Introduce TypePropagatorAnalyzer - pointer types. (Closed) Base URL: https://github.com/google/syzygy.git@master
Patch Set: Final nit Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/refinery/analyzers/type_propagator_analyzer.h"
16
17 #include <queue>
18
19 #include "syzygy/refinery/process_state/process_state_util.h"
20 #include "syzygy/refinery/process_state/refinery.pb.h"
21 #include "syzygy/refinery/types/type.h"
22
23 namespace refinery {
24
25 // static
26 const char TypePropagatorAnalyzer::kTypePropagatorAnalyzerName[] =
27 "TypePropagatorAnalyzer";
28
29 TypePropagatorAnalyzer::TypePropagatorAnalyzer(
30 scoped_refptr<SymbolProvider> symbol_provider)
31 : symbol_provider_(symbol_provider) {
32 DCHECK(symbol_provider.get() != nullptr);
33 }
34
35 Analyzer::AnalysisResult TypePropagatorAnalyzer::Analyze(
36 const minidump::Minidump& minidump,
37 ProcessState* process_state) {
38 DCHECK(process_state != nullptr);
39
40 // Analyzers that build content for the bytes and typed block layer must have
41 // already run. We use the existence of a bytes layer and a typed block layer
42 // as a proxy for this. Longer term, a proper notion of analyzer dependencies
43 // should be introduced.
44 BytesLayerPtr bytes_layer;
45 if (!process_state->FindLayer(&bytes_layer)) {
46 LOG(ERROR) << "Missing bytes layer.";
47 return ANALYSIS_ERROR;
48 }
49 TypedBlockLayerPtr typed_layer;
50 if (!process_state->FindLayer(&typed_layer)) {
51 LOG(ERROR) << "Missing typed block layer.";
52 return ANALYSIS_ERROR;
53 }
54
55 ModuleLayerAccessor accessor(process_state);
56
57 std::queue<TypedData> process_queue;
58
59 // Recover typed data from the typed block layer.
60 for (TypedBlockRecordPtr rec : *typed_layer) {
61 const TypedBlock& typedblock = rec->data();
62
63 // Recover the type.
64 pe::PEFile::Signature signature;
65 if (!accessor.GetModuleSignature(typedblock.module_id(), &signature))
66 return ANALYSIS_ERROR;
67
68 scoped_refptr<TypeRepository> type_repository;
69 if (!symbol_provider_->FindOrCreateTypeRepository(signature,
70 &type_repository)) {
71 return ANALYSIS_ERROR;
72 }
73
74 TypePtr type = type_repository->GetType(typedblock.type_id());
75 if (type == nullptr)
76 return ANALYSIS_ERROR;
77
78 // Queue typed data for processing.
79 process_queue.push(TypedData(process_state, type, rec->range().start()));
80 }
81
82 // Process typed data looking for pointers or contained pointers.
83 while (!process_queue.empty()) {
84 if (!AnalyzeTypedData(process_queue.front(), process_state))
85 return ANALYSIS_ERROR;
86 process_queue.pop();
87 }
88
89 return ANALYSIS_COMPLETE;
90 }
91
92 bool TypePropagatorAnalyzer::AnalyzeTypedData(const TypedData& typed_data,
93 ProcessState* process_state) {
94 DCHECK(process_state != nullptr);
95
96 TypePtr type = typed_data.type();
97 DCHECK(type.get());
98
99 switch (type->kind()) {
100 case Type::USER_DEFINED_TYPE_KIND:
101 return AnalyzeTypedDataUDT(typed_data, process_state);
102 case Type::POINTER_TYPE_KIND:
103 return AnalyzeTypedDataPointer(typed_data, process_state);
104 case Type::ARRAY_TYPE_KIND:
105 return AnalyzeTypedDataArray(typed_data, process_state);
106 case Type::BASIC_TYPE_KIND:
107 case Type::FUNCTION_TYPE_KIND:
108 case Type::GLOBAL_TYPE_KIND:
109 case Type::WILDCARD_TYPE_KIND:
110 // Nothing to do with these.
111 return true;
112 default:
113 DCHECK(false);
114 return false;
115 }
116 }
117
118 bool TypePropagatorAnalyzer::AnalyzeTypedDataUDT(const TypedData& typed_data,
119 ProcessState* process_state) {
120 DCHECK_EQ(Type::USER_DEFINED_TYPE_KIND, typed_data.type()->kind());
121 DCHECK(process_state != nullptr);
122
123 // TODO(manzagop): implement.
124
125 return true;
126 }
127
128 bool TypePropagatorAnalyzer::AnalyzeTypedDataPointer(
129 const TypedData& typed_data,
130 ProcessState* process_state) {
131 DCHECK_EQ(Type::POINTER_TYPE_KIND, typed_data.type()->kind());
132 DCHECK(process_state != nullptr);
133
134 TypedData content_data;
135 if (!typed_data.Dereference(&content_data)) {
136 // Unable to dereference. This may be because the pointer's contents (the
137 // address of the pointee) are not available.
138 // TODO(manzagop): have a better way to distinguish a failure (can't cast
139 // pointer) from an acceptable negative result (missing the required bytes)
140 // and have counters for these kinds of events.
141 return true;
142 }
143
144 return AddTypedBlock(content_data, process_state);
145 }
146
147 bool TypePropagatorAnalyzer::AnalyzeTypedDataArray(
148 const TypedData& typed_data,
149 ProcessState* process_state) {
150 DCHECK_EQ(Type::ARRAY_TYPE_KIND, typed_data.type()->kind());
151 DCHECK(process_state != nullptr);
152
153 // TODO(manzagop): implement.
154 return true;
155 }
156
157 bool TypePropagatorAnalyzer::AddTypedBlock(const TypedData& typed_data,
158 ProcessState* process_state) {
159 ModuleLayerAccessor accessor(process_state);
160 pe::PEFile::Signature signature;
161 if (!typed_data.type()->repository()->GetModuleSignature(&signature))
162 return false;
163 ModuleId module_id = accessor.GetModuleId(signature);
164 if (module_id == kNoModuleId)
165 return false;
166
167 return AddTypedBlockRecord(typed_data.GetRange(), L"", module_id,
168 typed_data.type()->type_id(), process_state);
169 }
170
171 } // namespace refinery
OLDNEW
« no previous file with comments | « syzygy/refinery/analyzers/type_propagator_analyzer.h ('k') | syzygy/refinery/analyzers/type_propagator_analyzer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698