1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COURGETTE_DISASSEMBLER_H_
6 #define COURGETTE_DISASSEMBLER_H_
13 #include "courgette/courgette.h"
14 #include "courgette/image_utils.h"
15 #include "courgette/instruction_utils.h"
19 class AssemblyProgram;
22 class Disassembler : public AddressTranslator {
24 // Visitor/adaptor to translate RVA to target RVA for abs32.
25 class RvaVisitor_Abs32 : public VectorRvaVisitor<RVA> {
27 RvaVisitor_Abs32(const std::vector<RVA>& rva_locations,
28 const AddressTranslator& translator);
30 RvaVisitor_Abs32(const RvaVisitor_Abs32&) = delete;
31 RvaVisitor_Abs32& operator=(const RvaVisitor_Abs32&) = delete;
33 ~RvaVisitor_Abs32() override { }
35 // VectorRvaVisitor<RVA> interfaces.
36 RVA Get() const override;
39 const AddressTranslator& translator_;
42 // Visitor/adaptor to translate RVA to target RVA for rel32.
43 class RvaVisitor_Rel32 : public VectorRvaVisitor<RVA> {
45 RvaVisitor_Rel32(const std::vector<RVA>& rva_locations,
46 const AddressTranslator& translator);
48 RvaVisitor_Rel32(const RvaVisitor_Rel32&) = delete;
49 RvaVisitor_Rel32& operator=(const RvaVisitor_Rel32&) = delete;
51 ~RvaVisitor_Rel32() override { }
53 // VectorRvaVisitor<RVA> interfaces.
54 RVA Get() const override;
57 const AddressTranslator& translator_;
60 Disassembler(const Disassembler&) = delete;
61 Disassembler& operator=(const Disassembler&) = delete;
63 virtual ~Disassembler();
65 // AddressTranslator interfaces.
66 RVA FileOffsetToRVA(FileOffset file_offset) const override = 0;
67 FileOffset RVAToFileOffset(RVA rva) const override = 0;
68 const uint8_t* FileOffsetToPointer(FileOffset file_offset) const override;
69 const uint8_t* RVAToPointer(RVA rva) const override;
70 RVA PointerToTargetRVA(const uint8_t* p) const override = 0;
72 virtual ExecutableType kind() const = 0;
74 // Returns the preferred image base address. Using uint64_t to accommodate the
75 // general case of 64-bit architectures.
76 virtual uint64_t image_base() const = 0;
78 // Extracts and stores locations of abs32 references from the image file.
79 virtual bool ExtractAbs32Locations() = 0;
81 // Extracts and stores locations of rel32 references from the image file.
82 virtual bool ExtractRel32Locations() = 0;
84 // Returns a caller-owned new RvaVisitor to iterate through abs32 target RVAs.
85 virtual RvaVisitor* CreateAbs32TargetRvaVisitor() = 0;
87 // Returns a caller-owned new RvaVisitor to iterate through rel32 target RVAs.
88 virtual RvaVisitor* CreateRel32TargetRvaVisitor() = 0;
90 // Removes unused rel32 locations (architecture-specific). This is needed
91 // because we may remove rel32 Labels along the way. As a result the matching
92 // rel32 addresses become unused. Removing them saves space.
93 virtual void RemoveUnusedRel32Locations(AssemblyProgram* program) = 0;
95 // Extracts structural data from the main image. Returns true if the image
96 // appears to be a valid executable of the expected type, or false otherwise.
97 // This needs to be called before Disassemble().
98 virtual bool ParseHeader() = 0;
100 // Extracts and stores references from the main image. Returns a new
101 // AssemblyProgram with initialized Labels, or null on failure.
102 std::unique_ptr<AssemblyProgram> CreateProgram(bool annotate);
104 // Goes through the entire program (with the help of |program|), computes all
105 // instructions, and stores them into |encoded|.
106 Status DisassembleAndEncode(AssemblyProgram* program,
107 EncodedProgram* encoded);
109 // ok() may always be called but returns true only after ParseHeader()
111 bool ok() const { return failure_reason_ == nullptr; }
113 // Returns the length of the image. May reduce after ParseHeader().
114 size_t length() const { return length_; }
115 const uint8_t* start() const { return start_; }
116 const uint8_t* end() const { return end_; }
119 Disassembler(const uint8_t* start, size_t length);
122 bool Bad(const char *reason);
124 // Returns true if the given range lies within our memory region.
125 bool IsRangeInBounds(size_t offset, size_t size) {
126 return offset <= length() && size <= length() - offset;
129 // Returns true if the given array lies within our memory region.
130 bool IsArrayInBounds(size_t offset, size_t elements, size_t element_size) {
131 return offset <= length() && elements <= (length() - offset) / element_size;
134 // Computes and stores all Labels before scanning program bytes.
135 void PrecomputeLabels(AssemblyProgram* program);
137 // Reduce the length of the image in memory. Does not actually free
138 // (or realloc) any memory. Usually only called via ParseHeader().
139 void ReduceLength(size_t reduced_length);
141 // Returns a generator that emits instructions to a given receptor. |program|
142 // is required as helper.
143 virtual InstructionGenerator GetInstructionGenerator(
144 AssemblyProgram* program) = 0;
147 const char* failure_reason_;
150 // Basic information that is always valid after construction, although
151 // ParseHeader() may shorten |length_| if the executable is shorter than the
154 size_t length_; // In current memory.
155 const uint8_t* start_; // In current memory, base for 'file offsets'.
156 const uint8_t* end_; // In current memory.
159 } // namespace courgette
161 #endif // COURGETTE_DISASSEMBLER_H_