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 <LIEF/LIEF.hpp>
#include <LIEF/ELF/Builder.hpp>
#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<uint8_t>& 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<LIEF::ELF::Binary> bin = LIEF::ELF::Parser::parse(bin_file);
std::unique_ptr<Binary> 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<uint8_t>& program) {
@ -256,7 +301,7 @@ bool assemble_patcher_program(uint64_t vaddr_pivot, std::vector<uint8_t>& 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;