UnivesalDisassembler(2003)

elf.cc

Go to the documentation of this file.
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"