Katayoun Farrahi

55 papers A* 4A 2B 3C 1Misc 8Journal 24Unranked 11
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Huahua Lin, Katayoun Farrahi, Xiaohao Cai
2025 J jnl
Neural Comput. Appl.
Xin Du, Rajesh Jena, Katayoun Farrahi, Mahesan Niranjan
2025 J jnl
IEEE Pervasive Comput.
Katayoun Farrahi, Tanaya Guha
2024 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Jiejun Hu, Katayoun Farrahi, Manuel Cebrián
2024 J jnl
IEEE Pervasive Comput.
Andrei C. Rusu, Katayoun Farrahi, Mahesan Niranjan
2024 Misc conf
HotMobile
Julia Lee Romero, Andrea Ferlini, Dimitris Spathis, Ting Dang, Katayoun Farrahi, Fahim Kawsar, Alessandro Montanari
2024 J jnl
Pattern Recognit. Lett.
Wei He, Katayoun Farrahi, Bin Chen, Bohua Peng, Aline Villavicencio
2024 conf
ML4H@NeurIPS
Eirini Kateri, Katayoun Farrahi
2024 J jnl
CoRR
Zygimantas Jocys, Henriëtte M. G. Willems, Katayoun Farrahi
2023 J jnl
CoRR
Junwen Wang, Katayoun Farrahi
2023 conf
UbiComp/ISWC Adjunct
Andrea Ferlini, Alessandro Montanari, Nirupam Roy, Katayoun Farrahi
2022 J jnl
J. Mach. Learn. Res.
Bhumika Mistry, Katayoun Farrahi, Jonathon S. Hare
2022 J jnl
CoRR
Emilien Valat, Katayoun Farrahi, Thomas Blumensath
2022 conf
MLHC
Junwen Wang, Xin Du, Katayoun Farrahi, Mahesan Niranjan
2022 J jnl
Trans. Mach. Learn. Res.
Bhumika Mistry, Katayoun Farrahi, Jonathon S. Hare
2022 conf
PervasiveHealth
Andrei C. Rusu, Katayoun Farrahi, Mahesan Niranjan
2022 J jnl
CoRR
Bhumika Mistry, Katayoun Farrahi, Jonathon S. Hare
2022 J jnl
CoRR
Juliusz Ziomek, Katayoun Farrahi
2022 J jnl
CoRR
Emilien Valat, Katayoun Farrahi, Thomas Blumensath
2021 J jnl
CoRR
Bhumika Mistry, Katayoun Farrahi, Jonathon S. Hare
2021 J jnl
Entropy
Xin Du, Katayoun Farrahi, Mahesan Niranjan
2021 J jnl
CoRR
Bhumika Mistry, Katayoun Farrahi, Jonathon S. Hare
2019 conf
PervasiveHealth
Dimitris Spathis, Sandra Servia Rodríguez, Katayoun Farrahi, Cecilia Mascolo, Jason Rentfrow
2019 ed.
UbiComp/ISWC Adjunct
Robert Harle, Katayoun Farrahi, Nicholas D. Lane
2019 Misc ed.
UbiComp
Katayoun Farrahi, Robert Harle, Nicholas D. Lane
2019 A* conf
KDD
Dimitris Spathis, Sandra Servia Rodríguez, Katayoun Farrahi, Cecilia Mascolo, Jason Rentfrow
2019 Misc conf
UbiComp
Xin Du, Katayoun Farrahi, Mahesan Niranjan
2018 C conf
HealthCom
Fayez Alharbi, Katayoun Farrahi
2018 B conf
DS
Antony Milne, Katayoun Farrahi, Mihalis A. Nicolaou
2017 A* conf
ACM Multimedia
Ishrat Rahman Sami, Katayoun Farrahi
2017 conf
SocInfo (2)
Antony Milne, Mihalis Nicolaou, Katayoun Farrahi
2017 J jnl
Hum. centric Comput. Inf. Sci.
Katayoun Farrahi, Kashif Zia
2015 A conf
ECIR
Markus Schedl, David Hauger, Katayoun Farrahi, Marko Tkalcic
2015 A conf
CSCW
Katayoun Farrahi, Rémi Emonet, Manuel Cebrián
2014 J jnl
Pers. Ubiquitous Comput.
Katayoun Farrahi, Daniel Gatica-Perez
2014 conf
ISMIR
Katayoun Farrahi, Markus Schedl, Andreu Vall, David Hauger, Marko Tkalcic
2014 A* conf
SIGIR
Markus Schedl, Andreu Vall, Katayoun Farrahi
2013 Misc conf
PAAMS
Katayoun Farrahi, Kashif Zia, Alexei Sharpanskykh, Alois Ferscha, Lev Muchnik
2013 J jnl
Simul.
Kashif Zia, Katayoun Farrahi, Andreas Riener, Alois Ferscha
2013 Misc conf
PAAMS
Kashif Zia, Katayoun Farrahi, Alexei Sharpanskykh, Alois Ferscha, Lev Muchnik
2013 J jnl
CoRR
Alois Ferscha, Katayoun Farrahi, Jeroen van den Hoven, David Hales, Andrzej Nowak, Paul Lukowicz, Dirk Helbing
2013 conf
HPCS
Katayoun Farrahi, Alois Ferscha
2012 B conf
PADS
Kashif Zia, Andreas Riener, Katayoun Farrahi, Alois Ferscha
2012 Misc conf
ISWC
Katayoun Farrahi, Daniel Gatica-Perez
2012 J jnl
IEEE Pervasive Comput.
Anmol Madan, Manuel Cebrián, Sai T. Moturu, Katayoun Farrahi, Alex Pentland
2012 Misc conf
ISWC
Katayoun Farrahi, Rémi Emonet, Alois Ferscha
2011
Katayoun Farrahi
2011 J jnl
ACM Trans. Intell. Syst. Technol.
Katayoun Farrahi, Daniel Gatica-Perez
2011 conf
Pervasive
Anmol Madan, Katayoun Farrahi, Daniel Gatica-Perez, Alex Pentland
2010 conf
SocialCom/PASSAT
Katayoun Farrahi, Daniel Gatica-Perez
2010 J jnl
IEEE J. Sel. Top. Signal Process.
Katayoun Farrahi, Daniel Gatica-Perez
2009 B conf
ICMI
Katayoun Farrahi, Daniel Gatica-Perez
2008 conf
MLMI
Katayoun Farrahi, Daniel Gatica-Perez
2008 Misc conf
ISWC
Katayoun Farrahi, Daniel Gatica-Perez
2008 A* conf
ACM Multimedia
Katayoun Farrahi, Daniel Gatica-Perez
redb/extractors/apk_extractors/apk_features.py
← Index redb/extractors/apk_extractors/apk_features.py python
import inspect
import zipfile
from datetime import datetime, timezone
from typing import Any

