abs32_utils.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright 2017 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 COMPONENTS_ZUCCHINI_ABS32_UTILS_H_
  5. #define COMPONENTS_ZUCCHINI_ABS32_UTILS_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <deque>
  9. #include "components/zucchini/address_translator.h"
  10. #include "components/zucchini/buffer_view.h"
  11. #include "components/zucchini/image_utils.h"
  12. #include "third_party/abseil-cpp/absl/types/optional.h"
  13. namespace zucchini {
  14. // A class to represent an abs32 address (32-bit or 64-bit). Accessors are
  15. // provided to translate from / to RVA, and to read / write the represented
  16. // abs32 address from / to an image.
  17. class AbsoluteAddress {
  18. public:
  19. AbsoluteAddress(Bitness bitness, uint64_t image_base);
  20. AbsoluteAddress(AbsoluteAddress&&);
  21. ~AbsoluteAddress();
  22. // Attempts to translate |rva| to an abs32 address. On success, assigns
  23. // |value_| to the result and returns true. On failure (invalid |rva| or
  24. // overflow), returns false.
  25. bool FromRva(rva_t rva);
  26. // Returns the RVA for |value_|, or |kInvalidRva| if the represented value
  27. // address does not correspond to a valid RVA.
  28. rva_t ToRva() const;
  29. // Attempts to read the abs32 address at |image[offset]| into |value_|. On
  30. // success, updates |value_| and returns true. On failure (invalid |offset|),
  31. // returns false.
  32. bool Read(offset_t offset, const ConstBufferView& image);
  33. // Attempts to write |value_| to to |(*image)[offset]|. On success, performs
  34. // the write and returns true. On failure (invalid |offset|), returns false.
  35. bool Write(offset_t offset, MutableBufferView* image);
  36. uint32_t width() const { return WidthOf(bitness_); }
  37. // Exposing |value_| for testing.
  38. uint64_t* mutable_value() { return &value_; }
  39. private:
  40. const Bitness bitness_;
  41. const uint64_t image_base_; // Accommodates 32-bit and 64-bit.
  42. uint64_t value_; // Accommodates 32-bit and 64-bit.
  43. };
  44. // A class to extract Win32 abs32 references from |abs32_locations| within
  45. // |image_| bounded by |[lo, hi)|. GetNext() is used to successively return
  46. // data as Units, which are locations and (potentially out-of-bound) RVAs.
  47. // |addr| determines the bitness of abs32 values stored, and mediates all reads.
  48. class Abs32RvaExtractorWin32 {
  49. public:
  50. struct Unit {
  51. offset_t location;
  52. rva_t target_rva;
  53. };
  54. // Requires |lo| <= |hi|, and they must not straddle a reference body (with
  55. // length |addr.width()|) in |abs32_locations|.
  56. Abs32RvaExtractorWin32(ConstBufferView image,
  57. AbsoluteAddress&& addr,
  58. const std::deque<offset_t>& abs32_locations,
  59. offset_t lo,
  60. offset_t hi);
  61. Abs32RvaExtractorWin32(Abs32RvaExtractorWin32&&);
  62. ~Abs32RvaExtractorWin32();
  63. // Visits given abs32 locations, rejects invalid locations and non-existent
  64. // RVAs, and returns reference as Unit, or absl::nullopt on completion.
  65. absl::optional<Unit> GetNext();
  66. private:
  67. ConstBufferView image_;
  68. AbsoluteAddress addr_;
  69. std::deque<offset_t>::const_iterator cur_abs32_;
  70. std::deque<offset_t>::const_iterator end_abs32_;
  71. };
  72. // A reader for Win32 abs32 references that filters and translates results from
  73. // |abs32_rva_extractor_|.
  74. class Abs32ReaderWin32 : public ReferenceReader {
  75. public:
  76. Abs32ReaderWin32(Abs32RvaExtractorWin32&& abs32_rva_extractor,
  77. const AddressTranslator& translator);
  78. Abs32ReaderWin32(const Abs32ReaderWin32&) = delete;
  79. const Abs32ReaderWin32& operator=(const Abs32ReaderWin32&) = delete;
  80. ~Abs32ReaderWin32() override;
  81. // ReferenceReader:
  82. absl::optional<Reference> GetNext() override;
  83. private:
  84. Abs32RvaExtractorWin32 abs32_rva_extractor_;
  85. AddressTranslator::RvaToOffsetCache target_rva_to_offset_;
  86. };
  87. // A writer for Win32 abs32 references. |addr| determines the bitness of the
  88. // abs32 values stored, and mediates all writes.
  89. class Abs32WriterWin32 : public ReferenceWriter {
  90. public:
  91. Abs32WriterWin32(MutableBufferView image,
  92. AbsoluteAddress&& addr,
  93. const AddressTranslator& translator);
  94. Abs32WriterWin32(const Abs32WriterWin32&) = delete;
  95. const Abs32WriterWin32& operator=(const Abs32WriterWin32&) = delete;
  96. ~Abs32WriterWin32() override;
  97. // ReferenceWriter:
  98. void PutNext(Reference ref) override;
  99. private:
  100. MutableBufferView image_;
  101. AbsoluteAddress addr_;
  102. AddressTranslator::OffsetToRvaCache target_offset_to_rva_;
  103. };
  104. // Given a list of abs32 |locations|, removes all elements whose targets cannot
  105. // be translated. Returns the number of elements removed.
  106. size_t RemoveUntranslatableAbs32(ConstBufferView image,
  107. AbsoluteAddress&& addr,
  108. const AddressTranslator& translator,
  109. std::deque<offset_t>* locations);
  110. // Given a sorted list of abs32 |locations|, removes all elements whose body
  111. // (with |width| given) overlaps with the body of a previous element.
  112. size_t RemoveOverlappingAbs32Locations(uint32_t width,
  113. std::deque<offset_t>* locations);
  114. } // namespace zucchini
  115. #endif // COMPONENTS_ZUCCHINI_ABS32_UTILS_H_