From 9c1769549c6342c92936947fd614558a7e277759 Mon Sep 17 00:00:00 2001 From: York Jasper Niebuhr Date: Mon, 27 Oct 2025 22:37:48 +0100 Subject: [PATCH] Finalizer patcher program segment --- finalize/finalize.cpp | 63 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/finalize/finalize.cpp b/finalize/finalize.cpp index 934d58c..1246bdd 100644 --- a/finalize/finalize.cpp +++ b/finalize/finalize.cpp @@ -5,6 +5,7 @@ #include #include +#include #include "accumulation.h" #include "symbol_collection.h" @@ -19,7 +20,9 @@ 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); +using namespace LIEF::ELF; + +static bool disassemble_ipin(const Section* text, IPIN::HIT& pin); static bool assemble_patcher_program(uint64_t vaddr_pivot, std::vector& program); int main(int argc, char** argv) { @@ -85,7 +88,7 @@ int main(int argc, char** argv) { std::cout << "Gathered a total of " << targets.size() << " distinct targets from " << units.size() << " compilation units!" << std::endl; - std::unique_ptr bin = LIEF::ELF::Parser::parse(bin_file); + std::unique_ptr bin = Parser::parse(bin_file); if (!bin) { std::cerr << "Failed to parse binary \"" << bin_file << "\"!" << std::endl; return 1; @@ -102,7 +105,7 @@ int main(int argc, char** argv) { } // For each ipin, disassemble instruction and find immediate offset - const LIEF::ELF::Section* text = bin->get_section(".text"); + const Section* text = bin->get_section(".text"); if (!text) { std::cerr << "Unable to locate .text section for ipin disassembly!" << std::endl; return 1; @@ -137,12 +140,54 @@ int main(int argc, char** argv) { return 1; } + std::cout << "Generated patcher program of 0x" << std::hex << patcher_program.size() + << std::dec << " bytes!" << std::endl; + + // Add new section ".spslr" with patcher program + + uint64_t page_align = 0x1000; + for (const auto& seg : bin->segments()) { + if (seg.type() == Segment::TYPE::LOAD) { + if (seg.alignment() > page_align) page_align = seg.alignment(); + } + } + + uint64_t max_end_vaddr = 0; + for (const auto& seg : bin->segments()) { + if (seg.type() == Segment::TYPE::LOAD) { + uint64_t endv = seg.virtual_address() + seg.virtual_size(); + if (endv > max_end_vaddr) max_end_vaddr = endv; + } + } + + uint64_t new_vaddr = max_end_vaddr; + if (new_vaddr % page_align != 0) + new_vaddr += page_align - (new_vaddr % page_align); + + std::cout << "Adding patcher program at 0x" << std::hex << new_vaddr << std::dec << std::endl; + + Segment new_seg; + new_seg.type(Segment::TYPE::LOAD); + new_seg.flags(Segment::FLAGS::R); //(ELF_SEGMENT_FLAGS::PF_R); + new_seg.alignment(page_align); + new_seg.file_offset(0); // Writer decides where to put it + new_seg.virtual_address(new_vaddr); + new_seg.content(patcher_program); + new_seg.virtual_size(patcher_program.size()); + + bin->add(new_seg); + + // Set __spslr_program to (new_vaddr - &__spslr_program) // TODO - /* - 1. Add new section .spslr with patcher program - 2. Set __spslr_program to (&.spslr - &__spslr_program) - 3. Output final program - */ + + // Output final program + Builder builder{ *bin }; + builder.build(); + builder.write(out_file); + + std::cout << "Wrote final binary to \"" << out_file << "\"" << std::endl; + + return 0; } bool assemble_patcher_program(uint64_t vaddr_pivot, std::vector& program) { @@ -256,7 +301,7 @@ bool assemble_patcher_program(uint64_t vaddr_pivot, std::vector& progra return true; } -bool disassemble_ipin(const LIEF::ELF::Section* text, IPIN::HIT& pin) { +bool disassemble_ipin(const Section* text, IPIN::HIT& pin) { if (!text) return false;