refactored the code so that there are 3 main namespaces: decomp, obf,

and recomp...
3.0
_xeroxz 2 years ago
parent 9cf6cc8f03
commit 78f2b39b71

@ -54,38 +54,38 @@ set(CMKR_TARGET Theodosius)
set(Theodosius_SOURCES "")
list(APPEND Theodosius_SOURCES
"include/comp/comp.hpp"
"include/comp/obf/engine.hpp"
"include/comp/obf/pass.hpp"
"include/comp/obf/passes/jcc_rewrite_pass.hpp"
"include/comp/obf/passes/next_inst_pass.hpp"
"include/comp/obf/passes/reloc_transform_pass.hpp"
"include/comp/obf/transform/add_op.hpp"
"include/comp/obf/transform/and_op.hpp"
"include/comp/obf/transform/operation.hpp"
"include/comp/obf/transform/or_op.hpp"
"include/comp/obf/transform/rol_op.hpp"
"include/comp/obf/transform/ror_op.hpp"
"include/comp/obf/transform/sub_op.hpp"
"include/comp/obf/transform/transform.hpp"
"include/comp/obf/transform/xor_op.hpp"
"include/comp/reloc.hpp"
"include/comp/symbol_table.hpp"
"include/decomp/decomp.hpp"
"include/decomp/routine.hpp"
"include/decomp/symbol.hpp"
"include/obf/engine.hpp"
"include/obf/pass.hpp"
"include/obf/passes/jcc_rewrite_pass.hpp"
"include/obf/passes/next_inst_pass.hpp"
"include/obf/passes/reloc_transform_pass.hpp"
"include/obf/transform/add_op.hpp"
"include/obf/transform/and_op.hpp"
"include/obf/transform/operation.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/transform.hpp"
"include/obf/transform/xor_op.hpp"
"include/recomp/recomp.hpp"
"include/recomp/reloc.hpp"
"include/recomp/symbol_table.hpp"
"include/theo.hpp"
"src/theo/comp/comp.cpp"
"src/theo/comp/obf/engine.cpp"
"src/theo/comp/obf/passes/jcc_rewrite_pass.cpp"
"src/theo/comp/obf/passes/next_inst_pass.cpp"
"src/theo/comp/obf/passes/reloc_transform_pass.cpp"
"src/theo/comp/obf/transform/add_op.cpp"
"src/theo/comp/obf/transform/sub_op.cpp"
"src/theo/comp/symbol_table.cpp"
"src/theo/decomp/decomp.cpp"
"src/theo/decomp/routine.cpp"
"src/theo/decomp/symbol.cpp"
"src/theo/obf/engine.cpp"
"src/theo/obf/passes/jcc_rewrite_pass.cpp"
"src/theo/obf/passes/next_inst_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/symbol_table.cpp"
"src/theo/theo.cpp"
)

@ -5,8 +5,8 @@
#include <optional>
#include <vector>
#include <comp/symbol_table.hpp>
#include <decomp/routine.hpp>
#include <recomp/symbol_table.hpp>
#include <coff/archive.hpp>
#include <coff/image.hpp>
@ -14,20 +14,21 @@
namespace theo::decomp {
class decomp_t {
public:
explicit decomp_t(std::vector<std::uint8_t>& lib, comp::symbol_table_t* syms);
explicit decomp_t(std::vector<std::uint8_t>& lib,
recomp::symbol_table_t* syms);
std::vector<routine_t> rtns();
std::vector<std::uint8_t> lib();
std::vector<coff::image_t*> objs();
comp::symbol_table_t* syms();
recomp::symbol_table_t* syms();
std::map<coff::section_header_t*, std::size_t>& scn_hash_tbl();
std::optional<comp::symbol_table_t*> decompose();
std::optional<recomp::symbol_table_t*> decompose();
private:
const std::vector<std::uint8_t> m_lib;
std::vector<coff::image_t*> m_objs;
std::vector<routine_t> m_rtns;
std::map<coff::section_header_t*, std::size_t> m_scn_hash_tbl;
comp::symbol_table_t* m_syms;
recomp::symbol_table_t* m_syms;
};
} // namespace theo::decomp

