UnivesalDisassembler(2003)
|
00001 // elf.cc 00002 // 00003 // plugin for uda - universal disassembler 00004 // Date: 2003-05-04 00005 // 00006 // Copyright (c) 2002-2003 Ales Smrcka 00007 // 00008 // This library is licensed under GNU Library GPL. See the file COPYING. 00009 // 00010 // This library makes possible to read unix ELF format. 00011 // 00012 00013 #include <iostream> 00014 #include <libelf.h> 00015 #include <sys/types.h> 00016 #include <sys/stat.h> 00017 #include <fcntl.h> 00018 #include <unistd.h> 00019 #include "shared.h" 00020 using namespace std; 00021 00022 #define pluginname "elf.so" 00023 00024 Parameters *Params; 00025 00026 extern "C" { 00027 00028 void plugin_init(int &type, const char *&ident, const char *&syntax, Parameters *p) 00029 { 00030 Params=p; 00031 if (elf_version(EV_CURRENT) == EV_NONE) 00032 type=0; 00033 else 00034 type=PLUGIN_SECTIONS+PLUGIN_SYMTABLE; 00035 ident="Universal disassembler plugin for ELF format"; 00036 syntax=NULL; 00037 } 00038 00039 int is_file_defined(const char *file) 00040 { 00041 debug(pluginname<<": is_file_defined...\n"); 00042 int result=0; 00043 int fildes=open(file, O_RDONLY); 00044 if (fildes==-1) 00045 return 0; 00046 Elf_Cmd cmd = ELF_C_READ; 00047 Elf *elf, *arf = elf_begin(fildes, cmd, (Elf*)0); 00048 if ((elf = elf_begin(fildes, cmd, arf))) 00049 if (elf_kind(elf)==ELF_K_ELF) 00050 result=1; 00051 elf_end(elf); 00052 elf_end(arf); 00053 close(fildes); 00054 if (result) 00055 debug(pluginname<<": is_file_defined...yes\n"); 00056 else 00057 debug(pluginname<<": is_file_defined...no\n"); 00058 return result; 00059 } 00060 00061 int load_sections(BinFileData &bfdata) 00062 { 00063 debug(pluginname<<": load_sections...\n"); 00064 int sectionnum=0; 00065 if (elf_version(EV_CURRENT)==EV_NONE) return 0; 00066 Elf32_Ehdr *ehdr; //elf header 00067 Elf_Scn *scn; //section 00068 Elf32_Shdr *shdr; //section header 00069 Elf_Data *strtab; //loaded shstrtab 00070 debug(pluginname<<": load_sections: opening "<<bfdata.name.c_str()<<endl); 00071 int fildes=open(bfdata.name.c_str(), O_RDONLY); 00072 if (fildes==-1) 00073 { 00074 debug(pluginname<<": load_sections: can not open "<<bfdata.name.c_str()<<endl); 00075 return 0; 00076 } 00077 Elf_Cmd cmd = ELF_C_READ; //command for elf_begin 00078 Elf *elf, *arf = elf_begin(fildes, cmd, (Elf*)0); //initiate 00079 SectionData *sd; 00080 if ((elf = elf_begin(fildes, cmd, arf))) 00081 { 00082 if (elf_kind(elf)!=ELF_K_ELF) 00083 { 00084 debug(pluginname<<": load_sections: not an ELF format "<<bfdata.name.c_str()<<endl); 00085 // not an ELF format 00086 elf_end(elf); 00087 elf_end(arf); 00088 close(fildes); 00089 return 0; 00090 } 00091 ehdr = elf32_getehdr(elf); 00092 bfdata.entry = ehdr->e_entry; //entry loaded 00093 scn = elf_getscn(elf, (size_t)ehdr->e_shstrndx); //load shstrtab section 00094 shdr = elf32_getshdr(scn); 00095 if (shdr->sh_type != SHT_STRTAB) 00096 { 00097 debug(pluginname<<": load_sections: not a string table "<<bfdata.name.c_str()<<endl); 00098 // not a string table 00099 elf_end(elf); 00100 elf_end(arf); 00101 close(fildes); 00102 return 0; 00103 } 00104 debug(pluginname<<": load_sections: found .shstrtab\n"); 00105 if ((strtab=elf_getdata(scn, (Elf_Data*)0))==0 || strtab->d_size==0) 00106 { 00107 debug(pluginname<<": load_sections: .shstrtab no data "<<bfdata.name.c_str()<<endl); 00108 // error or no data 00109 elf_end(elf); 00110 elf_end(arf); 00111 close(fildes); 00112 return 0; 00113 } 00114 debug(pluginname<<": load_sections: loaded .shstrtab\n"); 00115 //got section .shstrtab in data->d_buf 00116 scn=0; 00117 while ((scn=elf_nextscn(elf, scn))) 00118 { 00119 shdr=elf32_getshdr(scn); 00120 if (strtab) 00121 { 00122 sd = new SectionData; 00123 sd->addr=shdr->sh_addr; 00124 sd->size=shdr->sh_size; 00125 sd->executable=shdr->sh_flags&SHF_EXECINSTR; 00126 sd->name=&((char*)(strtab->d_buf))[shdr->sh_name]; 00127 int in=open(bfdata.name.c_str(), O_RDONLY); 00128 if (in!=-1) 00129 { 00130 lseek(in, shdr->sh_offset, SEEK_SET); 00131 sd->content = new byte[shdr->sh_size]; 00132 read(in, sd->content, shdr->sh_size); 00133 close(in); 00134 bfdata.Sections.push_back(sd); 00135 sectionnum++; 00136 } 00137 else 00138 { 00139 elf_end(elf); 00140 elf_end(arf); 00141 delete sd; 00142 return sectionnum; 00143 } 00144 } 00145 } 00146 cmd=elf_next(elf); 00147 elf_end(elf); 00148 } 00149 elf_end(arf); 00150 00151 debug(pluginname<<": load_sections "<<sectionnum<<"...ok\n"); 00152 return sectionnum; 00153 } 00154 00155 int load_symbols(AbstractSymbols &Symbols) 00156 { 00157 Elf32_Sym *sym=NULL; 00158 char *strtab=NULL; 00159 int nsym; //number of symbols needs to be load 00160 for (unsigned i=0;i<Symbols.bfdata.Sections.size();i++) 00161 if (Symbols.bfdata.Sections[i]!=NULL) 00162 if (Symbols.bfdata.Sections[i]->name==".symtab") 00163 { 00164 sym=(Elf32_Sym*)Symbols.bfdata.Sections[i]->content; 00165 nsym=Symbols.bfdata.Sections[i]->size/sizeof(Elf32_Sym); 00166 if (strtab!=NULL) break; 00167 } 00168 else 00169 if (Symbols.bfdata.Sections[i]->name==".strtab") 00170 { 00171 strtab=(char*)Symbols.bfdata.Sections[i]->content; 00172 if (sym!=NULL) break; 00173 } 00174 if (sym==NULL||strtab==NULL) 00175 return 0; 00176 typedef MSymbols::value_type vt; 00177 for (int i=0;i<nsym;i++,sym++) 00178 if (strtab[sym->st_name]) 00179 Symbols.symbols[sym->st_value] = &strtab[sym->st_name]; 00180 // Symbols.symbols.insert(vt(sym->st_value, &strtab[sym->st_name])); 00181 return nsym; 00182 } 00183 00184 } // extern "C"