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

Side by Side Diff: courgette/disassembler_win32_x86.cc

Issue 1676683002: [Courgette] Clean up Disassembler; fix ELF Memory leaks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sync. Created 4 years, 9 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 (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "courgette/disassembler_win32_x86.h" 5 #include "courgette/disassembler_win32_x86.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <string> 11 #include <iostream>
12 #include <vector>
13 12
14 #include "base/logging.h" 13 #include "base/logging.h"
15
16 #include "courgette/assembly_program.h" 14 #include "courgette/assembly_program.h"
17 #include "courgette/courgette.h" 15 #include "courgette/courgette.h"
18 #include "courgette/encoded_program.h"
19 #include "courgette/rel32_finder_win32_x86.h" 16 #include "courgette/rel32_finder_win32_x86.h"
20 17
21 namespace courgette { 18 namespace courgette {
22 19
23 DisassemblerWin32X86::DisassemblerWin32X86(const void* start, size_t length) 20 DisassemblerWin32X86::DisassemblerWin32X86(const void* start, size_t length)
24 : Disassembler(start, length), 21 : Disassembler(start, length),
25 incomplete_disassembly_(false), 22 incomplete_disassembly_(false),
26 is_PE32_plus_(false), 23 is_PE32_plus_(false),
27 optional_header_(NULL), 24 optional_header_(nullptr),
28 size_of_optional_header_(0), 25 size_of_optional_header_(0),
29 offset_of_data_directories_(0), 26 offset_of_data_directories_(0),
30 machine_type_(0), 27 machine_type_(0),
31 number_of_sections_(0), 28 number_of_sections_(0),
32 sections_(NULL), 29 sections_(nullptr),
33 has_text_section_(false), 30 has_text_section_(false),
34 size_of_code_(0), 31 size_of_code_(0),
35 size_of_initialized_data_(0), 32 size_of_initialized_data_(0),
36 size_of_uninitialized_data_(0), 33 size_of_uninitialized_data_(0),
37 base_of_code_(0), 34 base_of_code_(0),
38 base_of_data_(0), 35 base_of_data_(0),
39 image_base_(0), 36 image_base_(0),
40 size_of_image_(0), 37 size_of_image_(0),
41 number_of_data_directories_(0) { 38 number_of_data_directories_(0) {
42 } 39 }
43 40
41 FileOffset DisassemblerWin32X86::RVAToFileOffset(RVA rva) const {
42 const Section* section = RVAToSection(rva);
43 if (section != nullptr) {
44 uint32_t offset_in_section = rva - section->virtual_address;
45 // Need this extra check, since an |rva| may be valid for a section, but is
46 // non-existent in an image (e.g. uninit data).
47 if (offset_in_section >= section->size_of_raw_data)
48 return kNoFileOffset;
49
50 return static_cast<FileOffset>(
51 section->file_offset_of_raw_data + offset_in_section);
52 }
53
54 // Small RVA values point into the file header in the loaded image.
55 // RVA 0 is the module load address which Windows uses as the module handle.
56 // RVA 2 sometimes occurs, I'm not sure what it is, but it would map into the
57 // DOS header.
58 if (rva == 0 || rva == 2)
59 return static_cast<FileOffset>(rva);
60
61 NOTREACHED();
62 return kNoFileOffset;
63 }
64
65 RVA DisassemblerWin32X86::FileOffsetToRVA(FileOffset file_offset) const {
66 for (int i = 0; i < number_of_sections_; ++i) {
67 const Section* section = &sections_[i];
68 if (file_offset >= section->file_offset_of_raw_data) {
69 uint32_t offset_in_section =
70 file_offset - section->file_offset_of_raw_data;
71 if (offset_in_section < section->size_of_raw_data)
72 return static_cast<RVA>(section->virtual_address + offset_in_section);
73 }
74 }
75
76 NOTREACHED();
77 return kNoRVA;
78 }
79
44 // ParseHeader attempts to match up the buffer with the Windows data 80 // ParseHeader attempts to match up the buffer with the Windows data
45 // structures that exist within a Windows 'Portable Executable' format file. 81 // structures that exist within a Windows 'Portable Executable' format file.
46 // Returns 'true' if the buffer matches, and 'false' if the data looks 82 // Returns 'true' if the buffer matches, and 'false' if the data looks
47 // suspicious. Rather than try to 'map' the buffer to the numerous windows 83 // suspicious. Rather than try to 'map' the buffer to the numerous windows
48 // structures, we extract the information we need into the courgette::PEInfo 84 // structures, we extract the information we need into the courgette::PEInfo
49 // structure. 85 // structure.
50 // 86 //
51 bool DisassemblerWin32X86::ParseHeader() { 87 bool DisassemblerWin32X86::ParseHeader() {
52 if (length() < kOffsetOfFileAddressOfNewExeHeader + 4 /*size*/) 88 if (length() < kOffsetOfFileAddressOfNewExeHeader + 4 /*size*/)
53 return Bad("Too small"); 89 return Bad("Too small");
54 90
55 // Have 'MZ' magic for a DOS header? 91 // Have 'MZ' magic for a DOS header?
56 if (start()[0] != 'M' || start()[1] != 'Z') 92 if (start()[0] != 'M' || start()[1] != 'Z')
57 return Bad("Not MZ"); 93 return Bad("Not MZ");
58 94
59 // offset from DOS header to PE header is stored in DOS header. 95 // offset from DOS header to PE header is stored in DOS header.
60 uint32_t offset = ReadU32(start(), kOffsetOfFileAddressOfNewExeHeader); 96 FileOffset file_offset = static_cast<FileOffset>(
97 ReadU32(start(), kOffsetOfFileAddressOfNewExeHeader));
61 98
62 if (offset >= length()) 99 if (file_offset >= length())
63 return Bad("Bad offset to PE header"); 100 return Bad("Bad offset to PE header");
64 101
65 const uint8_t* const pe_header = OffsetToPointer(offset); 102 const uint8_t* const pe_header = FileOffsetToPointer(file_offset);
66 const size_t kMinPEHeaderSize = 4 /*signature*/ + kSizeOfCoffHeader; 103 const size_t kMinPEHeaderSize = 4 /*signature*/ + kSizeOfCoffHeader;
67 if (pe_header <= start() || 104 if (pe_header <= start() ||
68 pe_header >= end() - kMinPEHeaderSize) 105 pe_header >= end() - kMinPEHeaderSize)
69 return Bad("Bad offset to PE header"); 106 return Bad("Bad file offset to PE header");
70 107
71 if (offset % 8 != 0) 108 if (file_offset % 8 != 0)
72 return Bad("Misaligned PE header"); 109 return Bad("Misaligned PE header");
73 110
74 // The 'PE' header is an IMAGE_NT_HEADERS structure as defined in WINNT.H. 111 // The 'PE' header is an IMAGE_NT_HEADERS structure as defined in WINNT.H.
75 // See http://msdn.microsoft.com/en-us/library/ms680336(VS.85).aspx 112 // See http://msdn.microsoft.com/en-us/library/ms680336(VS.85).aspx
76 // 113 //
77 // The first field of the IMAGE_NT_HEADERS is the signature. 114 // The first field of the IMAGE_NT_HEADERS is the signature.
78 if (!(pe_header[0] == 'P' && 115 if (!(pe_header[0] == 'P' &&
79 pe_header[1] == 'E' && 116 pe_header[1] == 'E' &&
80 pe_header[2] == 0 && 117 pe_header[2] == 0 &&
81 pe_header[3] == 0)) 118 pe_header[3] == 0))
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 if (!b) { 199 if (!b) {
163 return Bad("malformed data directory"); 200 return Bad("malformed data directory");
164 } 201 }
165 202
166 // Sections follow the optional header. 203 // Sections follow the optional header.
167 sections_ = 204 sections_ =
168 reinterpret_cast<const Section*>(optional_header + 205 reinterpret_cast<const Section*>(optional_header +
169 size_of_optional_header_); 206 size_of_optional_header_);
170 size_t detected_length = 0; 207 size_t detected_length = 0;
171 208
172 for (int i = 0; i < number_of_sections_; ++i) { 209 for (int i = 0; i < number_of_sections_; ++i) {
173 const Section* section = &sections_[i]; 210 const Section* section = &sections_[i];
174 211
175 // TODO(sra): consider using the 'characteristics' field of the section 212 // TODO(sra): consider using the 'characteristics' field of the section
176 // header to see if the section contains instructions. 213 // header to see if the section contains instructions.
177 if (memcmp(section->name, ".text", 6) == 0) 214 if (memcmp(section->name, ".text", 6) == 0)
178 has_text_section_ = true; 215 has_text_section_ = true;
179 216
180 uint32_t section_end = 217 uint32_t section_end =
181 section->file_offset_of_raw_data + section->size_of_raw_data; 218 section->file_offset_of_raw_data + section->size_of_raw_data;
182 if (section_end > detected_length) 219 if (section_end > detected_length)
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 block += size; 323 block += size;
287 } 324 }
288 325
289 std::sort(relocs->begin(), relocs->end()); 326 std::sort(relocs->begin(), relocs->end());
290 DCHECK(relocs->empty() || relocs->back() != kUnassignedRVA); 327 DCHECK(relocs->empty() || relocs->back() != kUnassignedRVA);
291 328
292 return true; 329 return true;
293 } 330 }
294 331
295 const Section* DisassemblerWin32X86::RVAToSection(RVA rva) const { 332 const Section* DisassemblerWin32X86::RVAToSection(RVA rva) const {
296 for (int i = 0; i < number_of_sections_; i++) { 333 for (int i = 0; i < number_of_sections_; ++i) {
297 const Section* section = &sections_[i]; 334 const Section* section = &sections_[i];
298 uint32_t offset = rva - section->virtual_address; 335 if (rva >= section->virtual_address) {
299 if (offset < section->virtual_size) { 336 uint32_t offset_in_section = rva - section->virtual_address;
300 return section; 337 if (offset_in_section < section->virtual_size)
338 return section;
301 } 339 }
302 } 340 }
303 return NULL; 341 return nullptr;
304 }
305
306 int DisassemblerWin32X86::RVAToFileOffset(RVA rva) const {
307 const Section* section = RVAToSection(rva);
308 if (section) {
309 uint32_t offset = rva - section->virtual_address;
310 if (offset < section->size_of_raw_data) {
311 return section->file_offset_of_raw_data + offset;
312 } else {
313 return kNoOffset; // In section but not in file (e.g. uninit data).
314 }
315 }
316
317 // Small RVA values point into the file header in the loaded image.
318 // RVA 0 is the module load address which Windows uses as the module handle.
319 // RVA 2 sometimes occurs, I'm not sure what it is, but it would map into the
320 // DOS header.
321 if (rva == 0 || rva == 2)
322 return rva;
323
324 NOTREACHED();
325 return kNoOffset;
326 }
327
328 const uint8_t* DisassemblerWin32X86::RVAToPointer(RVA rva) const {
329 int file_offset = RVAToFileOffset(rva);
330 if (file_offset == kNoOffset)
331 return NULL;
332 else
333 return OffsetToPointer(file_offset);
334 } 342 }
335 343
336 std::string DisassemblerWin32X86::SectionName(const Section* section) { 344 std::string DisassemblerWin32X86::SectionName(const Section* section) {
337 if (section == NULL) 345 if (section == nullptr)
338 return "<none>"; 346 return "<none>";
339 char name[9]; 347 char name[9];
340 memcpy(name, section->name, 8); 348 memcpy(name, section->name, 8);
341 name[8] = '\0'; // Ensure termination. 349 name[8] = '\0'; // Ensure termination.
342 return name; 350 return name;
343 } 351 }
344 352
345 CheckBool DisassemblerWin32X86::ParseFile(AssemblyProgram* program) { 353 CheckBool DisassemblerWin32X86::ParseFile(AssemblyProgram* program) {
346 // Walk all the bytes in the file, whether or not in a section. 354 // Walk all the bytes in the file, whether or not in a section.
347 uint32_t file_offset = 0; 355 FileOffset file_offset = 0;
348 while (file_offset < length()) { 356 while (file_offset < length()) {
349 const Section* section = FindNextSection(file_offset); 357 const Section* section = FindNextSection(file_offset);
350 if (section == NULL) { 358 if (section == nullptr) {
351 // No more sections. There should not be extra stuff following last 359 // No more sections. There should not be extra stuff following last
352 // section. 360 // section.
353 // ParseNonSectionFileRegion(file_offset, pe_info().length(), program); 361 // ParseNonSectionFileRegion(file_offset, pe_info().length(), program);
354 break; 362 break;
355 } 363 }
356 if (file_offset < section->file_offset_of_raw_data) { 364 if (file_offset < section->file_offset_of_raw_data) {
357 uint32_t section_start_offset = section->file_offset_of_raw_data; 365 FileOffset section_start_offset = section->file_offset_of_raw_data;
358 if(!ParseNonSectionFileRegion(file_offset, section_start_offset, 366 if(!ParseNonSectionFileRegion(file_offset, section_start_offset,
359 program)) 367 program)) {
360 return false; 368 return false;
369 }
361 370
362 file_offset = section_start_offset; 371 file_offset = section_start_offset;
363 } 372 }
364 uint32_t end = file_offset + section->size_of_raw_data; 373 FileOffset end = file_offset + section->size_of_raw_data;
365 if (!ParseFileRegion(section, file_offset, end, program)) 374 if (!ParseFileRegion(section, file_offset, end, program))
366 return false; 375 return false;
367 file_offset = end; 376 file_offset = end;
368 } 377 }
369 378
370 #if COURGETTE_HISTOGRAM_TARGETS 379 #if COURGETTE_HISTOGRAM_TARGETS
371 HistogramTargets("abs32 relocs", abs32_target_rvas_); 380 HistogramTargets("abs32 relocs", abs32_target_rvas_);
372 HistogramTargets("rel32 relocs", rel32_target_rvas_); 381 HistogramTargets("rel32 relocs", rel32_target_rvas_);
373 #endif 382 #endif
374 383
375 return true; 384 return true;
376 } 385 }
377 386
378 bool DisassemblerWin32X86::ParseAbs32Relocs() { 387 bool DisassemblerWin32X86::ParseAbs32Relocs() {
379 abs32_locations_.clear(); 388 abs32_locations_.clear();
380 if (!ParseRelocs(&abs32_locations_)) 389 if (!ParseRelocs(&abs32_locations_))
381 return false; 390 return false;
382 391
383 #if COURGETTE_HISTOGRAM_TARGETS 392 #if COURGETTE_HISTOGRAM_TARGETS
384 for (size_t i = 0; i < abs32_locations_.size(); ++i) { 393 for (size_t i = 0; i < abs32_locations_.size(); ++i) {
385 RVA rva = abs32_locations_[i]; 394 RVA rva = abs32_locations_[i];
386 // The 4 bytes at the relocation are a reference to some address. 395 // The 4 bytes at the relocation are a reference to some address.
387 uint32_t target_address = Read32LittleEndian(RVAToPointer(rva)); 396 uint32_t target_address = Read32LittleEndian(RVAToPointer(rva));
388 ++abs32_target_rvas_[target_address - image_base()]; 397 ++abs32_target_rvas_[target_address - image_base()];
389 } 398 }
390 #endif 399 #endif
391 return true; 400 return true;
392 } 401 }
393 402
394 void DisassemblerWin32X86::ParseRel32RelocsFromSections() { 403 void DisassemblerWin32X86::ParseRel32RelocsFromSections() {
395 uint32_t file_offset = 0; 404 uint32_t file_offset = 0;
396 while (file_offset < length()) { 405 while (file_offset < length()) {
397 const Section* section = FindNextSection(file_offset); 406 const Section* section = FindNextSection(file_offset);
398 if (section == NULL) 407 if (section == nullptr)
399 break; 408 break;
400 if (file_offset < section->file_offset_of_raw_data) 409 if (file_offset < section->file_offset_of_raw_data)
401 file_offset = section->file_offset_of_raw_data; 410 file_offset = section->file_offset_of_raw_data;
402 ParseRel32RelocsFromSection(section); 411 ParseRel32RelocsFromSection(section);
403 file_offset += section->size_of_raw_data; 412 file_offset += section->size_of_raw_data;
404 } 413 }
405 std::sort(rel32_locations_.begin(), rel32_locations_.end()); 414 std::sort(rel32_locations_.begin(), rel32_locations_.end());
406 DCHECK(rel32_locations_.empty() || 415 DCHECK(rel32_locations_.empty() ||
407 rel32_locations_.back() != kUnassignedRVA); 416 rel32_locations_.back() != kUnassignedRVA);
408 417
409 #if COURGETTE_HISTOGRAM_TARGETS 418 #if COURGETTE_HISTOGRAM_TARGETS
410 VLOG(1) << "abs32_locations_ " << abs32_locations_.size() 419 VLOG(1) << "abs32_locations_ " << abs32_locations_.size()
411 << "\nrel32_locations_ " << rel32_locations_.size() 420 << "\nrel32_locations_ " << rel32_locations_.size()
412 << "\nabs32_target_rvas_ " << abs32_target_rvas_.size() 421 << "\nabs32_target_rvas_ " << abs32_target_rvas_.size()
413 << "\nrel32_target_rvas_ " << rel32_target_rvas_.size(); 422 << "\nrel32_target_rvas_ " << rel32_target_rvas_.size();
414 423
415 int common = 0; 424 int common = 0;
416 std::map<RVA, int>::iterator abs32_iter = abs32_target_rvas_.begin(); 425 std::map<RVA, int>::iterator abs32_iter = abs32_target_rvas_.begin();
417 std::map<RVA, int>::iterator rel32_iter = rel32_target_rvas_.begin(); 426 std::map<RVA, int>::iterator rel32_iter = rel32_target_rvas_.begin();
418 while (abs32_iter != abs32_target_rvas_.end() && 427 while (abs32_iter != abs32_target_rvas_.end() &&
419 rel32_iter != rel32_target_rvas_.end()) { 428 rel32_iter != rel32_target_rvas_.end()) {
420 if (abs32_iter->first < rel32_iter->first) 429 if (abs32_iter->first < rel32_iter->first) {
421 ++abs32_iter; 430 ++abs32_iter;
422 else if (rel32_iter->first < abs32_iter->first) 431 } else if (rel32_iter->first < abs32_iter->first) {
423 ++rel32_iter; 432 ++rel32_iter;
424 else { 433 } else {
425 ++common; 434 ++common;
426 ++abs32_iter; 435 ++abs32_iter;
427 ++rel32_iter; 436 ++rel32_iter;
428 } 437 }
429 } 438 }
430 VLOG(1) << "common " << common; 439 VLOG(1) << "common " << common;
431 #endif 440 #endif
432 } 441 }
433 442
434 void DisassemblerWin32X86::ParseRel32RelocsFromSection(const Section* section) { 443 void DisassemblerWin32X86::ParseRel32RelocsFromSection(const Section* section) {
435 // TODO(sra): use characteristic. 444 // TODO(sra): use characteristic.
436 bool isCode = strcmp(section->name, ".text") == 0; 445 bool isCode = strcmp(section->name, ".text") == 0;
437 if (!isCode) 446 if (!isCode)
438 return; 447 return;
439 448
440 uint32_t start_file_offset = section->file_offset_of_raw_data; 449 FileOffset start_file_offset = section->file_offset_of_raw_data;
441 uint32_t end_file_offset = start_file_offset + section->size_of_raw_data; 450 FileOffset end_file_offset = start_file_offset + section->size_of_raw_data;
442 451
443 const uint8_t* start_pointer = OffsetToPointer(start_file_offset); 452 const uint8_t* start_pointer = FileOffsetToPointer(start_file_offset);
444 const uint8_t* end_pointer = OffsetToPointer(end_file_offset); 453 const uint8_t* end_pointer = FileOffsetToPointer(end_file_offset);
445 454
446 RVA start_rva = FileOffsetToRVA(start_file_offset); 455 RVA start_rva = FileOffsetToRVA(start_file_offset);
447 RVA end_rva = start_rva + section->virtual_size; 456 RVA end_rva = start_rva + section->virtual_size;
448 457
449 Rel32FinderWin32X86_Basic finder( 458 Rel32FinderWin32X86_Basic finder(
450 base_relocation_table().address_, 459 base_relocation_table().address_,
451 base_relocation_table().address_ + base_relocation_table().size_, 460 base_relocation_table().address_ + base_relocation_table().size_);
452 size_of_image_);
453 finder.Find(start_pointer, end_pointer, start_rva, end_rva, abs32_locations_); 461 finder.Find(start_pointer, end_pointer, start_rva, end_rva, abs32_locations_);
454 finder.SwapRel32Locations(&rel32_locations_); 462 finder.SwapRel32Locations(&rel32_locations_);
455 463
456 #if COURGETTE_HISTOGRAM_TARGETS 464 #if COURGETTE_HISTOGRAM_TARGETS
457 DCHECK(rel32_target_rvas_.empty()); 465 DCHECK(rel32_target_rvas_.empty());
458 finder.SwapRel32TargetRVAs(&rel32_target_rvas_); 466 finder.SwapRel32TargetRVAs(&rel32_target_rvas_);
459 #endif 467 #endif
460 } 468 }
461 469
462 CheckBool DisassemblerWin32X86::ParseNonSectionFileRegion( 470 CheckBool DisassemblerWin32X86::ParseNonSectionFileRegion(
463 uint32_t start_file_offset, 471 FileOffset start_file_offset,
464 uint32_t end_file_offset, 472 FileOffset end_file_offset,
465 AssemblyProgram* program) { 473 AssemblyProgram* program) {
466 if (incomplete_disassembly_) 474 if (incomplete_disassembly_)
467 return true; 475 return true;
468 476
469 if (end_file_offset > start_file_offset) { 477 if (end_file_offset > start_file_offset) {
470 if (!program->EmitBytesInstruction(OffsetToPointer(start_file_offset), 478 if (!program->EmitBytesInstruction(FileOffsetToPointer(start_file_offset),
471 end_file_offset - start_file_offset)) { 479 end_file_offset - start_file_offset)) {
472 return false; 480 return false;
473 } 481 }
474 } 482 }
475 483
476 return true; 484 return true;
477 } 485 }
478 486
479 CheckBool DisassemblerWin32X86::ParseFileRegion(const Section* section, 487 CheckBool DisassemblerWin32X86::ParseFileRegion(const Section* section,
480 uint32_t start_file_offset, 488 FileOffset start_file_offset,
481 uint32_t end_file_offset, 489 FileOffset end_file_offset,
482 AssemblyProgram* program) { 490 AssemblyProgram* program) {
483 RVA relocs_start_rva = base_relocation_table().address_; 491 RVA relocs_start_rva = base_relocation_table().address_;
484 492
485 const uint8_t* start_pointer = OffsetToPointer(start_file_offset); 493 const uint8_t* start_pointer = FileOffsetToPointer(start_file_offset);
486 const uint8_t* end_pointer = OffsetToPointer(end_file_offset); 494 const uint8_t* end_pointer = FileOffsetToPointer(end_file_offset);
487 495
488 RVA start_rva = FileOffsetToRVA(start_file_offset); 496 RVA start_rva = FileOffsetToRVA(start_file_offset);
489 RVA end_rva = start_rva + section->virtual_size; 497 RVA end_rva = start_rva + section->virtual_size;
490 498
491 // Quick way to convert from Pointer to RVA within a single Section is to 499 // Quick way to convert from Pointer to RVA within a single Section is to
492 // subtract 'pointer_to_rva'. 500 // subtract 'pointer_to_rva'.
493 const uint8_t* const adjust_pointer_to_rva = start_pointer - start_rva; 501 const uint8_t* const adjust_pointer_to_rva = start_pointer - start_rva;
494 502
495 std::vector<RVA>::iterator rel32_pos = rel32_locations_.begin(); 503 std::vector<RVA>::iterator rel32_pos = rel32_locations_.begin();
496 std::vector<RVA>::iterator abs32_pos = abs32_locations_.begin(); 504 std::vector<RVA>::iterator abs32_pos = abs32_locations_.begin();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 p != h.rend(); 593 p != h.rend();
586 ++p) { 594 ++p) {
587 ++index; 595 ++index;
588 if (index <= kFirstN || p->first <= 3) { 596 if (index <= kFirstN || p->first <= 3) {
589 if (someSkipped) { 597 if (someSkipped) {
590 std::cout << "..." << std::endl; 598 std::cout << "..." << std::endl;
591 } 599 }
592 size_t count = p->second.size(); 600 size_t count = p->second.size();
593 std::cout << std::dec << p->first << ": " << count; 601 std::cout << std::dec << p->first << ": " << count;
594 if (count <= 2) { 602 if (count <= 2) {
595 for (size_t i = 0; i < count; ++i) 603 for (size_t i = 0; i < count; ++i)
596 std::cout << " " << DescribeRVA(p->second[i]); 604 std::cout << " " << DescribeRVA(p->second[i]);
597 } 605 }
598 std::cout << std::endl; 606 std::cout << std::endl;
599 someSkipped = false; 607 someSkipped = false;
600 } else { 608 } else {
601 someSkipped = true; 609 someSkipped = true;
602 } 610 }
603 } 611 }
604 } 612 }
605 #endif // COURGETTE_HISTOGRAM_TARGETS 613 #endif // COURGETTE_HISTOGRAM_TARGETS
606 614
607
608 // DescribeRVA is for debugging only. I would put it under #ifdef DEBUG except 615 // DescribeRVA is for debugging only. I would put it under #ifdef DEBUG except
609 // that during development I'm finding I need to call it when compiled in 616 // that during development I'm finding I need to call it when compiled in
610 // Release mode. Hence: 617 // Release mode. Hence:
611 // TODO(sra): make this compile only for debug mode. 618 // TODO(sra): make this compile only for debug mode.
612 std::string DisassemblerWin32X86::DescribeRVA(RVA rva) const { 619 std::string DisassemblerWin32X86::DescribeRVA(RVA rva) const {
613 const Section* section = RVAToSection(rva); 620 const Section* section = RVAToSection(rva);
614 std::ostringstream s; 621 std::ostringstream s;
615 s << std::hex << rva; 622 s << std::hex << rva;
616 if (section) { 623 if (section) {
617 s << " ("; 624 s << " (";
618 s << SectionName(section) << "+" 625 s << SectionName(section) << "+"
619 << std::hex << (rva - section->virtual_address) 626 << std::hex << (rva - section->virtual_address)
620 << ")"; 627 << ")";
621 } 628 }
622 return s.str(); 629 return s.str();
623 } 630 }
624 631
625 const Section* DisassemblerWin32X86::FindNextSection( 632 const Section* DisassemblerWin32X86::FindNextSection(
626 uint32_t fileOffset) const { 633 FileOffset file_offset) const {
627 const Section* best = 0; 634 const Section* best = 0;
628 for (int i = 0; i < number_of_sections_; i++) { 635 for (int i = 0; i < number_of_sections_; ++i) {
629 const Section* section = &sections_[i]; 636 const Section* section = &sections_[i];
630 if (section->size_of_raw_data > 0) { // i.e. has data in file. 637 if (section->size_of_raw_data > 0) { // i.e. has data in file.
631 if (fileOffset <= section->file_offset_of_raw_data) { 638 if (file_offset <= section->file_offset_of_raw_data) {
632 if (best == 0 || 639 if (best == 0 ||
633 section->file_offset_of_raw_data < best->file_offset_of_raw_data) { 640 section->file_offset_of_raw_data < best->file_offset_of_raw_data) {
634 best = section; 641 best = section;
635 } 642 }
636 } 643 }
637 } 644 }
638 } 645 }
639 return best; 646 return best;
640 } 647 }
641 648
642 RVA DisassemblerWin32X86::FileOffsetToRVA(uint32_t file_offset) const {
643 for (int i = 0; i < number_of_sections_; i++) {
644 const Section* section = &sections_[i];
645 uint32_t offset = file_offset - section->file_offset_of_raw_data;
646 if (offset < section->size_of_raw_data) {
647 return section->virtual_address + offset;
648 }
649 }
650 return 0;
651 }
652
653 bool DisassemblerWin32X86::ReadDataDirectory( 649 bool DisassemblerWin32X86::ReadDataDirectory(
654 int index, 650 int index,
655 ImageDataDirectory* directory) { 651 ImageDataDirectory* directory) {
656 652
657 if (index < number_of_data_directories_) { 653 if (index < number_of_data_directories_) {
658 size_t offset = index * 8 + offset_of_data_directories_; 654 FileOffset file_offset = index * 8 + offset_of_data_directories_;
659 if (offset >= size_of_optional_header_) 655 if (file_offset >= size_of_optional_header_)
660 return Bad("number of data directories inconsistent"); 656 return Bad("number of data directories inconsistent");
661 const uint8_t* data_directory = optional_header_ + offset; 657 const uint8_t* data_directory = optional_header_ + file_offset;
662 if (data_directory < start() || 658 if (data_directory < start() ||
663 data_directory + 8 >= end()) 659 data_directory + 8 >= end())
664 return Bad("data directory outside image"); 660 return Bad("data directory outside image");
665 RVA rva = ReadU32(data_directory, 0); 661 RVA rva = ReadU32(data_directory, 0);
666 size_t size = ReadU32(data_directory, 4); 662 size_t size = ReadU32(data_directory, 4);
667 if (size > size_of_image_) 663 if (size > size_of_image_)
668 return Bad("data directory size too big"); 664 return Bad("data directory size too big");
669 665
670 // TODO(sra): validate RVA. 666 // TODO(sra): validate RVA.
671 directory->address_ = rva; 667 directory->address_ = rva;
672 directory->size_ = static_cast<uint32_t>(size); 668 directory->size_ = static_cast<uint32_t>(size);
673 return true; 669 return true;
674 } else { 670 } else {
675 directory->address_ = 0; 671 directory->address_ = 0;
676 directory->size_ = 0; 672 directory->size_ = 0;
677 return true; 673 return true;
678 } 674 }
679 } 675 }
680 676
681 } // namespace courgette 677 } // namespace courgette
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698