Finalizer scanning for symbols
This commit is contained in:
parent
222e3c570d
commit
a55009342f
@ -1,5 +1,5 @@
|
|||||||
find_package(LIEF REQUIRED)
|
find_package(LIEF REQUIRED)
|
||||||
|
|
||||||
add_executable(spslr_finalize finalize.cpp accumulation.cpp)
|
add_executable(spslr_finalize finalize.cpp accumulation.cpp symbol_collection.cpp)
|
||||||
target_link_libraries(spslr_finalize PRIVATE LIEF::LIEF)
|
target_link_libraries(spslr_finalize PRIVATE LIEF::LIEF)
|
||||||
set_target_properties(spslr_finalize PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO)
|
set_target_properties(spslr_finalize PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO)
|
||||||
|
|||||||
@ -2,7 +2,10 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#include <LIEF/LIEF.hpp>
|
||||||
|
|
||||||
#include "accumulation.h"
|
#include "accumulation.h"
|
||||||
|
#include "symbol_collection.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Notes:
|
Notes:
|
||||||
@ -75,13 +78,21 @@ 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);
|
||||||
|
if (!bin) {
|
||||||
|
std::cerr << "Failed to parse binary \"" << bin_file << "\"!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!collect_symbols(bin)) {
|
||||||
|
std::cerr << "Failed to collect symbols from \"" << bin_file << "\"!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
/*
|
/*
|
||||||
1. Loop over all symbols of the binary
|
1. Find virtual address and file address for all pins
|
||||||
-> associate blocks via CU uid symbol
|
2. Emit patcher program into final executable and set __spslr_program
|
||||||
-> find __spslr_program symbol (spslr vaddr pivot)
|
|
||||||
2. Find virtual address and file address for all pins
|
|
||||||
3. Emit patcher program into final executable and set __spslr_program
|
|
||||||
-> make all patcher addresses relative to &__spslr_program
|
-> make all patcher addresses relative to &__spslr_program
|
||||||
-> dpatch entries ordered by level (high levels/nest depths first)
|
-> dpatch entries ordered by level (high levels/nest depths first)
|
||||||
*/
|
*/
|
||||||
|
|||||||
93
finalize/symbol_collection.cpp
Normal file
93
finalize/symbol_collection.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "symbol_collection.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define SPSLR_PINPOINT_CU_UID_LABEL "__spslr_cu_" /* suffixed with "<uid>" */
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct GlobalSymtab {
|
||||||
|
std::unordered_map<std::string, VADDR> symbols;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LocalSymtab {
|
||||||
|
std::string cu;
|
||||||
|
std::unordered_map<std::string, VADDR> symbols;
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace LIEF::ELF;
|
||||||
|
|
||||||
|
GlobalSymtab global_syms;
|
||||||
|
std::unordered_map<std::string, LocalSymtab> local_syms;
|
||||||
|
|
||||||
|
bool collect_symbols(const std::unique_ptr<LIEF::ELF::Binary>& bin) {
|
||||||
|
if (!bin)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool cu_uid_found = false;
|
||||||
|
LocalSymtab tmp_local_syms;
|
||||||
|
|
||||||
|
auto finish_cu_symbols = [&]() -> bool {
|
||||||
|
if (cu_uid_found) {
|
||||||
|
if (local_syms.contains(tmp_local_syms.cu)) {
|
||||||
|
std::cerr << "Duplicate CU UID -> " << tmp_local_syms.cu << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
local_syms.emplace(tmp_local_syms.cu, std::move(tmp_local_syms));
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_local_syms.cu.clear();
|
||||||
|
tmp_local_syms.symbols.clear();
|
||||||
|
cu_uid_found = false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const Symbol& sym : bin->symbols()) {
|
||||||
|
if (sym.type() == Symbol::TYPE::FILE) {
|
||||||
|
if (!finish_cu_symbols())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sym.name().empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sym.type() != Symbol::TYPE::OBJECT && sym.type() != Symbol::TYPE::NOTYPE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
VADDR vaddr = sym.value();
|
||||||
|
|
||||||
|
if (sym.binding() == Symbol::BINDING::GLOBAL) {
|
||||||
|
if (global_syms.symbols.contains(sym.name())) {
|
||||||
|
std::cerr << "Duplicate global symbol \"" << sym.name() << "\"!" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
global_syms.symbols.emplace(sym.name(), vaddr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sym.binding() != Symbol::BINDING::LOCAL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sym.name().starts_with(SPSLR_PINPOINT_CU_UID_LABEL)) {
|
||||||
|
tmp_local_syms.cu = sym.name().substr(std::strlen(SPSLR_PINPOINT_CU_UID_LABEL));
|
||||||
|
cu_uid_found = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp_local_syms.symbols.contains(sym.name())) {
|
||||||
|
std::cerr << "Duplicate local symbol \"" << sym.name() << "\"!" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_local_syms.symbols.emplace(sym.name(), vaddr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!finish_cu_symbols())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
22
finalize/symbol_collection.h
Normal file
22
finalize/symbol_collection.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <LIEF/LIEF.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
using VADDR = uint64_t;
|
||||||
|
|
||||||
|
struct GlobalSymtab {
|
||||||
|
std::unordered_map<std::string, VADDR> symbols;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LocalSymtab {
|
||||||
|
std::string cu;
|
||||||
|
std::unordered_map<std::string, VADDR> symbols;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern GlobalSymtab global_syms;
|
||||||
|
extern std::unordered_map<std::string, LocalSymtab> local_syms;
|
||||||
|
|
||||||
|
bool collect_symbols(const std::unique_ptr<LIEF::ELF::Binary>& bin);
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ With ASLR, there are 2 options to make it function correctly:
|
|||||||
1. Make sure __spslr_program is relocated with program image shift (preferred)
|
1. Make sure __spslr_program is relocated with program image shift (preferred)
|
||||||
2. __spslr_program = spslr_ptr_absolute((uint64_t)__spslr_program) and postprocessor inserts relative value (kinda weird)
|
2. __spslr_program = spslr_ptr_absolute((uint64_t)__spslr_program) and postprocessor inserts relative value (kinda weird)
|
||||||
*/
|
*/
|
||||||
static const uint8_t* __spslr_program = NULL;
|
const uint8_t* __spslr_program = NULL;
|
||||||
|
|
||||||
static void* spslr_ptr_absolute(uint64_t relative) {
|
static void* spslr_ptr_absolute(uint64_t relative) {
|
||||||
// To allow ASLR, all patcher addresses are relative to &__spslr_program
|
// To allow ASLR, all patcher addresses are relative to &__spslr_program
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user