| Index: syzygy/experimental/protect/protect_lib/integrity_check_layout_transform.h
|
| diff --git a/syzygy/experimental/protect/protect_lib/integrity_check_layout_transform.h b/syzygy/experimental/protect/protect_lib/integrity_check_layout_transform.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d0cf106b5689173129e790744a9151e9439df168
|
| --- /dev/null
|
| +++ b/syzygy/experimental/protect/protect_lib/integrity_check_layout_transform.h
|
| @@ -0,0 +1,156 @@
|
| +// Copyright 2015 Google Inc. All Rights Reserved.
|
| +//
|
| +// Licensed under the Apache License, Version 2.0 (the "License");
|
| +// you may not use this file except in compliance with the License.
|
| +// You may obtain a copy of the License at
|
| +//
|
| +// http://www.apache.org/licenses/LICENSE-2.0
|
| +//
|
| +// Unless required by applicable law or agreed to in writing, software
|
| +// distributed under the License is distributed on an "AS IS" BASIS,
|
| +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| +// See the License for the specific language governing permissions and
|
| +// limitations under the License.
|
| +
|
| +#ifndef SYZYGY_PROTECT_PROTECT_LIB_INTEGRITY_CHECK_LAYOUT_TRANSFORM_H_
|
| +#define SYZYGY_PROTECT_PROTECT_LIB_INTEGRITY_CHECK_LAYOUT_TRANSFORM_H_
|
| +
|
| +#include "syzygy/block_graph/basic_block.h"
|
| +#include "syzygy/block_graph/basic_block_decomposer.h"
|
| +#include "syzygy/block_graph/basic_block_subgraph.h"
|
| +#include "syzygy/block_graph/block_graph.h"
|
| +#include "syzygy/block_graph/ordered_block_graph.h"
|
| +#include "syzygy/block_graph/transforms/named_transform.h"
|
| +#include "syzygy/experimental/protect/protect_lib/protect_utils.h"
|
| +
|
| +namespace protect {
|
| +
|
| +class IntegrityCheckLayoutTransform
|
| + : public block_graph::transforms::
|
| + NamedImageLayoutTransformImpl<IntegrityCheckLayoutTransform> {
|
| + public:
|
| + typedef block_graph::BasicBlockDecomposer BasicBlockDecomposer;
|
| + typedef block_graph::BasicBlockSubGraph BasicBlockSubGraph;
|
| + typedef block_graph::BasicCodeBlock BasicCodeBlock;
|
| + typedef block_graph::BlockGraph BlockGraph;
|
| + typedef block_graph::OrderedBlockGraph OrderedBlockGraph;
|
| + typedef block_graph::TransformPolicyInterface TransformPolicyInterface;
|
| +
|
| + // The transform name.
|
| + static const char kTransformName[];
|
| +
|
| + // Constructor.
|
| + explicit IntegrityCheckLayoutTransform(FlummoxConfig* config)
|
| + {
|
| + for (const std::string& target : config->target_set())
|
| + target_names_[target] = false;
|
| +
|
| + this->chunk_checking_coverage =config->chunk_checking_coverage();
|
| + if (chunk_checking_coverage == 0.0f){
|
| + bool *pcc = config->perform_chunk_checks();
|
| + *pcc = false;
|
| + }
|
| + this->basic_block_sizes_ = config->basic_block_sizes();
|
| + this->checker_to_checkee_map_ = config->checker_to_checkee_map();
|
| + this->ic_block_chunk_index_map_ = config->ic_block_chunk_index_map();
|
| + this->ic_block_reference_free_chunks =
|
| + config->ic_block_reference_free_chunks();
|
| + this->ic_chunk_checker_to_checkee_map_ =
|
| + config->ic_chunk_checker_to_checkee_map();
|
| + this->id_to_label_ = config->id_to_label();
|
| + this->label_name_to_block_ = config->label_name_to_block();
|
| + this->nr_hashes_patched_ = config->nr_hashes_patched();
|
| + this->perform_chunk_checks_ = config->perform_chunk_checks();
|
| + this->precomputed_hashes_ = config->precomputed_hashes();
|
| + }
|
| +
|
| + //
|
| + virtual bool TransformImageLayout(
|
| + const TransformPolicyInterface* policy,
|
| + const pe::ImageLayout* image_layout,
|
| + const OrderedBlockGraph* ordered_block_graph);
|
| +
|
| + private:
|
| + uint8_t ComputeAggregatedChunksHash(const std::set<uint32_t> chunk_indexes);
|
| + uint8_t ComputeAggregatedBlocksHash(uint64_t bb_id);
|
| +
|
| + bool IntegrityCheckLayoutTransform::RecomputePivot(
|
| + const uint64_t bb_id,
|
| + const uint8_t precomputed_hash,
|
| + const uint8_t precomputed_xor,
|
| + const size_t pivot_offset,
|
| + const size_t sub_offset,
|
| + block_graph::BlockGraph::Block *block);
|
| +
|
| + // Patches pivot byte within the integrity checker assembly code
|
| + // this will maintain the cylcic relations, e.g. A->B,B->A
|
| + // (-> stands for checking) given some value changes in block A,
|
| + // the precomputed hash by B becomes invalid recomputation of which makes A's
|
| + // precomputed hash invalid. Therefore, it's impossible to maintain both
|
| + // hashes valid. We use a pivot to preserve the previously computed hash by
|
| + // checker blocks. Precomputed hash + pivot = Initially precomputed hash
|
| + // @param bb - the basic block where the patching will be done
|
| + // @param subgraph - subgraph containing basic blocks we want to transform
|
| + bool PatchPivot(BlockGraph::Label label);
|
| + //
|
| + virtual int PatchPrecomputedHashes(
|
| + const TransformPolicyInterface* policy,
|
| + BlockGraph::Block* block);
|
| +
|
| + //
|
| + virtual bool FixPrecomputedHashes(const TransformPolicyInterface* policy,
|
| + const core::AbsoluteAddress image_base,
|
| + BlockGraph::Block* block,
|
| + std::vector<uint8_t> new_block_buffer);
|
| +
|
| + //
|
| + bool CheckHash(block_graph::BasicCodeBlock* bb,
|
| + std::vector<uint8_t> new_block_buffer,
|
| + const core::AbsoluteAddress image_base);
|
| +
|
| + //TODO: remove file
|
| + FILE* phash;
|
| +
|
| + // This attribute keeps track of the address range that should be protected
|
| + // by integrity-checks
|
| + std::map<std::string, bool> target_names_;
|
| +
|
| + // Map indicating which BBs will be hashed by the checker
|
| + std::map<uint64_t, std::map<uint64_t, int>> *checker_to_checkee_map_;
|
| +
|
| + // Vector indicating chunks within Integrity checker block without absolute
|
| + // references
|
| + std::vector<ChunkInfo> *ic_block_reference_free_chunks;
|
| + // Map for retrieveing chunk id(unit32) from bb_id + chunk_index
|
| + // useful in patching bb chunks
|
| + std::map<uint64_t, uint32_t> *ic_block_chunk_index_map_;
|
| +
|
| + // Map< CheckerId, set < Chunk indexes > >
|
| + std::map<uint64_t, std::set<uint32_t>> *ic_chunk_checker_to_checkee_map_;
|
| +
|
| + // Map holding precomputed hashes of original BB
|
| + std::map<uint64_t, uint32_t> *precomputed_hashes_;
|
| +
|
| + // Map from BB address to its size
|
| + std::map<uint64_t, uint32_t> *basic_block_sizes_;
|
| +
|
| + //
|
| + std::map<std::string, std::pair<BlockGraph::Block*, uint32_t>>
|
| + *label_name_to_block_;
|
| +
|
| + // Map of original custom basic block ID to a label
|
| + std::map<uint64_t, BlockGraph::Label> *id_to_label_;
|
| +
|
| + //
|
| + bool *perform_chunk_checks_;
|
| + float chunk_checking_coverage = 1.0f;
|
| +
|
| + // Number of precomputed hash values which were patched
|
| + int *nr_hashes_patched_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(IntegrityCheckLayoutTransform);
|
| +};
|
| +
|
| +}// namespace protect
|
| +
|
| +#endif// SYZYGY_PROTECT_PROTECT_LIB_INTEGRITY_CHECK_LAYOUT_TRANSFORM_H_
|
|
|