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