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