about half way done with transformations... imm's cant be 8 bytes, only

4...
3.0
_xeroxz 3 years ago
parent 78f2b39b71
commit 9199d5bef7

@ -82,8 +82,6 @@ list(APPEND Theodosius_SOURCES
"src/theo/obf/passes/jcc_rewrite_pass.cpp" "src/theo/obf/passes/jcc_rewrite_pass.cpp"
"src/theo/obf/passes/next_inst_pass.cpp" "src/theo/obf/passes/next_inst_pass.cpp"
"src/theo/obf/passes/reloc_transform_pass.cpp" "src/theo/obf/passes/reloc_transform_pass.cpp"
"src/theo/obf/transform/add_op.cpp"
"src/theo/obf/transform/sub_op.cpp"
"src/theo/recomp/recomp.cpp" "src/theo/recomp/recomp.cpp"
"src/theo/recomp/symbol_table.cpp" "src/theo/recomp/symbol_table.cpp"
"src/theo/theo.cpp" "src/theo/theo.cpp"

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <obf/pass.hpp> #include <obf/pass.hpp>
#include <obf/transform/operation.hpp>
#include <obf/transform/transform.hpp>
namespace theo::obf { namespace theo::obf {
class reloc_transform_pass_t : public pass_t { class reloc_transform_pass_t : public pass_t {
@ -10,6 +12,6 @@ class reloc_transform_pass_t : public pass_t {
void run(decomp::symbol_t* sym); void run(decomp::symbol_t* sym);
private: private:
bool has_legit_reloc(decomp::symbol_t* sym); std::optional<recomp::reloc_t*> has_legit_reloc(decomp::symbol_t* sym);
}; };
} // namespace theo::comp::obf } // namespace theo::obf

@ -6,10 +6,12 @@ class add_op_t : public operation_t {
explicit add_op_t() explicit add_op_t()
: operation_t([&](std::size_t val, : operation_t([&](std::size_t val,
std::size_t imm) -> std::size_t { return val + imm; }, std::size_t imm) -> std::size_t { return val + imm; },
type_t::add_op) {} XED_ICLASS_ADD) {}
public: public:
static add_op_t* get(); static add_op_t* get() {
std::vector<std::uint8_t> native(xed_inst_t* inst, std::size_t imm); static add_op_t obj;
return &obj;
}
}; };
} // namespace theo::obf::transform } // namespace theo::obf::transform

@ -1,6 +1,8 @@
#pragma once #pragma once
#include <spdlog/spdlog.h>
#include <functional> #include <functional>
#include <map> #include <map>
#include <random>
#define XED_ENCODER #define XED_ENCODER
extern "C" { extern "C" {
@ -13,24 +15,56 @@ using transform_t = std::function<std::size_t(std::size_t, std::size_t)>;
class operation_t { class operation_t {
public: public:
enum type_t { add_op, sub_op, and_op, or_op, rol_op, ror_op, xor_op }; explicit operation_t(transform_t op, xed_iclass_enum_t type)
explicit operation_t(transform_t op, type_t type)
: m_transform(op), m_type(type) {} : m_transform(op), m_type(type) {}
virtual std::vector<std::uint8_t> native(xed_inst_t* inst, std::vector<std::uint8_t> native(const xed_decoded_inst_t* inst,
std::size_t imm) = 0; std::size_t imm) {
xed_error_enum_t err;
xed_encoder_request_t req;
xed_state_t istate{XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b};
xed_encoder_request_zero_set_mode(&req, &istate);
xed_encoder_request_set_effective_operand_width(&req, 64);
xed_encoder_request_set_iclass(&req, m_type);
xed_encoder_request_set_reg(&req, XED_OPERAND_REG0, XED_REG_RAX);
xed_encoder_request_set_operand_order(&req, 0, XED_OPERAND_REG0);
xed_encoder_request_set_uimm0(&req, imm, 4);
xed_encoder_request_set_operand_order(&req, 1, XED_OPERAND_IMM0);
std::uint8_t inst_buff[XED_MAX_INSTRUCTION_BYTES];
std::uint32_t inst_len = {};
if ((err = xed_encode(&req, inst_buff, sizeof(inst_buff), &inst_len)) !=
XED_ERROR_NONE) {
spdlog::error("failed to encode instruction... reason: {}",
xed_error_enum_t2str(err));
assert(err == XED_ERROR_NONE);
}
return std::vector<std::uint8_t>(inst_buff, inst_buff + inst_len);
}
xed_iclass_enum_t inverse() { return m_inverse_op[m_type]; }
transform_t* get_transform() { return &m_transform; }
type_t inverse() { return m_inverse_op[m_type]; } static std::size_t random(std::size_t lowest, std::size_t largest) {
transform_t get_transform() { return m_transform; } std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<std::size_t> distr(lowest, largest);
return distr(gen);
}
private: private:
transform_t m_transform; transform_t m_transform;
type_t m_type; xed_iclass_enum_t m_type;
std::map<type_t, type_t> m_inverse_op = { std::map<xed_iclass_enum_t, xed_iclass_enum_t> m_inverse_op = {
{add_op, sub_op}, {sub_op, add_op}, {and_op, or_op}, {or_op, and_op}, {XED_ICLASS_ADD, XED_ICLASS_SUB}, {XED_ICLASS_SUB, XED_ICLASS_ADD},
{rol_op, ror_op}, {ror_op, rol_op}, {xor_op, xor_op}}; {XED_ICLASS_AND, XED_ICLASS_OR}, {XED_ICLASS_OR, XED_ICLASS_AND},
{XED_ICLASS_ROL, XED_ICLASS_ROR}, {XED_ICLASS_ROR, XED_ICLASS_ROL},
{XED_ICLASS_XOR, XED_ICLASS_XOR}};
}; };
} // namespace theo::obf::transform } // namespace theo::obf::transform

@ -0,0 +1,17 @@
#pragma once
#include <obf/transform/operation.hpp>
namespace theo::obf::transform {
class sub_op_t : public operation_t {
explicit sub_op_t()
: operation_t([&](std::size_t val,
std::size_t imm) -> std::size_t { return val - imm; },
XED_ICLASS_SUB) {}
public:
static sub_op_t* get() {
static sub_op_t obj;
return &obj;
}
};
} // namespace theo::obf::transform

@ -1,9 +1,10 @@
#pragma once #pragma once
#include <comp/obf/transform/add_op.hpp> #include <obf/transform/add_op.hpp>
#include <comp/obf/transform/operation.hpp> #include <obf/transform/operation.hpp>
#include <comp/obf/transform/sub_op.hpp> #include <obf/transform/sub_op.hpp>
namespace theo::comp::obf::transform { namespace theo::obf::transform {
std::map<operation_t::type_t, operation_t*> operations = { inline std::map<xed_iclass_enum_t, operation_t*> operations = {
{operation_t::type_t::add_op, add_op_t::get()}}; {XED_ICLASS_ADD, add_op_t::get()},
{XED_ICLASS_SUB, sub_op_t::get()}};
} }

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <obf/transform/transform.hpp>
namespace theo::recomp { namespace theo::recomp {
class reloc_t { class reloc_t {
@ -14,9 +15,21 @@ class reloc_t {
std::string name() { return m_sym_name; } std::string name() { return m_sym_name; }
std::uint16_t offset() { return m_offset; } std::uint16_t offset() { return m_offset; }
void add_transform(
std::pair<obf::transform::transform_t*, std::size_t> entry) {
m_transforms.push_back(entry);
}
std::vector<std::pair<obf::transform::transform_t*, std::size_t>>&
get_transforms() {
return m_transforms;
}
private: private:
std::vector<std::pair<obf::transform::transform_t*, std::size_t>>
m_transforms;
std::string m_sym_name; std::string m_sym_name;
std::size_t m_hash; std::size_t m_hash;
std::uint16_t m_offset; std::uint16_t m_offset;
}; };
} // namespace theo::comp } // namespace theo::recomp

@ -7,7 +7,8 @@ reloc_transform_pass_t* reloc_transform_pass_t::get() {
} }
void reloc_transform_pass_t::run(decomp::symbol_t* sym) { void reloc_transform_pass_t::run(decomp::symbol_t* sym) {
if (!has_legit_reloc(sym)) std::optional<recomp::reloc_t*> reloc;
if (!(reloc = has_legit_reloc(sym)).has_value())
return; return;
spdlog::info("adding transformations to relocation in symbol: {}", spdlog::info("adding transformations to relocation in symbol: {}",
@ -25,9 +26,47 @@ void reloc_transform_pass_t::run(decomp::symbol_t* sym) {
assert(err == XED_ERROR_NONE); assert(err == XED_ERROR_NONE);
} }
// determine how many transformations we will generate...
//
auto num_transforms = transform::operation_t::random(1, 10);
auto num_ops = transform::operations.size();
for (auto cnt = 0u; cnt < num_transforms; ++cnt) {
// generate random imm value...
//
std::size_t imm = transform::operation_t::random(
0, std::numeric_limits<std::size_t>::max());
// get a random transformation...
//
auto itr = transform::operations.begin();
std::advance(itr, transform::operation_t::random(0, num_ops - 1));
// generate the native code for the transformation...
//
auto transform_bytes = itr->second->native(&inst, imm);
// insert the bytes of the native instruction into the data buffer...
//
sym->data().insert(sym->data().end(), transform_bytes.begin(),
transform_bytes.end());
// add the inverse operation to the relocation for encrypting the relocation
// pointer...
//
reloc.value()->add_transform(
{transform::operations[itr->second->inverse()]->get_transform(), imm});
}
// inverse the order in which the transformations are executed...
//
std::reverse(reloc.value()->get_transforms().begin(),
reloc.value()->get_transforms().end());
}; };
bool reloc_transform_pass_t::has_legit_reloc(decomp::symbol_t* sym) { std::optional<recomp::reloc_t*> reloc_transform_pass_t::has_legit_reloc(
decomp::symbol_t* sym) {
auto res = // see if there are any relocations with offset not equal to auto res = // see if there are any relocations with offset not equal to
// zero... relocations with zero mean its a relocation to the next // zero... relocations with zero mean its a relocation to the next
// instruction... // instruction...
@ -35,6 +74,7 @@ bool reloc_transform_pass_t::has_legit_reloc(decomp::symbol_t* sym) {
sym->relocs().begin(), sym->relocs().end(), sym->relocs().begin(), sym->relocs().end(),
[&](recomp::reloc_t& reloc) -> bool { return reloc.offset(); }); [&](recomp::reloc_t& reloc) -> bool { return reloc.offset(); });
return res != sym->relocs().end(); return res != sym->relocs().end() ? res._Ptr
: std::optional<recomp::reloc_t*>();
} }
} // namespace theo::obf } // namespace theo::obf

@ -1,14 +0,0 @@
#include <obf/transform/add_op.hpp>
namespace theo::obf::transform {
add_op_t* add_op_t::get() {
static add_op_t obj;
return &obj;
}
std::vector<std::uint8_t> add_op_t::native(xed_inst_t* inst, std::size_t imm) {
auto op = xed_inst_operand(inst, 0);
auto reg = xed_operand_reg(op);
return {};
}
} // namespace theo::comp::obf::transform
Loading…
Cancel
Save