Finalizer patcher program segment

This commit is contained in:
York Jasper Niebuhr 2025-10-27 22:37:48 +01:00
parent 77d9de8e48
commit 9c1769549c

View File

@ -5,6 +5,7 @@
#include <getopt.h> #include <getopt.h>
#include <LIEF/LIEF.hpp> #include <LIEF/LIEF.hpp>
#include <LIEF/ELF/Builder.hpp>
#include "accumulation.h" #include "accumulation.h"
#include "symbol_collection.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)! 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<uint8_t>& program); static bool assemble_patcher_program(uint64_t vaddr_pivot, std::vector<uint8_t>& program);
int main(int argc, char** argv) { 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 " std::cout << "Gathered a total of " << targets.size() << " distinct targets from "
<< units.size() << " compilation units!" << std::endl; << units.size() << " compilation units!" << std::endl;
std::unique_ptr<LIEF::ELF::Binary> bin = LIEF::ELF::Parser::parse(bin_file); std::unique_ptr<Binary> bin = Parser::parse(bin_file);
if (!bin) { if (!bin) {
std::cerr << "Failed to parse binary \"" << bin_file << "\"!" << std::endl; std::cerr << "Failed to parse binary \"" << bin_file << "\"!" << std::endl;
return 1; return 1;
@ -102,7 +105,7 @@ int main(int argc, char** argv) {
} }
// For each ipin, disassemble instruction and find immediate offset // 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) { if (!text) {
std::cerr << "Unable to locate .text section for ipin disassembly!" << std::endl; std::cerr << "Unable to locate .text section for ipin disassembly!" << std::endl;
return 1; return 1;
@ -137,12 +140,54 @@ int main(int argc, char** argv) {
return 1; 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 // TODO
/*
1. Add new section .spslr with patcher program // Output final program
2. Set __spslr_program to (&.spslr - &__spslr_program) Builder builder{ *bin };
3. Output final program 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<uint8_t>& program) { bool assemble_patcher_program(uint64_t vaddr_pivot, std::vector<uint8_t>& program) {
@ -256,7 +301,7 @@ bool assemble_patcher_program(uint64_t vaddr_pivot, std::vector<uint8_t>& progra
return true; return true;
} }
bool disassemble_ipin(const LIEF::ELF::Section* text, IPIN::HIT& pin) { bool disassemble_ipin(const Section* text, IPIN::HIT& pin) {
if (!text) if (!text)
return false; return false;