Theodosius  v3.0
Jit linker, mapper, obfuscator, and mutator
next_inst_pass.cpp
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 
32 
33 namespace theo::obf {
35  static next_inst_pass_t obj;
36  return &obj;
37 }
39  std::optional<recomp::reloc_t*> reloc;
40  if (!(reloc = has_next_inst_reloc(sym)).has_value())
41  return;
42 
43  xed_decoded_inst_t inst = m_tmp_inst;
44  std::vector<std::uint8_t> new_inst_bytes =
45  transform::generate(&inst, reloc.value(), 3, 6);
46 
47  // add a push [rip+offset] and update reloc->offset()...
48  //
49  std::uint32_t inst_len = {};
50  std::uint8_t inst_buff[XED_MAX_INSTRUCTION_BYTES];
51 
52  xed_error_enum_t err;
53  xed_encoder_request_t req;
54  xed_state_t istate{XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b};
55 
56  xed_encoder_request_zero_set_mode(&req, &istate);
57  xed_encoder_request_set_effective_operand_width(&req, 64);
58  xed_encoder_request_set_iclass(&req, XED_ICLASS_PUSH);
59 
60  xed_encoder_request_set_mem0(&req);
61  xed_encoder_request_set_operand_order(&req, 0, XED_OPERAND_MEM0);
62 
63  xed_encoder_request_set_base0(&req, XED_REG_RIP);
64  xed_encoder_request_set_seg0(&req, XED_REG_INVALID);
65  xed_encoder_request_set_index(&req, XED_REG_INVALID);
66  xed_encoder_request_set_scale(&req, 0);
67 
68  xed_encoder_request_set_memory_operand_length(&req, 8);
69  xed_encoder_request_set_memory_displacement(&req, new_inst_bytes.size() + 1,
70  1);
71 
72  if ((err = xed_encode(&req, inst_buff, sizeof(inst_buff), &inst_len)) !=
73  XED_ERROR_NONE) {
74  spdlog::info("failed to encode instruction... reason: {}",
75  xed_error_enum_t2str(err));
76 
77  assert(err == XED_ERROR_NONE);
78  }
79 
80  new_inst_bytes.insert(new_inst_bytes.begin(), inst_buff,
81  inst_buff + inst_len);
82 
83  // put a return instruction at the end of the decrypt instructions...
84  //
85  new_inst_bytes.push_back(0xC3);
86 
87  sym->data().insert(sym->data().end(), new_inst_bytes.begin(),
88  new_inst_bytes.end());
89 
90  reloc.value()->offset(sym->data().size());
91  sym->data().resize(sym->data().size() + 8);
92 }
93 
94 std::optional<recomp::reloc_t*> next_inst_pass_t::has_next_inst_reloc(
95  decomp::symbol_t* sym) {
96  auto res = std::find_if(
97  sym->relocs().begin(), sym->relocs().end(),
98  [&](recomp::reloc_t& reloc) -> bool { return !reloc.offset(); });
99 
100  return res != sym->relocs().end() ? &(*res)
101  : std::optional<recomp::reloc_t*>();
102 }
103 } // namespace theo::obf
symbol_t is an abstraction upon the coff symbol. this allows for easier manipulation of the symbol....
Definition: symbol.hpp:53
std::vector< std::uint8_t > & data()
returns a vector by reference of bytes containing the data of the symbol.
Definition: symbol.cpp:76
std::vector< recomp::reloc_t > & relocs()
returns a vector of relocations.
Definition: symbol.cpp:96
This pass is used to generate transformations and jmp code to change RIP to the next instruction.
static next_inst_pass_t * get()
void run(decomp::symbol_t *sym)
virtual method which must be implimented by the pass that inherits this class.
meta data about a relocation for a symbol
Definition: reloc.hpp:41
std::vector< std::uint8_t > generate(xed_decoded_inst_t *inst, recomp::reloc_t *reloc, std::uint8_t low, std::uint8_t high)
generate a sequence of transformations given an instruction that has a relocation in it.
Definition: gen.hpp:45
this is the main namespace for obfuscation related things.
Definition: engine.hpp:36