from redb.extractors.enum import Tag
from redb.extractors.apk_extractor import APKExtractor
from redb.models.dataclasses import APKFeatures


class APKFeaturesExtractor(APKExtractor):

    def __init__(
        self, filepath, log, exporters=None, index_prefix=None,
        known_benign=False, known_malicious=False,
        apk=None,
    ):
        super().__init__(
            filepath, log, exporters, index_prefix,
            known_benign, known_malicious, apk,
        )
        self.apk_features = None
        self.log.debug(inspect.currentframe().f_code.co_name)

    def tag(self):
        return Tag.APK_FEATURES.value

    def _extract_zip_timestamps(self):
        """Extract earliest and latest content modification from ZIP entries."""
        earliest = None
        latest = None
        try:
            zf = self._get_zip_file()
            if zf:
                with zf:
                    for info in zf.infolist():
                        try:
                            dt = datetime(*info.date_time)
                            if earliest is None or dt < earliest:
                                earliest = dt
                            if latest is None or dt > latest:
                                latest = dt
                        except (ValueError, TypeError):
                            continue
        except Exception as e:
            self.log.warning(f"Error extracting ZIP timestamps: {e}")
        return (
            earliest.isoformat() if earliest else None,
            latest.isoformat() if latest else None,
        )

    def _extract_supported_abis(self):
        """Determine supported ABIs from lib/ directory."""
        abis = set()
        for f in self._list_files():
            if f.startswith("lib/") and f.endswith(".so"):
                parts = f.split("/")
                if len(parts) >= 3:
                    abis.add(parts[1])
        return sorted(abis)

    def _count_dex_files(self):
        """Count DEX files and compute total size."""
        dex_count = 0
        total_size = 0
        try:
            zf = self._get_zip_file()
            if zf:
                with zf:
                    for info in zf.infolist():
                        if info.filename.endswith(".dex"):
                            dex_count += 1
                            total_size += info.file_size
        except Exception as e:
            self.log.warning(f"Error counting DEX files: {e}")
        return dex_count, total_size

    def _check_embedded_apk(self):
        """Check if the archive contains nested APK files."""
        for f in self._list_files():
            if f.lower().endswith(".apk"):
                return True
        return False

    def _safe_extract(self, field_name, func, default=None):
        """Extract a single field, logging and returning default on failure."""
        try:
            return func()
        except Exception as e:
            self.log.warning(
                f"Error extracting APK field '{field_name}' for "
                f"{self.hash.sha256}: {e}"
            )
            return default

    def extract(self):
        if not self._is_valid_apk():
            self.log.error(f"Invalid APK for {self.hash.sha256}")
            return None

        package_name = self._safe_extract(
            "package_name", lambda: self.apk.get_package()
        )
        app_name = self._safe_extract(
            "app_name", lambda: self.apk.get_app_name()
        )

        def _get_version_code():
            try:
                return int(self.apk.get_androidversion_code() or 0)
            except (ValueError, TypeError):
                return 0

        version_code = self._safe_extract("version_code", _get_version_code)
        version_name = self._safe_extract(
            "version_name", lambda: self.apk.get_androidversion_name()
        )

        def _get_sdk(getter):
            val = getter()
            return int(val) if val else None

        min_sdk = self._safe_extract(
            "min_sdk_version", lambda: _get_sdk(self.apk.get_min_sdk_version)
        )
        target_sdk = self._safe_extract(
            "target_sdk_version", lambda: _get_sdk(self.apk.get_target_sdk_version)
        )
        compile_sdk = self._safe_extract(
            "compile_sdk_version",
            lambda: _get_sdk(self.apk.get_effective_target_sdk_version),
        )

        main_activity = self._safe_extract(
            "main_activity", lambda: self.apk.get_main_activity()
        )

        is_debuggable = self._safe_extract(
            "is_debuggable",
            lambda: self.apk.get_attribute_value(
                "application", "debuggable"
            ) == "true",
            False,
        )
        allow_backup = self._safe_extract(
            "allow_backup",
            lambda: self.apk.get_attribute_value(
                "application", "allowBackup"
            ) != "false",
            True,
        )
        uses_cleartext = self._safe_extract(
            "uses_cleartext_traffic",
            lambda: self.apk.get_attribute_value(
                "application", "usesCleartextTraffic"
            ) == "true",
            False,
        )

        supported_abis = self._safe_extract(
            "supported_abis", self._extract_supported_abis, []
        )
        dex_count, total_dex_size = self._safe_extract(
            "dex_files", self._count_dex_files, (0, 0)
        )
        all_files = self._safe_extract("file_list", self._list_files, [])
        total_file_count = len(all_files)
        has_native_code = any(
            f.startswith("lib/") and f.endswith(".so") for f in all_files
        )
        has_assets = any(f.startswith("assets/") for f in all_files)
        contains_embedded_apk = self._safe_extract(
            "contains_embedded_apk", self._check_embedded_apk, False
        )

        uses_libraries = self._safe_extract(
            "uses_libraries",
            lambda: list(self.apk.get_libraries() or []),
            [],
        )

        earliest_mod, latest_mod = self._safe_extract(
            "zip_timestamps", self._extract_zip_timestamps, (None, None)
        )

        self.apk_features = APKFeatures(
            package_name=package_name,
            app_name=app_name,
            version_code=version_code,
            version_name=version_name,
            min_sdk_version=min_sdk,
            target_sdk_version=target_sdk,
            compile_sdk_version=compile_sdk,
            main_activity=main_activity,
            is_debuggable=is_debuggable,
            allow_backup=allow_backup,
            uses_cleartext_traffic=uses_cleartext,
            supported_abis=supported_abis,
            dex_count=dex_count,
            total_dex_size=total_dex_size,
            total_file_count=total_file_count,
            has_native_code=has_native_code,
            has_assets=has_assets,
            uses_libraries=uses_libraries,
            earliest_content_modification=earliest_mod,
            latest_content_modification=latest_mod,
            contains_embedded_apk=contains_embedded_apk,
        )
        return self.apk_features

    def prepare_export_data(self, exporter_type: str) -> Any:
        if exporter_type == "ClickHouseExporter":
            if not self.apk_features:
                return None

            f = self.apk_features
            current_time = datetime.now(timezone.utc)
            data = [[
                self.sha256,
                f.package_name,
                f.app_name,
                f.version_code,
                f.version_name,
                f.min_sdk_version,
                f.target_sdk_version,
                f.compile_sdk_version,
                f.main_activity,
                int(f.is_debuggable),
                int(f.allow_backup),
                int(f.uses_cleartext_traffic),
                f.supported_abis,
                f.dex_count,
                f.total_dex_size,
                f.total_file_count,
                int(f.has_native_code),
                int(f.has_assets),
                f.uses_libraries,
                f.earliest_content_modification,
                f.latest_content_modification,
                int(f.contains_embedded_apk),
                current_time,
            ]]

            column_names = [
                "sha256",
                "package_name", "app_name", "version_code", "version_name",
                "min_sdk_version", "target_sdk_version", "compile_sdk_version",
                "main_activity",
                "is_debuggable", "allow_backup", "uses_cleartext_traffic",
                "supported_abis",
                "dex_count", "total_dex_size", "total_file_count",
                "has_native_code", "has_assets",
                "uses_libraries",
                "earliest_content_modification", "latest_content_modification",
                "contains_embedded_apk",
                "analysis_date",
            ]

            column_type_names = [
                "FixedString(64)",
                "Nullable(String)", "Nullable(String)", "Nullable(UInt32)", "Nullable(String)",
                "Nullable(UInt16)", "Nullable(UInt16)", "Nullable(UInt16)",
                "Nullable(String)",
                "UInt8", "UInt8", "UInt8",
                "Array(String)",
                "UInt16", "UInt64", "UInt32",
                "UInt8", "UInt8",
                "Array(String)",
                "Nullable(String)", "Nullable(String)",
                "UInt8",
                "DateTime64(3, 'UTC')",
            ]

            return (data, column_names, column_type_names)

    def get_clickhouse_table(self) -> str:
        return "redb_apk_features"