| 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_
|
|
|