1 : // Copyright 2016 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/teb_analyzer.h"
16 :
17 : #include "base/strings/string_util.h"
18 : #include "base/strings/stringprintf.h"
19 : #include "syzygy/refinery/process_state/process_state_util.h"
20 : #include "syzygy/refinery/types/typed_data.h"
21 :
22 m : namespace refinery {
23 :
24 m : namespace {
25 :
26 : // TODO(siggi): This functionality needs to move somewhere central.
27 m : scoped_refptr<TypeRepository> GetNtdllTypes(ProcessState* process_state,
28 m : SymbolProvider* symbol_provider,
29 m : ModuleId* module_id) {
30 m : DCHECK(process_state);
31 m : DCHECK(symbol_provider);
32 m : DCHECK(module_id);
33 m : *module_id = kNoModuleId;
34 :
35 m : ModuleLayerPtr modules;
36 m : if (!process_state->FindLayer(&modules)) {
37 m : LOG(ERROR) << "No modules layer.";
38 m : return nullptr;
39 m : }
40 :
41 m : for (const auto& module_sig : modules->data().signatures()) {
42 m : if (base::EndsWith(module_sig.path, L"ntdll.dll",
43 m : base::CompareCase::INSENSITIVE_ASCII)) {
44 m : pe::PEFile::Signature signature(
45 m : module_sig.path, core::AbsoluteAddress(0U), module_sig.module_size,
46 m : module_sig.module_checksum, module_sig.module_time_date_stamp);
47 m : ModuleLayerAccessor module_access(process_state);
48 :
49 m : *module_id = module_access.GetModuleId(signature);
50 m : if (*module_id == kNoModuleId)
51 m : return nullptr;
52 :
53 m : scoped_refptr<TypeRepository> ret;
54 m : if (symbol_provider->FindOrCreateTypeRepository(signature, &ret))
55 m : return ret;
56 m : }
57 m : }
58 :
59 m : return nullptr;
60 m : }
61 :
62 m : } // namespace
63 :
64 : // static
65 m : const char TebAnalyzer::kTebAnalyzerName[] = "TebAnalyzer";
66 :
67 m : TebAnalyzer::TebAnalyzer() {
68 m : }
69 :
70 m : Analyzer::AnalysisResult TebAnalyzer::Analyze(
71 m : const minidump::Minidump& minidump,
72 m : const ProcessAnalysis& process_analysis) {
73 m : DCHECK(process_analysis.process_state() != nullptr);
74 :
75 : // Start by finding the NTDLL module record and symbols, as that's where we
76 : // come by the symbols that describe the heap.
77 m : ModuleId module_id = kNoModuleId;
78 m : scoped_refptr<TypeRepository> ntdll_repo =
79 m : GetNtdllTypes(process_analysis.process_state(),
80 m : process_analysis.symbol_provider().get(), &module_id);
81 m : if (!ntdll_repo || module_id == kNoModuleId) {
82 m : LOG(ERROR) << "Couldn't get types for NTDLL.";
83 m : return ANALYSIS_ERROR;
84 m : }
85 :
86 m : UserDefinedTypePtr teb_type;
87 m : for (const auto& type : *ntdll_repo) {
88 m : if (type->GetName() == L"_TEB" && type->CastTo(&teb_type))
89 m : break;
90 m : }
91 :
92 m : if (!teb_type) {
93 m : LOG(ERROR) << "Unable to find TEB UDT.";
94 m : return ANALYSIS_ERROR;
95 m : }
96 :
97 m : minidump::Minidump::TypedThreadList threads = minidump.GetThreadList();
98 m : if (!threads.IsValid()) {
99 m : LOG(ERROR) << "No threads in minidump.";
100 m : return ANALYSIS_ERROR;
101 m : }
102 :
103 m : for (const auto& thread : threads) {
104 m : TypedData teb(process_analysis.process_state(), teb_type,
105 m : Address(thread.Teb));
106 :
107 m : if (!AddTypedBlockRecord(teb.GetRange(), teb_type->GetName(), module_id,
108 m : teb_type->type_id(),
109 m : process_analysis.process_state())) {
110 m : LOG(ERROR) << "Failed to add TEB record for thread " << thread.ThreadId;
111 m : return ANALYSIS_ERROR;
112 m : }
113 m : }
114 :
115 m : return ANALYSIS_COMPLETE;
116 m : }
117 :
118 m : } // namespace refinery
|