[docs]classELFHashTable:""" Functions to do lookup from a HASH section of an ELF file. Information: http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-48031.html """
[docs]def__init__(self,symtab,stream,offset,arch):""" :param symtab: The symbol table to perform lookups from (as a pyelftools SymbolTableSection). :param stream: A file-like object to read from the ELF's memory. :param offset: The offset in the object where the table starts. :param arch: The ArchInfo object for the ELF file. """self.symtab=symtabfmt="<"ifarch.memory_endness=="Iend_LE"else">"stream.seek(offset)self.nbuckets,self.nchains=struct.unpack(fmt+"II",stream.read(8))self.buckets=struct.unpack(fmt+"I"*self.nbuckets,stream.read(4*self.nbuckets))self.chains=struct.unpack(fmt+"I"*self.nchains,stream.read(4*self.nchains))
[docs]defget(self,k):""" Perform a lookup. Returns a pyelftools Symbol object, or None if there is no match. :param k: The string to look up. """ifself.nbuckets==0:returnNone,Nonehval=self.elf_hash(k)%self.nbucketssymndx=self.buckets[hval]whilesymndx!=0:sym=self.symtab.get_symbol(symndx)ifsym.name==k:returnsymndx,symsymndx=self.chains[symndx]returnNone,None
# from http://www.partow.net/programming/hashfunctions/
[docs]classGNUHashTable:""" Functions to do lookup from a GNU_HASH section of an ELF file. Information: https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections """
[docs]def__init__(self,symtab,stream,offset,arch):""" :param symtab: The symbol table to perform lookups from (as a pyelftools SymbolTableSection). :param stream: A file-like object to read from the ELF's memory. :param offset: The offset in the object where the table starts. :param arch: The ArchInfo object for the ELF file. """self.symtab=symtabfmt="<"ifarch.memory_endness=="Iend_LE"else">"self.c=arch.bitsfmtsz="I"ifself.c==32else"Q"stream.seek(offset)data=stream.read(16)self.nbuckets,self.symndx,self.maskwords,self.shift2=struct.unpack(fmt+"IIII",data)self.bloom=struct.unpack(fmt+fmtsz*self.maskwords,stream.read(self.c*self.maskwords//8))self.buckets=struct.unpack(fmt+"I"*self.nbuckets,stream.read(4*self.nbuckets))self.hash_ptr=stream.tell()self.stream=stream
[docs]defget(self,k):""" Perform a lookup. Returns a pyelftools Symbol object, or None if there is no match. :param k: The string to look up """h=self.gnu_hash(k)ifnotself._matches_bloom(h):returnNone,Nonen=self.buckets[h%self.nbuckets]ifn==0:returnNone,NonewhileTrue:sym=self.symtab.get_symbol(n)ifsym.name==k:returnn,symself.stream.seek(self.hash_ptr+4*(n-self.symndx))ifstruct.unpack("I",self.stream.read(4))[0]&1==1:breakn+=1returnNone,None