#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int main(const int argc, char* argv[]) { bool skipSyscallCheck = false; std::string inputPath; std::string outputElfPath; std::optional registryPath; for (int i = 1; i < argc; ++i) { const std::string arg = argv[i]; if (arg == "--skip-syscall-check") { skipSyscallCheck = true; } else if (inputPath.empty()) { inputPath = arg; } else if (outputElfPath.empty()) { outputElfPath = arg; } else if (!registryPath.has_value()) { registryPath = arg; } } if (inputPath.empty() || outputElfPath.empty()) { std::cerr << "Usage: relinker [--skip-syscall-check] [output_registry.json]\n"; return 1; } try { Io::FileReader fileReader; Io::FileWriter fileWriter; auto sourceBytes = fileReader.Read(inputPath); auto elfReader = std::make_shared(sourceBytes); auto syscallScanner = skipSyscallCheck ? Relinker::MakeNullSyscallScanner() : Relinker::MakeSyscallScanner(); const auto pipeline = std::make_shared( elfReader, std::move(syscallScanner), Relinker::MakeCallSiteResolver(), std::make_shared(), std::make_shared() ); auto result = pipeline->Relink(sourceBytes); if (registryPath.has_value()) { auto callRegistryWriter = std::make_shared(); fileWriter.Write(*registryPath, callRegistryWriter->WriteCallRegistry(result.RegistryEntries)); } auto byteWriter = std::make_shared(); Elfpatcher::Linux::LinuxElfPatcher elfPatcher( std::make_shared(), std::make_shared( std::make_shared(), byteWriter ), std::make_shared(byteWriter), byteWriter ); auto patchedElf = elfPatcher.Patch(sourceBytes, result.OriginalHeaders, result.DynamicSection); fileWriter.Write(outputElfPath, patchedElf); } catch (const Domain::RelinkerException& e) { std::cerr << "FAIL: " << e.what(); if (e.FailureOffset != 0) std::cerr << " (offset 0x" << std::hex << e.FailureOffset << ")"; std::cerr << "\n"; return 2; } catch (const std::exception& e) { std::cerr << "FAIL: " << e.what() << "\n"; return 2; } return 0; }