1 : // Copyright 2014 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 : #include "syzygy/block_graph/block_hash.h"
16 :
17 : #include "gmock/gmock.h"
18 : #include "gtest/gtest.h"
19 :
20 : namespace block_graph {
21 :
22 E : TEST(BlockHash, HashAndCompare) {
23 E : BlockGraph block_graph;
24 E : const size_t kBlockSize = 0x20;
25 E : const uint8_t kMagicValue = 0xAB;
26 :
27 E : BlockGraph::Block* code_block_1 = block_graph.AddBlock(BlockGraph::CODE_BLOCK,
28 : kBlockSize,
29 : "code block");
30 :
31 E : EXPECT_NE(reinterpret_cast<uint8_t*>(NULL),
32 E : code_block_1->ResizeData(kBlockSize));
33 :
34 E : ::memset(code_block_1->GetMutableData(), kMagicValue, kBlockSize);
35 E : BlockHash code_block_1_hash(code_block_1);
36 :
37 E : BlockGraph::Block* test_block = block_graph.AddBlock(BlockGraph::DATA_BLOCK,
38 : kBlockSize,
39 : "test block");
40 E : EXPECT_NE(reinterpret_cast<uint8_t*>(NULL),
41 E : test_block->ResizeData(kBlockSize));
42 E : ::memset(test_block->GetMutableData(), kMagicValue, kBlockSize);
43 :
44 : // The blocks don't have the same type, they should have a different hash.
45 E : EXPECT_NE(0, code_block_1_hash.Compare(BlockHash(test_block)));
46 E : test_block->set_type(BlockGraph::CODE_BLOCK);
47 E : EXPECT_EQ(0, code_block_1_hash.Compare(BlockHash(test_block)));
48 :
49 : // Change the data size and make sure that this results in a different hash
50 : // value.
51 E : test_block->ResizeData(kBlockSize + 1);
52 E : EXPECT_NE(0, code_block_1_hash.Compare(BlockHash(test_block)));
53 E : test_block->ResizeData(kBlockSize);
54 E : ::memset(test_block->GetMutableData(), kMagicValue, kBlockSize);
55 E : EXPECT_EQ(0, code_block_1_hash.Compare(BlockHash(test_block)));
56 :
57 E : BlockGraph::Block* code_block_2 = block_graph.AddBlock(BlockGraph::CODE_BLOCK,
58 : kBlockSize,
59 : "code block 2");
60 E : BlockGraph::Reference block_reference_abs(BlockGraph::ABSOLUTE_REF,
61 : 4, code_block_2, 0, 0);
62 E : BlockGraph::Reference block_reference_pc(BlockGraph::PC_RELATIVE_REF,
63 : 4, code_block_2, 0, 0);
64 E : const size_t kReferenceOffset = 4;
65 :
66 : // |test_block| has a reference but not |code_block_1|, their hashes should
67 : // be different.
68 E : EXPECT_TRUE(test_block->SetReference(kReferenceOffset, block_reference_abs));
69 E : EXPECT_NE(0, code_block_1_hash.Compare(BlockHash(test_block)));
70 :
71 E : EXPECT_TRUE(code_block_1->SetReference(kReferenceOffset,
72 E : block_reference_abs));
73 E : code_block_1_hash.Hash(code_block_1);
74 : // |test_block| and |code_block_1| have the same reference, they should have
75 : // the same hash.
76 E : EXPECT_EQ(0, code_block_1_hash.Compare(BlockHash(test_block)));
77 :
78 : // Alter the data in |test_block| (outside of the reference) and make sure
79 : // that this results in a different hash.
80 E : test_block->GetMutableData()[0] = static_cast<uint8_t>(~kMagicValue);
81 E : EXPECT_NE(0, code_block_1_hash.Compare(BlockHash(test_block)));
82 E : test_block->GetMutableData()[0] = kMagicValue;
83 E : EXPECT_EQ(0, code_block_1_hash.Compare(BlockHash(test_block)));
84 :
85 : // Alter the data in |test_block| in the reference and make sure that this
86 : // doesn't alter the hash.
87 E : test_block->GetMutableData()[kReferenceOffset] =
88 : static_cast<uint8_t>(~kMagicValue);
89 E : EXPECT_EQ(0, code_block_1_hash.Compare(BlockHash(test_block)));
90 E : test_block->GetMutableData()[kReferenceOffset] = kMagicValue;
91 :
92 : // Modify the reference of |test_block| and make sure that this results in a
93 : // different hash.
94 E : EXPECT_TRUE(test_block->RemoveReference(kReferenceOffset));
95 E : test_block->SetReference(kReferenceOffset + 1, block_reference_abs);
96 E : EXPECT_NE(0, code_block_1_hash.Compare(BlockHash(test_block)));
97 E : EXPECT_TRUE(test_block->RemoveReference(kReferenceOffset + 1));
98 :
99 E : test_block->SetReference(kReferenceOffset, block_reference_pc);
100 E : EXPECT_NE(0, code_block_1_hash.Compare(BlockHash(test_block)));
101 E : }
102 :
103 : } // namespace block_graph
|