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

Side by Side Diff: snapshot/win/pe_image_reader.cc

Issue 1311003003: Implement ModuleSnapshotWin::UUID (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: . Created 5 years, 3 months 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
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 "snapshot/win/pe_image_reader.h" 15 #include "snapshot/win/pe_image_reader.h"
16 16
17 #include <string.h> 17 #include <string.h>
18 18
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/memory/scoped_ptr.h"
20 #include "base/strings/stringprintf.h" 21 #include "base/strings/stringprintf.h"
21 #include "client/crashpad_info.h" 22 #include "client/crashpad_info.h"
22 #include "snapshot/win/process_reader_win.h" 23 #include "snapshot/win/process_reader_win.h"
23 24
24 namespace crashpad { 25 namespace crashpad {
25 26
26 namespace { 27 namespace {
27 28
28 std::string RangeToString(const CheckedWinAddressRange& range) { 29 std::string RangeToString(const CheckedWinAddressRange& range) {
29 return base::StringPrintf("[0x%llx + 0x%llx (%s)]", 30 return base::StringPrintf("[0x%llx + 0x%llx (%s)]",
30 range.Base(), 31 range.Base(),
31 range.Size(), 32 range.Size(),
32 range.Is64Bit() ? "64" : "32"); 33 range.Is64Bit() ? "64" : "32");
33 } 34 }
34 35
36 struct CodeviewInfoPDB70 {
Mark Mentovai 2015/08/31 21:48:20 Isn’t this MinidumpModuleCodeViewRecordPDB70 from
scottmg 2015/08/31 23:05:02 Done.
37 DWORD codeview_signature;
38 GUID guid;
39 DWORD age;
40 char pdb_filename[1];
41 };
42
35 } // namespace 43 } // namespace
36 44
37 PEImageReader::PEImageReader() 45 PEImageReader::PEImageReader()
38 : process_reader_(nullptr), 46 : process_reader_(nullptr),
39 module_range_(), 47 module_range_(),
40 module_name_(), 48 module_name_(),
41 initialized_() { 49 initialized_() {
42 } 50 }
43 51
44 PEImageReader::~PEImageReader() { 52 PEImageReader::~PEImageReader() {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 111
104 if (crashpad_info->signature != CrashpadInfo::kSignature || 112 if (crashpad_info->signature != CrashpadInfo::kSignature ||
105 crashpad_info->version < 1) { 113 crashpad_info->version < 1) {
106 LOG(WARNING) << "unexpected crashpad info data " << module_name_; 114 LOG(WARNING) << "unexpected crashpad info data " << module_name_;
107 return false; 115 return false;
108 } 116 }
109 117
110 return true; 118 return true;
111 } 119 }
112 120
113 bool PEImageReader::GetSectionByName(const std::string& name, 121 bool PEImageReader::DebugDirectoryInformation(UUID* uuid,
114 IMAGE_SECTION_HEADER* section) const { 122 DWORD* age,
115 if (name.size() > sizeof(section->Name)) { 123 std::string* pdbname) {
116 LOG(WARNING) << "supplied section name too long " << name; 124 WinVMAddress nt_headers_address;
125 IMAGE_NT_HEADERS nt_headers;
126 if (!ReadNtHeaders(&nt_headers_address, &nt_headers))
127 return false;
128
129 const IMAGE_DATA_DIRECTORY& data_directory =
130 nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
131 if (data_directory.VirtualAddress == 0 || data_directory.Size == 0)
132 return false;
133 if (data_directory.Size % sizeof(IMAGE_DEBUG_DIRECTORY) != 0)
134 return false;
135 IMAGE_DEBUG_DIRECTORY debug_directory;
Mark Mentovai 2015/08/31 21:48:20 Declare this before the test above so that you can
scottmg 2015/08/31 23:05:02 Done.
136 if (!CheckedReadMemory(Address() + data_directory.VirtualAddress,
Mark Mentovai 2015/08/31 21:48:20 This allowed data_directory.Size to be larger than
scottmg 2015/08/31 23:05:01 Done. The correct type to read is IMAGE_DEBUG_TYPE
137 data_directory.Size,
138 &debug_directory)) {
139 LOG(WARNING) << "could not read data directory";
140 return false;
141 }
Mark Mentovai 2015/08/31 21:48:21 Validate the Type (and slash or version fields) to
scottmg 2015/08/31 23:05:02 Done.
142 scoped_ptr<char []> data(new char[debug_directory.SizeOfData]);
143 if (!CheckedReadMemory(Address() + debug_directory.AddressOfRawData,
144 debug_directory.SizeOfData,
145 data.get())) {
Mark Mentovai 2015/08/31 21:48:20 Don’t do this if debug_directory.SizeOfData was 0.
scottmg 2015/08/31 23:05:01 Done.
146 LOG(WARNING) << "could not read debug directory";
117 return false; 147 return false;
118 } 148 }
119 149
150 CodeviewInfoPDB70* codeview =
Mark Mentovai 2015/08/31 21:48:21 How are you sure it’s 7.0?
scottmg 2015/08/31 23:05:01 Done.
151 reinterpret_cast<CodeviewInfoPDB70*>(data.get());
Mark Mentovai 2015/08/31 21:48:20 Speaking of that… You don’t need to worry about n
scottmg 2015/08/31 23:05:02 Done.
152 uuid->InitializeFromSystemUUID(&codeview->guid);
153 *age = codeview->age;
154 *pdbname = std::string(codeview->pdb_filename);
155 return true;
156 }
157
158 // TODO(scottmg): This needs to be made cross-bitness supporting.
159 bool PEImageReader::ReadNtHeaders(WinVMAddress* nt_headers_address,
160 IMAGE_NT_HEADERS* nt_headers) const {
120 IMAGE_DOS_HEADER dos_header; 161 IMAGE_DOS_HEADER dos_header;
121 if (!CheckedReadMemory(Address(), sizeof(IMAGE_DOS_HEADER), &dos_header)) { 162 if (!CheckedReadMemory(Address(), sizeof(IMAGE_DOS_HEADER), &dos_header)) {
122 LOG(WARNING) << "could not read dos header of " << module_name_; 163 LOG(WARNING) << "could not read dos header of " << module_name_;
123 return false; 164 return false;
124 } 165 }
125 166
126 if (dos_header.e_magic != IMAGE_DOS_SIGNATURE) { 167 if (dos_header.e_magic != IMAGE_DOS_SIGNATURE) {
127 LOG(WARNING) << "invalid e_magic in dos header of " << module_name_; 168 LOG(WARNING) << "invalid e_magic in dos header of " << module_name_;
128 return false; 169 return false;
129 } 170 }
130 171
131 // TODO(scottmg): This is reading a same-bitness sized structure. 172 *nt_headers_address = Address() + dos_header.e_lfanew;
132 IMAGE_NT_HEADERS nt_headers;
133 WinVMAddress nt_headers_address = Address() + dos_header.e_lfanew;
134 if (!CheckedReadMemory( 173 if (!CheckedReadMemory(
135 nt_headers_address, sizeof(IMAGE_NT_HEADERS), &nt_headers)) { 174 *nt_headers_address, sizeof(IMAGE_NT_HEADERS), nt_headers)) {
136 LOG(WARNING) << "could not read nt headers of " << module_name_; 175 LOG(WARNING) << "could not read nt headers of " << module_name_;
137 return false; 176 return false;
138 } 177 }
139 178
140 if (nt_headers.Signature != IMAGE_NT_SIGNATURE) { 179 if (nt_headers->Signature != IMAGE_NT_SIGNATURE) {
141 LOG(WARNING) << "invalid signature in nt headers of " << module_name_; 180 LOG(WARNING) << "invalid signature in nt headers of " << module_name_;
142 return false; 181 return false;
143 } 182 }
144 183
184 return true;
185 }
186
187 bool PEImageReader::GetSectionByName(const std::string& name,
188 IMAGE_SECTION_HEADER* section) const {
189 if (name.size() > sizeof(section->Name)) {
190 LOG(WARNING) << "supplied section name too long " << name;
191 return false;
192 }
193
194 WinVMAddress nt_headers_address;
195 IMAGE_NT_HEADERS nt_headers;
196 if (!ReadNtHeaders(&nt_headers_address, &nt_headers))
197 return false;
198
145 WinVMAddress first_section_address = 199 WinVMAddress first_section_address =
146 nt_headers_address + offsetof(IMAGE_NT_HEADERS, OptionalHeader) + 200 nt_headers_address + offsetof(IMAGE_NT_HEADERS, OptionalHeader) +
147 nt_headers.FileHeader.SizeOfOptionalHeader; 201 nt_headers.FileHeader.SizeOfOptionalHeader;
148 for (DWORD i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) { 202 for (DWORD i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) {
149 WinVMAddress section_address = 203 WinVMAddress section_address =
150 first_section_address + sizeof(IMAGE_SECTION_HEADER) * i; 204 first_section_address + sizeof(IMAGE_SECTION_HEADER) * i;
151 if (!CheckedReadMemory( 205 if (!CheckedReadMemory(
152 section_address, sizeof(IMAGE_SECTION_HEADER), section)) { 206 section_address, sizeof(IMAGE_SECTION_HEADER), section)) {
153 LOG(WARNING) << "could not read section " << i << " of " << module_name_; 207 LOG(WARNING) << "could not read section " << i << " of " << module_name_;
154 return false; 208 return false;
(...skipping 18 matching lines...) Expand all
173 } 227 }
174 if (!module_range_.ContainsRange(read_range)) { 228 if (!module_range_.ContainsRange(read_range)) {
175 LOG(WARNING) << "attempt to read outside of module " << module_name_ 229 LOG(WARNING) << "attempt to read outside of module " << module_name_
176 << " at range: " << RangeToString(read_range); 230 << " at range: " << RangeToString(read_range);
177 return false; 231 return false;
178 } 232 }
179 return process_reader_->ReadMemory(address, size, into); 233 return process_reader_->ReadMemory(address, size, into);
180 } 234 }
181 235
182 } // namespace crashpad 236 } // namespace crashpad
OLDNEW
« snapshot/win/pe_image_reader.h ('K') | « snapshot/win/pe_image_reader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698