main.cpp revision 280ef45f9b1385da8cc5ac5b131cd9ad3165e908
1#include "ELFObject.h"
2
3#include "utils/serialize.h"
4
5#include <llvm/ADT/OwningPtr.h>
6#include <iomanip>
7#include <iostream>
8
9#include <elf.h>
10#include <fcntl.h>
11#include <stdlib.h>
12#include <sys/mman.h>
13#include <sys/stat.h>
14#include <sys/types.h>
15
16using namespace serialization;
17using namespace std;
18
19bool open_mmap_file(char const *filename,
20                    int &fd,
21                    unsigned char const *&image,
22                    size_t &size);
23
24void close_mmap_file(int fd,
25                     unsigned char const *image,
26                     size_t size);
27
28void dump_file(unsigned char const *image, size_t size);
29
30int main(int argc, char **argv) {
31  // Filename from argument
32  char const *filename = argv[0];
33  if (argc >= 2) {
34    filename = argv[1];
35  }
36
37  cout << left;
38
39  // Open the file
40  int fd = -1;
41  unsigned char const *image = NULL;
42  size_t image_size = 0;
43
44  if (!open_mmap_file(filename, fd, image, image_size)) {
45    cerr << "ERROR: Unable to open the file: " << filename << endl;
46  }
47
48  // Dump the file
49  dump_file(image, image_size);
50
51  // Close the file
52  close_mmap_file(fd, image, image_size);
53
54  return EXIT_SUCCESS;
55}
56
57void *find_sym(char const *name_, void *context) {
58  std::string name = name_;
59
60#define DEF_FUNC(FUNC) \
61  if (name == #FUNC) { return (void *)&FUNC; }
62
63  DEF_FUNC(rand);
64  DEF_FUNC(printf);
65  DEF_FUNC(scanf);
66  DEF_FUNC(srand);
67  DEF_FUNC(time);
68
69#undef DEF_FUNC
70
71  return 0;
72}
73
74template <size_t Bitwidth, typename Archiver>
75void dump_object(Archiver &AR) {
76  llvm::OwningPtr<ELFObject<Bitwidth> > object(ELFObject<Bitwidth>::read(AR));
77
78  if (!object) {
79    cerr << "ERROR: Unable to load object" << endl;
80  }
81
82  object->print();
83
84  ELFSectionSymTab<Bitwidth> *symtab =
85    static_cast<ELFSectionSymTab<Bitwidth> *>(
86        object->getSectionByName(".symtab"));
87
88  object->relocate(find_sym, 0);
89
90  cout << "main address: " << symtab->getByName("main")->getAddress() << endl;
91  cout << "printf address: " << (void *)printf << endl;
92  void *ptr = symtab->getByName("main")->getAddress();
93  ((int (*)(int, char **))ptr)(0,0);
94}
95
96template <typename Archiver>
97void dump_file_from_archive(bool is32bit, Archiver &AR) {
98  if (is32bit) {
99    dump_object<32>(AR);
100  } else {
101    dump_object<64>(AR);
102  }
103}
104
105void dump_file(unsigned char const *image, size_t size) {
106  if (size < EI_NIDENT) {
107    cerr << "ERROR: ELF identification corrupted." << endl;
108    return;
109  }
110
111  if (image[EI_DATA] != ELFDATA2LSB && image[EI_DATA] != ELFDATA2MSB) {
112    cerr << "ERROR: Unknown endianness." << endl;
113    return;
114  }
115
116  if (image[EI_CLASS] != ELFCLASS32 && image[EI_CLASS] != ELFCLASS64) {
117    cerr << "ERROR: Unknown machine class." << endl;
118    return;
119  }
120
121  bool isLittleEndian = (image[EI_DATA] == ELFDATA2LSB);
122  bool is32bit = (image[EI_CLASS] == ELFCLASS32);
123
124  if (isLittleEndian) {
125    archive_reader_le AR(image, size);
126    dump_file_from_archive(is32bit, AR);
127  } else {
128    archive_reader_be AR(image, size);
129    dump_file_from_archive(is32bit, AR);
130  }
131}
132
133bool open_mmap_file(char const *filename,
134                    int &fd,
135                    unsigned char const *&image,
136                    size_t &size) {
137  // Open the file in readonly mode
138  fd = open(filename, O_RDONLY);
139  if (fd < 0) {
140    return false;
141  }
142
143  // Query the file size
144  struct stat sb;
145  if (fstat(fd, &sb) != 0) {
146    close(fd);
147    return false;
148  }
149
150  size = (size_t)sb.st_size;
151
152  // Map the file image
153  image = static_cast<unsigned char const *>(
154    mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0));
155
156  if (image == NULL || image == MAP_FAILED) {
157    close(fd);
158    return false;
159  }
160
161  return true;
162}
163
164void close_mmap_file(int fd,
165                     unsigned char const *image,
166                     size_t size) {
167  if (image) {
168    munmap((void *)image, size);
169  }
170
171  if (fd >= 0) {
172    close(fd);
173  }
174}
175