@ -1,6 +1,6 @@
#pragma once
#include <coff/image.hpp>
#include <comp/reloc.hpp>
#include <recomp/reloc.hpp>
#include <cstdint>
#include <string>
#include <vector>
@ -15,7 +15,7 @@ class symbol_t {
std::vector<std::uint8_t> data,
coff::section_header_t* scn = {},
coff::symbol_t* sym = {},
std::vector<comp::reloc_t> relocs = {},
std::vector<recomp::reloc_t> relocs = {},
sym_type_t dcmp_type = {});
std::string name() const;
@ -26,7 +26,7 @@ class symbol_t {
std::vector<std::uint8_t>& data();
coff::symbol_t* sym() const;
sym_type_t type() const;
std::vector<comp::reloc_t>& relocs();
std::vector<recomp::reloc_t>& relocs();
void allocated_at(std::uintptr_t allocated_at);
std::size_t hash();
@ -37,7 +37,7 @@ class symbol_t {
std::uintptr_t m_offset, m_allocated_at;
std::vector<std::uint8_t> m_data;
coff::section_header_t* m_scn;
std::vector<comp::reloc_t> m_relocs;
std::vector<recomp::reloc_t> m_relocs;
sym_type_t m_sym_type;
coff::symbol_t* m_sym;
};

@ -1,9 +1,9 @@
#pragma once
#include <algorithm>
#include <comp/obf/pass.hpp>
#include <obf/pass.hpp>
#include <vector>
namespace theo::comp::obf {
namespace theo::obf {
class engine_t {
explicit engine_t(){};

@ -8,7 +8,7 @@ extern "C" {
#include <xed-interface.h>
}
namespace theo::comp::obf {
namespace theo::obf {
class pass_t {
public:
explicit pass_t(decomp::sym_type_t sym_type) : m_sym_type(sym_type){};

@ -1,7 +1,7 @@
#pragma once
#include <comp/obf/pass.hpp>
#include <obf/pass.hpp>
namespace theo::comp::obf {
namespace theo::obf {
class jcc_rewrite_pass_t : public pass_t {
explicit jcc_rewrite_pass_t() : pass_t(decomp::sym_type_t::inst_split){};

@ -1,7 +1,7 @@
#pragma once
#include <comp/obf/pass.hpp>
#include <obf/pass.hpp>
namespace theo::comp::obf {
namespace theo::obf {
class next_inst_pass_t : public pass_t {
explicit next_inst_pass_t() : pass_t(decomp::sym_type_t::inst_split){};

@ -1,7 +1,7 @@
#pragma once
#include <comp/obf/pass.hpp>
#include <obf/pass.hpp>
namespace theo::comp::obf {
namespace theo::obf {
class reloc_transform_pass_t : public pass_t {
explicit reloc_transform_pass_t() : pass_t(decomp::sym_type_t::inst_split){};

@ -1,8 +1,8 @@
#pragma once
#include <comp/obf/transform/operation.hpp>
#include <obf/transform/operation.hpp>
namespace theo::comp::obf::transform {
class add_op_t : operation_t {
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; },
@ -12,4 +12,4 @@ class add_op_t : operation_t {
static add_op_t* get();
std::vector<std::uint8_t> native(xed_inst_t* inst, std::size_t imm);
};
} // namespace theo::comp::obf::transform
} // namespace theo::obf::transform

@ -8,7 +8,7 @@ extern "C" {
#include <xed-interface.h>
}
namespace theo::comp::obf::transform {
namespace theo::obf::transform {
using transform_t = std::function<std::size_t(std::size_t, std::size_t)>;
class operation_t {
@ -33,4 +33,4 @@ class operation_t {
{rol_op, ror_op}, {ror_op, rol_op}, {xor_op, xor_op}};
};
} // namespace theo::comp::obf::transform
} // namespace theo::obf::transform

@ -4,5 +4,6 @@
#include <comp/obf/transform/sub_op.hpp>
namespace theo::comp::obf::transform {
std::map<operation_t::type_t, operation_t*> operations;
std::map<operation_t::type_t, operation_t*> operations = {
{operation_t::type_t::add_op, add_op_t::get()}};
}

@ -1,19 +1,19 @@
#pragma once
#include <comp/obf/engine.hpp>
#include <comp/symbol_table.hpp>
#include <obf/engine.hpp>
#include <recomp/symbol_table.hpp>
#include <decomp/decomp.hpp>
namespace theo::comp {
namespace theo::recomp {
using resolver_t = std::function<std::uintptr_t(std::string)>;
using copier_t = std::function<void(std::uintptr_t, void*, std::uint32_t)>;
using allocator_t =
std::function<std::uintptr_t(std::uint32_t,
coff::section_characteristics_t)>;
class comp_t {
class recomp_t {
public:
explicit comp_t(decomp::decomp_t* dcmp);
explicit comp_t(decomp::decomp_t* dcmp,
explicit recomp_t(decomp::decomp_t* dcmp);
explicit recomp_t(decomp::decomp_t* dcmp,
allocator_t alloc,
copier_t copy,
resolver_t resolve);

@ -2,7 +2,7 @@
#include <cstddef>
#include <cstdint>
namespace theo::comp {
namespace theo::recomp {
class reloc_t {
public:
explicit reloc_t(std::uint16_t offset,

@ -7,7 +7,7 @@
#include <decomp/symbol.hpp>
namespace theo::comp {
namespace theo::recomp {
class symbol_table_t {
public:
symbol_table_t() {}

@ -1,12 +1,13 @@
#pragma once
#include <spdlog/spdlog.h>
#include <comp/comp.hpp>
#include <comp/obf/engine.hpp>
#include <decomp/decomp.hpp>
#include <obf/engine.hpp>
#include <recomp/recomp.hpp>
#include <recomp/symbol_table.hpp>
#include <comp/obf/passes/reloc_transform_pass.hpp>
#include <comp/obf/passes/next_inst_pass.hpp>
#include <comp/obf/passes/jcc_rewrite_pass.hpp>
#include <obf/passes/jcc_rewrite_pass.hpp>
#include <obf/passes/next_inst_pass.hpp>
#include <obf/passes/reloc_transform_pass.hpp>
#include <optional>
#include <tuple>
@ -20,7 +21,7 @@ extern "C" {
namespace theo {
using lnk_fns_t =
std::tuple<comp::allocator_t, comp::copier_t, comp::resolver_t>;
std::tuple<recomp::allocator_t, recomp::copier_t, recomp::resolver_t>;
class theo_t {
public:
@ -32,7 +33,7 @@ class theo_t {
private:
decomp::decomp_t m_dcmp;
comp::comp_t m_cmp;
comp::symbol_table_t m_sym_tbl;
recomp::recomp_t m_recmp;
recomp::symbol_table_t m_sym_tbl;
};
} // namespace theo

@ -18,7 +18,7 @@ int main(int argc, char* argv[]) {
fdata.resize(fsize);
f.read((char*)fdata.data(), fsize);
theo::comp::allocator_t allocator =
theo::recomp::allocator_t allocator =
[&](std::uint32_t size,
coff::section_characteristics_t section_type) -> std::uintptr_t {
return reinterpret_cast<std::uintptr_t>(VirtualAlloc(
@ -26,12 +26,12 @@ int main(int argc, char* argv[]) {
section_type.mem_execute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE));
};
theo::comp::copier_t copier = [&](std::uintptr_t ptr, void* buff,
theo::recomp::copier_t copier = [&](std::uintptr_t ptr, void* buff,
std::uint32_t size) {
std::memcpy((void*)ptr, buff, size);
};
theo::comp::resolver_t resolver = [&](std::string sym) -> std::uintptr_t {
theo::recomp::resolver_t resolver = [&](std::string sym) -> std::uintptr_t {
return reinterpret_cast<std::uintptr_t>(
GetProcAddress(LoadLibraryA("user32.dll"), sym.data()));
};

@ -1,10 +1,10 @@
#include <decomp/decomp.hpp>
namespace theo::decomp {
decomp_t::decomp_t(std::vector<std::uint8_t>& lib, comp::symbol_table_t* syms)
decomp_t::decomp_t(std::vector<std::uint8_t>& lib, recomp::symbol_table_t* syms)
: m_lib(lib), m_syms(syms) {}
std::optional<comp::symbol_table_t*> decomp_t::decompose() {
std::optional<recomp::symbol_table_t*> decomp_t::decompose() {
// extract obj files from the archive file...
//
ar::view<false> lib(m_lib.data(), m_lib.size());
@ -148,7 +148,7 @@ std::vector<coff::image_t*> decomp_t::objs() {
return m_objs;
}
comp::symbol_table_t* decomp_t::syms() {
recomp::symbol_table_t* decomp_t::syms() {
return m_syms;
}

@ -13,7 +13,7 @@ std::vector<decomp::symbol_t> routine_t::decompose() {
switch (m_dcmp_type) {
case function: {
std::vector<comp::reloc_t> relocs;
std::vector<recomp::reloc_t> relocs;
auto scn_relocs = reinterpret_cast<coff::reloc_t*>(
m_scn->ptr_relocs + reinterpret_cast<std::uint8_t*>(m_img));
@ -27,7 +27,7 @@ std::vector<decomp::symbol_t> routine_t::decompose() {
m_sym->name.to_string(m_img->get_strings()), sym_name,
sym_hash, scn_reloc->virtual_address);
relocs.push_back(comp::reloc_t(scn_reloc->virtual_address, sym_hash,
relocs.push_back(recomp::reloc_t(scn_reloc->virtual_address, sym_hash,
sym_name.data()));
}
@ -58,7 +58,7 @@ std::vector<decomp::symbol_t> routine_t::decompose() {
if (offset)
new_sym_name.append("@").append(std::to_string(offset));
std::vector<comp::reloc_t> relocs;
std::vector<recomp::reloc_t> relocs;
auto scn_relocs = reinterpret_cast<coff::reloc_t*>(
m_scn->ptr_relocs + reinterpret_cast<std::uint8_t*>(m_img));
@ -85,7 +85,7 @@ std::vector<decomp::symbol_t> routine_t::decompose() {
reloc_offset);
relocs.push_back(
comp::reloc_t(reloc_offset, sym_hash, sym_name.data()));
recomp::reloc_t(reloc_offset, sym_hash, sym_name.data()));
}
// add a reloc to the next instruction...
@ -98,7 +98,7 @@ std::vector<decomp::symbol_t> routine_t::decompose() {
.append(std::to_string(offset +
xed_decoded_inst_get_length(&instr)));
relocs.push_back(comp::reloc_t(0, decomp::symbol_t::hash(next_inst_sym),
relocs.push_back(recomp::reloc_t(0, decomp::symbol_t::hash(next_inst_sym),
next_inst_sym.data()));
// get the instructions bytes
@ -126,8 +126,8 @@ std::vector<decomp::symbol_t> routine_t::decompose() {
// remove the relocation to the next symbol from the last instruction
//
auto last_inst = result.back();
auto last_inst_relocs = last_inst.relocs();
auto& last_inst = result.back();
auto& last_inst_relocs = last_inst.relocs();
last_inst_relocs.erase(last_inst_relocs.end() - 1);
break;
}

@ -6,7 +6,7 @@ symbol_t::symbol_t(std::string name,
std::vector<std::uint8_t> data,
coff::section_header_t* scn,
coff::symbol_t* sym,
std::vector<comp::reloc_t> relocs,
std::vector<recomp::reloc_t> relocs,
sym_type_t dcmp_type)
: m_name(name),
m_offset(offset),
@ -57,7 +57,7 @@ coff::symbol_t* symbol_t::sym() const {
return m_sym;
}
std::vector<comp::reloc_t>& symbol_t::relocs() {
std::vector<recomp::reloc_t>& symbol_t::relocs() {
return m_relocs;
}

@ -1,6 +1,6 @@
#include <comp/obf/engine.hpp>
#include <obf/engine.hpp>
namespace theo::comp::obf {
namespace theo::obf {
engine_t* engine_t::get() {
static engine_t obj;
return &obj;

@ -1,6 +1,6 @@
#include <comp/obf/passes/reloc_transform_pass.hpp>
#include <obf/passes/reloc_transform_pass.hpp>
namespace theo::comp::obf {
namespace theo::obf {
reloc_transform_pass_t* reloc_transform_pass_t::get() {
static reloc_transform_pass_t obj;
return &obj;
@ -31,9 +31,10 @@ 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(); });
std::find_if(
sym->relocs().begin(), sym->relocs().end(),
[&](recomp::reloc_t& reloc) -> bool { return reloc.offset(); });
return res != sym->relocs().end();
}
} // namespace theo::comp::obf
} // namespace theo::obf

@ -1,6 +1,6 @@
#include <comp/obf/transform/add_op.hpp>
#include <obf/transform/add_op.hpp>
namespace theo::comp::obf::transform {
namespace theo::obf::transform {
add_op_t* add_op_t::get() {
static add_op_t obj;
return &obj;

@ -1,14 +1,14 @@
#include <comp/comp.hpp>
#include <recomp/recomp.hpp>
namespace theo::comp {
comp_t::comp_t(decomp::decomp_t* dcmp) : m_dcmp(dcmp) {}
comp_t::comp_t(decomp::decomp_t* dcmp,
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)
: m_dcmp(dcmp), m_allocator(alloc), m_copier(copy), m_resolver(resolve) {}
void comp_t::allocate() {
void recomp_t::allocate() {
// map code & data/rdata/bss sections first...
//
m_dcmp->syms()->for_each([&](theo::decomp::symbol_t& sym) {
@ -60,7 +60,7 @@ void comp_t::allocate() {
});
}
void comp_t::resolve() {
void recomp_t::resolve() {
// resolve relocations in all symbols...
//
m_dcmp->syms()->for_each([&](theo::decomp::symbol_t& sym) {
@ -109,7 +109,7 @@ void comp_t::resolve() {
});
}
void comp_t::copy_syms() {
void recomp_t::copy_syms() {
// copy symbols into memory using the copier supplied...
//
m_dcmp->syms()->for_each([&](theo::decomp::symbol_t& sym) {
@ -117,19 +117,19 @@ void comp_t::copy_syms() {
});
}
void comp_t::allocator(allocator_t alloc) {
void recomp_t::allocator(allocator_t alloc) {
m_allocator = alloc;
}
void comp_t::copier(copier_t copy) {
void recomp_t::copier(copier_t copy) {
m_copier = copy;
}
void comp_t::resolver(resolver_t resolve) {
void recomp_t::resolver(resolver_t resolve) {
m_resolver = resolve;
}
std::uintptr_t comp_t::resolve(const std::string&& sym) {
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;
}

@ -1,6 +1,6 @@
#include <comp/symbol_table.hpp>
#include <recomp/symbol_table.hpp>
namespace theo::comp {
namespace theo::recomp {
symbol_table_t::symbol_table_t(const std::vector<decomp::symbol_t>&& syms) {
std::for_each(syms.begin(), syms.end(), [&](decomp::symbol_t sym) {
m_table.insert({sym.hash(), sym});

@ -2,7 +2,7 @@
namespace theo {
theo_t::theo_t(std::vector<std::uint8_t>& lib, lnk_fns_t lnkr_fns)
: m_dcmp(lib, &m_sym_tbl), m_cmp(&m_dcmp) {
: m_dcmp(lib, &m_sym_tbl), m_recmp(&m_dcmp) {
// init enc/dec tables only once... add obfuscation passes to the engine...
//
if (static std::atomic_bool v = true; v.exchange(false)) {
@ -11,15 +11,15 @@ theo_t::theo_t(std::vector<std::uint8_t>& lib, lnk_fns_t lnkr_fns)
// order matters, the order in which the pass is added is the order they
// will be executed!
//
auto engine = comp::obf::engine_t::get();
engine->add_pass(comp::obf::reloc_transform_pass_t::get());
engine->add_pass(comp::obf::next_inst_pass_t::get());
engine->add_pass(comp::obf::jcc_rewrite_pass_t::get());
auto engine = obf::engine_t::get();
engine->add_pass(obf::reloc_transform_pass_t::get());
engine->add_pass(obf::next_inst_pass_t::get());
engine->add_pass(obf::jcc_rewrite_pass_t::get());
}
m_cmp.allocator(std::get<0>(lnkr_fns));
m_cmp.copier(std::get<1>(lnkr_fns));
m_cmp.resolver(std::get<2>(lnkr_fns));
m_recmp.allocator(std::get<0>(lnkr_fns));
m_recmp.copier(std::get<1>(lnkr_fns));
m_recmp.resolver(std::get<2>(lnkr_fns));
}
std::optional<std::uint32_t> theo_t::decompose() {
@ -39,12 +39,12 @@ std::optional<std::uint32_t> theo_t::decompose() {
std::uintptr_t theo_t::compose(const std::string&& entry_sym) {
// run obfuscation engine on all symbols...
//
auto engine = comp::obf::engine_t::get();
auto engine = obf::engine_t::get();
m_sym_tbl.for_each([&](decomp::symbol_t& sym) { engine->run(&sym); });
m_cmp.allocate();
m_cmp.resolve();
m_cmp.copy_syms();
return m_cmp.resolve(entry_sym.data());
m_recmp.allocate();
m_recmp.resolve();
m_recmp.copy_syms();
return m_recmp.resolve(entry_sym.data());
}
} // namespace theo
Loading…
Cancel
Save