diff options
author | norly <ny-git@enpas.org> | 2013-06-16 00:47:23 +0100 |
---|---|---|
committer | norly <ny-git@enpas.org> | 2013-06-16 00:51:22 +0100 |
commit | 150d0c42d423fe49304d648e2c19ff08f6c2e0ad (patch) | |
tree | 04b3a4f78481707903463dd7ee7424ce0d003774 /src/elfucli.c | |
parent | 02355128ce1f36bbc4edb5d3a4d4d31b179de6d6 (diff) |
mv main.c -> elfucli.c, make it scriptable via argssymrel
Diffstat (limited to 'src/elfucli.c')
-rw-r--r-- | src/elfucli.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/elfucli.c b/src/elfucli.c new file mode 100644 index 0000000..0fd5a2d --- /dev/null +++ b/src/elfucli.c @@ -0,0 +1,178 @@ +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> +#include <libelfu/libelfu.h> + +#include "elfhandle.h" + + + +static void printUsage(char *progname) +{ + printf("Usage: %s -i <inputfile> [OPTIONS]\n", progname); + printf("\n" + "Options, executed in order given:\n" + " -h, --help Print this help message\n" + "\n" + " -i, --input infile Load new ELF file (must be first command)\n" + "\n" + " -c, --check Do a few sanity checks and print any errors\n" + " -d, --dump Dump current model state (debug only)\n" + " --reladd obj.o Insert object file contents\n" + " -o, --output outfile Where to write the modified ELF file to\n" + "\n"); +} + + + + +int main(int argc, char **argv) +{ + ELFHandles hIn = { 0 }; + int exitval = EXIT_SUCCESS; + char *progname = argv[0]; + int c; + int option_index = 0; + ElfuElf *me = NULL; + + static struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"check", 0, 0, 'c'}, + {"dump", 0, 0, 'd'}, + {"input", 1, 0, 'i'}, + {"output", 1, 0, 'o'}, + {"reladd", 1, 0, 10001}, + {NULL, 0, NULL, 0} + }; + + + if (argc < 3) { + printUsage(progname); + goto EXIT; + } + + + /* Is libelf alive and well? */ + if (elf_version(EV_CURRENT) == EV_NONE) { + fprintf(stderr, "libelf init error: %s\n", elf_errmsg(-1)); + } + + + /* Parse and and execute user commands */ + while ((c = getopt_long(argc, argv, "hcdi:o:", + long_options, &option_index)) != -1) { + switch (c) { + case 'h': + printUsage(progname); + goto EXIT; + case 'c': + if (!me) { + goto ERR_NO_INPUT; + } else { + printf("Checking model validity...\n"); + elfu_mCheck(me); + } + break; + case 'd': + if (!me) { + goto ERR_NO_INPUT; + } else { + elfu_mDumpElf(me); + } + break; + case 'i': + printf("Opening input file %s.\n", optarg); + openElf(&hIn, optarg, ELF_C_READ); + if (!hIn.e) { + printf("Error: Failed to open input file. Aborting.\n"); + exitval = EXIT_FAILURE; + goto EXIT; + } + + me = elfu_mFromElf(hIn.e); + closeElf(&hIn); + + if (!me) { + printf("Error: Failed to load model, aborting.\n"); + goto EXIT; + } + break; + case 'o': + if (!me) { + goto ERR_NO_INPUT; + } else { + ELFHandles hOut = { 0 }; + + printf("Writing modified file to %s.\n", optarg); + + openElf(&hOut, optarg, ELF_C_WRITE); + if (!hOut.e) { + printf("Failed to open output file. Aborting.\n"); + closeElf(&hOut); + exitval = EXIT_FAILURE; + goto EXIT; + } + + elfu_mToElf(me, hOut.e); + + if (elf_update(hOut.e, ELF_C_WRITE) < 0) { + fprintf(stderr, "elf_update() failed: %s\n", elf_errmsg(-1)); + } + closeElf(&hOut); + } + break; + case 10001: + if (!me) { + goto ERR_NO_INPUT; + } else { + ELFHandles hRel = { 0 }; + ElfuElf *mrel = NULL; + + openElf(&hRel, optarg, ELF_C_READ); + if (!hRel.e) { + printf("--reladd: Failed to open file for --reladd, aborting.\n"); + closeElf(&hRel); + goto ERR; + } + + mrel = elfu_mFromElf(hRel.e); + closeElf(&hRel); + if (!mrel) { + printf("--reladd: Failed to load model for --reladd, aborting.\n"); + goto ERR; + } else { + printf("--reladd: Injecting %s...\n", optarg); + elfu_mCheck(mrel); + elfu_mReladd(me, mrel); + printf("--reladd: Injected %s.\n", optarg); + } + } + break; + case '?': + default: + printUsage(progname); + goto EXIT; + } + } + + while (optind < argc) { + optind++; + } + + + +EXIT: + if (hIn.e) { + closeElf(&hIn); + } + + return (exitval); + + +ERR_NO_INPUT: + printf("Error: No input file opened. Aborting.\n"); + +ERR: + exitval = EXIT_FAILURE; + goto EXIT; +} |