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

Side by Side Diff: courgette/disassembler_win32_x86.cc

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

Powered by Google App Engine
This is Rietveld 408576698