1 : // Copyright 2012 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/pe/transforms/explode_basic_blocks_transform.h"
16 :
17 : #include "gtest/gtest.h"
18 : #include "syzygy/block_graph/orderers/random_orderer.h"
19 : #include "syzygy/core/unittest_util.h"
20 : #include "syzygy/pe/decomposer.h"
21 : #include "syzygy/pe/pe_relinker.h"
22 : #include "syzygy/pe/unittest_util.h"
23 :
24 : namespace pe {
25 : namespace transforms {
26 :
27 : using block_graph::BlockGraph;
28 :
29 : namespace {
30 :
31 : class ExplodeBasicBlocksTransformTest : public testing::PELibUnitTest {
32 : public:
33 : ExplodeBasicBlocksTransformTest()
34 : : image_layout_(&block_graph_),
35 : dos_header_block_(NULL),
36 E : input_path_(testing::GetExeRelativePath(testing::kTestDllName)) {
37 E : }
38 :
39 E : virtual void SetUp() OVERRIDE {
40 E : this->CreateTemporaryDir(&temp_dir_);
41 E : output_path_ = temp_dir_.Append(testing::kTestDllName);
42 E : }
43 :
44 E : void PerformRandomizationTest(ExplodeBasicBlocksTransform* transform) {
45 E : pe::PERelinker relinker;
46 E : relinker.set_input_path(input_path_);
47 E : relinker.set_output_path(output_path_);
48 E : relinker.set_padding(8);
49 E : relinker.set_add_metadata(true);
50 E : relinker.set_allow_overwrite(true);
51 E : relinker.set_augment_pdb(true);
52 E : ASSERT_TRUE(relinker.Init());
53 :
54 E : relinker.AppendTransform(transform);
55 :
56 E : block_graph::orderers::RandomOrderer orderer(true, 123456);
57 E : relinker.AppendOrderer(&orderer);
58 :
59 : // Perform the actual relink.
60 E : ASSERT_TRUE(relinker.Relink());
61 :
62 : // Validate that the binary still loads.
63 E : ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_path_));
64 E : }
65 :
66 : BlockGraph block_graph_;
67 : ImageLayout image_layout_;
68 : BlockGraph::Block* dos_header_block_;
69 : base::FilePath input_path_;
70 : base::FilePath temp_dir_;
71 : base::FilePath output_path_;
72 : };
73 :
74 : class DllMainRandomizer : public ExplodeBasicBlocksTransform {
75 : protected:
76 E : bool SkipThisBlock(const BlockGraph::Block* candidate) OVERRIDE {
77 E : return candidate->name() != "DllMain";
78 E : }
79 : };
80 :
81 : } // namespace
82 :
83 E : TEST_F(ExplodeBasicBlocksTransformTest, RandomizeDllMain) {
84 E : DllMainRandomizer transform;
85 E : PerformRandomizationTest(&transform);
86 E : }
87 :
88 E : TEST_F(ExplodeBasicBlocksTransformTest, RandomizeAllBasicBlocks) {
89 E : ExplodeBasicBlocksTransform transform;
90 E : PerformRandomizationTest(&transform);
91 E : }
92 :
93 E : TEST_F(ExplodeBasicBlocksTransformTest, RandomizeAllBasicBlocksNoPadding) {
94 E : ExplodeBasicBlocksTransform transform;
95 E : transform.set_exclude_padding(true);
96 E : PerformRandomizationTest(&transform);
97 E : }
98 :
99 : } // namespace transforms
100 : } // namespace pe
|