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

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

Issue 1360863006: win: Add more memory regions to gathering of PEB (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@save-peb
Patch Set: determine size of envblock Created 5 years, 2 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/process_snapshot_win.h ('k') | no next file » | 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,
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/process_snapshot_win.h" 15 #include "snapshot/win/process_snapshot_win.h"
16 16
17 #include <algorithm>
18
17 #include "base/logging.h" 19 #include "base/logging.h"
18 #include "snapshot/win/module_snapshot_win.h" 20 #include "snapshot/win/module_snapshot_win.h"
19 #include "util/win/registration_protocol_win.h" 21 #include "util/win/registration_protocol_win.h"
20 #include "util/win/time.h" 22 #include "util/win/time.h"
21 23
22 namespace crashpad { 24 namespace crashpad {
23 25
24 ProcessSnapshotWin::ProcessSnapshotWin() 26 ProcessSnapshotWin::ProcessSnapshotWin()
25 : ProcessSnapshot(), 27 : ProcessSnapshot(),
26 system_(), 28 system_(),
(...skipping 14 matching lines...) Expand all
41 bool ProcessSnapshotWin::Initialize(HANDLE process, 43 bool ProcessSnapshotWin::Initialize(HANDLE process,
42 ProcessSuspensionState suspension_state) { 44 ProcessSuspensionState suspension_state) {
43 INITIALIZATION_STATE_SET_INITIALIZING(initialized_); 45 INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
44 46
45 GetTimeOfDay(&snapshot_time_); 47 GetTimeOfDay(&snapshot_time_);
46 48
47 if (!process_reader_.Initialize(process, suspension_state)) 49 if (!process_reader_.Initialize(process, suspension_state))
48 return false; 50 return false;
49 51
50 system_.Initialize(&process_reader_); 52 system_.Initialize(&process_reader_);
51 WinVMAddress peb_address; 53
52 WinVMSize peb_size; 54 if (process_reader_.Is64Bit())
53 process_reader_.GetProcessInfo().Peb(&peb_address, &peb_size); 55 InitializePebData<process_types::internal::Traits64>();
54 peb_.Initialize(&process_reader_, peb_address, peb_size); 56 else
57 InitializePebData<process_types::internal::Traits32>();
55 58
56 InitializeThreads(); 59 InitializeThreads();
57 InitializeModules(); 60 InitializeModules();
58 61
59 INITIALIZATION_STATE_SET_VALID(initialized_); 62 INITIALIZATION_STATE_SET_VALID(initialized_);
60 return true; 63 return true;
61 } 64 }
62 65
63 bool ProcessSnapshotWin::InitializeException( 66 bool ProcessSnapshotWin::InitializeException(
64 WinVMAddress exception_information_address) { 67 WinVMAddress exception_information_address) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 return modules; 182 return modules;
180 } 183 }
181 184
182 const ExceptionSnapshot* ProcessSnapshotWin::Exception() const { 185 const ExceptionSnapshot* ProcessSnapshotWin::Exception() const {
183 return exception_.get(); 186 return exception_.get();
184 } 187 }
185 188
186 std::vector<const MemorySnapshot*> ProcessSnapshotWin::ExtraMemory() const { 189 std::vector<const MemorySnapshot*> ProcessSnapshotWin::ExtraMemory() const {
187 INITIALIZATION_STATE_DCHECK_VALID(initialized_); 190 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
188 std::vector<const MemorySnapshot*> extra_memory; 191 std::vector<const MemorySnapshot*> extra_memory;
189 extra_memory.push_back(&peb_); 192 for (const auto& peb_memory : peb_memory_)
193 extra_memory.push_back(peb_memory);
190 return extra_memory; 194 return extra_memory;
191 } 195 }
192 196
193 void ProcessSnapshotWin::InitializeThreads() { 197 void ProcessSnapshotWin::InitializeThreads() {
194 const std::vector<ProcessReaderWin::Thread>& process_reader_threads = 198 const std::vector<ProcessReaderWin::Thread>& process_reader_threads =
195 process_reader_.Threads(); 199 process_reader_.Threads();
196 for (const ProcessReaderWin::Thread& process_reader_thread : 200 for (const ProcessReaderWin::Thread& process_reader_thread :
197 process_reader_threads) { 201 process_reader_threads) {
198 auto thread = make_scoped_ptr(new internal::ThreadSnapshotWin()); 202 auto thread = make_scoped_ptr(new internal::ThreadSnapshotWin());
199 if (thread->Initialize(&process_reader_, process_reader_thread)) { 203 if (thread->Initialize(&process_reader_, process_reader_thread)) {
200 threads_.push_back(thread.release()); 204 threads_.push_back(thread.release());
201 } 205 }
202 } 206 }
203 } 207 }
204 208
205 void ProcessSnapshotWin::InitializeModules() { 209 void ProcessSnapshotWin::InitializeModules() {
206 const std::vector<ProcessInfo::Module>& process_reader_modules = 210 const std::vector<ProcessInfo::Module>& process_reader_modules =
207 process_reader_.Modules(); 211 process_reader_.Modules();
208 for (const ProcessInfo::Module& process_reader_module : 212 for (const ProcessInfo::Module& process_reader_module :
209 process_reader_modules) { 213 process_reader_modules) {
210 auto module = make_scoped_ptr(new internal::ModuleSnapshotWin()); 214 auto module = make_scoped_ptr(new internal::ModuleSnapshotWin());
211 if (module->Initialize(&process_reader_, process_reader_module)) { 215 if (module->Initialize(&process_reader_, process_reader_module)) {
212 modules_.push_back(module.release()); 216 modules_.push_back(module.release());
213 } 217 }
214 } 218 }
215 } 219 }
216 220
221 template <class Traits>
222 void ProcessSnapshotWin::InitializePebData() {
223 WinVMAddress peb_address;
224 WinVMSize peb_size;
225 process_reader_.GetProcessInfo().Peb(&peb_address, &peb_size);
226 AddMemorySnapshot(peb_address, peb_size, &peb_memory_);
227
228 process_types::PEB<Traits> peb_data;
229 if (!process_reader_.ReadMemory(peb_address, peb_size, &peb_data)) {
230 LOG(ERROR) << "ReadMemory PEB";
231 return;
232 }
233 AddMemorySnapshot(
234 peb_data.Ldr, sizeof(process_types::PEB_LDR_DATA<Traits>), &peb_memory_);
235
236 process_types::RTL_USER_PROCESS_PARAMETERS<Traits> process_parameters;
237 if (!process_reader_.ReadMemory(peb_data.ProcessParameters,
238 sizeof(process_parameters),
239 &process_parameters)) {
240 LOG(ERROR) << "ReadMemory RTL_USER_PROCESS_PARAMETERS";
241 return;
242 }
243
244 AddMemorySnapshotForUNICODE_STRING(
245 process_parameters.CurrentDirectory.DosPath, &peb_memory_);
246 AddMemorySnapshotForUNICODE_STRING(process_parameters.DllPath, &peb_memory_);
247 AddMemorySnapshotForUNICODE_STRING(process_parameters.ImagePathName,
248 &peb_memory_);
249 AddMemorySnapshotForUNICODE_STRING(process_parameters.CommandLine,
250 &peb_memory_);
251
252 AddMemorySnapshot(
253 process_parameters.Environment,
254 DetermineSizeOfEnvironmentBlock(process_parameters.Environment),
255 &peb_memory_);
256 }
257
258 void ProcessSnapshotWin::AddMemorySnapshot(
259 WinVMAddress address,
260 WinVMSize size,
261 PointerVector<internal::MemorySnapshotWin>* into) {
262 if (size == 0)
263 return;
264 internal::MemorySnapshotWin* memory_snapshot =
265 new internal::MemorySnapshotWin();
266 memory_snapshot->Initialize(&process_reader_, address, size);
267 into->push_back(memory_snapshot);
268 }
269
270 template <class Traits>
271 void ProcessSnapshotWin::AddMemorySnapshotForUNICODE_STRING(
272 const process_types::UNICODE_STRING<Traits>& us,
273 PointerVector<internal::MemorySnapshotWin>* into) {
274 AddMemorySnapshot(us.Buffer, us.Length, into);
275 }
276
277 WinVMSize ProcessSnapshotWin::DetermineSizeOfEnvironmentBlock(
278 WinVMAddress start_of_environment_block) {
279 // http://blogs.msdn.com/b/oldnewthing/archive/2010/02/03/9957320.aspx On
280 // newer OSs there's no stated limit, but in practice grabbing 32k characters
281 // should be more than enough.
282 int env_block_size = 32768;
283 scoped_ptr<wchar_t[]> env_block(new wchar_t[env_block_size]);
284 while (env_block_size > 0) {
285 if (process_reader_.ReadMemory(start_of_environment_block,
286 env_block_size * sizeof(wchar_t),
Mark Mentovai 2015/09/26 01:46:48 sizeof(env_block[0])
scottmg 2015/09/28 22:38:09 Done.
287 env_block.get())) {
288 break;
289 }
290 // We could be out of range of the process so the read might
Mark Mentovai 2015/09/26 01:46:48 TODO to revisit this with a more generic “read as
scottmg 2015/09/28 22:38:09 Uses the memory map-aware read now.
291 // fail. Decrease by a bit and try again.
292 env_block_size -= 1024;
293 }
294 if (env_block_size > 0) {
295 std::wstring look_in(&env_block[0], env_block_size);
Mark Mentovai 2015/09/26 01:46:48 Since you’re just copying the whole thing into loo
scottmg 2015/09/28 22:38:09 Done.
296 const wchar_t terminator[] = { 0, 0 };
297 size_t at = look_in.find(std::wstring(terminator, arraysize(terminator)));
298 if (at != std::wstring::npos)
299 env_block_size = static_cast<int>(at) + arraysize(terminator);
300 // If we didn't find a terminator, then just add the whole (presumably
301 // partial) block.
302 return env_block_size * sizeof(wchar_t);
303 }
304
305 return 0;
306 }
307
217 } // namespace crashpad 308 } // namespace crashpad
OLDNEW
« no previous file with comments | « snapshot/win/process_snapshot_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698