1 : // Copyright 2011 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/reorder/random_order_generator.h"
16 :
17 : #include <algorithm>
18 :
19 : #include "syzygy/core/random_number_generator.h"
20 : #include "syzygy/pe/pe_utils.h"
21 :
22 : namespace reorder {
23 :
24 : RandomOrderGenerator::RandomOrderGenerator(int seed)
25 : : Reorderer::OrderGenerator("Random Order Generator"),
26 E : seed_(seed) {
27 E : }
28 :
29 E : RandomOrderGenerator::~RandomOrderGenerator() {
30 E : }
31 :
32 : bool RandomOrderGenerator::OnCodeBlockEntry(const BlockGraph::Block* /*block*/,
33 : RelativeAddress /*address*/,
34 : uint32 /*process_id*/,
35 : uint32 /*thread_id*/,
36 i : const UniqueTime& /*time*/) {
37 : // This is a NOP.
38 i : return true;
39 i : }
40 :
41 : bool RandomOrderGenerator::CalculateReordering(const PEFile& pe_file,
42 : const ImageLayout& image,
43 : bool reorder_code,
44 : bool reorder_data,
45 E : Order* order) {
46 E : DCHECK(order != NULL);
47 E : order->comment = "Random block ordering";
48 E : order->sections.clear();
49 E : order->sections.resize(image.sections.size());
50 E : for (size_t i = 0; i < image.sections.size(); ++i) {
51 E : const ImageLayout::SectionInfo& section = image.sections[i];
52 E : order->sections[i].id = i;
53 E : order->sections[i].name = section.name;
54 E : order->sections[i].characteristics = section.characteristics;
55 :
56 : // Prepare to iterate over all block in the section.
57 E : BlockGraph::AddressSpace::Range section_range(section.addr, section.size);
58 : AddressSpace::RangeMapConstIterPair section_blocks(
59 : image.blocks.GetIntersectingBlocks(
60 E : section_range.start(), section_range.size()));
61 :
62 : // Gather up all blocks within the section.
63 E : AddressSpace::RangeMapConstIter& section_it = section_blocks.first;
64 E : const AddressSpace::RangeMapConstIter& section_end = section_blocks.second;
65 E : for (; section_it != section_end; ++section_it) {
66 E : const BlockGraph::Block* block = section_it->second;
67 E : order->sections[i].blocks.push_back(Order::BlockSpec(block));
68 E : }
69 :
70 E : bool is_code = (section.characteristics & IMAGE_SCN_CNT_CODE) != 0;
71 E : bool is_data = !is_code;
72 : // If we're not supposed to randomly reorder this section, then we're done.
73 E : if ((is_code && !reorder_code) || (is_data && !reorder_data))
74 E : continue;
75 :
76 : // Otherwise, randomly shuffle blocks in this section.
77 E : LOG(INFO) << "Randomizing section " << i << " (" << section.name << ").";
78 E : core::RandomNumberGenerator random_number_generator(seed_ + i);
79 : std::random_shuffle(order->sections[i].blocks.begin(),
80 : order->sections[i].blocks.end(),
81 E : random_number_generator);
82 E : }
83 :
84 E : return true;
85 E : }
86 :
87 : } // namespace reorder
|