finished coding transformations, next_inst_pass, jcc_rewrite_pass and

reloc_transform_pass are all done....
3.0
_xeroxz 3 years ago
parent df0ba19093
commit c7eb3c83bf

@ -63,9 +63,7 @@ list(APPEND Theodosius_SOURCES
"include/obf/passes/next_inst_pass.hpp" "include/obf/passes/next_inst_pass.hpp"
"include/obf/passes/reloc_transform_pass.hpp" "include/obf/passes/reloc_transform_pass.hpp"
"include/obf/transform/add_op.hpp" "include/obf/transform/add_op.hpp"
"include/obf/transform/and_op.hpp"
"include/obf/transform/operation.hpp" "include/obf/transform/operation.hpp"
"include/obf/transform/or_op.hpp"
"include/obf/transform/rol_op.hpp" "include/obf/transform/rol_op.hpp"
"include/obf/transform/ror_op.hpp" "include/obf/transform/ror_op.hpp"
"include/obf/transform/sub_op.hpp" "include/obf/transform/sub_op.hpp"

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <coff/image.hpp> #include <coff/image.hpp>
#include <recomp/reloc.hpp>
#include <cstdint> #include <cstdint>
#include <recomp/reloc.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
@ -10,7 +10,8 @@ enum sym_type_t { function, inst_split, data, section };
class symbol_t { class symbol_t {
public: public:
explicit symbol_t(std::string name, explicit symbol_t(coff::image_t* img,
std::string name,
std::uintptr_t offset, std::uintptr_t offset,
std::vector<std::uint8_t> data, std::vector<std::uint8_t> data,
coff::section_header_t* scn = {}, coff::section_header_t* scn = {},
@ -23,6 +24,7 @@ class symbol_t {
std::uintptr_t allocated_at() const; std::uintptr_t allocated_at() const;
std::uint32_t size() const; std::uint32_t size() const;
coff::section_header_t* scn() const; coff::section_header_t* scn() const;
coff::image_t* img() const;
std::vector<std::uint8_t>& data(); std::vector<std::uint8_t>& data();
coff::symbol_t* sym() const; coff::symbol_t* sym() const;
sym_type_t type() const; sym_type_t type() const;
@ -40,5 +42,6 @@ class symbol_t {
std::vector<recomp::reloc_t> m_relocs; std::vector<recomp::reloc_t> m_relocs;
sym_type_t m_sym_type; sym_type_t m_sym_type;
coff::symbol_t* m_sym; coff::symbol_t* m_sym;
coff::image_t* m_img;
}; };
} // namespace theo::decomp } // namespace theo::decomp

@ -13,9 +13,39 @@ class pass_t {
public: public:
explicit pass_t(decomp::sym_type_t sym_type) : m_sym_type(sym_type){}; explicit pass_t(decomp::sym_type_t sym_type) : m_sym_type(sym_type){};
virtual void run(decomp::symbol_t* sym) = 0; virtual void run(decomp::symbol_t* sym) = 0;
decomp::sym_type_t sym_type() { return m_sym_type; } decomp::sym_type_t sym_type() { return m_sym_type; }
std::vector<std::uint8_t> generate_transforms(xed_decoded_inst_t* inst,
recomp::reloc_t* reloc,
std::uint8_t low,
std::uint8_t high) {
auto num_transforms = transform::operation_t::random(low, high);
auto num_ops = transform::operations.size();
std::vector<std::uint8_t> new_inst_bytes;
for (auto cnt = 0u; cnt < num_transforms; ++cnt) {
std::uint32_t imm = transform::operation_t::random(
0, std::numeric_limits<std::int32_t>::max());
auto itr = transform::operations.begin();
std::advance(itr, transform::operation_t::random(0, num_ops - 1));
auto transform_bytes = itr->second->native(inst, imm);
new_inst_bytes.insert(new_inst_bytes.end(), transform_bytes.begin(),
transform_bytes.end());
reloc->add_transform(
{transform::operations[itr->second->inverse()]->get_transform(),
imm});
}
// inverse the order in which the transformations are executed...
//
std::reverse(reloc->get_transforms().begin(),
reloc->get_transforms().end());
return new_inst_bytes;
}
private: private:
decomp::sym_type_t m_sym_type; decomp::sym_type_t m_sym_type;
}; };
} // namespace theo::comp::obf } // namespace theo::obf

@ -6,11 +6,7 @@ class jcc_rewrite_pass_t : public pass_t {
explicit jcc_rewrite_pass_t() : pass_t(decomp::sym_type_t::inst_split){}; explicit jcc_rewrite_pass_t() : pass_t(decomp::sym_type_t::inst_split){};
public: public:
static jcc_rewrite_pass_t* get() { static jcc_rewrite_pass_t* get();
static jcc_rewrite_pass_t obj; void run(decomp::symbol_t* sym);
return &obj;
}
void run(decomp::symbol_t* sym){};
}; };
} // namespace theo::comp::obf } // namespace theo::obf

