def test_add_symbols(self): ef = UnpreparedElfFile() sect = UnpreparedElfSection(ef, "test_sect") symtab = UnpreparedElfSymbolTable(ef, ".symtab") for name in ["foo", "bar"]: symtab.add_symbol(ElfSymbol(name, sect)) ef = UnpreparedElfFile() sect = UnpreparedElfSection(ef, "test_ect") strtab = UnpreparedElfStringTable(ef, ".strtab") symtab = UnpreparedElfSymbolTable(ef, ".symtab", link=strtab) for name in ["foo", "bar"]: symtab.add_symbol(ElfSymbol(name, sect))
def parse(self): class SymbolStruct: def __init__(self, value, size, sym_type, bind, other, shndx): self.st_value = value self.st_size = size self.st_type = sym_type self.st_bind = bind self.st_other = other self.st_shndx = shndx if Command.verbose: print "Symbol object" sym = Command.sym_tab.get_symbol(self.name) if sym: sym.value = Command.addr sym.type = STT_OBJECT sym.shndx = SHN_ABS sym.section = None else: sym_st = SymbolStruct(Command.addr, 0, STT_OBJECT, STB_GLOBAL, STV_DEFAULT, SHN_ABS) Command.sym_tab.add_symbol(ElfSymbol(self.name, None, sym_st)) if Command.verbose: print "\tCreated symbol %s at address %x" % (self.name, Command.addr)
def test_init(self): name = "test_symbol" ef, sect, symbol = self._build_test_symbol(name) self.assertEqual(symbol.name, name) self.assertEqual(symbol.section, sect) self.assertEqual(symbol.value, 0) self.assertEqual(symbol.size, 0) self.assertEqual(symbol.type, 0) self.assertEqual(symbol.bind, 0) self.assertEqual(symbol.other, 0) self.assertEqual(symbol.shndx, 0) self._set_symbol_values(symbol) new_name = "new_symbol" new_symbol = ElfSymbol(new_name, sect, old_sym=symbol) self.assertEqual(new_symbol.name, new_name) self.assertEqual(new_symbol.section, sect) self.assertEqual(new_symbol.value, 1) self.assertEqual(new_symbol.size, 2) self.assertEqual(new_symbol.type, 3) self.assertEqual(new_symbol.bind, 4) self.assertEqual(new_symbol.other, 5) self.assertEqual(new_symbol.shndx, 6) sym_struct = ElfSymbolStruct("<") sym_struct.st_value = 1 sym_struct.st_size = 2 sym_struct.st_type = 3 sym_struct.st_bind = 4 sym_struct.st_other = 5 sym_struct._st_shndx = 6 symbol = ElfSymbol("struct_symbol", sect, sym_struct=sym_struct) self.assertEqual(symbol.name, "struct_symbol") self.assertEqual(symbol.section, sect) self.assertEqual(symbol.value, 1) self.assertEqual(symbol.size, 2) self.assertEqual(symbol.type, 3) self.assertEqual(symbol.bind, 4) self.assertEqual(symbol.other, 5) self.assertEqual(symbol.shndx, 6)
def test_prepare(self): ef = UnpreparedElfFile() sect = UnpreparedElfSection(ef, "test_sect") symtab = UnpreparedElfSymbolTable(ef, ".symtab") for name in ["foo", "bar"]: symtab.add_symbol(ElfSymbol(name, sect)) ef.wordsize = 32 ef.endianess = "<" symtab = symtab.prepare(0x1000, 1, 0)
def test_add_symbols(self): # Adding symbols to a file with no symbol table # should create a new symbol table symbols = [] ef = UnpreparedElfFile() self.assertEqual(ef.get_symbol_table(), None) self.assertEqual(ef.get_symbols(), []) ef.add_symbols(symbols) self.assertNotEqual(ef.get_symbol_table(), None) # Apart from the opening null symbol, we should have nothing self.assertEqual(ef.get_symbols()[1:], []) sect_a = UnpreparedElfSection(ef) symbols = [ElfSymbol("a", sect_a), ElfSymbol("b", sect_a)] ef.add_symbols(symbols) self.assertEqual(ef.get_symbols()[1:], symbols) sect_b = UnpreparedElfSection(ef) symbols_b = [ElfSymbol("c", sect_b), ElfSymbol("d", sect_b)] ef.add_symbols(symbols_b) self.assertEqual(ef.section_symbols(sect_a), symbols) self.assertEqual(ef.section_symbols(sect_b), symbols_b) symbol_dict = {} for name in ["foo", "bar"]: symbol = ElfSymbol(name, sect_a) symbol_dict[name] = symbol ef.add_symbols(symbol_dict.values()) for name in symbol_dict.keys(): #full string match self.assertEqual(ef.find_symbol(name), symbol_dict[name]) # partial suffix match self.assertEqual(ef.find_symbol(name[1:]), symbol_dict[name]) self.assertEqual(ef.find_symbol("missing"), None)
def test_repr(self): ef, sect, symbol = self._build_test_symbol() s1 = str(symbol) # We expect a differnt result when we have actual values symbol.value = 37 symbol.size = 100 s2 = str(symbol) self.assertNotEqual(s1, s2) # Same symbol, different section, should give differnt string sect = UnpreparedElfSection(ef, "test_section") symbol2 = ElfSymbol("test_symbol", sect, old_sym=symbol) s3 = str(symbol2) self.assertNotEqual(s2, s3)
def __init__(self, elffile, name=None, section_type=SHT_SYMTAB, address=0, data=None, flags=0, addralign=0, info=None, link=None, entsize=None): UnpreparedElfSection.__init__(self, elffile, name, section_type, address, data, flags, addralign, info, link, entsize) BaseElfSymbolTable.__init__(self) # The code below is highly optimized, since we reading in the symbol # table is one of the slow parts of loading an elf file. # We create local versions of all objects, classes and methods # we would otherwise have to repeated be looked up in a deeper scope. int_syms = self._unpack() # int_syms are now structures symbols = self.symbols = [ElfSymbol(None, None)] strtab = self.link = self._get_strtab(link) sections = self.elffile.sections num_sections = len(sections) get_string_ofs = strtab.get_string_ofs append = symbols.append ES = ElfSymbol shn_lo = SHN_LORESERVE for sym_struct in int_syms: name = get_string_ofs(sym_struct.st_name) shndx = sym_struct.st_shndx if shndx < num_sections: section = sections[shndx] elif shndx < shn_lo: raise IndexError, \ "Invalid section index %d for symbol %s." \ "Only %d sections in file." \ % (shndx, name, num_sections) else: section = None append(ES(name, section, sym_struct))
def _build_test_symbol(self, name="test_symbol"): ef = UnpreparedElfFile() sect = UnpreparedElfSection(ef) symbol = ElfSymbol(name, sect) return ef, sect, symbol