disassembler_win32.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Copyright 2016 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. #ifndef COURGETTE_DISASSEMBLER_WIN32_H_
  5. #define COURGETTE_DISASSEMBLER_WIN32_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <map>
  9. #include <string>
  10. #include <vector>
  11. #include "base/memory/raw_ptr.h"
  12. #include "courgette/disassembler.h"
  13. #include "courgette/image_utils.h"
  14. #include "courgette/instruction_utils.h"
  15. #include "courgette/memory_allocator.h"
  16. #include "courgette/types_win_pe.h"
  17. namespace courgette {
  18. class AssemblyProgram;
  19. class DisassemblerWin32 : public Disassembler {
  20. public:
  21. DisassemblerWin32(const DisassemblerWin32&) = delete;
  22. DisassemblerWin32& operator=(const DisassemblerWin32&) = delete;
  23. virtual ~DisassemblerWin32() = default;
  24. // Disassembler interfaces.
  25. RVA FileOffsetToRVA(FileOffset file_offset) const override;
  26. FileOffset RVAToFileOffset(RVA rva) const override;
  27. ExecutableType kind() const override = 0;
  28. uint64_t image_base() const override { return image_base_; }
  29. RVA PointerToTargetRVA(const uint8_t* p) const override = 0;
  30. bool ParseHeader() override;
  31. // Exposed for test purposes
  32. bool has_text_section() const { return has_text_section_; }
  33. uint32_t size_of_code() const { return size_of_code_; }
  34. // Returns 'true' if the base relocation table can be parsed.
  35. // Output is a vector of the RVAs corresponding to locations within executable
  36. // that are listed in the base relocation table.
  37. bool ParseRelocs(std::vector<RVA>* addresses);
  38. // Returns Section containing the relative virtual address, or null if none.
  39. const Section* RVAToSection(RVA rva) const;
  40. static std::string SectionName(const Section* section);
  41. protected:
  42. // Returns true if a valid executable is detected using only quick checks.
  43. // Derived classes should inject |magic| corresponding to their architecture,
  44. // which will be checked against the detected one.
  45. static bool QuickDetect(const uint8_t* start, size_t length, uint16_t magic);
  46. // Returns true if the given RVA range lies within [0, |size_of_image_|).
  47. bool IsRvaRangeInBounds(size_t start, size_t length);
  48. // Returns whether all sections lie within image.
  49. bool CheckSectionRanges();
  50. // Disassembler interfaces.
  51. bool ExtractAbs32Locations() override;
  52. bool ExtractRel32Locations() override;
  53. RvaVisitor* CreateAbs32TargetRvaVisitor() override;
  54. RvaVisitor* CreateRel32TargetRvaVisitor() override;
  55. void RemoveUnusedRel32Locations(AssemblyProgram* program) override;
  56. InstructionGenerator GetInstructionGenerator(
  57. AssemblyProgram* program) override;
  58. DisassemblerWin32(const uint8_t* start, size_t length);
  59. [[nodiscard]] CheckBool ParseFile(AssemblyProgram* target,
  60. InstructionReceptor* receptor) const;
  61. virtual void ParseRel32RelocsFromSection(const Section* section) = 0;
  62. [[nodiscard]] CheckBool ParseNonSectionFileRegion(
  63. FileOffset start_file_offset,
  64. FileOffset end_file_offset,
  65. InstructionReceptor* receptor) const;
  66. [[nodiscard]] CheckBool ParseFileRegion(const Section* section,
  67. FileOffset start_file_offset,
  68. FileOffset end_file_offset,
  69. AssemblyProgram* program,
  70. InstructionReceptor* receptor) const;
  71. // Returns address width in byte count.
  72. virtual int AbsVAWidth() const = 0;
  73. // Emits Abs 32/64 |label| to the |receptor|.
  74. virtual CheckBool EmitAbs(Label* label,
  75. InstructionReceptor* receptor) const = 0;
  76. // Returns true if type is recognized.
  77. virtual bool SupportsRelTableType(int type) const = 0;
  78. virtual uint16_t RelativeOffsetOfDataDirectories() const = 0;
  79. #if COURGETTE_HISTOGRAM_TARGETS
  80. void HistogramTargets(const char* kind, const std::map<RVA, int>& map) const;
  81. #endif
  82. const ImageDataDirectory& base_relocation_table() const {
  83. return base_relocation_table_;
  84. }
  85. // Returns description of the RVA, e.g. ".text+0x1243". For debugging only.
  86. std::string DescribeRVA(RVA rva) const;
  87. // Finds the first section at file_offset or above. Does not return sections
  88. // that have no raw bytes in the file.
  89. const Section* FindNextSection(FileOffset file_offset) const;
  90. bool ReadDataDirectory(int index, ImageDataDirectory* dir);
  91. bool incomplete_disassembly_ =
  92. false; // true if can omit "uninteresting" bits.
  93. std::vector<RVA> abs32_locations_;
  94. std::vector<RVA> rel32_locations_;
  95. // Location and size of IMAGE_OPTIONAL_HEADER in the buffer.
  96. const uint8_t* optional_header_ = nullptr;
  97. uint16_t size_of_optional_header_ = 0;
  98. uint16_t machine_type_ = 0;
  99. uint16_t number_of_sections_ = 0;
  100. raw_ptr<const Section> sections_ = nullptr;
  101. bool has_text_section_ = false;
  102. uint32_t size_of_code_ = 0;
  103. uint32_t size_of_initialized_data_ = 0;
  104. uint32_t size_of_uninitialized_data_ = 0;
  105. RVA base_of_code_ = 0;
  106. RVA base_of_data_ = 0;
  107. uint64_t image_base_ = 0; // Range limited to 32 bits for 32 bit executable.
  108. // Specifies size of loaded PE in memory, and provides bound on RVA.
  109. uint32_t size_of_image_ = 0;
  110. int number_of_data_directories_ = 0;
  111. ImageDataDirectory export_table_;
  112. ImageDataDirectory import_table_;
  113. ImageDataDirectory resource_table_;
  114. ImageDataDirectory exception_table_;
  115. ImageDataDirectory base_relocation_table_;
  116. ImageDataDirectory bound_import_table_;
  117. ImageDataDirectory import_address_table_;
  118. ImageDataDirectory delay_import_descriptor_;
  119. ImageDataDirectory clr_runtime_header_;
  120. #if COURGETTE_HISTOGRAM_TARGETS
  121. std::map<RVA, int> abs32_target_rvas_;
  122. std::map<RVA, int> rel32_target_rvas_;
  123. #endif
  124. };
  125. } // namespace courgette
  126. #endif // COURGETTE_DISASSEMBLER_WIN32_H_