summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornorly <ny-git@enpas.org>2013-06-16 00:47:23 +0100
committernorly <ny-git@enpas.org>2013-06-16 00:51:22 +0100
commit150d0c42d423fe49304d648e2c19ff08f6c2e0ad (patch)
tree04b3a4f78481707903463dd7ee7424ce0d003774
parent02355128ce1f36bbc4edb5d3a4d4d31b179de6d6 (diff)
mv main.c -> elfucli.c, make it scriptable via argssymrel
-rw-r--r--include/options.h22
-rw-r--r--include/printing.h18
-rw-r--r--src/elfucli.c178
-rw-r--r--src/main.c100
-rw-r--r--src/options.c129
5 files changed, 178 insertions, 269 deletions
diff --git a/include/options.h b/include/options.h
deleted file mode 100644
index 2210c85..0000000
--- a/include/options.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef __OPTIONS_H__
-#define __OPTIONS_H__
-
-
-typedef struct {
- char *fnInput;
- char *fnOutput;
- int printHeader;
- int printSegments;
- int printSections;
- unsigned insertBeforeOffs;
- unsigned insertBeforeSz;
- unsigned insertAfterOffs;
- unsigned insertAfterSz;
- unsigned expandNobitsOffs;
- char *fnReladd;
-} CLIOpts;
-
-
-void parseOptions(CLIOpts *opts, int argc, char **argv);
-
-#endif
diff --git a/include/printing.h b/include/printing.h
deleted file mode 100644
index bda2fc1..0000000
--- a/include/printing.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __PRINTING_H__
-#define __PRINTING_H__
-
-#include <libelf.h>
-
-
-void printHeader(Elf *e);
-
-void printSegmentsWithSection(Elf *e, Elf_Scn *scn);
-void printSection(Elf *e, Elf_Scn *scn);
-void printSections(Elf *e);
-
-char* segmentTypeStr(size_t pt);
-void printSectionsInSegment(Elf *e, GElf_Phdr *phdr);
-void printSegments(Elf *e);
-
-
-#endif
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;
+}
diff --git a/src/main.c b/src/main.c
deleted file mode 100644
index eda76e5..0000000
--- a/src/main.c
+++ /dev/null
@@ -1,100 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <libelfu/libelfu.h>
-
-#include "elfhandle.h"
-#include "options.h"
-#include "printing.h"
-
-
-int main(int argc, char **argv)
-{
- CLIOpts opts = { 0 };
- ELFHandles hIn = { 0 };
- ELFHandles hOut = { 0 };
- int exitval = EXIT_SUCCESS;
- ElfuElf *me;
-
- /* Is libelf alive and well? */
- if (elf_version(EV_CURRENT) == EV_NONE) {
- fprintf(stderr, "libelf init error: %s\n", elf_errmsg(-1));
- }
-
-
- /* Parse and validate user input */
- parseOptions(&opts, argc, argv);
-
-
- /* Open input/output files */
- openElf(&hIn, opts.fnInput, ELF_C_READ);
- if (!hIn.e) {
- exitval = EXIT_FAILURE;
- goto EXIT;
- }
-
- /* Now that we have a (hopefully) sane environment, execute commands. */
- me = elfu_mFromElf(hIn.e);
- closeElf(&hIn);
- if (!me) {
- printf("Failed to load model, aborting.\n");
- goto EXIT;
- }
-
- elfu_mCheck(me);
-
- //elfu_mDumpElf(me);
-
- /* Perform requested transformations on the memory model on-the-fly. */
- if (opts.fnReladd) {
- ELFHandles hRel = { 0 };
- ElfuElf *mrel = NULL;
-
- openElf(&hRel, opts.fnReladd, ELF_C_READ);
- if (!hRel.e) {
- printf("--reladd: Failed to open file for --reladd, skipping operation.\n");
- } else {
- mrel = elfu_mFromElf(hRel.e);
- closeElf(&hRel);
- if (!mrel) {
- printf("--reladd: Failed to load model for --reladd, skipping operation.\n");
- } else {
- elfu_mCheck(mrel);
- elfu_mReladd(me, mrel);
- printf("--reladd: Injected %s.\n", opts.fnReladd);
- }
- }
- }
-
- //elfu_mDumpElf(me);
-
- /* Copy the input ELF to the output file if one is specified. */
- if (opts.fnOutput) {
- printf("Writing modified file to %s.\n", opts.fnOutput);
- elfu_mCheck(me);
-
-
- openElf(&hOut, opts.fnOutput, ELF_C_WRITE);
- if (!hOut.e) {
- printf("Failed to open output file. Aborting.\n");
- 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);
- }
-
-
-
-EXIT:
- if (hIn.e) {
- closeElf(&hIn);
- }
-
- return (exitval);
-}
diff --git a/src/options.c b/src/options.c
deleted file mode 100644
index b5018d3..0000000
--- a/src/options.c
+++ /dev/null
@@ -1,129 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <getopt.h>
-
-#include "options.h"
-
-
-static void printUsage(char *progname)
-{
- printf("Usage: %s [OPTIONS] <elf-file>\n", progname);
- printf("\n"
- "Options:\n"
- " -h, --help Print this help message\n"
- " -o, --output Where to write the modified ELF file to\n"
- "\n"
-// "ELF dump:\n"
-// " --print-header Print ELF header\n"
-// " --print-segments Print program headers\n"
-// " --print-sections Print sections\n"
-// "\n"
-// "Space insertion:\n"
-// " off: File offset, not within any structure (headers or sections).\n"
-// " sz: A multiple of the maximum alignment of all PHDRs.\n"
-// "\n"
-// " --expand-nobits off Expand virtual areas (NOBITS sections and similar PHDRs).\n"
-// " --insert-before off,sz Insert spacing at given offset,\n"
-// " mapping everything before it to lower mem addresses.\n"
-// " --insert-after off,sz Insert spacing at given offset,\n"
-// " mapping everything after it to higher mem addresses.\n"
-// "\n"
- "High-level insertion:\n"
- " --reladd obj.o Automatically insert object file contents\n"
- "\n");
-}
-
-
-
-void parseOptions(CLIOpts *opts, int argc, char **argv)
-{
- char *progname = argv[0];
- int c;
- int option_index = 0;
- char *endptr;
-
- static struct option long_options[] = {
- {"help", 0, 0, 'h'},
- {"output", 1, 0, 'o'},
- {"print-header", 0, 0, 10001},
- {"print-segments", 0, 0, 10002},
- {"print-sections", 0, 0, 10003},
- {"insert-before", 1, 0, 10004},
- {"insert-after", 1, 0, 10005},
- {"expand-nobits", 1, 0, 10006},
- {"reladd", 1, 0, 10007},
- {NULL, 0, NULL, 0}
- };
-
- while ((c = getopt_long(argc, argv, "e:ho:",
- long_options, &option_index)) != -1) {
- switch (c) {
- case 'h':
- printUsage(progname);
- exit(EXIT_SUCCESS);
- case 'o':
- opts->fnOutput = optarg;
- break;
- case 10001:
- opts->printHeader = 1;
- break;
- case 10002:
- opts->printSegments = 1;
- break;
- case 10003:
- opts->printSections = 1;
- break;
- case 10004:
- opts->insertBeforeOffs = strtoul(optarg, &endptr, 0);
- if (endptr[0] != ',') {
- goto USAGE;
- }
- opts->insertBeforeSz = strtoul(endptr + 1, &endptr, 0);
- if (endptr[0] != '\0' || opts->insertBeforeSz == 0) {
- goto USAGE;
- }
- break;
- case 10005:
- opts->insertAfterOffs = strtoul(optarg, &endptr, 0);
- if (endptr[0] != ',') {
- goto USAGE;
- }
- opts->insertAfterSz = strtoul(endptr + 1, &endptr, 0);
- if (endptr[0] != '\0' || opts->insertAfterSz == 0) {
- goto USAGE;
- }
- break;
- case 10006:
- opts->expandNobitsOffs = strtoul(optarg, &endptr, 0);
- if (endptr[0] != '\0' || opts->expandNobitsOffs < 1) {
- goto USAGE;
- }
- break;
- case 10007:
- opts->fnReladd = optarg;
- break;
- case '?':
- default:
- goto USAGE;
- }
- }
-
- while (optind < argc) {
- if (!opts->fnInput) {
- opts->fnInput = argv[optind];
- }
- optind++;
- }
-
- if (!opts->fnInput) {
- fprintf(stderr, "Error: No input file specified.\n\n");
- goto USAGE;
- }
-
- return;
-
-USAGE:
- printUsage(progname);
- exit(1);
-}