| Index: syzygy/experimental/protect/protect_lib/code_randomizer.h
 | 
| diff --git a/syzygy/experimental/protect/protect_lib/code_randomizer.h b/syzygy/experimental/protect/protect_lib/code_randomizer.h
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..442aa14b9ee20b6182cdeff016bb2012c2c4ae5e
 | 
| --- /dev/null
 | 
| +++ b/syzygy/experimental/protect/protect_lib/code_randomizer.h
 | 
| @@ -0,0 +1,162 @@
 | 
| +// Copyright 2015 Google Inc. All Rights Reserved.
 | 
| +//
 | 
| +// Licensed under the Apache License, Version 2.0 (the "License");
 | 
| +// you may not use this file except in compliance with the License.
 | 
| +// You may obtain a copy of the License at
 | 
| +//
 | 
| +//     http://www.apache.org/licenses/LICENSE-2.0
 | 
| +//
 | 
| +// Unless required by applicable law or agreed to in writing, software
 | 
| +// distributed under the License is distributed on an "AS IS" BASIS,
 | 
| +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
| +// See the License for the specific language governing permissions and
 | 
| +// limitations under the License.
 | 
| +
 | 
| +#include <cstdlib>
 | 
| +#include <ctime>
 | 
| +#include <iostream>
 | 
| +
 | 
| +#include "syzygy/assm/assembler.h"
 | 
| +#include "syzygy/assm/assembler_base.h"
 | 
| +#include "syzygy/block_graph/basic_block_subgraph.h"
 | 
| +#include "syzygy/block_graph/basic_block_assembler.h"
 | 
| +
 | 
| +#ifndef SYZYGY_PROTECT_PROTECT_LIB_CODE_RANDOMIZER_H_
 | 
| +#define SYZYGY_PROTECT_PROTECT_LIB_CODE_RANDOMIZER_H_
 | 
| +
 | 
| +class RegState {
 | 
| +public:
 | 
| +  // Construct a state in which all registers are live
 | 
| +  RegState() {
 | 
| +    _live_regs.insert(assm::RegisterId::kRegisterEax);
 | 
| +    _live_regs.insert(assm::RegisterId::kRegisterEbx);
 | 
| +    _live_regs.insert(assm::RegisterId::kRegisterEcx);
 | 
| +    _live_regs.insert(assm::RegisterId::kRegisterEdx);
 | 
| +    //_live_regs.insert(assm::RegisterId::kRegisterEsi);
 | 
| +    //_live_regs.insert(assm::RegisterId::kRegisterEdi);
 | 
| +  }
 | 
| +
 | 
| +  // Adds a register to the used register vector
 | 
| +  // @param reg register to be added
 | 
| +  void Add(assm::RegisterId reg) {
 | 
| +    _live_regs.insert(reg);
 | 
| +  }
 | 
| +
 | 
| +  // Removes a register from the used register vector
 | 
| +  // @param reg register to be removed
 | 
| +  void Delete(assm::RegisterId reg) {
 | 
| +    _live_regs.erase(reg);
 | 
| +  }
 | 
| +
 | 
| +  // Returns true if a register is safe to use,
 | 
| +  // false otherwise.
 | 
| +  // @param reg register to be removed
 | 
| +  bool IsSafe(assm::RegisterId reg) {
 | 
| +    if (_live_regs.count(reg) > 0)
 | 
| +      return false;
 | 
| +
 | 
| +    return true;
 | 
| +  }
 | 
| +
 | 
| +  // Function for pretty printing, prints
 | 
| +  // directly to stdout
 | 
| +  void Print() {
 | 
| +    for (auto it = _live_regs.begin(); it != _live_regs.end(); ++it)
 | 
| +      std::cout << *it << " ";
 | 
| +
 | 
| +    std::cout << std::endl;
 | 
| +  }
 | 
| +
 | 
| +  int instruction_count = 0;  // Instructions added so far
 | 
| +  int extra_stack = 0;  // Extra stack that has been allocated
 | 
| +
 | 
| +protected:
 | 
| +  std::set<assm::RegisterId> _live_regs;
 | 
| +};
 | 
| +
 | 
