OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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 <cstdlib> |
| 16 #include <ctime> |
| 17 #include <iostream> |
| 18 |
| 19 #include "syzygy/assm/assembler.h" |
| 20 #include "syzygy/assm/assembler_base.h" |
| 21 #include "syzygy/block_graph/basic_block_subgraph.h" |
| 22 #include "syzygy/block_graph/basic_block_assembler.h" |
| 23 |
| 24 #ifndef SYZYGY_PROTECT_PROTECT_LIB_CODE_RANDOMIZER_H_ |
| 25 #define SYZYGY_PROTECT_PROTECT_LIB_CODE_RANDOMIZER_H_ |
| 26 |
| 27 class RegState { |
| 28 public: |
| 29 // Construct a state in which all registers are live |
| 30 RegState() { |
| 31 _live_regs.insert(assm::RegisterId::kRegisterEax); |
| 32 _live_regs.insert(assm::RegisterId::kRegisterEbx); |
| 33 _live_regs.insert(assm::RegisterId::kRegisterEcx); |
| 34 _live_regs.insert(assm::RegisterId::kRegisterEdx); |
| 35 //_live_regs.insert(assm::RegisterId::kRegisterEsi); |
| 36 //_live_regs.insert(assm::RegisterId::kRegisterEdi); |
| 37 } |
| 38 |
| 39 // Adds a register to the used register vector |
| 40 // @param reg register to be added |
| 41 void Add(assm::RegisterId reg) { |
| 42 _live_regs.insert(reg); |
| 43 } |
| 44 |
| 45 // Removes a register from the used register vector |
| 46 // @param reg register to be removed |
| 47 void Delete(assm::RegisterId reg) { |
| 48 _live_regs.erase(reg); |
| 49 } |
| 50 |
| 51 // Returns true if a register is safe to use, |
| 52 // false otherwise. |
| 53 // @param reg register to be removed |
| 54 bool IsSafe(assm::RegisterId reg) { |
| 55 if (_live_regs.count(reg) > 0) |
| 56 return false; |
| 57 |
| 58 return true; |
| 59 } |
| 60 |
| 61 // Function for pretty printing, prints |
| 62 // directly to stdout |
| 63 void Print() { |
| 64 for (auto it = _live_regs.begin(); it != _live_regs.end(); ++it) |
| 65 std::cout << *it << " "; |
| 66 |
| 67 std::cout << std::endl; |
| 68 } |
| 69 |
| 70 int instruction_count = 0; // Instructions added so far |
| 71 int extra_stack = 0; // Extra stack that has been allocated |
| 72 |
| 73 protected: |
| 74 std::set<assm::RegisterId> _live_regs; |
| 75 }; |
| 76 |
| 77 class CodeRandomizer { |
| 78 public: |
| 79 typedef block_graph::BasicBlock::Instructions Instructions; |
| 80 typedef block_graph::Instruction Instruction; |
| 81 |
| 82 // Tries to reorder a list o instructions |
| 83 // @param where iterator to the starting point of the section |
| 84 // @param list list containing the range of instructions |
| 85 // @param size number of instructions that need to be shuffled |
| 86 static void Shuffle(const Instructions::iterator& where, |
| 87 Instructions *list, int size); |
| 88 |
| 89 // Adds a random ADD X / SUB -X to the assembler provided |
| 90 // @param assm assembler in which the randomized add/sub will be added |
| 91 // @param reg register to which the value is added |
| 92 // @param val value to be added |
| 93 // @param reg_size register size |
| 94 // @param state state used for keeping track of number of operations |
| 95 // and used registers |
| 96 static void RandAdd(block_graph::BasicBlockAssembler &assm, |
| 97 const assm::Register32 ®, uint32_t val, assm::ValueSize reg_size, |
| 98 RegState &state); |
| 99 |
| 100 // Adds a random SUB X / ADD -X to the assembler provided |
| 101 // @param assm assembler in which the randomized sub/add will be added |
| 102 // @param reg register to which the value is added |
| 103 // @param val value to be added |
| 104 // @param reg_size register size |
| 105 // @param state state used for keeping track of number of operations |
| 106 // and used registers |
| 107 static void RandSub(block_graph::BasicBlockAssembler &assm, |
| 108 const assm::Register32 ®, uint32_t val, assm::ValueSize reg_size, |
| 109 RegState &state); |
| 110 |
| 111 // Adds a PUSH or equivalent code to the assembler provided |
| 112 // @param assm assembler to which the randomized push will be added |
| 113 // @param T source from which the data is pushed; can be a register, |
| 114 // immediate or operand |
| 115 // @param reg_size register size |
| 116 // @param state state used for keeping track of number of operations |
| 117 // and used registers |
| 118 template<typename T> |
| 119 static void RandPush(block_graph::BasicBlockAssembler &assm, |
| 120 const T &source, assm::ValueSize reg_size, |
| 121 RegState &state); |
| 122 |
| 123 // Adds a POP or equivalent code to the assembler provided |
| 124 // @param assm assembler to which the randomized pop will be added |
| 125 // @param T dest from which the data is pushed; can be a register |
| 126 // or operand |
| 127 // @param reg_size register size |
| 128 // @param state state used for keeping track of number of operations |
| 129 // and used registers |
| 130 template<typename T> |
| 131 static void RandPop(block_graph::BasicBlockAssembler &assm, |
| 132 const T &dest, assm::ValueSize reg_size, |
| 133 RegState &state); |
| 134 |
| 135 // Applies a random modification to the ESP register, an ADD/SUB with a |
| 136 // random value |
| 137 // @param assm assembler to which the instruction will be added |
| 138 // @param state state used for keeping track of number of operations |
| 139 // and used registers |
| 140 static void RandModifyESP(block_graph::BasicBlockAssembler &assm, |
| 141 RegState &state); |
| 142 |
| 143 // Resets the value of ESP to the real one |
| 144 // Whenever RandPush or RandPop are used, this function needs to be called |
| 145 // afterwards, to ensure the correct state of the ESP register |
| 146 // @param assm assembler to which the instruction will be added |
| 147 // @param state state used for keeping track of number of operations |
| 148 // and used registers |
| 149 static void ClearExtraStack(block_graph::BasicBlockAssembler &assm, |
| 150 RegState &state); |
| 151 |
| 152 // Generates code that calculates a given addres in the provided reg |
| 153 // @param assm assembler to which the instruction will be added |
| 154 // @param reg register which will hold the calculated value |
| 155 // @param address address which has to be calculated |
| 156 // @param reg_size size of the address |
| 157 static void GenerateAddress(block_graph::BasicBlockAssembler &assm, |
| 158 const assm::Register32 ®, uint32_t address, assm::ValueSize reg_size); |
| 159 |
| 160 }; |
| 161 |
| 162 #endif // SYZYGY_PROTECT_PROTECT_LIB_CODE_RANDOMIZER_H_ |
OLD | NEW |