Theodosius  v3.0
Jit linker, mapper, obfuscator, and mutator
operation.hpp
Go to the documentation of this file.
1 // Copyright (c) 2022, _xeroxz
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // 1. Redistributions of source code must retain the above copyright notice,
8 // this list of conditions and the following disclaimer.
9 //
10 // 2. Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution.
13 //
14 // 3. Neither the name of the copyright holder nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 // POSSIBILITY OF SUCH DAMAGE.
29 //
30 
31 #pragma once
32 #include <spdlog/spdlog.h>
33 #include <bit>
34 #include <bitset>
35 #include <functional>
36 #include <map>
37 #include <random>
38 
39 #define XED_ENCODER
40 extern "C" {
41 #include <xed-decode.h>
42 #include <xed-interface.h>
43 }
44 
48 namespace theo::obf::transform {
49 
54 using transform_t = std::function<std::size_t(std::size_t, std::uint32_t)>;
55 
61 class operation_t {
62  public:
69  explicit operation_t(transform_t op, xed_iclass_enum_t type)
70  : m_transform(op), m_type(type) {}
71 
89  std::vector<std::uint8_t> native(const xed_decoded_inst_t* inst,
90  std::uint32_t imm) {
91  std::uint32_t inst_len = {};
92  std::uint8_t inst_buff[XED_MAX_INSTRUCTION_BYTES];
93 
94  xed_error_enum_t err;
95  xed_encoder_request_init_from_decode((xed_decoded_inst_s*)inst);
96  xed_encoder_request_t* req = (xed_encoder_request_t*)inst;
97 
98  switch (m_type) {
99  case XED_ICLASS_ROR:
100  case XED_ICLASS_ROL:
101  xed_encoder_request_set_uimm0(req, imm, 1);
102  break;
103  default:
104  xed_encoder_request_set_uimm0(req, imm, 4);
105  break;
106  }
107 
108  xed_encoder_request_set_iclass(req, m_type);
109  xed_encoder_request_set_operand_order(req, 1, XED_OPERAND_IMM0);
110 
111  if ((err = xed_encode(req, inst_buff, sizeof(inst_buff), &inst_len)) !=
112  XED_ERROR_NONE) {
113  spdlog::error("failed to encode instruction... reason: {}",
114  xed_error_enum_t2str(err));
115 
116  assert(err == XED_ERROR_NONE);
117  }
118 
119  return std::vector<std::uint8_t>(inst_buff, inst_buff + inst_len);
120  }
121 
126  xed_iclass_enum_t inverse() { return m_inverse_op[m_type]; }
127 
133  transform_t* get_transform() { return &m_transform; }
134 
140  xed_iclass_enum_t type() { return m_type; }
141 
148  static std::size_t random(std::size_t lowest, std::size_t largest) {
149  std::random_device rd;
150  std::mt19937 gen(rd());
151  std::uniform_int_distribution<std::size_t> distr(lowest, largest);
152  return distr(gen);
153  }
154 
155  private:
156  transform_t m_transform;
157  xed_iclass_enum_t m_type;
158 
159  std::map<xed_iclass_enum_t, xed_iclass_enum_t> m_inverse_op = {
160  {XED_ICLASS_ADD, XED_ICLASS_SUB},
161  {XED_ICLASS_SUB, XED_ICLASS_ADD},
162  {XED_ICLASS_ROL, XED_ICLASS_ROR},
163  {XED_ICLASS_ROR, XED_ICLASS_ROL},
164  {XED_ICLASS_XOR, XED_ICLASS_XOR}};
165 };
166 
167 } // namespace theo::obf::transform
operation_t is the base class for all types of transformations. classes that inherit this class are s...
Definition: operation.hpp:61
transform_t * get_transform()
gets a pointer to the lambda function which contains the transform logic.
Definition: operation.hpp:133
operation_t(transform_t op, xed_iclass_enum_t type)
explicit constructor for operation_t
Definition: operation.hpp:69
std::vector< std::uint8_t > native(const xed_decoded_inst_t *inst, std::uint32_t imm)
generates a native transform instruction given an existing instruction. it works like so:
Definition: operation.hpp:89
xed_iclass_enum_t type()
gets the operation type. such as XED_ICLASS_ADD, XED_ICLASS_SUB, etc...
Definition: operation.hpp:140
xed_iclass_enum_t inverse()
gets the inverse operation of the current operation.
Definition: operation.hpp:126
static std::size_t random(std::size_t lowest, std::size_t largest)
generate a random number in a range.
Definition: operation.hpp:148
this namespace encompasses the code for transforming relocations.
Definition: add_op.hpp:34
std::function< std::size_t(std::size_t, std::uint32_t)> transform_t
lambda function which takes in a 64bit value (relocation address) and a 32bit value (random value use...
Definition: operation.hpp:54