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