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

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

Issue 1352323002: win: Make reading NT_IMAGE_HEADERS work cross-bitness (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@cleanup-crashpad-info
Patch Set: fixes2 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
« no previous file with comments | « snapshot/win/pe_image_reader.h ('k') | snapshot/win/process_snapshot_win_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 63
64 INITIALIZATION_STATE_SET_VALID(initialized_); 64 INITIALIZATION_STATE_SET_VALID(initialized_);
65 return true; 65 return true;
66 } 66 }
67 67
68 bool PEImageReader::GetCrashpadInfo( 68 bool PEImageReader::GetCrashpadInfo(
69 process_types::CrashpadInfo* crashpad_info) const { 69 process_types::CrashpadInfo* crashpad_info) const {
70 INITIALIZATION_STATE_DCHECK_VALID(initialized_); 70 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
71 71
72 IMAGE_SECTION_HEADER section; 72 IMAGE_SECTION_HEADER section;
73 if (!GetSectionByName("CPADinfo", &section)) 73 if (process_reader_->Is64Bit()) {
74 return false; 74 if (!GetSectionByName<IMAGE_NT_HEADERS64>("CPADinfo", &section))
75 return false;
76 } else {
77 if (!GetSectionByName<IMAGE_NT_HEADERS32>("CPADinfo", &section))
78 return false;
79 }
75 80
76 if (section.Misc.VirtualSize < sizeof(process_types::CrashpadInfo)) { 81 if (section.Misc.VirtualSize < sizeof(process_types::CrashpadInfo)) {
77 LOG(WARNING) << "small crashpad info section size " 82 LOG(WARNING) << "small crashpad info section size "
78 << section.Misc.VirtualSize << ", " << module_name_; 83 << section.Misc.VirtualSize << ", " << module_name_;
79 return false; 84 return false;
80 } 85 }
81 86
82 WinVMAddress crashpad_info_address = Address() + section.VirtualAddress; 87 WinVMAddress crashpad_info_address = Address() + section.VirtualAddress;
83 CheckedWinAddressRange crashpad_info_range(process_reader_->Is64Bit(), 88 CheckedWinAddressRange crashpad_info_range(process_reader_->Is64Bit(),
84 crashpad_info_address, 89 crashpad_info_address,
(...skipping 22 matching lines...) Expand all
107 crashpad_info->version < 1) { 112 crashpad_info->version < 1) {
108 LOG(WARNING) << "unexpected crashpad info data " << module_name_; 113 LOG(WARNING) << "unexpected crashpad info data " << module_name_;
109 return false; 114 return false;
110 } 115 }
111 116
112 return true; 117 return true;
113 } 118 }
114 119
115 bool PEImageReader::DebugDirectoryInformation(UUID* uuid, 120 bool PEImageReader::DebugDirectoryInformation(UUID* uuid,
116 DWORD* age, 121 DWORD* age,
117 std::string* pdbname) { 122 std::string* pdbname) const {
123 if (process_reader_->Is64Bit()) {
124 return ReadDebugDirectoryInformation<IMAGE_NT_HEADERS64>(
125 uuid, age, pdbname);
126 } else {
127 return ReadDebugDirectoryInformation<IMAGE_NT_HEADERS32>(
128 uuid, age, pdbname);
129 }
130 }
131
132 template <class NtHeadersType>
133 bool PEImageReader::ReadDebugDirectoryInformation(UUID* uuid,
134 DWORD* age,
135 std::string* pdbname) const {
118 WinVMAddress nt_headers_address; 136 WinVMAddress nt_headers_address;
119 IMAGE_NT_HEADERS nt_headers; 137 NtHeadersType nt_headers;
120 if (!ReadNtHeaders(&nt_headers_address, &nt_headers)) 138 if (!ReadNtHeaders(&nt_headers_address, &nt_headers))
121 return false; 139 return false;
122 140
123 const IMAGE_DATA_DIRECTORY& data_directory = 141 const IMAGE_DATA_DIRECTORY& data_directory =
124 nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]; 142 nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
125 if (data_directory.VirtualAddress == 0 || data_directory.Size == 0) 143 if (data_directory.VirtualAddress == 0 || data_directory.Size == 0)
126 return false; 144 return false;
127 IMAGE_DEBUG_DIRECTORY debug_directory; 145 IMAGE_DEBUG_DIRECTORY debug_directory;
128 if (data_directory.Size % sizeof(debug_directory) != 0) 146 if (data_directory.Size % sizeof(debug_directory) != 0)
129 return false; 147 return false;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 // This is a NUL-terminated string encoded in the codepage of the system 184 // This is a NUL-terminated string encoded in the codepage of the system
167 // where the binary was linked. We have no idea what that was, so we just 185 // where the binary was linked. We have no idea what that was, so we just
168 // assume ASCII. 186 // assume ASCII.
169 *pdbname = std::string(reinterpret_cast<char*>(&codeview->pdb_name[0])); 187 *pdbname = std::string(reinterpret_cast<char*>(&codeview->pdb_name[0]));
170 return true; 188 return true;
171 } 189 }
172 190
173 return false; 191 return false;
174 } 192 }
175 193
176 // TODO(scottmg): This needs to be made cross-bitness supporting. 194 template <class NtHeadersType>
177 bool PEImageReader::ReadNtHeaders(WinVMAddress* nt_headers_address, 195 bool PEImageReader::ReadNtHeaders(WinVMAddress* nt_headers_address,
178 IMAGE_NT_HEADERS* nt_headers) const { 196 NtHeadersType* nt_headers) const {
179 IMAGE_DOS_HEADER dos_header; 197 IMAGE_DOS_HEADER dos_header;
180 if (!CheckedReadMemory(Address(), sizeof(IMAGE_DOS_HEADER), &dos_header)) { 198 if (!CheckedReadMemory(Address(), sizeof(IMAGE_DOS_HEADER), &dos_header)) {
181 LOG(WARNING) << "could not read dos header of " << module_name_; 199 LOG(WARNING) << "could not read dos header of " << module_name_;
182 return false; 200 return false;
183 } 201 }
184 202
185 if (dos_header.e_magic != IMAGE_DOS_SIGNATURE) { 203 if (dos_header.e_magic != IMAGE_DOS_SIGNATURE) {
186 LOG(WARNING) << "invalid e_magic in dos header of " << module_name_; 204 LOG(WARNING) << "invalid e_magic in dos header of " << module_name_;
187 return false; 205 return false;
188 } 206 }
189 207
190 *nt_headers_address = Address() + dos_header.e_lfanew; 208 *nt_headers_address = Address() + dos_header.e_lfanew;
191 if (!CheckedReadMemory( 209 if (!CheckedReadMemory(
192 *nt_headers_address, sizeof(IMAGE_NT_HEADERS), nt_headers)) { 210 *nt_headers_address, sizeof(NtHeadersType), nt_headers)) {
193 LOG(WARNING) << "could not read nt headers of " << module_name_; 211 LOG(WARNING) << "could not read nt headers of " << module_name_;
194 return false; 212 return false;
195 } 213 }
196 214
197 if (nt_headers->Signature != IMAGE_NT_SIGNATURE) { 215 if (nt_headers->Signature != IMAGE_NT_SIGNATURE) {
198 LOG(WARNING) << "invalid signature in nt headers of " << module_name_; 216 LOG(WARNING) << "invalid signature in nt headers of " << module_name_;
199 return false; 217 return false;
200 } 218 }
201 219
202 return true; 220 return true;
203 } 221 }
204 222
223 template <class NtHeadersType>
205 bool PEImageReader::GetSectionByName(const std::string& name, 224 bool PEImageReader::GetSectionByName(const std::string& name,
206 IMAGE_SECTION_HEADER* section) const { 225 IMAGE_SECTION_HEADER* section) const {
207 if (name.size() > sizeof(section->Name)) { 226 if (name.size() > sizeof(section->Name)) {
208 LOG(WARNING) << "supplied section name too long " << name; 227 LOG(WARNING) << "supplied section name too long " << name;
209 return false; 228 return false;
210 } 229 }
211 230
212 WinVMAddress nt_headers_address; 231 WinVMAddress nt_headers_address;
213 IMAGE_NT_HEADERS nt_headers; 232 NtHeadersType nt_headers;
214 if (!ReadNtHeaders(&nt_headers_address, &nt_headers)) 233 if (!ReadNtHeaders(&nt_headers_address, &nt_headers))
215 return false; 234 return false;
216 235
217 WinVMAddress first_section_address = 236 WinVMAddress first_section_address =
218 nt_headers_address + offsetof(IMAGE_NT_HEADERS, OptionalHeader) + 237 nt_headers_address + offsetof(NtHeadersType, OptionalHeader) +
219 nt_headers.FileHeader.SizeOfOptionalHeader; 238 nt_headers.FileHeader.SizeOfOptionalHeader;
220 for (DWORD i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) { 239 for (DWORD i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) {
221 WinVMAddress section_address = 240 WinVMAddress section_address =
222 first_section_address + sizeof(IMAGE_SECTION_HEADER) * i; 241 first_section_address + sizeof(IMAGE_SECTION_HEADER) * i;
223 if (!CheckedReadMemory( 242 if (!CheckedReadMemory(
224 section_address, sizeof(IMAGE_SECTION_HEADER), section)) { 243 section_address, sizeof(IMAGE_SECTION_HEADER), section)) {
225 LOG(WARNING) << "could not read section " << i << " of " << module_name_; 244 LOG(WARNING) << "could not read section " << i << " of " << module_name_;
226 return false; 245 return false;
227 } 246 }
228 if (strncmp(reinterpret_cast<const char*>(section->Name), 247 if (strncmp(reinterpret_cast<const char*>(section->Name),
(...skipping 16 matching lines...) Expand all
245 } 264 }
246 if (!module_range_.ContainsRange(read_range)) { 265 if (!module_range_.ContainsRange(read_range)) {
247 LOG(WARNING) << "attempt to read outside of module " << module_name_ 266 LOG(WARNING) << "attempt to read outside of module " << module_name_
248 << " at range: " << RangeToString(read_range); 267 << " at range: " << RangeToString(read_range);
249 return false; 268 return false;
250 } 269 }
251 return process_reader_->ReadMemory(address, size, into); 270 return process_reader_->ReadMemory(address, size, into);
252 } 271 }
253 272
254 } // namespace crashpad 273 } // namespace crashpad
OLDNEW
« no previous file with comments | « snapshot/win/pe_image_reader.h ('k') | snapshot/win/process_snapshot_win_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698