First memory model of an ELF file
authornorly <ny-git@enpas.org>
Sun, 10 Feb 2013 00:36:16 +0000 (00:36 +0000)
committernorly <ny-git@enpas.org>
Mon, 11 Feb 2013 01:24:36 +0000 (01:24 +0000)
include/libelfu/libelfu.h
include/libelfu/model.h [new file with mode: 0644]
include/options.h
src/main.c
src/model/fromFile.c [new file with mode: 0644]
src/options.c

index 1c40541ece0d50c3dba52d14c1a42267c8b2d6e3..28a1e9af0b31eb1b2c2a70f222cf9ac6f1680733 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <libelfu/analysis.h>
 #include <libelfu/lookup.h>
+#include <libelfu/model.h>
 
 
 #endif
diff --git a/include/libelfu/model.h b/include/libelfu/model.h
new file mode 100644 (file)
index 0000000..05f31ca
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef __LIBELFU_MODEL_H__
+#define __LIBELFU_MODEL_H__
+
+#include <sys/queue.h>
+
+#include <elf.h>
+#include <gelf.h>
+
+
+typedef struct ElfuData {
+  Elf_Data data;
+
+  CIRCLEQ_ENTRY(ElfuData) elem;
+} ElfuData;
+
+
+typedef struct ElfuScn {
+  GElf_Shdr shdr;
+
+  CIRCLEQ_HEAD(DataList, ElfuData) dataList;
+
+  CIRCLEQ_ENTRY(ElfuScn) elem;
+} ElfuScn;
+
+
+typedef struct ElfuPhdr {
+  GElf_Phdr phdr;
+
+  CIRCLEQ_ENTRY(ElfuPhdr) elem;
+} ElfuPhdr;
+
+
+typedef struct {
+  int elfclass;
+  GElf_Ehdr ehdr;
+
+  CIRCLEQ_HEAD(ScnList, ElfuScn) scnList;
+  CIRCLEQ_HEAD(PhdrList, ElfuPhdr) phdrList;
+
+  ElfuPhdr *entryBase;
+  GElf_Addr *entryOffs;
+} ElfuElf;
+
+
+
+ElfuPhdr* elfu_modelFromPhdr(GElf_Phdr *phdr);
+ElfuScn* elfu_modelFromSection(Elf_Scn *scn);
+ElfuElf* elfu_modelFromElf(Elf *e);
+
+#endif
index f39f01e8de9858f0914af2e78ea325aa7ae65bdd..ddd44be0c73f7b0f3c297c548aa208b5fb3f8a84 100644 (file)
@@ -8,6 +8,7 @@ typedef struct {
   int printHeader;
   int printSegments;
   int printSections;
+  int model;
 } CLIOpts;
 
 
index 9791feb477820de5b70c27866f3eb57620d8a622..87b47efc4ebe92b49c9db535ef627b711878676a 100644 (file)
@@ -5,6 +5,8 @@
 #include <libelf.h>
 #include <gelf.h>
 
+#include <libelfu/libelfu.h>
+
 #include "elfhandle.h"
 #include "options.h"
 #include "printing.h"
@@ -57,6 +59,18 @@ int main(int argc, char **argv)
   }
 
 