@ -3,14 +3,20 @@
namespace theo::obf { namespace theo::obf {
class next_inst_pass_t : public pass_t { class next_inst_pass_t : public pass_t {
explicit next_inst_pass_t() : pass_t(decomp::sym_type_t::inst_split){}; explicit next_inst_pass_t() : pass_t(decomp::sym_type_t::inst_split) {
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));
};
public: public:
static next_inst_pass_t* get() { static next_inst_pass_t* get();
static next_inst_pass_t obj; void run(decomp::symbol_t* sym);
return &obj;
}
void run(decomp::symbol_t* sym){}; private:
std::optional<recomp::reloc_t*> has_next_inst_reloc(decomp::symbol_t*);
xed_decoded_inst_t m_tmp_inst;
std::uint8_t m_type_inst_bytes[8] = {0x48, 0xC7, 0x04, 0x24,
0x44, 0x33, 0x22, 0x11};
}; };
} // namespace theo::comp::obf } // namespace theo::obf

@ -1,17 +0,0 @@
#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

@ -19,14 +19,13 @@ class operation_t {
: m_transform(op), m_type(type) {} : m_transform(op), m_type(type) {}
std::vector<std::uint8_t> native(const xed_decoded_inst_t* inst, std::vector<std::uint8_t> native(const xed_decoded_inst_t* inst,
std::size_t imm) { std::uint32_t imm) {
std::uint32_t inst_len = {}; std::uint32_t inst_len = {};
std::uint8_t inst_buff[XED_MAX_INSTRUCTION_BYTES]; std::uint8_t inst_buff[XED_MAX_INSTRUCTION_BYTES];
xed_error_enum_t err; xed_error_enum_t err;
xed_encoder_request_init_from_decode((xed_decoded_inst_s*)inst); xed_encoder_request_init_from_decode((xed_decoded_inst_s*)inst);
xed_encoder_request_t* req = (xed_encoder_request_t*)inst; xed_encoder_request_t* req = (xed_encoder_request_t*)inst;
xed_state_t istate{XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b};
switch (m_type) { switch (m_type) {
case XED_ICLASS_ROR: case XED_ICLASS_ROR:
@ -54,6 +53,7 @@ class operation_t {
xed_iclass_enum_t inverse() { return m_inverse_op[m_type]; } xed_iclass_enum_t inverse() { return m_inverse_op[m_type]; }
transform_t* get_transform() { return &m_transform; } transform_t* get_transform() { return &m_transform; }
xed_iclass_enum_t type() { return m_type; }
static std::size_t random(std::size_t lowest, std::size_t largest) { static std::size_t random(std::size_t lowest, std::size_t largest) {
std::random_device rd; std::random_device rd;
@ -67,9 +67,10 @@ class operation_t {
xed_iclass_enum_t m_type; xed_iclass_enum_t m_type;
std::map<xed_iclass_enum_t, xed_iclass_enum_t> m_inverse_op = { std::map<xed_iclass_enum_t, xed_iclass_enum_t> m_inverse_op = {
{XED_ICLASS_ADD, XED_ICLASS_SUB}, {XED_ICLASS_SUB, XED_ICLASS_ADD}, {XED_ICLASS_ADD, XED_ICLASS_SUB},
{XED_ICLASS_AND, XED_ICLASS_OR}, {XED_ICLASS_OR, XED_ICLASS_AND}, {XED_ICLASS_SUB, XED_ICLASS_ADD},
{XED_ICLASS_ROL, XED_ICLASS_ROR}, {XED_ICLASS_ROR, XED_ICLASS_ROL}, {XED_ICLASS_ROL, XED_ICLASS_ROR},
{XED_ICLASS_ROR, XED_ICLASS_ROL},
{XED_ICLASS_XOR, XED_ICLASS_XOR}}; {XED_ICLASS_XOR, XED_ICLASS_XOR}};
}; };

@ -1,17 +0,0 @@
#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

@ -2,8 +2,6 @@
#include <obf/transform/operation.hpp> #include <obf/transform/operation.hpp>
#include <obf/transform/add_op.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/rol_op.hpp>
#include <obf/transform/ror_op.hpp> #include <obf/transform/ror_op.hpp>
#include <obf/transform/sub_op.hpp> #include <obf/transform/sub_op.hpp>
@ -11,8 +9,9 @@
namespace theo::obf::transform { namespace theo::obf::transform {
inline std::map<xed_iclass_enum_t, operation_t*> operations = { 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_AND, and_op_t::get()}, {XED_ICLASS_OR, or_op_t::get()}, {XED_ICLASS_SUB, sub_op_t::get()},
{XED_ICLASS_ROL, rol_op_t::get()}, {XED_ICLASS_ROR, ror_op_t::get()}, {XED_ICLASS_ROL, rol_op_t::get()},
{XED_ICLASS_XOR, xor_op_t::get()}}; {XED_ICLASS_ROR, ror_op_t::get()},
/*{XED_ICLASS_XOR, xor_op_t::get()}*/};
} }

@ -14,19 +14,20 @@ class reloc_t {
std::size_t hash() { return m_hash; } std::size_t hash() { return m_hash; }
std::string name() { return m_sym_name; } std::string name() { return m_sym_name; }
std::uint16_t offset() { return m_offset; } std::uint16_t offset() { return m_offset; }
void offset(std::uint16_t offset) { m_offset = offset; }
void add_transform( void add_transform(
std::pair<obf::transform::transform_t*, std::size_t> entry) { std::pair<obf::transform::transform_t*, std::uint32_t> entry) {
m_transforms.push_back(entry); m_transforms.push_back(entry);
} }
std::vector<std::pair<obf::transform::transform_t*, std::size_t>>& std::vector<std::pair<obf::transform::transform_t*, std::uint32_t>>&
get_transforms() { get_transforms() {
return m_transforms; return m_transforms;
} }
private: private:
std::vector<std::pair<obf::transform::transform_t*, std::size_t>> std::vector<std::pair<obf::transform::transform_t*, std::uint32_t>>
m_transforms; m_transforms;
std::string m_sym_name; std::string m_sym_name;
std::size_t m_hash; std::size_t m_hash;

@ -27,7 +27,7 @@ int main(int argc, char* argv[]) {
}; };
theo::recomp::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::uint32_t size) {
std::memcpy((void*)ptr, buff, size); std::memcpy((void*)ptr, buff, size);
}; };
@ -47,6 +47,6 @@ int main(int argc, char* argv[]) {
spdlog::info("decomposed {} symbols...", res.value()); spdlog::info("decomposed {} symbols...", res.value());
auto entry_pnt = t.compose("EntryPoint"); auto entry_pnt = t.compose("EntryPoint");
spdlog::info("entry point address: {:X}", entry_pnt); spdlog::info("entry point address: {:X}", entry_pnt);
// reinterpret_cast<void (*)()>(entry_pnt)();
std::getchar(); std::getchar();
reinterpret_cast<void (*)()>(entry_pnt)();
} }

@ -89,8 +89,8 @@ std::optional<recomp::symbol_table_t*> decomp_t::decompose() {
reinterpret_cast<std::uint8_t*>(img) + scn->ptr_raw_data + reinterpret_cast<std::uint8_t*>(img) + scn->ptr_raw_data +
scn->size_raw_data); scn->size_raw_data);
decomp::symbol_t new_scn_sym(scn_sym_name, 0, scn_data, scn, {}, {}, decomp::symbol_t new_scn_sym(img, scn_sym_name, 0, scn_data, scn,
sym_type_t::section); {}, {}, sym_type_t::section);
spdlog::info( spdlog::info(
"generating symbol for section: {} sym name: {} hash: {:X} " "generating symbol for section: {} sym name: {} hash: {:X} "
@ -104,8 +104,8 @@ std::optional<recomp::symbol_table_t*> decomp_t::decompose() {
// create a symbol for the data... // create a symbol for the data...
// //
decomp::symbol_t new_sym( decomp::symbol_t new_sym(
sym->name.to_string(img->get_strings()).data(), sym->value, {}, img, sym->name.to_string(img->get_strings()).data(), sym->value,
scn, sym, {}, sym_type_t::data); {}, scn, sym, {}, sym_type_t::data);
spdlog::info("adding data symbol: {} located inside of section: {}", spdlog::info("adding data symbol: {} located inside of section: {}",
new_sym.name(), new_sym.name(),
@ -123,7 +123,8 @@ std::optional<recomp::symbol_table_t*> decomp_t::decompose() {
// them... // them...
std::vector<std::uint8_t> data(sym->value, 0); std::vector<std::uint8_t> data(sym->value, 0);
decomp::symbol_t bss_sym(sym->name.to_string(img->get_strings()).data(), decomp::symbol_t bss_sym(img,
sym->name.to_string(img->get_strings()).data(),
{}, data, {}, sym, {}, sym_type_t::data); {}, data, {}, sym, {}, sym_type_t::data);
m_syms->add_symbol(bss_sym); m_syms->add_symbol(bss_sym);

@ -28,12 +28,12 @@ std::vector<decomp::symbol_t> routine_t::decompose() {
sym_hash, scn_reloc->virtual_address); sym_hash, scn_reloc->virtual_address);
relocs.push_back(recomp::reloc_t(scn_reloc->virtual_address, sym_hash, relocs.push_back(recomp::reloc_t(scn_reloc->virtual_address, sym_hash,
sym_name.data())); sym_name.data()));
} }
result.push_back(decomp::symbol_t( result.push_back(decomp::symbol_t(
m_sym->name.to_string(m_img->get_strings()).data(), m_sym->value, m_img, m_sym->name.to_string(m_img->get_strings()).data(),
m_data, m_scn, m_sym, relocs, sym_type_t::function)); m_sym->value, m_data, m_scn, m_sym, relocs, sym_type_t::function));
break; break;
} }
case inst_split: { case inst_split: {
@ -98,8 +98,8 @@ std::vector<decomp::symbol_t> routine_t::decompose() {
.append(std::to_string(offset + .append(std::to_string(offset +
xed_decoded_inst_get_length(&instr))); xed_decoded_inst_get_length(&instr)));
relocs.push_back(recomp::reloc_t(0, decomp::symbol_t::hash(next_inst_sym), relocs.push_back(recomp::reloc_t(
next_inst_sym.data())); 0, decomp::symbol_t::hash(next_inst_sym), next_inst_sym.data()));
// get the instructions bytes // get the instructions bytes
// //
@ -107,8 +107,8 @@ std::vector<decomp::symbol_t> routine_t::decompose() {
m_data.data() + offset, m_data.data() + offset,
m_data.data() + offset + xed_decoded_inst_get_length(&instr)); m_data.data() + offset + xed_decoded_inst_get_length(&instr));
result.push_back(decomp::symbol_t(new_sym_name, offset, inst_bytes, result.push_back(decomp::symbol_t(m_img, new_sym_name, offset,
m_scn, m_sym, relocs, inst_bytes, m_scn, m_sym, relocs,
sym_type_t::inst_split)); sym_type_t::inst_split));
// after creating the symbol and dealing with relocs then print the // after creating the symbol and dealing with relocs then print the

@ -1,7 +1,8 @@
#include <decomp/symbol.hpp> #include <decomp/symbol.hpp>
namespace theo::decomp { namespace theo::decomp {
symbol_t::symbol_t(std::string name, symbol_t::symbol_t(coff::image_t* img,
std::string name,
std::uintptr_t offset, std::uintptr_t offset,
std::vector<std::uint8_t> data, std::vector<std::uint8_t> data,
coff::section_header_t* scn, coff::section_header_t* scn,
@ -15,6 +16,7 @@ symbol_t::symbol_t(std::string name,
m_relocs(relocs), m_relocs(relocs),
m_sym_type(dcmp_type), m_sym_type(dcmp_type),
m_sym(sym), m_sym(sym),
m_img(img),
m_allocated_at(0) {} m_allocated_at(0) {}
std::string symbol_t::name() const { std::string symbol_t::name() const {
@ -33,6 +35,10 @@ coff::section_header_t* symbol_t::scn() const {
return m_scn; return m_scn;
} }
coff::image_t* symbol_t::img() const {
return m_img;
}
std::uint32_t symbol_t::size() const { std::uint32_t symbol_t::size() const {
return m_data.size(); return m_data.size();
} }

@ -0,0 +1,53 @@
#include <obf/passes/jcc_rewrite_pass.hpp>
#include <obf/passes/next_inst_pass.hpp>
namespace theo::obf {
jcc_rewrite_pass_t* jcc_rewrite_pass_t::get() {
static jcc_rewrite_pass_t obj;
return &obj;
}
void jcc_rewrite_pass_t::run(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};
xed_decoded_inst_zero_set_mode(&inst, &istate);
xed_decode(&inst, sym->data().data(), XED_MAX_INSTRUCTION_BYTES);
// if the instruction is branching...
if ((disp = xed_decoded_inst_get_branch_displacement(&inst))) {
disp += xed_decoded_inst_get_length(&inst);
// update displacement...
xed_decoded_inst_set_branch_displacement(
&inst, sym->data().size() - xed_decoded_inst_get_length(&inst),
xed_decoded_inst_get_branch_displacement_width(&inst));
xed_encoder_request_init_from_decode(&inst);
xed_encoder_request_t* req = &inst;
// update jcc in the buffer...
std::uint32_t len = {};
xed_encode(req, sym->data().data(), xed_decoded_inst_get_length(&inst),
&len);
// create a relocation to the instruction the branch would normally go
// too...
auto offset = disp < 0 ? sym->offset() - std::abs(disp)
: sym->offset() + std::abs(disp);
auto sym_name =
std::string(
sym->sym()->name.to_string(sym->img()->get_strings()).data())
.append("@")
.append(std::to_string(offset));
sym->relocs().push_back(
recomp::reloc_t(0, decomp::symbol_t::hash(sym_name), sym_name.data()));
// 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);
}
};
} // namespace theo::obf

@ -0,0 +1,73 @@
#include <obf/passes/next_inst_pass.hpp>
namespace theo::obf {
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) {
std::optional<recomp::reloc_t*> reloc;
if (!(reloc = has_next_inst_reloc(sym)).has_value())
return;
xed_decoded_inst_t inst = m_tmp_inst;
std::vector<std::uint8_t> new_inst_bytes =
generate_transforms(&inst, reloc.value(), 3, 6);
// add a push [rip+offset] and update reloc->offset()...
//
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_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, XED_ICLASS_PUSH);
xed_encoder_request_set_mem0(&req);
xed_encoder_request_set_operand_order(&req, 0, XED_OPERAND_MEM0);
xed_encoder_request_set_base0(&req, XED_REG_RIP);
xed_encoder_request_set_seg0(&req, XED_REG_INVALID);
xed_encoder_request_set_index(&req, XED_REG_INVALID);
xed_encoder_request_set_scale(&req, 0);
xed_encoder_request_set_memory_operand_length(&req, 8);
xed_encoder_request_set_memory_displacement(&req, new_inst_bytes.size() + 1,
1);
if ((err = xed_encode(&req, inst_buff, sizeof(inst_buff), &inst_len)) !=
XED_ERROR_NONE) {
spdlog::info("failed to encode instruction... reason: {}",
xed_error_enum_t2str(err));
assert(err == XED_ERROR_NONE);
}
new_inst_bytes.insert(new_inst_bytes.begin(), inst_buff,
inst_buff + inst_len);
// put a return instruction at the end of the decrypt instructions...
//
new_inst_bytes.push_back(0xC3);
sym->data().insert(sym->data().end(), new_inst_bytes.begin(),
new_inst_bytes.end());
reloc.value()->offset(sym->data().size());
sym->data().resize(sym->data().size() + 8);
}
std::optional<recomp::reloc_t*> next_inst_pass_t::has_next_inst_reloc(
decomp::symbol_t* sym) {
auto res = std::find_if(
sym->relocs().begin(), sym->relocs().end(),
[&](recomp::reloc_t& reloc) -> bool { return !reloc.offset(); });
return res != sym->relocs().end() ? res._Ptr
: std::optional<recomp::reloc_t*>();
}
} // namespace theo::obf

@ -27,42 +27,9 @@ void reloc_transform_pass_t::run(decomp::symbol_t* sym) {
assert(err == XED_ERROR_NONE); assert(err == XED_ERROR_NONE);
} }
// determine how many transformations we will generate... auto transforms_bytes = generate_transforms(&inst, reloc.value(), 3, 6);
// sym->data().insert(sym->data().end(), transforms_bytes.begin(),
auto num_transforms = transform::operation_t::random(1, 10); transforms_bytes.end());
auto num_ops = transform::operations.size();
for (auto cnt = 0u; cnt < num_transforms; ++cnt) {
// generate random imm value...
//
std::size_t imm = transform::operation_t::random(
0, std::numeric_limits<std::size_t>::max());
// get a random transformation...
//
auto itr = transform::operations.begin();
std::advance(itr, transform::operation_t::random(0, num_ops - 1));
// generate the native code for the transformation...
//
auto transform_bytes = itr->second->native(&inst, imm);
// insert the bytes of the native instruction into the data buffer...
//
sym->data().insert(sym->data().end(), transform_bytes.begin(),
transform_bytes.end());
// add the inverse operation to the relocation for encrypting the relocation
// pointer...
//
reloc.value()->add_transform(
{transform::operations[itr->second->inverse()]->get_transform(), imm});
}
// inverse the order in which the transformations are executed...
//
std::reverse(reloc.value()->get_transforms().begin(),
reloc.value()->get_transforms().end());
}; };
std::optional<recomp::reloc_t*> reloc_transform_pass_t::has_legit_reloc( std::optional<recomp::reloc_t*> reloc_transform_pass_t::has_legit_reloc(

@ -96,20 +96,15 @@ void recomp_t::resolve() {
break; break;
} }
case decomp::sym_type_t::inst_split: { case decomp::sym_type_t::inst_split: {
// TODO: change this if statement into a sanity check with an assert auto& transforms = reloc.get_transforms();
// after coding the next_inst_pass to ensure it works... std::for_each(
// transforms.begin(), transforms.end(),
if (reloc.offset()) { [&](std::pair<obf::transform::transform_t*, std::uint32_t>& t) {
auto& transforms = reloc.get_transforms(); allocated_at = (*t.first)(allocated_at, t.second);
std::for_each( });
transforms.begin(), transforms.end(),
[&](std::pair<obf::transform::transform_t*, std::size_t>& t) { *reinterpret_cast<std::uintptr_t*>(sym.data().data() +
allocated_at = (*t.first)(allocated_at, t.second); reloc.offset()) = allocated_at;
});
*reinterpret_cast<std::uintptr_t*>(sym.data().data() +
reloc.offset()) = allocated_at;
}
break; break;
} }
default: default:

Loading…
Cancel
Save