// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef COMPONENTS_ZUCCHINI_REL32_FINDER_H_ #define COMPONENTS_ZUCCHINI_REL32_FINDER_H_ #include <stddef.h> #include <deque> #include "components/zucchini/address_translator.h" #include "components/zucchini/arm_utils.h" #include "components/zucchini/buffer_view.h" #include "components/zucchini/image_utils.h" namespace zucchini { // See README.md for definitions on abs32 and rel32 references. The following // are assumed: // * Abs32 reference bodies have fixed widths. // * Rel32 locations can be identified by heuristically disassembling machine // code, and errors are tolerated. // * The collection all abs32 and rel32 reference bodies do not overlap. // A class to visit non-empty contiguous gaps in |region| that lie outside of // |abs32_locations| elements, each with a body that spans |abs32_width_| bytes. // For example, given: // region = [base_ + 4, base_ + 26), // abs32_locations = {2, 6, 15, 20, 27}, // abs32_width_ = 4, // the following is obtained: // 111111111122222222223 -> offsets // 0123456789012345678901234567890 // ....**********************..... -> region = * // ^ ^ ^ ^ ^ -> abs32 locations // aaaaaaaa aaaa aaaa aaaa -> abs32 bodies // ....------*****----*----**..... -> regions excluding abs32 -> 3 gaps // The resulting gaps (non-empty, so [6, 6) is excluded) are: // [10, 15), [19, 20), [24, 26). // These gaps can then be passed to Rel32Finder (below) to find rel32 references // with bodies that are guaranteed to not overlap with any abs32 bodies. class Abs32GapFinder { … }; // A class to scan regions within an image to find successive rel32 references. // Architecture-specific parsing and result extraction are delegated to // inherited classes (say, Rel32Finder_Impl). Sample extraction loop, combined // with Abs32GapFinder usage: // // Abs32GapFinder gap_finder(...); // Rel32Finder_Impl finder(...); // while (gap_finder.FindNext()) { // rel_finder.SetRegion(gap_finder.GetGap()); // while (rel_finder.FindNext()) { // auto rel32 = rel_finder.GetRel32(); // In Rel32Finder_Impl. // if (architecture_specific_validation(rel32)) { // rel_finder.Accept(); // // Store rel32. // } // } // } class Rel32Finder { … }; // Parsing for X86 or X64: we perform naive scan for opcodes that have rel32 as // an argument, and disregard instruction alignment. class Rel32FinderIntel : public Rel32Finder { … }; // X86 instructions. class Rel32FinderX86 : public Rel32FinderIntel { … }; // X64 instructions. class Rel32FinderX64 : public Rel32FinderIntel { … }; // Base class for ARM (AArch32 and AArch64) instructions. template <typename ADDR_TYPE> class Rel32FinderArm : public Rel32Finder { … }; // AArch32 instructions. class Rel32FinderAArch32 : public Rel32FinderArm<AArch32Rel32Translator::AddrType> { … }; // AArch64 instructions. class Rel32FinderAArch64 : public Rel32FinderArm<AArch64Rel32Translator::AddrType> { … }; } // namespace zucchini #endif // COMPONENTS_ZUCCHINI_REL32_FINDER_H_