#ifndef COURGETTE_DISASSEMBLER_H_
#define COURGETTE_DISASSEMBLER_H_
#include <stdint.h>
#include <memory>
#include <vector>
#include "base/memory/raw_ref.h"
#include "courgette/courgette.h"
#include "courgette/image_utils.h"
#include "courgette/instruction_utils.h"
namespace courgette {
class AssemblyProgram;
class EncodedProgram;
class Disassembler : public AddressTranslator {
public:
class RvaVisitor_Abs32 : public VectorRvaVisitor<RVA> {
public:
RvaVisitor_Abs32(const std::vector<RVA>& rva_locations,
const AddressTranslator& translator);
RvaVisitor_Abs32(const RvaVisitor_Abs32&) = delete;
RvaVisitor_Abs32& operator=(const RvaVisitor_Abs32&) = delete;
~RvaVisitor_Abs32() override { }
RVA Get() const override;
private:
const raw_ref<const AddressTranslator> translator_;
};
class RvaVisitor_Rel32 : public VectorRvaVisitor<RVA> {
public:
RvaVisitor_Rel32(const std::vector<RVA>& rva_locations,
const AddressTranslator& translator);
RvaVisitor_Rel32(const RvaVisitor_Rel32&) = delete;
RvaVisitor_Rel32& operator=(const RvaVisitor_Rel32&) = delete;
~RvaVisitor_Rel32() override { }
RVA Get() const override;
private:
const raw_ref<const AddressTranslator> translator_;
};
Disassembler(const Disassembler&) = delete;
Disassembler& operator=(const Disassembler&) = delete;
virtual ~Disassembler();
RVA FileOffsetToRVA(FileOffset file_offset) const override = 0;
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 override = 0;
virtual ExecutableType kind() const = 0;
virtual uint64_t image_base() const = 0;
virtual bool ExtractAbs32Locations() = 0;
virtual bool ExtractRel32Locations() = 0;
virtual RvaVisitor* CreateAbs32TargetRvaVisitor() = 0;
virtual RvaVisitor* CreateRel32TargetRvaVisitor() = 0;
virtual void RemoveUnusedRel32Locations(AssemblyProgram* program) = 0;
virtual bool ParseHeader() = 0;
std::unique_ptr<AssemblyProgram> CreateProgram(bool annotate);
Status DisassembleAndEncode(AssemblyProgram* program,
EncodedProgram* encoded);
bool ok() const { return failure_reason_ == nullptr; }
size_t length() const { return length_; }
const uint8_t* start() const { return start_; }
const uint8_t* end() const { return end_; }
protected:
Disassembler(const uint8_t* start, size_t length);
bool Good();
bool Bad(const char *reason);
bool IsRangeInBounds(size_t offset, size_t size) {
return offset <= length() && size <= length() - offset;
}
bool IsArrayInBounds(size_t offset, size_t elements, size_t element_size) {
return offset <= length() && elements <= (length() - offset) / element_size;
}
void PrecomputeLabels(AssemblyProgram* program);
void ReduceLength(size_t reduced_length);
virtual InstructionGenerator GetInstructionGenerator(
AssemblyProgram* program) = 0;
private:
const char* failure_reason_;
size_t length_;
const uint8_t* start_;
const uint8_t* end_;
};
}
#endif