diff --git a/finalize/finalize.cpp b/finalize/finalize.cpp index 8274950..ae90fb8 100644 --- a/finalize/finalize.cpp +++ b/finalize/finalize.cpp @@ -15,6 +15,8 @@ Notes: To begin with, anonymous types are not allowed for randomization (later solved with hash(type) instead of name)! */ +static bool disassemble_ipin(const LIEF::ELF::Section* text, IPIN::HIT& pin); + int main(int argc, char** argv) { static option long_options[] = { { "help", no_argument, 0, 0 }, @@ -94,16 +96,63 @@ int main(int argc, char** argv) { return 1; } + // For each ipin, disassemble instruction and find immediate offset + const LIEF::ELF::Section* text = bin->get_section(".text"); + if (!text) { + std::cerr << "Unable to locate .text section for ipin disassembly!" << std::endl; + return 1; + } + + for (auto& [cu_uid, cu] : units) { + for (auto& [_, ipin] : cu.ipins) { + if (!ipin.hit.has_value()) { + std::cerr << "Encountered ipin without vaddr!" << std::endl; + return 1; + } + + if (!disassemble_ipin(text, ipin.hit.value())) { + std::cerr << "Failed to disassemble ipin!" << std::endl; + return 1; + } + } + } + // TODO /* - 1. For each ipin, disassemble instruction and find immediate offset - 2. Find __spslr_program - 3. Serialize entire patcher program + 1. Find __spslr_program + 2. Serialize entire patcher program -> all pin addresses relative to &__spslr_program -> dpatch entry components ordered by level - 4. Add new section .spslr with patcher program - 5. Set __spslr_program to (&.spslr - &__spslr_program) - 6. Output final program + 3. Add new section .spslr with patcher program + 4. Set __spslr_program to (&.spslr - &__spslr_program) + 5. Output final program */ } +bool disassemble_ipin(const LIEF::ELF::Section* text, IPIN::HIT& pin) { + if (!text) + return false; + + uint64_t text_begin = text->virtual_address(); + uint64_t text_size = text->size(); + auto text_data = text->content(); + + uint64_t pin_addr = pin.vaddr; + + if (pin_addr < text_begin || pin_addr >= text_begin + text_size) + return false; + + uint64_t pin_offset = pin_addr - text_begin; + + // 32 bit mov of immediate to 64 bit register: 0x48 0xc7 [8 bit reg] [32 bit immediate] + + if (text_data[pin_offset] != 0x48 || text_data[pin_offset + 1] != 0xc7) { + std::cerr << "Ipin uses not yet handled instruction!" << std::endl; + return false; + } + + pin.imm_offset = 3; + pin.imm_size = 4; + return true; +} +