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

Code before:
        name_buf = self.buf[name_offset : name_offset + namesz]
        self.name = read_cstr(name_buf, 0x0)
        logger.debug("sh:name: %s", self.name)

    @property
    def abi_tag(self) -> Optional[ABITag]:
        if self.name != "GNU":
            return None

        if self.descsz < 16:
            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

Review comment (suggestion):
```suggestion
    def __init__(self, endian: str, bitness: int, symtab_buf: bytes, symtab_entsize: int, symtab_sz: int, strtab_buf: bytes, strtab_sz: int) -> None:
```

Code after:
        name_buf = self.buf[name_offset : name_offset + namesz]
        self.name = read_cstr(name_buf, 0x0)
        logger.debug("sh:name: %s", self.name)

    @property
    def abi_tag(self) -> Optional[ABITag]:
        if self.name != "GNU":
            return None

        if self.descsz < 16:
            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