예제 #1
0
def show_sym(fname, data, endian, evtype, sym):
    """Show information about an evspy entry

    Args:
        fname (str): Filename of ELF file
        data (bytes): Data for this symbol
        endian (str): Endianness to use ('little', 'big', 'auto')
        evtype (str): Event type, e.g. 'MISC_INIT_F'
        sym (elf.Symbol): Symbol to show
    """
    def _unpack_val(sym_data, offset):
        start = offset * func_size
        val_data = sym_data[start:start + func_size]
        fmt = '%s%s' % ('>' if endian == 'big' else '<',
                        'L' if func_size == 4 else 'Q')
        val = struct.unpack(fmt, val_data)[0]
        return val

    # Get the data, which is a struct evspy_info
    sym_data = data[sym.offset:sym.offset + sym.size]

    # Figure out the word size of the struct
    func_size = 4 if sym.size < 16 else 8

    # Read the function name for evspy_info->func
    while True:
        # Switch to big-endian if we see a failure
        func_addr = _unpack_val(sym_data, 0)
        func_name = elf.GetSymbolFromAddress(fname, func_addr)
        if not func_name and endian == 'auto':
            endian = 'big'
        else:
            break
    has_id = sym.size in [12, 24]
    if has_id:
        # Find the address of evspy_info->id in the ELF
        id_addr = _unpack_val(sym_data, 2)

        # Get the file offset for that address
        id_ofs = elf.GetFileOffset(fname, id_addr)

        # Read out a nul-terminated string
        id_data = data[id_ofs:id_ofs + 80]
        pos = id_data.find(0)
        if pos:
            id_data = id_data[:pos]
        id_str = id_data.decode('utf-8')
    else:
        id_str = None

    # Find the file/line for the function
    cmd = ['addr2line', '-e', fname, '%x' % func_addr]
    out = tools.run(*cmd).strip()

    # Drop the full path if it is the current directory
    if out.startswith(src_path):
        out = out[len(src_path) + 1:]
    print('%-20s  %-30s  %s' % (evtype, id_str or f'f:{func_name}', out))
예제 #2
0
 def test_get_file_offset_fail(self):
     """Test calling GetFileOffset() without elftools"""
     try:
         old_val = elf.ELF_TOOLS
         elf.ELF_TOOLS = False
         fname = self.ElfTestFile('embed_data')
         with self.assertRaises(ValueError) as e:
             elf.GetFileOffset(fname, 0)
         self.assertIn("Python: No module named 'elftools'",
                       str(e.exception))
     finally:
         elf.ELF_TOOLS = old_val
예제 #3
0
    def test_get_file_offset(self):
        """Test GetFileOffset() gives the correct file offset for a symbol"""
        fname = self.ElfTestFile('embed_data')
        syms = elf.GetSymbols(fname, ['embed'])
        addr = syms['embed'].address
        offset = elf.GetFileOffset(fname, addr)
        data = tools.read_file(fname)

        # Just use the first 4 bytes and assume it is little endian
        embed_data = data[offset:offset + 4]
        embed_value = struct.unpack('<I', embed_data)[0]
        self.assertEqual(0x1234, embed_value)