def u16(buf, off): buf = buf[off:off + 2] try: buf = str2bytes(buf) except AttributeError: pass return struct.unpack("<H", buf)[0]
def get_section_data(self, section_name): section = self.elf.get_section_by_name(str2bytes(section_name)) if section != None: data = section.data() size = section['sh_size'] ''' Return [ADDR, DATA, SIZE] ''' return [section['sh_addr'], data, size] else: return [None, None, None]
def _section_from_spec(self, spec): """ Retrieve a section given a "spec" (either number or name). Return None if no such section exists in the file. """ try: num = int(spec) if num < self.elffile.num_sections(): return self.elffile.get_section(num) else: return None except ValueError: # Not a number. Must be a name then return self.elffile.get_section_by_name(str2bytes(spec))
def fetch_PC(filename, secname='.symtab'): toreturn=0 with open(filename, 'rb') as f: elffile = ELFFile(f) section=elffile.get_section_by_name(str2bytes(secname)) #print section['sh_entsize'] if section['sh_entsize'] == 0: print("\nSymbol table '%s' has a sh_entsize of zero!" % ( bytes2str(section.name))) print("Symbol table '%s' contains %s entries" % ( bytes2str(section.name), section.num_symbols())) for nsym, symbol in enumerate(section.iter_symbols()): if(bytes2str(symbol.name)=='_start'): toreturn = symbol['st_value'] setPC(toreturn)
def fetch_PC(filename, secname='.symtab'): toreturn = 0 with open(filename, 'rb') as f: elffile = ELFFile(f) section = elffile.get_section_by_name(str2bytes(secname)) #print section['sh_entsize'] if section['sh_entsize'] == 0: print("\nSymbol table '%s' has a sh_entsize of zero!" % (bytes2str(section.name))) print("Symbol table '%s' contains %s entries" % (bytes2str(section.name), section.num_symbols())) for nsym, symbol in enumerate(section.iter_symbols()): if (bytes2str(symbol.name) == '_start'): toreturn = symbol['st_value'] setPC(toreturn)
def kiddoc_from_shared_library(libpath, verbose_print): """ Do ELF symbol resolution to build a KidDoc class instance from a compiled .ws_so. hc svnt dracones, etc...""" fp = open(libpath, "rb") elf = ELFFile(fp) # First, find the .data and .rodata sections data_section = elf.get_section_by_name(str2bytes(".data")) rodata_section = elf.get_section_by_name(str2bytes(".rodata")) # We found .data and .rodata, now get their addresses and bytes. data_section_addr = data_section.header.sh_addr data_data = data_section.data() rodata_section_addr = rodata_section.header.sh_addr rodata_data = rodata_section.data() # Next, look for the symbol table. symbol_table_section = None for section in elf.iter_sections(): if not isinstance(section, SymbolTableSection): continue #if section["sh_entsize"] == 0: # continue symbol_table_section = section break if not symbol_table_section: return None # By this point we've found the symbol table. docsymbols = [ # symbols in .data "proc_description", "proc_name", "proc_purpose", "proc_requires", "proc_version" ] docsymbolsptr = [ # symbols in .data that need to be dereferenced "proc_input_ports", "proc_input_types", "proc_synopsis" ] doc_dict = {} # We found the symbol table, now iterate through its symbols. # When we encounter a symbol needed for documentation (see docsymbols), # we look for the corresponding bytes in the .data and .rodata sections. for symbol in symbol_table_section.iter_symbols(): if (section["sh_type"] == "SHT_DYNSYM"): name = str(symbol.name) # Skip if this isn't a symbol needed for documentation. if name not in docsymbols and name not in docsymbolsptr: continue offset = symbol["st_value"] - data_section_addr size = symbol["st_size"] if name in docsymbolsptr: symdata = get_list(data_data, rodata_data, rodata_section_addr, offset, size) else: # the -1 is to remove the NUL terminator (we already know it's # a string) symdata = data_data[offset:offset + size - 1] if symdata == "": symdata = "none" doc_dict[name] = symdata doc_dict["print_verbose"] = verbose_print return KidDoc(**doc_dict)
def return_parsed_section(filename, secname): with open(filename, 'rb') as f: elffile = ELFFile(f) #ll=elffile.iter_sections() #for x in ll: # print x.name section=elffile.get_section_by_name(str2bytes(secname)) if section is None: print 'ERROR! Section '+secname+' does not exist in the file!' #print 'Name of section is: '+bytes2str(section.name) ##assuming no relocation section for now #self._note_relocs_for_section(section) addr = section['sh_addr'] data = section.data() dataptr = 0 setStartAddress(' %s ' % _format_hex(addr, elffile, fieldsize=8 )) toreturn=[] while dataptr < len(data): bytesleft = len(data) - dataptr # chunks of 16 bytes per line linebytes = 16 if bytesleft > 16 else bytesleft #not adding addresses in beginning of 4 * 4 bytes #toreturn+=' %s ' % _format_hex(addr, elffile, fieldsize=8 ) for i in range(16): if i < linebytes: toreturn.append('%2.2x' % byte2int(data[dataptr + i])) else: pass #not doing anything #toreturn+=' ' if i % 4 == 3: pass #not doing anything #toreturn+=' ' for i in range(linebytes): c = data[dataptr + i : dataptr + i + 1] if byte2int(c[0]) >= 32 and byte2int(c[0]) < 0x7f: pass #removing not used info #toreturn+=bytes2str(c) else: pass #removing not used info #toreturn+=(bytes2str(b'.')) #again not adding string or newline #toreturn+='\n' addr += linebytes dataptr += linebytes for x in range(len(toreturn)%4): toreturn.append('') if toreturn==[]: print'No data to display in '+secname+' section' return global little little=isLittleEndian(elffile) finalreturn= arrangeData(toreturn, isLittleEndian(elffile)) setNumOfInst(len(finalreturn)) return finalreturn
def return_parsed_section(filename, secname): with open(filename, 'rb') as f: elffile = ELFFile(f) #ll=elffile.iter_sections() #for x in ll: # print x.name section = elffile.get_section_by_name(str2bytes(secname)) if section is None: print 'ERROR! Section ' + secname + ' does not exist in the file!' #print 'Name of section is: '+bytes2str(section.name) ##assuming no relocation section for now #self._note_relocs_for_section(section) addr = section['sh_addr'] data = section.data() dataptr = 0 setStartAddress(' %s ' % _format_hex(addr, elffile, fieldsize=8)) toreturn = [] while dataptr < len(data): bytesleft = len(data) - dataptr # chunks of 16 bytes per line linebytes = 16 if bytesleft > 16 else bytesleft #not adding addresses in beginning of 4 * 4 bytes #toreturn+=' %s ' % _format_hex(addr, elffile, fieldsize=8 ) for i in range(16): if i < linebytes: toreturn.append('%2.2x' % byte2int(data[dataptr + i])) else: pass #not doing anything #toreturn+=' ' if i % 4 == 3: pass #not doing anything #toreturn+=' ' for i in range(linebytes): c = data[dataptr + i:dataptr + i + 1] if byte2int(c[0]) >= 32 and byte2int(c[0]) < 0x7f: pass #removing not used info #toreturn+=bytes2str(c) else: pass #removing not used info #toreturn+=(bytes2str(b'.')) #again not adding string or newline #toreturn+='\n' addr += linebytes dataptr += linebytes for x in range(len(toreturn) % 4): toreturn.append('') if toreturn == []: print 'No data to display in ' + secname + ' section' return global little little = isLittleEndian(elffile) finalreturn = arrangeData(toreturn, isLittleEndian(elffile)) setNumOfInst(len(finalreturn)) return finalreturn
def kiddoc_from_shared_library(libpath, verbose_print): """ Do ELF symbol resolution to build a KidDoc class instance from a compiled .ws_so. hc svnt dracones, etc...""" fp = open(libpath, "rb") elf = ELFFile(fp) # First, find the .data and .rodata sections data_section = elf.get_section_by_name(str2bytes(".data")) rodata_section = elf.get_section_by_name(str2bytes(".rodata")) # We found .data and .rodata, now get their addresses and bytes. data_section_addr = data_section.header.sh_addr data_data = data_section.data() rodata_section_addr = rodata_section.header.sh_addr rodata_data = rodata_section.data() # Next, look for the symbol table. symbol_table_section = None for section in elf.iter_sections(): if not isinstance(section, SymbolTableSection): continue #if section["sh_entsize"] == 0: # continue symbol_table_section = section break if not symbol_table_section: return None # By this point we've found the symbol table. docsymbols = [ # symbols in .data "proc_description", "proc_name", "proc_purpose", "proc_requires", "proc_version" ] docsymbolsptr = [ # symbols in .data that need to be dereferenced "proc_input_ports", "proc_input_types", "proc_synopsis" ] doc_dict = {} # We found the symbol table, now iterate through its symbols. # When we encounter a symbol needed for documentation (see docsymbols), # we look for the corresponding bytes in the .data and .rodata sections. for symbol in symbol_table_section.iter_symbols(): if (section["sh_type"] == "SHT_DYNSYM"): name = str(symbol.name) # Skip if this isn't a symbol needed for documentation. if name not in docsymbols and name not in docsymbolsptr: continue offset = symbol["st_value"] - data_section_addr size = symbol["st_size"] if name in docsymbolsptr: symdata = get_list(data_data, rodata_data, rodata_section_addr, offset, size) else: # the -1 is to remove the NUL terminator (we already know it's # a string) symdata = data_data[offset:offset+size-1] if symdata == "": symdata = "none" doc_dict[name] = symdata doc_dict["print_verbose"] = verbose_print return KidDoc(**doc_dict)