Пример #1
0
def u16(buf, off):
    buf = buf[off:off + 2]
    try:
        buf = str2bytes(buf)
    except AttributeError:
        pass
    return struct.unpack("<H", buf)[0]
Пример #2
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]
Пример #3
0
 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))
Пример #4
0
 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))
Пример #5
0
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)
Пример #6
0
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)
Пример #7
0
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)
Пример #8
0
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
Пример #9
0
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
Пример #10
0
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)