+  /* Generate a memory model of the file */
+  if (opts.model) {
+    ElfuElf *me;
+
+    me = elfu_modelFromElf(hIn.e);
+
+    if (me) {
+      printf("Model successfully loaded.\n");
+    }
+  }
+
+
 
 EXIT:
   if (hOut.e) {
diff --git a/src/model/fromFile.c b/src/model/fromFile.c
new file mode 100644 (file)
index 0000000..f349335
--- /dev/null
@@ -0,0 +1,152 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <libelf.h>
+#include <gelf.h>
+
+#include <libelfu/libelfu.h>
+
+
+ElfuPhdr* elfu_modelFromPhdr(GElf_Phdr *phdr)
+{
+  ElfuPhdr *mp;
+
+  mp = malloc(sizeof(ElfuPhdr));
+  if (!mp) {
+    return NULL;
+  }
+
+  mp->phdr = *phdr;
+
+  return mp;
+}
+
+
+ElfuScn* elfu_modelFromSection(Elf_Scn *scn)
+{
+  ElfuScn *ms;
+  Elf_Data *data;
+
+  ms = malloc(sizeof(ElfuScn));
+  if (!ms) {
+    return NULL;
+  }
+
+  CIRCLEQ_INIT(&ms->dataList);
+
+
+  if (gelf_getshdr(scn, &ms->shdr) != &ms->shdr) {
+    fprintf(stderr, "gelf_getshdr() failed: %s\n", elf_errmsg(-1));
+    goto out;
+  }
+
+
+
+  /* Copy each data part in source segment */
+  data = elf_rawdata(scn, NULL);
+  while (data) {
+    ElfuData *md;
+
+    md = malloc(sizeof(ElfuData));
+    if (!md) {
+      goto out;
+    }
+
+    md->data = *data;
+
+    CIRCLEQ_INSERT_TAIL(&ms->dataList, md, elem);
+
+    data = elf_rawdata(scn, data);
+  }
+
+  return ms;
+
+  out:
+  // FIXME
+  return NULL;
+}
+
+
+
+
+ElfuElf* elfu_modelFromElf(Elf *e)
+{
+  ElfuElf *me;
+
+  me = malloc(sizeof(ElfuElf));
+  if (!me) {
+    return NULL;
+  }
+
+  CIRCLEQ_INIT(&me->scnList);
+  CIRCLEQ_INIT(&me->phdrList);
+
+  /*
+   * General stuff
+   */
+  me->elfclass = gelf_getclass(e);
+  if (me->elfclass == ELFCLASSNONE) {
+    fprintf(stderr, "getclass() failed: %s\n", elf_errmsg(-1));
+  }
+
+  if (!gelf_getehdr(e, &me->ehdr)) {
+    fprintf(stderr, "gelf_getehdr() failed: %s\n", elf_errmsg(-1));
+    goto out;
+  }
+
+
+  /*
+   * Sections
+   */
+  Elf_Scn *scn;
+
+  scn = elf_getscn(e, 1);
+  while (scn) {
+    ElfuScn *ms = elfu_modelFromSection(scn);
+
+    if (ms) {
+      CIRCLEQ_INSERT_TAIL(&me->scnList, ms, elem);
+    } else {
+      goto out;
+    }
+
+    scn = elf_nextscn(e, scn);
+  }
+
+
+
+  /*
+   * Segments
+   */
+  size_t i, n;
+
+  if (elf_getphdrnum(e, &n)) {
+    fprintf(stderr, "elf_getphdrnum() failed: %s\n", elf_errmsg(-1));
+  }
+
+  for (i = 0; i < n; i++) {
+    GElf_Phdr phdr;
+    ElfuPhdr *mp;
+
+    if (gelf_getphdr(e, i, &phdr) != &phdr) {
+      fprintf(stderr, "gelf_getphdr() failed for #%d: %s\n", i, elf_errmsg(-1));
+      break;
+    }
+
+    mp = elfu_modelFromPhdr(&phdr);
+
+    if (mp) {
+      CIRCLEQ_INSERT_TAIL(&me->phdrList, mp, elem);
+    } else {
+      goto out;
+    }
+  }
+
+
+
+  return me;
+
+  out:
+  // FIXME
+  return NULL;
+}
index 014a1f213d32dfc1178f506db6453bafcce108d4..42637f04c1940961ea00c22bd91e27f5edd402f7 100644 (file)
@@ -34,6 +34,7 @@ void parseOptions(CLIOpts *opts, int argc, char **argv)
     {"print-header", 0, 0, 10001},
     {"print-segments", 0, 0, 10002},
     {"print-sections", 0, 0, 10003},
+    {"model", 0, 0, 10004},
     {NULL, 0, NULL, 0}
   };
 
@@ -55,6 +56,9 @@ void parseOptions(CLIOpts *opts, int argc, char **argv)
       case 10003:
         opts->printSections = 1;
         break;
+      case 10004:
+        opts->model = 1;
+        break;
       case '?':
       default:
         goto USAGE;