finished relocation transformation pass... todo write other passes and

also move the code that checks to see if the section is .obf to outside
of routine_t so that you can re-use routine_t to decompose entire
functions after running them through obfuscation passes....
3.0
_xeroxz 2 years ago
parent 9199d5bef7
commit df0ba19093

@ -5,7 +5,7 @@ namespace theo::obf::transform {
class add_op_t : public operation_t {
explicit add_op_t()
: operation_t([&](std::size_t val,
std::size_t imm) -> std::size_t { return val + imm; },
std::uint32_t imm) -> std::size_t { return val + imm; },
XED_ICLASS_ADD) {}
public:

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

@ -11,7 +11,7 @@ extern "C" {
}
namespace theo::obf::transform {
using transform_t = std::function<std::size_t(std::size_t, std::size_t)>;
using transform_t = std::function<std::size_t(std::size_t, std::uint32_t)>;
class operation_t {
public:
@ -20,22 +20,28 @@ class operation_t {
std::vector<std::uint8_t> native(const xed_decoded_inst_t* inst,
std::size_t imm) {
std::uint32_t inst_len = {};
std::uint8_t inst_buff[XED_MAX_INSTRUCTION_BYTES];
xed_error_enum_t err;
xed_encoder_request_t req;
xed_encoder_request_init_from_decode((xed_decoded_inst_s*)inst);
xed_encoder_request_t* req = (xed_encoder_request_t*)inst;
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);
switch (m_type) {
case XED_ICLASS_ROR:
case XED_ICLASS_ROL:
xed_encoder_request_set_uimm0(req, imm, 1);
break;
default:
xed_encoder_request_set_uimm0(req, imm, 4);
break;
}
std::uint8_t inst_buff[XED_MAX_INSTRUCTION_BYTES];
std::uint32_t inst_len = {};
xed_encoder_request_set_iclass(req, m_type);
xed_encoder_request_set_operand_order(req, 1, XED_OPERAND_IMM0);
if ((err = xed_encode(&req, inst_buff, sizeof(inst_buff), &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));

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

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

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

@ -5,7 +5,7 @@ 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; },
std::uint32_t imm) -> std::size_t { return val - imm; },
XED_ICLASS_SUB) {}
public:

@ -1,10 +1,18 @@
#pragma once
#include <obf/transform/add_op.hpp>
#include <obf/transform/operation.hpp>
#include <obf/transform/add_op.hpp>
#include <obf/transform/and_op.hpp>
#include <obf/transform/or_op.hpp>
#include <obf/transform/rol_op.hpp>
#include <obf/transform/ror_op.hpp>
#include <obf/transform/sub_op.hpp>
#include <obf/transform/xor_op.hpp>
namespace theo::obf::transform {
inline std::map<xed_iclass_enum_t, operation_t*> operations = {
{XED_ICLASS_ADD, add_op_t::get()},
{XED_ICLASS_SUB, sub_op_t::get()}};
{XED_ICLASS_ADD, add_op_t::get()}, {XED_ICLASS_SUB, sub_op_t::get()},
{XED_ICLASS_AND, and_op_t::get()}, {XED_ICLASS_OR, or_op_t::get()},
{XED_ICLASS_ROL, rol_op_t::get()}, {XED_ICLASS_ROR, ror_op_t::get()},
{XED_ICLASS_XOR, xor_op_t::get()}};
}

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

@ -48,4 +48,5 @@ int main(int argc, char* argv[]) {
auto entry_pnt = t.compose("EntryPoint");
spdlog::info("entry point address: {:X}", entry_pnt);
// reinterpret_cast<void (*)()>(entry_pnt)();
std::getchar();
}

@ -3,9 +3,9 @@
namespace theo::recomp {
recomp_t::recomp_t(decomp::decomp_t* dcmp) : m_dcmp(dcmp) {}
recomp_t::recomp_t(decomp::decomp_t* dcmp,
allocator_t alloc,
copier_t copy,
resolver_t resolve)
allocator_t alloc,
copier_t copy,
resolver_t resolve)
: m_dcmp(dcmp), m_allocator(alloc), m_copier(copy), m_resolver(resolve) {}
void recomp_t::allocate() {
@ -96,10 +96,20 @@ void recomp_t::resolve() {
break;
}
case decomp::sym_type_t::inst_split: {
// TODO: run the vector of transformation operations here if the
// symbol is of type inst_split... the transformations will be applied
// to allocate_at() result on the symbol...
// TODO: change this if statement into a sanity check with an assert
// after coding the next_inst_pass to ensure it works...
//
if (reloc.offset()) {
auto& transforms = reloc.get_transforms();
std::for_each(
transforms.begin(), transforms.end(),
[&](std::pair<obf::transform::transform_t*, std::size_t>& t) {
allocated_at = (*t.first)(allocated_at, t.second);
});
*reinterpret_cast<std::uintptr_t*>(sym.data().data() +
reloc.offset()) = allocated_at;
}
break;
}
default:
@ -133,4 +143,4 @@ std::uintptr_t recomp_t::resolve(const std::string&& sym) {
auto res = m_dcmp->syms()->sym_from_hash(decomp::symbol_t::hash(sym));
return res.has_value() ? res->allocated_at() : 0;
}
} // namespace theo::comp
} // namespace theo::recomp

@ -43,6 +43,10 @@ std::uintptr_t theo_t::compose(const std::string&& entry_sym) {
m_sym_tbl.for_each([&](decomp::symbol_t& sym) { engine->run(&sym); });
m_recmp.allocate();
m_sym_tbl.for_each([&](decomp::symbol_t& sym) {
spdlog::info("{} allocated at {:X}", sym.name(), sym.allocated_at());
});
m_recmp.resolve();
m_recmp.copy_syms();
return m_recmp.resolve(entry_sym.data());

Loading…
Cancel
Save