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.
5 #ifndef COURGETTE_DISASSEMBLER_H_
6 #define COURGETTE_DISASSEMBLER_H_
13 #include "base/macros.h"
14 #include "courgette/courgette.h"
15 #include "courgette/image_utils.h"
16 #include "courgette/instruction_utils.h"
20 class AssemblyProgram;
23 class Disassembler : public AddressTranslator {
25 // Visitor/adaptor to translate RVA to target RVA for abs32.
26 class RvaVisitor_Abs32 : public VectorRvaVisitor<RVA> {
28 RvaVisitor_Abs32(const std::vector<RVA>& rva_locations,
29 const AddressTranslator& translator);
30 ~RvaVisitor_Abs32() override { }
32 // VectorRvaVisitor<RVA> interfaces.
33 RVA Get() const override;
36 const AddressTranslator& translator_;
38 DISALLOW_COPY_AND_ASSIGN(RvaVisitor_Abs32);
41 // Visitor/adaptor to translate RVA to target RVA for rel32.
42 class RvaVisitor_Rel32 : public VectorRvaVisitor<RVA> {
44 RvaVisitor_Rel32(const std::vector<RVA>& rva_locations,
45 const AddressTranslator& translator);
46 ~RvaVisitor_Rel32() override { }
48 // VectorRvaVisitor<RVA> interfaces.
49 RVA Get() const override;
52 const AddressTranslator& translator_;
54 DISALLOW_COPY_AND_ASSIGN(RvaVisitor_Rel32);
57 virtual ~Disassembler();
59 // AddressTranslator interfaces.
60 RVA FileOffsetToRVA(FileOffset file_offset) const override = 0;
61 FileOffset RVAToFileOffset(RVA rva) const override = 0;
62 const uint8_t* FileOffsetToPointer(FileOffset file_offset) const override;
63 const uint8_t* RVAToPointer(RVA rva) const override;
64 RVA PointerToTargetRVA(const uint8_t* p) const override = 0;
66 virtual ExecutableType kind() const = 0;
68 // Returns the preferred image base address. Using uint64_t to accommodate the
69 // general case of 64-bit architectures.
70 virtual uint64_t image_base() const = 0;
72 // Extracts and stores locations of abs32 references from the image file.
73 virtual bool ExtractAbs32Locations() = 0;
75 // Extracts and stores locations of rel32 references from the image file.
76 virtual bool ExtractRel32Locations() = 0;
78 // Returns a caller-owned new RvaVisitor to iterate through abs32 target RVAs.
79 virtual RvaVisitor* CreateAbs32TargetRvaVisitor() = 0;
81 // Returns a caller-owned new RvaVisitor to iterate through rel32 target RVAs.
82 virtual RvaVisitor* CreateRel32TargetRvaVisitor() = 0;
84 // Removes unused rel32 locations (architecture-specific). This is needed
85 // because we may remove rel32 Labels along the way. As a result the matching
86 // rel32 addresses become unused. Removing them saves space.
87 virtual void RemoveUnusedRel32Locations(AssemblyProgram* program) = 0;
89 // Extracts structural data from the main image. Returns true if the image
90 // appears to be a valid executable of the expected type, or false otherwise.
91 // This needs to be called before Disassemble().
92 virtual bool ParseHeader() = 0;
94 // Extracts and stores references from the main image. Returns a new
95 // AssemblyProgram with initialized Labels, or null on failure.
96 std::unique_ptr<AssemblyProgram> CreateProgram(bool annotate);
98 // Goes through the entire program (with the help of |program|), computes all
99 // instructions, and stores them into |encoded|.
100 Status DisassembleAndEncode(AssemblyProgram* program,
101 EncodedProgram* encoded);
103 // ok() may always be called but returns true only after ParseHeader()
105 bool ok() const { return failure_reason_ == nullptr; }
107 // Returns the length of the image. May reduce after ParseHeader().
108 size_t length() const { return length_; }
109 const uint8_t* start() const { return start_; }
110 const uint8_t* end() const { return end_; }
113 Disassembler(const uint8_t* start, size_t length);
116 bool Bad(const char *reason);
118 // Returns true if the given range lies within our memory region.
119 bool IsRangeInBounds(size_t offset, size_t size) {
120 return offset <= length() && size <= length() - offset;
123 // Returns true if the given array lies within our memory region.
124 bool IsArrayInBounds(size_t offset, size_t elements, size_t element_size) {
125 return offset <= length() && elements <= (length() - offset) / element_size;
128 // Computes and stores all Labels before scanning program bytes.
129 void PrecomputeLabels(AssemblyProgram* program);
131 // Reduce the length of the image in memory. Does not actually free
132 // (or realloc) any memory. Usually only called via ParseHeader().
133 void ReduceLength(size_t reduced_length);
135 // Returns a generator that emits instructions to a given receptor. |program|
136 // is required as helper.
137 virtual InstructionGenerator GetInstructionGenerator(
138 AssemblyProgram* program) = 0;
141 const char* failure_reason_;
144 // Basic information that is always valid after construction, although
145 // ParseHeader() may shorten |length_| if the executable is shorter than the
148 size_t length_; // In current memory.
149 const uint8_t* start_; // In current memory, base for 'file offsets'.
150 const uint8_t* end_; // In current memory.
152 DISALLOW_COPY_AND_ASSIGN(Disassembler);
155 } // namespace courgette
157 #endif // COURGETTE_DISASSEMBLER_H_