new pass system is done, old passes have been re-written to conform.

TODO: still need to write a pass to split functions into individual
instructions. I also need to add a pass for encrypting relocations.
master
_xeroxz 3 years ago
parent d744c6b585
commit 51d64b44b1

@ -36,8 +36,8 @@ namespace theo::obf {
/// <summary>
/// hello world pass example of how to inherit pass_t.
/// </summary>
class hello_world_pass_t : public pass_t {
hello_world_pass_t() : pass_t(decomp::sym_type_t::all) {
class hello_world_pass_t : public generic_pass_t {
hello_world_pass_t() : generic_pass_t(decomp::sym_type_t::all) {
spdlog::info("created hello world pass...");
}
@ -47,7 +47,7 @@ class hello_world_pass_t : public pass_t {
return &obj;
}
void run(decomp::symbol_t* sym) {
void generic_pass(decomp::symbol_t* sym) override {
spdlog::info("[hello_world_pass_t] symbol name: {}, symbol hash: {}",
sym->name(), sym->hash());
}

@ -82,7 +82,17 @@ class pass_t {
/// allows you to manipulate symbols in a generic manner.
/// </summary>
/// <param name="sym">a symbol of the same type of m_sym_type.</param>
virtual void pre_recomp_pass(decomp::symbol_t* sym) = 0;
virtual void generic_pass(decomp::symbol_t* sym) = 0;
/// <summary>
/// This virtual method is invoked prior to calling the "copier". This allows
/// you to manipulate the symbol prior to it being copied into memory.
/// </summary>
/// <param name="sym">Symbol being copied into memory.</param>
/// <param name="copier">copier lambda that the pass can use. if it does, then
/// you must return true.</param> <returns>returns true if the copy was done
/// by the pass. false if copying still needs to be done.</returns>
virtual bool copier_pass(decomp::symbol_t* sym, copier_t& copier) = 0;
/// <summary>
/// This virtual method is invoked prior to calling the "allocator". This
@ -100,16 +110,6 @@ class pass_t {
std::uint32_t size,
allocator_t& allocator) = 0;
/// <summary>
/// This virtual method is invoked prior to calling the "copier". This allows
/// you to manipulate the symbol prior to it being copied into memory.
/// </summary>
/// <param name="sym">Symbol being copied into memory.</param>
/// <param name="copier">copier lambda that the pass can use. if it does, then
/// you must return true.</param> <returns>returns true if the copy was done
/// by the pass. false if copying still needs to be done.</returns>
virtual bool copier_pass(decomp::symbol_t* sym, copier_t& copier) = 0;
/// <summary>
/// This virtual method is invoked before the call to the "resolver". This
/// allows you the manipulate the relocation address and symbol before
@ -134,4 +134,29 @@ class pass_t {
private:
decomp::sym_type_t m_sym_type;
};
/// <summary>
/// generic pass class overloads non-generic pass methods to return default
/// values... this makes it so generic passes dont need to overload all of these
/// methods and return default values every single time...
/// </summary>
class generic_pass_t : public pass_t {
public:
explicit generic_pass_t(decomp::sym_type_t sym_type) : pass_t(sym_type) {}
// default non-generic passes to return generic values...
//
bool copier_pass(decomp::symbol_t* sym, copier_t& copier) { return false; }
std::optional<std::uintptr_t> allocation_pass(decomp::symbol_t* sym,
std::uint32_t size,
allocator_t& allocator) {
return {};
}
std::optional<std::uintptr_t> resolver_pass(decomp::symbol_t* sym,
recomp::reloc_t* reloc,
std::uintptr_t allocated_t) {
return {};
}
};
} // namespace theo::obf

@ -58,11 +58,12 @@ namespace theo::obf {
/// of the next instruction. There is actually no jmp [rip] either, push/ret is
/// used.
/// </summary>
class jcc_rewrite_pass_t : public pass_t {
explicit jcc_rewrite_pass_t() : pass_t(decomp::sym_type_t::instruction) {}
class jcc_rewrite_pass_t : public generic_pass_t {
explicit jcc_rewrite_pass_t()
: generic_pass_t(decomp::sym_type_t::instruction) {}
public:
static jcc_rewrite_pass_t* get();
void run(decomp::symbol_t* sym);
void generic_pass(decomp::symbol_t* sym) override;
};
} // namespace theo::obf

@ -82,8 +82,9 @@ namespace theo::obf {
/// simply tells this pass that there needs to be a relocation to the next
/// symbol. the offset for these psuedo relocations is zero.
/// </summary>
class next_inst_pass_t : public pass_t {
explicit next_inst_pass_t() : pass_t(decomp::sym_type_t::instruction) {
class next_inst_pass_t : public generic_pass_t {
explicit next_inst_pass_t()
: generic_pass_t(decomp::sym_type_t::instruction) {
xed_state_t istate{XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b};
xed_decoded_inst_zero_set_mode(&m_tmp_inst, &istate);
xed_decode(&m_tmp_inst, m_type_inst_bytes, sizeof(m_type_inst_bytes));
@ -91,7 +92,7 @@ class next_inst_pass_t : public pass_t {
public:
static next_inst_pass_t* get();
void run(decomp::symbol_t* sym);
void generic_pass(decomp::symbol_t* sym) override;
private:
std::optional<recomp::reloc_t*> has_next_inst_reloc(decomp::symbol_t*);

@ -53,12 +53,13 @@ namespace theo::obf {
/// add rax, 0x345332567
/// ror rax, 0x5353
/// </summary>
class reloc_transform_pass_t : public pass_t {
explicit reloc_transform_pass_t() : pass_t(decomp::sym_type_t::instruction) {}
class reloc_transform_pass_t : public generic_pass_t {
explicit reloc_transform_pass_t()
: generic_pass_t(decomp::sym_type_t::instruction) {}
public:
static reloc_transform_pass_t* get();
void run(decomp::symbol_t* sym);
void generic_pass(decomp::symbol_t* sym) override;
private:
std::optional<recomp::reloc_t*> has_legit_reloc(decomp::symbol_t* sym);

@ -37,7 +37,7 @@ jcc_rewrite_pass_t* jcc_rewrite_pass_t::get() {
return &obj;
}
void jcc_rewrite_pass_t::run(decomp::symbol_t* sym) {
void jcc_rewrite_pass_t::generic_pass(decomp::symbol_t* sym) {
std::int32_t disp = {};
xed_decoded_inst_t inst;
xed_state_t istate{XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b};
@ -77,7 +77,7 @@ void jcc_rewrite_pass_t::run(decomp::symbol_t* sym) {
// run next_inst_pass on this symbol to generate the transformations for the
// relocation to the jcc branch dest instruction...
next_inst_pass_t::get()->run(sym);
next_inst_pass_t::get()->generic_pass(sym);
}
};
} // namespace theo::obf

@ -35,7 +35,8 @@ next_inst_pass_t* next_inst_pass_t::get() {
static next_inst_pass_t obj;
return &obj;
}
void next_inst_pass_t::run(decomp::symbol_t* sym) {
void next_inst_pass_t::generic_pass(decomp::symbol_t* sym) {
std::optional<recomp::reloc_t*> reloc;
if (!(reloc = has_next_inst_reloc(sym)).has_value())
return;

@ -36,7 +36,7 @@ reloc_transform_pass_t* reloc_transform_pass_t::get() {
return &obj;
}
void reloc_transform_pass_t::run(decomp::symbol_t* sym) {
void reloc_transform_pass_t::generic_pass(decomp::symbol_t* sym) {
std::optional<recomp::reloc_t*> reloc;
if (!(reloc = has_legit_reloc(sym)).has_value())
return;

@ -59,7 +59,7 @@ std::uintptr_t theo_t::compose() {
auto engine = obf::engine_t::get();
m_sym_tbl.for_each([&](decomp::symbol_t& sym) {
engine->for_each(&sym, [&](decomp::symbol_t* sym, obf::pass_t* pass) {
pass->pre_recomp_pass(sym);
pass->generic_pass(sym);
});
});

Loading…
Cancel
Save