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