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 3 // found in the LICENSE file. 4 5 #ifndef COURGETTE_DISASSEMBLER_H_ 6 #define COURGETTE_DISASSEMBLER_H_ 7 8 #include "base/basictypes.h" 9 10 #include "courgette/courgette.h" 11 12 // COURGETTE_HISTOGRAM_TARGETS prints out a histogram of how frequently 13 // different target addresses are referenced. Purely for debugging. 14 #define COURGETTE_HISTOGRAM_TARGETS 0 15 16 namespace courgette { 17 18 class AssemblyProgram; 19 20 // A Relative Virtual Address is the address in the image file after it is 21 // loaded into memory relative to the image load address. 22 typedef uint32 RVA; 23 24 class Disassembler { 25 public: 26 virtual ~Disassembler(); 27 kind()28 virtual ExecutableType kind() { return EXE_UNKNOWN; } 29 30 // ok() may always be called but returns 'true' only after ParseHeader 31 // succeeds. ok()32 bool ok() const { return failure_reason_ == NULL; } 33 34 // Returns 'true' if the buffer appears to be a valid executable of the 35 // expected type. It is not required that this be called before Disassemble. 36 virtual bool ParseHeader() = 0; 37 38 // Disassembles the item passed to the factory method into the output 39 // parameter 'program'. 40 virtual bool Disassemble(AssemblyProgram* program) = 0; 41 42 // Returns the length of the source executable. May reduce after ParseHeader. length()43 size_t length() const { return length_; } start()44 const uint8* start() const { return start_; } end()45 const uint8* end() const { return end_; } 46 47 // Returns a pointer into the memory copy of the file format. 48 // FileOffsetToPointer(0) returns a pointer to the start of the file format. 49 const uint8* OffsetToPointer(size_t offset) const; 50 51 protected: 52 Disassembler(const void* start, size_t length); 53 54 bool Good(); 55 bool Bad(const char *reason); 56 57 // These helper functions avoid the need for casts in the main code. ReadU16(const uint8 * address,size_t offset)58 uint16 ReadU16(const uint8* address, size_t offset) { 59 return *reinterpret_cast<const uint16*>(address + offset); 60 } 61 ReadU32(const uint8 * address,size_t offset)62 uint32 ReadU32(const uint8* address, size_t offset) { 63 return *reinterpret_cast<const uint32*>(address + offset); 64 } 65 ReadU64(const uint8 * address,size_t offset)66 uint64 ReadU64(const uint8* address, size_t offset) { 67 return *reinterpret_cast<const uint64*>(address + offset); 68 } 69 Read32LittleEndian(const void * address)70 static uint32 Read32LittleEndian(const void* address) { 71 return *reinterpret_cast<const uint32*>(address); 72 } 73 Read16LittleEndian(const void * address)74 static uint16 Read16LittleEndian(const void* address) { 75 return *reinterpret_cast<const uint16*>(address); 76 } 77 78 // Reduce the length of the image in memory. Does not actually free 79 // (or realloc) any memory. Usually only called via ParseHeader() 80 void ReduceLength(size_t reduced_length); 81 82 private: 83 const char* failure_reason_; 84 85 // 86 // Basic information that is always valid after Construction, though 87 // ParseHeader may shorten the length if the executable is shorter than 88 // the total data. 89 // 90 size_t length_; // In current memory. 91 const uint8* start_; // In current memory, base for 'file offsets'. 92 const uint8* end_; // In current memory. 93 94 DISALLOW_COPY_AND_ASSIGN(Disassembler); 95 }; 96 97 } // namespace courgette 98 #endif // COURGETTE_DISASSEMBLER_H_ 99