Theodosius  v3.0
Jit linker, mapper, obfuscator, and mutator
Public Member Functions | List of all members
theo::decomp::routine_t Class Reference

the routine class which is responsible for creating symbols for routines. if the routine is located inside a section with the name ".split" it will break functions into instruction symbols. More...

#include <routine.hpp>

Public Member Functions

 routine_t (coff::symbol_t *sym, coff::image_t *img, coff::section_header_t *scn, std::vector< std::uint8_t > &fn, sym_type_t dcmp_type)
 the explicit constructor for routine_t. More...
 
std::vector< decomp::symbol_tdecompose ()
 decompose the function into symbol(s). More...
 
coff::section_header_t * scn ()
 gets the section header of the section in which the symbol is located in. More...
 
std::vector< std::uint8_t > data ()
 gets the function bytes. More...
 

Detailed Description

the routine class which is responsible for creating symbols for routines. if the routine is located inside a section with the name ".split" it will break functions into instruction symbols.

Constructor & Destructor Documentation

◆ routine_t()

theo::decomp::routine_t::routine_t ( coff::symbol_t *  sym,
coff::image_t *  img,
coff::section_header_t *  scn,
std::vector< std::uint8_t > &  fn,
sym_type_t  dcmp_type 
)
explicit

the explicit constructor for routine_t.

Parameters
symthe coff symbol for the routine.
imgthe coff image which contains the symbol.
scnthe section header of the section that contains the symbol.
fnthe data (bytes) of the function.
dcmp_typethe type of decomp to do. if this is sym_type_t::function then this class wont split the function up into individual instructions.
39  : m_img(img), m_scn(scn), m_data(fn), m_dcmp_type(dcmp_type), m_sym(sym) {}
coff::section_header_t * scn()
gets the section header of the section in which the symbol is located in.
Definition: routine.cpp:168

Member Function Documentation

◆ data()

std::vector< std::uint8_t > theo::decomp::routine_t::data ( )

gets the function bytes.

Returns
the function bytes.
172  {
173  return m_data;
174 }

◆ decompose()

std::vector< decomp::symbol_t > theo::decomp::routine_t::decompose ( )

decompose the function into symbol(s).

