Theodosius v3.0
Jit linker, symbol mapper, and obfuscator
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
40extern "C" {
41#include <xed-decode.h>
42#include <xed-interface.h>
43}
44
45/// <summary>
46/// this namespace encompasses the code for transforming relocations.
47/// </summary>
48namespace theo::obf::transform {
49
50/// <summary>
51/// lambda function which takes in a 64bit value (relocation address) and a
52/// 32bit value (random value used in transformation).
53/// </summary>
54using transform_t = std::function<std::size_t(std::size_t, std::uint32_t)>;
55
56/// <summary>
57/// operation_t is the base class for all types of transformations. classes that
58/// inherit this class are singleton and simply call the super constructor
59/// (operation_t::operation_t).
60/// </summary>
62 public:
63 /// <summary>
64 /// explicit constructor for operation_t
65 /// </summary>
66 /// <param name="op">lambda function when executed applies
67 /// transformations.</param> <param name="type">type of transformation, such
68 /// as XOR, ADD, SUB, etc...</param>
69 explicit operation_t(transform_t op, xed_iclass_enum_t type)
70 : m_transform(op), m_type(type) {}
71
72 /// <summary>
73 /// generates a native transform instruction given an existing instruction. it
74 /// works like so:
75 ///
76 /// mov rax, &MessageBoxA ; original instruction with relocation
77 ///
78 /// ; this function takes the first operand and out of the original
79 /// ; instruction and uses it to generate a transformation.
80 ///
81 /// xor rax, 0x39280928 ; this would be an example output for the xor
82 /// ;operation.
83 ///
84 /// </summary>
85 /// <param name="inst">instruction with a relocation to generate a
86 /// transformation for.</param> <param name="imm">random 32bit number used in
87 /// the generate transform.</param> <returns>returns the bytes of the native
88 /// instruction that was encoded.</returns>
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
122 /// <summary>
123 /// gets the inverse operation of the current operation.
124 /// </summary>
125 /// <returns>the inverse operation of the current operation.</returns>
126 xed_iclass_enum_t inverse() { return m_inverse_op[m_type]; }
127
128 /// <summary>
129 /// gets a pointer to the lambda function which contains the transform logic.
130 /// </summary>
131 /// <returns>a pointer to the lambda function which contains the transform
132 /// logic.</returns>
133 transform_t* get_transform() { return &m_transform; }
134
135 /// <summary>
136 /// gets the operation type. such as XED_ICLASS_ADD, XED_ICLASS_SUB, etc...
137 /// </summary>
138 /// <returns>the operation type. such as XED_ICLASS_ADD, XED_ICLASS_SUB,
139 /// etc...</returns>
140 xed_iclass_enum_t type() { return m_type; }
141
142 /// <summary>
143 /// generate a random number in a range.
144 /// </summary>
145 /// <param name="lowest">lowest value of the range.</param>
146 /// <param name="largest">highest value of the range.</param>
147 /// <returns>a random value in a range.</returns>
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