| +class CodeRandomizer {
 | 
| +public:
 | 
| +  typedef block_graph::BasicBlock::Instructions Instructions;
 | 
| +  typedef block_graph::Instruction Instruction;
 | 
| +
 | 
| +  // Tries to reorder a list o instructions
 | 
| +  // @param where iterator to the starting point of the section
 | 
| +  // @param list list containing the range of instructions
 | 
| +  // @param size number of instructions that need to be shuffled
 | 
| +  static void Shuffle(const Instructions::iterator& where,
 | 
| +    Instructions *list, int size);
 | 
| +
 | 
| +  // Adds a random ADD X / SUB -X to the assembler provided
 | 
| +  // @param assm assembler in which the randomized add/sub will be added
 | 
| +  // @param reg register to which the value is added
 | 
| +  // @param val value to be added
 | 
| +  // @param reg_size register size
 | 
| +  // @param state state used for keeping track of number of operations
 | 
| +  //        and used registers
 | 
| +  static void RandAdd(block_graph::BasicBlockAssembler &assm,
 | 
| +    const assm::Register32 ®, uint32_t val, assm::ValueSize reg_size,
 | 
| +    RegState &state);
 | 
| +
 | 
| +  // Adds a random SUB X / ADD -X to the assembler provided
 | 
| +  // @param assm assembler in which the randomized sub/add will be added
 | 
| +  // @param reg register to which the value is added
 | 
| +  // @param val value to be added
 | 
| +  // @param reg_size register size
 | 
| +  // @param state state used for keeping track of number of operations
 | 
| +  //        and used registers
 | 
| +  static void RandSub(block_graph::BasicBlockAssembler &assm,
 | 
| +    const assm::Register32 ®, uint32_t val, assm::ValueSize reg_size,
 | 
| +    RegState &state);
 | 
| +
 | 
| +  // Adds a PUSH or equivalent code to the assembler provided
 | 
| +  // @param assm assembler to which the randomized push will be added
 | 
| +  // @param T source from which the data is pushed; can be a register,
 | 
| +  //        immediate or operand
 | 
| +  // @param reg_size register size
 | 
| +  // @param state state used for keeping track of number of operations
 | 
| +  //        and used registers
 | 
| +  template<typename T>
 | 
| +  static void RandPush(block_graph::BasicBlockAssembler &assm,
 | 
| +    const T &source, assm::ValueSize reg_size,
 | 
| +    RegState &state);
 | 
| +
 | 
| +  // Adds a POP or equivalent code to the assembler provided
 | 
| +  // @param assm assembler to which the randomized pop will be added
 | 
| +  // @param T dest from which the data is pushed; can be a register
 | 
| +  //          or operand
 | 
| +  // @param reg_size register size
 | 
| +  // @param state state used for keeping track of number of operations
 | 
| +  //        and used registers
 | 
| +  template<typename T>
 | 
| +  static void RandPop(block_graph::BasicBlockAssembler &assm,
 | 
| +    const T &dest, assm::ValueSize reg_size,
 | 
| +    RegState &state);
 | 
| +
 | 
| +  // Applies a random modification to the ESP register, an ADD/SUB with a
 | 
| +  // random value
 | 
| +  // @param assm assembler to which the instruction will be added
 | 
| +  // @param state state used for keeping track of number of operations
 | 
| +  //        and used registers
 | 
| +  static void RandModifyESP(block_graph::BasicBlockAssembler &assm,
 | 
| +                            RegState &state);
 | 
| +
 | 
| +  // Resets the value of ESP to the real one
 | 
| +  // Whenever RandPush or RandPop are used, this function needs to be called
 | 
| +  // afterwards, to ensure the correct state of the ESP register
 | 
| +  // @param assm assembler to which the instruction will be added
 | 
| +  // @param state state used for keeping track of number of operations
 | 
| +  //        and used registers
 | 
| +  static void ClearExtraStack(block_graph::BasicBlockAssembler &assm,
 | 
| +                              RegState &state);
 | 
| +
 | 
| +  // Generates code that calculates a given addres in the provided reg
 | 
| +  // @param assm assembler to which the instruction will be added
 | 
| +  // @param reg register which will hold the calculated value
 | 
| +  // @param address address which has to be calculated
 | 
| +  // @param reg_size size of the address
 | 
| +  static void GenerateAddress(block_graph::BasicBlockAssembler &assm,
 | 
| +    const assm::Register32 ®, uint32_t address, assm::ValueSize reg_size);
 | 
| +
 | 
| +};
 | 
| +
 | 
| +#endif  // SYZYGY_PROTECT_PROTECT_LIB_CODE_RANDOMIZER_H_
 | 
| 
 |