Returns
symbol(s) of the function.
41  {
42  std::vector<decomp::symbol_t> result;
43 
44  switch (m_dcmp_type) {
45  case function: {
46  std::vector<recomp::reloc_t> relocs;
47  auto scn_relocs = reinterpret_cast<coff::reloc_t*>(
48  m_scn->ptr_relocs + reinterpret_cast<std::uint8_t*>(m_img));
49 
50  for (auto idx = 0u; idx < m_scn->num_relocs; ++idx) {
51  auto scn_reloc = &scn_relocs[idx];
52  // if the reloc is in the current function...
53  if (scn_reloc->virtual_address >= m_sym->value &&
54  scn_reloc->virtual_address < m_sym->value + m_data.size()) {
55  auto sym_reloc = m_img->get_symbol(scn_relocs[idx].symbol_index);
56  auto sym_name = symbol_t::name(m_img, sym_reloc);
57  auto sym_hash = decomp::symbol_t::hash(sym_name.data());
58  relocs.push_back(
59  recomp::reloc_t(scn_reloc->virtual_address - m_sym->value,
60  sym_hash, sym_name.data()));
61  }
62  }
63 
64  result.push_back(decomp::symbol_t(
65  m_img, symbol_t::name(m_img, m_sym).data(), m_sym->value, m_data,
66  m_scn, m_sym, relocs, sym_type_t::function));
67  break;
68  }
69  case instruction: {
70  std::uint32_t offset = {};
71  xed_error_enum_t err;
72 
73  xed_decoded_inst_t instr;
74  xed_state_t istate{XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b};
75  xed_decoded_inst_zero_set_mode(&instr, &istate);
76 
77  // keep looping over the section, lower the number of bytes each time...
78  //
79  while ((err = xed_decode(&instr, m_data.data() + offset,
80  m_data.size() - offset)) == XED_ERROR_NONE) {
81  // symbol name is of the format: symbol@instroffset, I.E: main@11...
82  //
83  auto new_sym_name = symbol_t::name(m_img, m_sym);
84 
85  // first instruction doesnt need the @offset...
86  //
87  if (offset)
88  new_sym_name.append("@").append(std::to_string(offset));
89 
90  std::vector<recomp::reloc_t> relocs;
91  auto scn_relocs = reinterpret_cast<coff::reloc_t*>(
92  m_scn->ptr_relocs + reinterpret_cast<std::uint8_t*>(m_img));
93 
94  // find if this instruction has a relocation or not...
95  // if so, return the reloc_t...
96  //
97  auto reloc = std::find_if(
98  scn_relocs, scn_relocs + m_scn->num_relocs,
99  [&](coff::reloc_t reloc) {
100  return reloc.virtual_address >= m_sym->value + offset &&
101  reloc.virtual_address <
102  m_sym->value + offset +
103  xed_decoded_inst_get_length(&instr);
104  });
105 
106  // if there is indeed a reloc for this instruction...
107  //
108  if (reloc != scn_relocs + m_scn->num_relocs) {
109  auto sym_reloc = m_img->get_symbol(reloc->symbol_index);
110  auto sym_name = symbol_t::name(m_img, sym_reloc);
111  auto sym_hash = decomp::symbol_t::hash(sym_name.data());
112  auto reloc_offset = reloc->virtual_address - m_sym->value - offset;
113 
114  relocs.push_back(
115  recomp::reloc_t(reloc_offset, sym_hash, sym_name.data()));
116  }
117 
118  // add a reloc to the next instruction...
119  // note that the offset is ZERO... comp_t will understand that
120  // relocs with offset ZERO means the next instructions...
121  //
122  auto next_inst_sym =
123  symbol_t::name(m_img, m_sym)
124  .append("@")
125  .append(std::to_string(offset +
126  xed_decoded_inst_get_length(&instr)));
127 
128  relocs.push_back(recomp::reloc_t(
129  0, decomp::symbol_t::hash(next_inst_sym), next_inst_sym.data()));
130 
131  // get the instructions bytes
132  //
133  std::vector<std::uint8_t> inst_bytes(
134  m_data.data() + offset,
135  m_data.data() + offset + xed_decoded_inst_get_length(&instr));
136 
137  result.push_back(decomp::symbol_t(m_img, new_sym_name, offset,
138  inst_bytes, m_scn, m_sym, relocs,
140 
141  // after creating the symbol and dealing with relocs then print the
142  // information we have concluded...
143  //
144  char buff[255];
145  offset += xed_decoded_inst_get_length(&instr);
146  xed_format_context(XED_SYNTAX_INTEL, &instr, buff, sizeof buff, NULL,
147  NULL, NULL);
148 
149  spdlog::info("{}: {}", new_sym_name, buff);
150  // need to set this so that instr can be used to decode again...
151  xed_decoded_inst_zero_set_mode(&instr, &istate);
152  }
153 
154  // remove the relocation to the next symbol from the last instruction
155  //
156  auto& last_inst = result.back();
157  auto& last_inst_relocs = last_inst.relocs();
158  last_inst_relocs.erase(last_inst_relocs.end() - 1);
159  break;
160  }
161  default:
162  break;
163  }
164 
165  return result;
166 }
std::vector< std::uint8_t > data()
gets the function bytes.
Definition: routine.cpp:172
std::string name() const
gets the name of the symbol.
Definition: symbol.cpp:52
std::size_t hash()
gets the hash of the symbol name.
Definition: symbol.cpp:88
@ instruction
Definition: symbol.hpp:45
@ function
Definition: symbol.hpp:44

◆ scn()

coff::section_header_t * theo::decomp::routine_t::scn ( )

gets the section header of the section in which the symbol is located in.

Returns
the section header of the section in which the symbol is located in.
168  {
169  return m_scn;
170 }

The documentation for this class was generated from the following files: