selfpatch-slr/finalize/finalize.cpp

108 lines
3.3 KiB
C++

#include <iostream>
#include <string>
#include <getopt.h>
/*
TODO
1. Recursively gather all spslr CU files
cu uid -> data {
target uid -> fields
ipin label -> data
dpin symbol -> data (list of sub dpins)
}
2. Merge types between CUs (per CU mapping to global target UIDs)
3. Find dpatch application order based on levels (high level (very nested) to low level (root))
4. Loop over all symbols of the binary
-> associate blocks via CU uid symbol
-> find __spslr_program symbol (spslr vaddr pivot)
5. Find virtual address and file address for all pins
6. Emit patcher program into final executable and set __spslr_program
*/
/*
<sourcefile>.spslr:
SPSLR <CU filename> <CU uid symbol>
target <name> <local uid> <size> <field count>
f <offset> <size> <flags>
f <offset> <size> <flags>
...
ipin <label> <target uid> <field offset>
ipin <label> <target uid> <field offset>
ipin <label> <target uid> <field offset>
...
dpin <local/global> <symbol> <offset> <level> <target uid>
dpin <local/global> <symbol> <offset> <level> <target uid>
...
Datapins for same var/symbol are randomized in order of their level, from bottom of nest to top
The CU uid symbol helps differentiating between e.g. "file.c" and "sub/file.c" (symbtab has no idea)
Between CUs, types with the same name HAVE TO HAVE the same layout -> randomized together
To begin with, anonymous types are not allowed for randomization (later solved with hash(type) instead of name)!
Note -> field alignment should probably be gathered by pinpoint plugin!
*/
int main(int argc, char** argv) {
static option long_options[] = {
{ "help", no_argument, 0, 0 },
{ "spslr", required_argument, 0, 0 },
{ "bin", required_argument, 0, 0 },
{ "out", required_argument, 0, 0 },
{ "strip", no_argument, 0, 0 },
{ 0, 0, 0, 0 }
};
int option_index = 0;
int c;
std::string spslr_dir, bin_file, out_file;
while ((c = getopt_long(argc, argv, "", long_options, &option_index)) == 0) {
const option& opt = long_options[option_index];
std::string optname { opt.name };
if (optname == "help") {
std::cout << "To use spslr_finalize, supply these 3 arguments:" << std::endl;
std::cout << " --spslr=<dir> (the directory of .spslr files produced by spslr_pinpoint)" << std::endl;
std::cout << " --bin=<file> (the binary compiled with spslr_pinpoint to be finalized)" << std::endl;
std::cout << " --out=<file> (the finalized binary file to be written)" << std::endl;
return 0;
} else if (optname == "spslr") {
spslr_dir = std::string{ optarg };
} else if (optname == "bin") {
bin_file = std::string{ optarg };
} else if (optname == "out") {
out_file = std::string{ optarg };
} else if (optname == "strip") {
std::cerr << "Symbol stripping (--strip) is not yet implemented!" << std::endl;
return 1;
} else {
std::cerr << "Invalid option, try \"--help\"!" << std::endl;
return 1;
}
}
if (spslr_dir.empty()) {
std::cerr << "Missing spslr directory, supply it via --spslr=<dir>!" << std::endl;
return 1;
}
if (bin_file.empty()) {
std::cerr << "Missing input file path, supply it via --bin=<file>!" << std::endl;
return 1;
}
if (out_file.empty()) {
std::cerr << "Missing output file path, supply it via --out=<file>!" << std::endl;
return 1;
}
// TODO
std::cout << "Hello World!" << std::endl;
}