parent
c666bf8dbe
commit
9cf6cc8f03
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <algorithm>
|
||||
#include <comp/obf/pass.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace theo::comp::obf {
|
||||
class engine_t {
|
||||
explicit engine_t(){};
|
||||
|
||||
public:
|
||||
static engine_t* get();
|
||||
void add_pass(pass_t* pass);
|
||||
void run(decomp::symbol_t* sym);
|
||||
|
||||
private:
|
||||
std::vector<pass_t*> passes;
|
||||
};
|
||||
} // namespace theo::comp::obf
|
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <decomp/symbol.hpp>
|
||||
|
||||
#define XED_ENCODER
|
||||
extern "C" {
|
||||
#include <xed-decode.h>
|
||||
#include <xed-interface.h>
|
||||
}
|
||||
|
||||
namespace theo::comp::obf {
|
||||
class pass_t {
|
||||
public:
|
||||
explicit pass_t(decomp::sym_type_t sym_type) : m_sym_type(sym_type){};
|
||||
virtual void run(decomp::symbol_t* sym) = 0;
|
||||
decomp::sym_type_t sym_type() { return m_sym_type; }
|
||||
|
||||
private:
|
||||
decomp::sym_type_t m_sym_type;
|
||||
};
|
||||
} // namespace theo::comp::obf
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include <comp/obf/pass.hpp>
|
||||
|
||||
namespace theo::comp::obf {
|
||||
class jcc_rewrite_pass_t : public pass_t {
|
||||
explicit jcc_rewrite_pass_t() : pass_t(decomp::sym_type_t::inst_split){};
|
||||
|
||||
public:
|
||||
static jcc_rewrite_pass_t* get() {
|
||||
static jcc_rewrite_pass_t obj;
|
||||
return &obj;
|
||||
}
|
||||
|
||||
void run(decomp::symbol_t* sym){};
|
||||
};
|
||||
} // namespace theo::comp::obf
|
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include <comp/obf/pass.hpp>
|
||||
|
||||
namespace theo::comp::obf {
|
||||
class next_inst_pass_t : public pass_t {
|
||||
explicit next_inst_pass_t() : pass_t(decomp::sym_type_t::inst_split){};
|
||||
|
||||
public:
|
||||
static next_inst_pass_t* get() {
|
||||
static next_inst_pass_t obj;
|
||||
return &obj;
|
||||
}
|
||||
|
||||
void run(decomp::symbol_t* sym){};
|
||||
};
|
||||
} // namespace theo::comp::obf
|
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include <comp/obf/pass.hpp>
|
||||
|
||||
namespace theo::comp::obf {
|
||||
class reloc_transform_pass_t : public pass_t {
|
||||
explicit reloc_transform_pass_t() : pass_t(decomp::sym_type_t::inst_split){};
|
||||
|
||||
public:
|
||||
static reloc_transform_pass_t* get();
|
||||
void run(decomp::symbol_t* sym);
|
||||
|
||||
private:
|
||||
bool has_legit_reloc(decomp::symbol_t* sym);
|
||||
};
|
||||
} // namespace theo::comp::obf
|
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include <comp/obf/transform/operation.hpp>
|
||||
|
||||
namespace theo::comp::obf::transform {
|
||||
class add_op_t : operation_t {
|
||||
explicit add_op_t()
|
||||
: operation_t([&](std::size_t val,
|
||||
std::size_t imm) -> std::size_t { return val + imm; },
|
||||
type_t::add_op) {}
|
||||
|
||||
public:
|
||||
static add_op_t* get();
|
||||
std::vector<std::uint8_t> native(xed_inst_t* inst, std::size_t imm);
|
||||
};
|
||||
} // namespace theo::comp::obf::transform
|
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
#define XED_ENCODER
|
||||
extern "C" {
|
||||
#include <xed-decode.h>
|
||||
#include <xed-interface.h>
|
||||
}
|
||||
|
||||
namespace theo::comp::obf::transform {
|
||||
using transform_t = std::function<std::size_t(std::size_t, std::size_t)>;
|
||||
|
||||
class operation_t {
|
||||
public:
|
||||
enum type_t { add_op, sub_op, and_op, or_op, rol_op, ror_op, xor_op };
|
||||
|
||||
explicit operation_t(transform_t op, type_t type)
|
||||
: m_transform(op), m_type(type) {}
|
||||
|
||||
virtual std::vector<std::uint8_t> native(xed_inst_t* inst,
|
||||
std::size_t imm) = 0;
|
||||
|
||||
type_t inverse() { return m_inverse_op[m_type]; }
|
||||
transform_t get_transform() { return m_transform; }
|
||||
|
||||
private:
|
||||
transform_t m_transform;
|
||||
type_t m_type;
|
||||
|
||||
std::map<type_t, type_t> m_inverse_op = {
|
||||
{add_op, sub_op}, {sub_op, add_op}, {and_op, or_op}, {or_op, and_op},
|
||||
{rol_op, ror_op}, {ror_op, rol_op}, {xor_op, xor_op}};
|
||||
};
|
||||
|
||||
} // namespace theo::comp::obf::transform
|
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include <comp/obf/transform/add_op.hpp>
|
||||
#include <comp/obf/transform/operation.hpp>
|
||||
#include <comp/obf/transform/sub_op.hpp>
|
||||
|
||||
namespace theo::comp::obf::transform {
|
||||
std::map<operation_t::type_t, operation_t*> operations;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
#include <comp/obf/engine.hpp>
|
||||
|
||||
namespace theo::comp::obf {
|
||||
engine_t* engine_t::get() {
|
||||
static engine_t obj;
|
||||
return &obj;
|
||||
}
|
||||
|
||||
void engine_t::add_pass(pass_t* pass) {
|
||||
passes.push_back(pass);
|
||||
}
|
||||
|
||||
void engine_t::run(decomp::symbol_t* sym) {
|
||||
std::for_each(passes.begin(), passes.end(), [&](pass_t* pass) {
|
||||
if (sym->type() == pass->sym_type())
|
||||
pass->run(sym);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace theo::comp::obf
|
@ -0,0 +1,39 @@
|
||||
#include <comp/obf/passes/reloc_transform_pass.hpp>
|
||||
|
||||
namespace theo::comp::obf {
|
||||
reloc_transform_pass_t* reloc_transform_pass_t::get() {
|
||||
static reloc_transform_pass_t obj;
|
||||
return &obj;
|
||||
}
|
||||
|
||||
void reloc_transform_pass_t::run(decomp::symbol_t* sym) {
|
||||
if (!has_legit_reloc(sym))
|
||||
return;
|
||||
|
||||
spdlog::info("adding transformations to relocation in symbol: {}",
|
||||
sym->name());
|
||||
|
||||
xed_error_enum_t err;
|
||||
xed_decoded_inst_t inst;
|
||||
xed_state_t istate{XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b};
|
||||
xed_decoded_inst_zero_set_mode(&inst, &istate);
|
||||
|
||||
if ((err = xed_decode(&inst, sym->data().data(), sym->data().size())) !=
|
||||
XED_ERROR_NONE) {
|
||||
spdlog::error("failed to decode instruction, reason: {} in symbol: {}",
|
||||
xed_error_enum_t2str(err), sym->name());
|
||||
|
||||
assert(err == XED_ERROR_NONE);
|
||||
}
|
||||
};
|
||||
|
||||
bool reloc_transform_pass_t::has_legit_reloc(decomp::symbol_t* sym) {
|
||||
auto res = // see if there are any relocations with offset not equal to
|
||||
// zero... relocations with zero mean its a relocation to the next
|
||||
// instruction...
|
||||
std::find_if(sym->relocs().begin(), sym->relocs().end(),
|
||||
[&](reloc_t& reloc) -> bool { return reloc.offset(); });
|
||||
|
||||
return res != sym->relocs().end();
|
||||
}
|
||||
} // namespace theo::comp::obf
|
@ -0,0 +1,14 @@
|
||||
#include <comp/obf/transform/add_op.hpp>
|
||||
|
||||
namespace theo::comp::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…
Reference in new issue