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

Unified 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, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: syzygy/refinery/analyzers/type_propagator_analyzer.cc
diff --git a/syzygy/refinery/analyzers/type_propagator_analyzer.cc b/syzygy/refinery/analyzers/type_propagator_analyzer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..04e63bf0ee3b89dc4761412dcd534e3b2d782241
--- /dev/null
+++ b/syzygy/refinery/analyzers/type_propagator_analyzer.cc
@@ -0,0 +1,171 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "syzygy/refinery/analyzers/type_propagator_analyzer.h"
+
+#include <queue>
+
+#include "syzygy/refinery/process_state/process_state_util.h"
+#include "syzygy/refinery/process_state/refinery.pb.h"
+#include "syzygy/refinery/types/type.h"
+
+namespace refinery {
+
+// static
+const char TypePropagatorAnalyzer::kTypePropagatorAnalyzerName[] =
+ "TypePropagatorAnalyzer";
+
+TypePropagatorAnalyzer::TypePropagatorAnalyzer(
+ scoped_refptr<SymbolProvider> symbol_provider)
+ : symbol_provider_(symbol_provider) {
+ DCHECK(symbol_provider.get() != nullptr);
+}
+
+Analyzer::AnalysisResult TypePropagatorAnalyzer::Analyze(
+ const minidump::Minidump& minidump,
+ ProcessState* process_state) {
+ DCHECK(process_state != nullptr);
+
+ // Analyzers that build content for the bytes and typed block layer must have
+ // already run. We use the existence of a bytes layer and a typed block layer
+ // as a proxy for this. Longer term, a proper notion of analyzer dependencies
+ // should be introduced.
+ BytesLayerPtr bytes_layer;
+ if (!process_state->FindLayer(&bytes_layer)) {
+ LOG(ERROR) << "Missing bytes layer.";
+ return ANALYSIS_ERROR;
+ }
+ TypedBlockLayerPtr typed_layer;
+ if (!process_state->FindLayer(&typed_layer)) {
+ LOG(ERROR) << "Missing typed block layer.";
+ return ANALYSIS_ERROR;
+ }
+
+ ModuleLayerAccessor accessor(process_state);
+
+ std::queue<TypedData> process_queue;
+
+ // Recover typed data from the typed block layer.
+ for (TypedBlockRecordPtr rec : *typed_layer) {
+ const TypedBlock& typedblock = rec->data();
+
+ // Recover the type.
+ pe::PEFile::Signature signature;
+ if (!accessor.GetModuleSignature(typedblock.module_id(), &signature))
+ return ANALYSIS_ERROR;
+
+ scoped_refptr<TypeRepository> type_repository;
+ if (!symbol_provider_->FindOrCreateTypeRepository(signature,
+ &type_repository)) {
+ return ANALYSIS_ERROR;
+ }
+
+ TypePtr type = type_repository->GetType(typedblock.type_id());
+ if (type == nullptr)
+ return ANALYSIS_ERROR;
+
+ // Queue typed data for processing.
+ process_queue.push(TypedData(process_state, type, rec->range().start()));
+ }
+
+ // Process typed data looking for pointers or contained pointers.
+ while (!process_queue.empty()) {
+ if (!AnalyzeTypedData(process_queue.front(), process_state))
+ return ANALYSIS_ERROR;
+ process_queue.pop();
+ }
+
+ return ANALYSIS_COMPLETE;
+}
+
+bool TypePropagatorAnalyzer::AnalyzeTypedData(const TypedData& typed_data,
+ ProcessState* process_state) {
+ DCHECK(process_state != nullptr);
+
+ TypePtr type = typed_data.type();
+ DCHECK(type.get());
+
+ switch (type->kind()) {
+ case Type::USER_DEFINED_TYPE_KIND:
+ return AnalyzeTypedDataUDT(typed_data, process_state);
+ case Type::POINTER_TYPE_KIND:
+ return AnalyzeTypedDataPointer(typed_data, process_state);
+ case Type::ARRAY_TYPE_KIND:
+ return AnalyzeTypedDataArray(typed_data, process_state);
+ case Type::BASIC_TYPE_KIND:
+ case Type::FUNCTION_TYPE_KIND:
+ case Type::GLOBAL_TYPE_KIND:
+ case Type::WILDCARD_TYPE_KIND:
+ // Nothing to do with these.
+ return true;
+ default:
+ DCHECK(false);
+ return false;
+ }
+}
+
+bool TypePropagatorAnalyzer::AnalyzeTypedDataUDT(const TypedData& typed_data,
+ ProcessState* process_state) {
+ DCHECK_EQ(Type::USER_DEFINED_TYPE_KIND, typed_data.type()->kind());
+ DCHECK(process_state != nullptr);
+
+ // TODO(manzagop): implement.
+
+ return true;
+}
+
+bool TypePropagatorAnalyzer::AnalyzeTypedDataPointer(
+ const TypedData& typed_data,
+ ProcessState* process_state) {
+ DCHECK_EQ(Type::POINTER_TYPE_KIND, typed_data.type()->kind());
+ DCHECK(process_state != nullptr);
+
+ TypedData content_data;
+ if (!typed_data.Dereference(&content_data)) {
+ // Unable to dereference. This may be because the pointer's contents (the
+ // address of the pointee) are not available.
+ // TODO(manzagop): have a better way to distinguish a failure (can't cast
+ // pointer) from an acceptable negative result (missing the required bytes)
+ // and have counters for these kinds of events.
+ return true;
+ }
+
+ return AddTypedBlock(content_data, process_state);
+}
+
+bool TypePropagatorAnalyzer::AnalyzeTypedDataArray(
+ const TypedData& typed_data,
+ ProcessState* process_state) {
+ DCHECK_EQ(Type::ARRAY_TYPE_KIND, typed_data.type()->kind());
+ DCHECK(process_state != nullptr);
+
+ // TODO(manzagop): implement.
+ return true;
+}
+
+bool TypePropagatorAnalyzer::AddTypedBlock(const TypedData& typed_data,
+ ProcessState* process_state) {
+ ModuleLayerAccessor accessor(process_state);
+ pe::PEFile::Signature signature;
+ if (!typed_data.type()->repository()->GetModuleSignature(&signature))
+ return false;
+ ModuleId module_id = accessor.GetModuleId(signature);
+ if (module_id == kNoModuleId)
+ return false;
+
+ return AddTypedBlockRecord(typed_data.GetRange(), L"", module_id,
+ typed_data.type()->type_id(), process_state);
+}
+
+} // namespace refinery
« 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