|
|
@ -40,12 +40,23 @@ recomp_t::recomp_t(decomp::decomp_t* dcmp,
|
|
|
|
void recomp_t::allocate() {
|
|
|
|
void recomp_t::allocate() {
|
|
|
|
// map code & data/rdata/bss sections first...
|
|
|
|
// map code & data/rdata/bss sections first...
|
|
|
|
//
|
|
|
|
//
|
|
|
|
|
|
|
|
static const auto engine = obf::engine_t::get();
|
|
|
|
m_dcmp->syms()->for_each([&](theo::decomp::symbol_t& sym) {
|
|
|
|
m_dcmp->syms()->for_each([&](theo::decomp::symbol_t& sym) {
|
|
|
|
switch (sym.type()) {
|
|
|
|
switch (sym.type()) {
|
|
|
|
case decomp::sym_type_t::section:
|
|
|
|
case decomp::sym_type_t::section:
|
|
|
|
case decomp::sym_type_t::function:
|
|
|
|
case decomp::sym_type_t::function:
|
|
|
|
case decomp::sym_type_t::instruction: {
|
|
|
|
case decomp::sym_type_t::instruction: {
|
|
|
|
sym.allocated_at(m_allocator(sym.size(), sym.scn()->characteristics));
|
|
|
|
engine->for_each(&sym, [&](decomp::symbol_t* sym, obf::pass_t* pass) {
|
|
|
|
|
|
|
|
if (sym->allocated_at())
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto res = pass->allocation_pass(sym, sym->size(), m_allocator);
|
|
|
|
|
|
|
|
if (res.has_value())
|
|
|
|
|
|
|
|
sym->allocated_at(res.value());
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!sym.allocated_at())
|
|
|
|
|
|
|
|
sym.allocated_at(m_allocator(sym.size(), sym.scn()->characteristics));
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
default:
|
|
|
@ -83,7 +94,17 @@ void recomp_t::allocate() {
|
|
|
|
prot.mem_read = true;
|
|
|
|
prot.mem_read = true;
|
|
|
|
prot.mem_write = true;
|
|
|
|
prot.mem_write = true;
|
|
|
|
|
|
|
|
|
|
|
|
sym.allocated_at(m_allocator(sym.size(), sym.scn()->characteristics));
|
|
|
|
engine->for_each(&sym, [&](decomp::symbol_t* sym, obf::pass_t* pass) {
|
|
|
|
|
|
|
|
if (sym->allocated_at())
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto res = pass->allocation_pass(sym, sym->size(), m_allocator);
|
|
|
|
|
|
|
|
if (res.has_value())
|
|
|
|
|
|
|
|
sym->allocated_at(res.value());
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!sym.allocated_at())
|
|
|
|
|
|
|
|
sym.allocated_at(m_allocator(sym.size(), sym.scn()->characteristics));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
@ -112,6 +133,15 @@ void recomp_t::resolve() {
|
|
|
|
? reloc_sym.value()->allocated_at()
|
|
|
|
? reloc_sym.value()->allocated_at()
|
|
|
|
: m_resolver(reloc.name());
|
|
|
|
: m_resolver(reloc.name());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// run passes related to post symbol relocation...
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
static const auto engine = obf::engine_t::get();
|
|
|
|
|
|
|
|
engine->for_each(&sym, [&](decomp::symbol_t* sym, obf::pass_t* pass) {
|
|
|
|
|
|
|
|
auto res = pass->resolver_pass(sym, &reloc, allocated_at);
|
|
|
|
|
|
|
|
if (res.has_value())
|
|
|
|
|
|
|
|
allocated_at = res.value();
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!allocated_at) {
|
|
|
|
if (!allocated_at) {
|
|
|
|
spdlog::error("failed to resolve reloc from symbol: {} to symbol: {}",
|
|
|
|
spdlog::error("failed to resolve reloc from symbol: {} to symbol: {}",
|
|
|
|
sym.name(), reloc.name());
|
|
|
|
sym.name(), reloc.name());
|
|
|
@ -128,23 +158,12 @@ void recomp_t::resolve() {
|
|
|
|
reloc.offset()) = allocated_at;
|
|
|
|
reloc.offset()) = allocated_at;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
case decomp::sym_type_t::instruction:
|
|
|
|
case decomp::sym_type_t::function: {
|
|
|
|
case decomp::sym_type_t::function: {
|
|
|
|
*reinterpret_cast<std::uintptr_t*>(sym.data().data() +
|
|
|
|
*reinterpret_cast<std::uintptr_t*>(sym.data().data() +
|
|
|
|
reloc.offset()) = allocated_at;
|
|
|
|
reloc.offset()) = allocated_at;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case decomp::sym_type_t::instruction: {
|
|
|
|
|
|
|
|
auto& transforms = reloc.get_transforms();
|
|
|
|
|
|
|
|
std::for_each(
|
|
|
|
|
|
|
|
transforms.begin(), transforms.end(),
|
|
|
|
|
|
|
|
[&](std::pair<obf::transform::transform_t*, std::uint32_t>& t) {
|
|
|
|
|
|
|
|
allocated_at = (*t.first)(allocated_at, t.second);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*reinterpret_cast<std::uintptr_t*>(sym.data().data() +
|
|
|
|
|
|
|
|
reloc.offset()) = allocated_at;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -155,8 +174,19 @@ void recomp_t::resolve() {
|
|
|
|
void recomp_t::copy_syms() {
|
|
|
|
void recomp_t::copy_syms() {
|
|
|
|
// copy symbols into memory using the copier supplied...
|
|
|
|
// copy symbols into memory using the copier supplied...
|
|
|
|
//
|
|
|
|
//
|
|
|
|
|
|
|
|
static const auto engine = obf::engine_t::get();
|
|
|
|
m_dcmp->syms()->for_each([&](theo::decomp::symbol_t& sym) {
|
|
|
|
m_dcmp->syms()->for_each([&](theo::decomp::symbol_t& sym) {
|
|
|
|
m_copier(sym.allocated_at(), sym.data().data(), sym.data().size());
|
|
|
|
bool cpy = false;
|
|
|
|
|
|
|
|
engine->for_each(&sym, [&](decomp::symbol_t* sym, obf::pass_t* pass) {
|
|
|
|
|
|
|
|
if (cpy)
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
// returns true if the copy was done for this symbol...
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
cpy = pass->copier_pass(sym, m_copier);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!cpy)
|
|
|
|
|
|
|
|
m_copier(sym.allocated_at(), sym.data().data(), sym.data().size());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|