I should have probably done multiple commits, whatever. I still need to rework reloc_t/things that insert transforms into it...master
parent
51d64b44b1
commit
094ed9f15f
@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2022, _xeroxz
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include <obf/pass.hpp>
|
||||
|
||||
namespace theo::obf {
|
||||
class func_split_pass_t : public generic_pass_t {
|
||||
explicit func_split_pass_t() : generic_pass_t(decomp::sym_type_t::function) {}
|
||||
|
||||
public:
|
||||
static func_split_pass_t* get();
|
||||
void generic_pass(decomp::symbol_t* sym, sym_map_t& sym_tbl) override;
|
||||
};
|
||||
} // namespace theo::obf
|
@ -0,0 +1,135 @@
|
||||
// Copyright (c) 2022, _xeroxz
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include <obf/passes/func_split_pass.hpp>
|
||||
|
||||
namespace theo::obf {
|
||||
func_split_pass_t* func_split_pass_t::get() {
|
||||
static func_split_pass_t obj;
|
||||
return &obj;
|
||||
}
|
||||
|
||||
void func_split_pass_t::generic_pass(decomp::symbol_t* sym,
|
||||
sym_map_t& sym_tbl) {
|
||||
std::uint32_t offset = {};
|
||||
xed_error_enum_t err;
|
||||
xed_decoded_inst_t instr;
|
||||
std::vector<decomp::symbol_t> result;
|
||||
xed_state_t istate{XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b};
|
||||
xed_decoded_inst_zero_set_mode(&instr, &istate);
|
||||
|
||||
// keep looping over the function, lower the number of bytes each time...
|
||||
//
|
||||
while ((err = xed_decode(&instr, sym->data().data() + offset,
|
||||
sym->data().size() - offset)) == XED_ERROR_NONE) {
|
||||
// symbol name is of the format: symbol@instroffset, I.E: main@11...
|
||||
//
|
||||
auto new_sym_name = decomp::symbol_t::name(sym->img(), sym->sym());
|
||||
|
||||
// first instruction doesnt need the @offset...
|
||||
//
|
||||
if (offset)
|
||||
new_sym_name.append("@").append(std::to_string(offset));
|
||||
|
||||
std::vector<recomp::reloc_t> relocs;
|
||||
auto scn_relocs = reinterpret_cast<coff::reloc_t*>(
|
||||
sym->scn()->ptr_relocs + reinterpret_cast<std::uint8_t*>(sym->img()));
|
||||
|
||||
// find if this instruction has a relocation or not...
|
||||
// if so, return the reloc_t...
|
||||
//
|
||||
auto reloc = std::find_if(
|
||||
scn_relocs, scn_relocs + sym->scn()->num_relocs,
|
||||
[&](coff::reloc_t reloc) {
|
||||
return reloc.virtual_address >= sym->sym()->value + offset &&
|
||||
reloc.virtual_address <
|
||||
sym->sym()->value + offset +
|
||||
xed_decoded_inst_get_length(&instr);
|
||||
});
|
||||
|
||||
// if there is indeed a reloc for this instruction...
|
||||
//
|
||||
if (reloc != scn_relocs + sym->scn()->num_relocs) {
|
||||
auto sym_reloc = sym->img()->get_symbol(reloc->symbol_index);
|
||||
auto sym_name = decomp::symbol_t::name(sym->img(), sym_reloc);
|
||||
auto sym_hash = decomp::symbol_t::hash(sym_name.data());
|
||||
auto reloc_offset = reloc->virtual_address - sym->sym()->value - offset;
|
||||
relocs.push_back(
|
||||
recomp::reloc_t(reloc_offset, sym_hash, sym_name.data()));
|
||||
}
|
||||
// add a reloc to the next instruction...
|
||||
// note that the offset is ZERO... comp_t will understand that
|
||||
// relocs with offset ZERO means the next instructions...
|
||||
//
|
||||
auto next_inst_sym = decomp::symbol_t::name(sym->img(), sym->sym())
|
||||
.append("@")
|
||||
.append(std::to_string(
|
||||
offset + xed_decoded_inst_get_length(&instr)));
|
||||
|
||||
relocs.push_back(recomp::reloc_t(0, decomp::symbol_t::hash(next_inst_sym),
|
||||
next_inst_sym.data()));
|
||||
// get the instructions bytes
|
||||
//
|
||||
std::vector<std::uint8_t> inst_bytes(
|
||||
sym->data().data() + offset,
|
||||
sym->data().data() + offset + xed_decoded_inst_get_length(&instr));
|
||||
|
||||
result.push_back(decomp::symbol_t(sym->img(), new_sym_name, offset,
|
||||
inst_bytes, sym->scn(), sym->sym(),
|
||||
relocs, decomp::sym_type_t::instruction));
|
||||
// after creating the symbol and dealing with relocs then print the
|
||||
// information we have concluded...
|
||||
//
|
||||
char buff[255];
|
||||
offset += xed_decoded_inst_get_length(&instr);
|
||||
xed_format_context(XED_SYNTAX_INTEL, &instr, buff, sizeof buff, NULL, NULL,
|
||||
NULL);
|
||||
spdlog::info("[func_split_pass_t] {}: {}", new_sym_name, buff);
|
||||
// need to set this so that instr can be used to decode again...
|
||||
xed_decoded_inst_zero_set_mode(&instr, &istate);
|
||||
}
|
||||
|
||||
// remove the relocation to the next symbol from the last instruction
|
||||
//
|
||||
auto& last_inst = result.back();
|
||||
auto& last_inst_relocs = last_inst.relocs();
|
||||
last_inst_relocs.erase(last_inst_relocs.end() - 1);
|
||||
|
||||
// insert the split instructions into the symbol table.
|
||||
//
|
||||
for (auto& symbol : result) {
|
||||
auto itr = sym_tbl.find(symbol.hash());
|
||||
if (itr != sym_tbl.end())
|
||||
itr->second = symbol;
|
||||
else
|
||||
sym_tbl.insert({symbol.hash(), symbol});
|
||||
}
|
||||
}
|
||||
} // namespace theo::obf
|
Loading…
Reference in new issue