OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 Google Inc. All Rights Reserved. |
| 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at |
| 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. |
| 14 |
| 15 #ifndef SYZYGY_PROTECT_PROTECT_LIB_INTEGRITY_CHECK_LAYOUT_TRANSFORM_H_ |
| 16 #define SYZYGY_PROTECT_PROTECT_LIB_INTEGRITY_CHECK_LAYOUT_TRANSFORM_H_ |
| 17 |
| 18 #include "syzygy/block_graph/basic_block.h" |
| 19 #include "syzygy/block_graph/basic_block_decomposer.h" |
| 20 #include "syzygy/block_graph/basic_block_subgraph.h" |
| 21 #include "syzygy/block_graph/block_graph.h" |
| 22 #include "syzygy/block_graph/ordered_block_graph.h" |
| 23 #include "syzygy/block_graph/transforms/named_transform.h" |
| 24 #include "syzygy/experimental/protect/protect_lib/protect_utils.h" |
| 25 |
| 26 namespace protect { |
| 27 |
| 28 class IntegrityCheckLayoutTransform |
| 29 : public block_graph::transforms:: |
| 30 NamedImageLayoutTransformImpl<IntegrityCheckLayoutTransform> { |
| 31 public: |
| 32 typedef block_graph::BasicBlockDecomposer BasicBlockDecomposer; |
| 33 typedef block_graph::BasicBlockSubGraph BasicBlockSubGraph; |
| 34 typedef block_graph::BasicCodeBlock BasicCodeBlock; |
| 35 typedef block_graph::BlockGraph BlockGraph; |
| 36 typedef block_graph::OrderedBlockGraph OrderedBlockGraph; |
| 37 typedef block_graph::TransformPolicyInterface TransformPolicyInterface; |
| 38 |
| 39 // The transform name. |
| 40 static const char kTransformName[]; |
| 41 |
| 42 // Constructor. |
| 43 explicit IntegrityCheckLayoutTransform(FlummoxConfig* config) |
| 44 { |
| 45 for (const std::string& target : config->target_set()) |
| 46 target_names_[target] = false; |
| 47 |
| 48 this->chunk_checking_coverage =config->chunk_checking_coverage(); |
| 49 if (chunk_checking_coverage == 0.0f){ |
| 50 bool *pcc = config->perform_chunk_checks(); |
| 51 *pcc = false; |
| 52 } |
| 53 this->basic_block_sizes_ = config->basic_block_sizes(); |
| 54 this->checker_to_checkee_map_ = config->checker_to_checkee_map(); |
| 55 this->ic_block_chunk_index_map_ = config->ic_block_chunk_index_map(); |
| 56 this->ic_block_reference_free_chunks = |
| 57 config->ic_block_reference_free_chunks(); |
| 58 this->ic_chunk_checker_to_checkee_map_ = |
| 59 config->ic_chunk_checker_to_checkee_map(); |
| 60 this->id_to_label_ = config->id_to_label(); |
| 61 this->label_name_to_block_ = config->label_name_to_block(); |
| 62 this->nr_hashes_patched_ = config->nr_hashes_patched(); |
| 63 this->perform_chunk_checks_ = config->perform_chunk_checks(); |
| 64 this->precomputed_hashes_ = config->precomputed_hashes(); |
| 65 } |
| 66 |
| 67 // |
| 68 virtual bool TransformImageLayout( |
| 69 const TransformPolicyInterface* policy, |
| 70 const pe::ImageLayout* image_layout, |
| 71 const OrderedBlockGraph* ordered_block_graph); |
| 72 |
| 73 private: |
| 74 uint8_t ComputeAggregatedChunksHash(const std::set<uint32_t> chunk_indexes); |
| 75 uint8_t ComputeAggregatedBlocksHash(uint64_t bb_id); |
| 76 |
| 77 bool IntegrityCheckLayoutTransform::RecomputePivot( |
| 78 const uint64_t bb_id, |
| 79 const uint8_t precomputed_hash, |
| 80 const uint8_t precomputed_xor, |
| 81 const size_t pivot_offset, |
| 82 const size_t sub_offset, |
| 83 block_graph::BlockGraph::Block *block); |
| 84 |
| 85 // Patches pivot byte within the integrity checker assembly code |
| 86 // this will maintain the cylcic relations, e.g. A->B,B->A |
| 87 // (-> stands for checking) given some value changes in block A, |
| 88 // the precomputed hash by B becomes invalid recomputation of which makes A's |
| 89 // precomputed hash invalid. Therefore, it's impossible to maintain both |
| 90 // hashes valid. We use a pivot to preserve the previously computed hash by |
| 91 // checker blocks. Precomputed hash + pivot = Initially precomputed hash |
| 92 // @param bb - the basic block where the patching will be done |
| 93 // @param subgraph - subgraph containing basic blocks we want to transform |
| 94 bool PatchPivot(BlockGraph::Label label); |
| 95 // |
| 96 virtual int PatchPrecomputedHashes( |
| 97 const TransformPolicyInterface* policy, |
| 98 BlockGraph::Block* block); |
| 99 |
| 100 // |
| 101 virtual bool FixPrecomputedHashes(const TransformPolicyInterface* policy, |
| 102 const core::AbsoluteAddress image_base, |
| 103 BlockGraph::Block* block, |
| 104 std::vector<uint8_t> new_block_buffer); |
| 105 |
| 106 // |
| 107 bool CheckHash(block_graph::BasicCodeBlock* bb, |
| 108 std::vector<uint8_t> new_block_buffer, |
| 109 const core::AbsoluteAddress image_base); |
| 110 |
| 111 //TODO: remove file |
| 112 FILE* phash; |
| 113 |
| 114 // This attribute keeps track of the address range that should be protected |
| 115 // by integrity-checks |
| 116 std::map<std::string, bool> target_names_; |
| 117 |
| 118 // Map indicating which BBs will be hashed by the checker |
| 119 std::map<uint64_t, std::map<uint64_t, int>> *checker_to_checkee_map_; |
| 120 |
| 121 // Vector indicating chunks within Integrity checker block without absolute |
| 122 // references |
| 123 std::vector<ChunkInfo> *ic_block_reference_free_chunks; |
| 124 // Map for retrieveing chunk id(unit32) from bb_id + chunk_index |
| 125 // useful in patching bb chunks |
| 126 std::map<uint64_t, uint32_t> *ic_block_chunk_index_map_; |
| 127 |
| 128 // Map< CheckerId, set < Chunk indexes > > |
| 129 std::map<uint64_t, std::set<uint32_t>> *ic_chunk_checker_to_checkee_map_; |
| 130 |
| 131 // Map holding precomputed hashes of original BB |
| 132 std::map<uint64_t, uint32_t> *precomputed_hashes_; |
| 133 |
| 134 // Map from BB address to its size |
| 135 std::map<uint64_t, uint32_t> *basic_block_sizes_; |
| 136 |
| 137 // |
| 138 std::map<std::string, std::pair<BlockGraph::Block*, uint32_t>> |
| 139 *label_name_to_block_; |
| 140 |
| 141 // Map of original custom basic block ID to a label |
| 142 std::map<uint64_t, BlockGraph::Label> *id_to_label_; |
| 143 |
| 144 // |
| 145 bool *perform_chunk_checks_; |
| 146 float chunk_checking_coverage = 1.0f; |
| 147 |
| 148 // Number of precomputed hash values which were patched |
| 149 int *nr_hashes_patched_; |
| 150 |
| 151 DISALLOW_COPY_AND_ASSIGN(IntegrityCheckLayoutTransform); |
| 152 }; |
| 153 |
| 154 }// namespace protect |
| 155 |
| 156 #endif// SYZYGY_PROTECT_PROTECT_LIB_INTEGRITY_CHECK_LAYOUT_TRANSFORM_H_ |
OLD | NEW |