| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COURGETTE_DISASSEMBLER_H_ |
| #define COURGETTE_DISASSEMBLER_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <vector> |
| |
| #include "base/macros.h" |
| #include "courgette/courgette.h" |
| #include "courgette/image_utils.h" |
| |
| namespace courgette { |
| |
| class AssemblyProgram; |
| |
| class Disassembler : public AddressTranslator { |
| public: |
| // Visitor/adaptor to translate RVA to target RVA for abs32. |
| class RvaVisitor_Abs32 : public VectorRvaVisitor<RVA> { |
| public: |
| RvaVisitor_Abs32(const std::vector<RVA>& rva_locations, |
| const AddressTranslator& translator); |
| ~RvaVisitor_Abs32() override { } |
| |
| // VectorRvaVisitor<RVA> interfaces. |
| RVA Get() const override; |
| |
| private: |
| const AddressTranslator& translator_; |
| |
| DISALLOW_COPY_AND_ASSIGN(RvaVisitor_Abs32); |
| }; |
| |
| // Visitor/adaptor to translate RVA to target RVA for rel32. |
| class RvaVisitor_Rel32 : public VectorRvaVisitor<RVA> { |
| public: |
| RvaVisitor_Rel32(const std::vector<RVA>& rva_locations, |
| const AddressTranslator& translator); |
| ~RvaVisitor_Rel32() override { } |
| |
| // VectorRvaVisitor<RVA> interfaces. |
| RVA Get() const override; |
| |
| private: |
| const AddressTranslator& translator_; |
| |
| DISALLOW_COPY_AND_ASSIGN(RvaVisitor_Rel32); |
| }; |
| |
| virtual ~Disassembler(); |
| |
| // AddressTranslator interfaces. |
| virtual RVA FileOffsetToRVA(FileOffset file_offset) const override = 0; |
| virtual FileOffset RVAToFileOffset(RVA rva) const override = 0; |
| const uint8_t* FileOffsetToPointer(FileOffset file_offset) const override; |
| const uint8_t* RVAToPointer(RVA rva) const override; |
| RVA PointerToTargetRVA(const uint8_t* p) const = 0; |
| |
| virtual ExecutableType kind() const = 0; |
| |
| // Returns a caller-owned new RvaVisitor to iterate through abs32 target RVAs. |
| virtual RvaVisitor* CreateAbs32TargetRvaVisitor() = 0; |
| |
| // Returns a caller-owned new RvaVisitor to iterate through rel32 target RVAs. |
| virtual RvaVisitor* CreateRel32TargetRvaVisitor() = 0; |
| |
| // Removes unused rel32 locations (architecture-specific). This is needed |
| // because we may remove rel32 Labels along the way. As a result the matching |
| // matching rel32 addresses become unused. Removing them saves space. |
| virtual void RemoveUnusedRel32Locations(AssemblyProgram* program) = 0; |
| |
| // Returns true if the buffer appears to be a valid executable of the expected |
| // type, and false otherwise. This needs not be called before Disassemble(). |
| virtual bool ParseHeader() = 0; |
| |
| // Disassembles the item passed to the factory method into the output |
| // parameter 'program'. |
| virtual bool Disassemble(AssemblyProgram* program) = 0; |
| |
| // ok() may always be called but returns true only after ParseHeader() |
| // succeeds. |
| bool ok() const { return failure_reason_ == nullptr; } |
| |
| // Returns the length of the image. May reduce after ParseHeader(). |
| size_t length() const { return length_; } |
| const uint8_t* start() const { return start_; } |
| const uint8_t* end() const { return end_; } |
| |
| protected: |
| Disassembler(const void* start, size_t length); |
| |
| bool Good(); |
| bool Bad(const char *reason); |
| |
| // Returns true if the array lies within our memory region. |
| bool IsArrayInBounds(size_t offset, size_t elements, size_t element_size) { |
| return offset <= length() && elements <= (length() - offset) / element_size; |
| } |
| |
| // Computes and stores all Labels before scanning program bytes. |
| void PrecomputeLabels(AssemblyProgram* program); |
| |
| // Reduce the length of the image in memory. Does not actually free |
| // (or realloc) any memory. Usually only called via ParseHeader(). |
| void ReduceLength(size_t reduced_length); |
| |
| private: |
| const char* failure_reason_; |
| |
| // |
| // Basic information that is always valid after construction, although |
| // ParseHeader() may shorten |length_| if the executable is shorter than the |
| // total data. |
| // |
| size_t length_; // In current memory. |
| const uint8_t* start_; // In current memory, base for 'file offsets'. |
| const uint8_t* end_; // In current memory. |
| |
| DISALLOW_COPY_AND_ASSIGN(Disassembler); |
| }; |
| |
| } // namespace courgette |
| |
| #endif // COURGETTE_DISASSEMBLER_H_ |