Repository: mandiant/capa
File: capa/features/extractors/elf.py (Python)

Code before:
            return None

        desc = self.buf[self.desc_offset : self.desc_offset + self.descsz]
        abi_tag, kmajor, kminor, kpatch = struct.unpack_from(self.endian + "IIII", desc, 0x0)
        logger.debug("GNU_ABI_TAG: 0x%02x", abi_tag)

        os = GNU_ABI_TAG.get(abi_tag)
        if not os:
            return None

        logger.debug("abi tag: %s earliest compatible kernel: %d.%d.%d", os, kmajor, kminor, kpatch)
        return ABITag(os, kmajor, kminor, kpatch)


class SymTab:
    def __init__(self, endian: str, bitness: int, symtab_buf: bytes, symtab_entsize:int, symtab_sz: int, strtab_buf: bytes, strtab_sz: int) -> None:
        self.symbols = []
        self.symnum = int(symtab_sz / symtab_entsize)
        self.entsize = symtab_entsize
        
        self.strings = strtab_buf
        self.strings_sz = strtab_sz

        self._parse(endian, bitness, symtab_buf)

    def _parse(self, endian: str, bitness: int, symtab_buf) -> None:
        """
        return the symbol's information in 
        the order specified by sys/elf32.h
        """
        for i in range(self.symnum):
            if bitness == 32:
                name, value, size, info, other, shndx = struct.unpack_from(endian+"IIIBBH", symtab_buf, i*self.entsize)
            elif bitness == 64:
                name, info, other, shndx, value, size = struct.unpack_from(endian+"IBBBQQ", symtab_buf, i*self.entsize)

            self.symbols.append((name, value, size, info, other, shndx))

    def fetch_str(self, offset) -> str:
        """
        fetch a symbol's name from symtab's
        associated strings' section (SHT_STRTAB)
        """
        for i in range(offset, self.strings_sz):
            if self.strings[i] == 0:
                return self.strings[offset:i].decode()

    def get_symbols(self) -> Iterator[Tuple[int, int, int, int, int, int]]:
        """
        return a tuple: (name, value, size, info, other, shndx)
        for each symbol contained in the symbol table

Review comment (suggestion):
```suggestion
    def _parse(self, endian: str, bitness: int, symtab_buf: bytes) -> None:
```

Code after:
            return None

        desc = self.buf[self.desc_offset : self.desc_offset + self.descsz]
        abi_tag, kmajor, kminor, kpatch = struct.unpack_from(self.endian + "IIII", desc, 0x0)
        logger.debug("GNU_ABI_TAG: 0x%02x", abi_tag)

        os = GNU_ABI_TAG.get(abi_tag)
        if not os:
            return None

        logger.debug("abi tag: %s earliest compatible kernel: %d.%d.%d", os, kmajor, kminor, kpatch)
        return ABITag(os, kmajor, kminor, kpatch)


class SymTab:
    def __init__(self, endian: str, bitness: int, symtab_buf: bytes, symtab_entsize: int, symtab_sz: int, strtab_buf: bytes, strtab_sz: int) -> None:
        self.symbols = []
        self.symnum = int(symtab_sz / symtab_entsize)
        self.entsize = symtab_entsize
        
        self.strings = strtab_buf
        self.strings_sz = strtab_sz

        self._parse(endian, bitness, symtab_buf)

    def _parse(self, endian: str, bitness: int, symtab_buf: bytes) -> None:
        """
        return the symbol's information in 
        the order specified by sys/elf32.h
        """
        for i in range(self.symnum):
            if bitness == 32:
                name, value, size, info, other, shndx = struct.unpack_from(endian+"IIIBBH", symtab_buf, i*self.entsize)
            elif bitness == 64:
                name, info, other, shndx, value, size = struct.unpack_from(endian+"IBBBQQ", symtab_buf, i*self.entsize)

            self.symbols.append((name, value, size, info, other, shndx))

    def fetch_str(self, offset) -> str:
        """
        fetch a symbol's name from symtab's
        associated strings' section (SHT_STRTAB)
        """
        for i in range(offset, self.strings_sz):
            if self.strings[i] == 0:
                return self.strings[offset:i].decode()

    def get_symbols(self) -> Iterator[Tuple[int, int, int, int, int, int]]:
        """
        return a tuple: (name, value, size, info, other, shndx)
        for each symbol contained in the symbol table