Radu Sion

147 papers A* 33A 5B 6C 4Misc 2Journal 45Unranked 30
YearRankTypeTitle / Venue / Authors
2025 J jnl
SIGMOD Rec.
Radu Sion
2025 conf
CODASPY
Yuzhou Feng, Sandeep Kiran Pinjala, Radu Sion, Bogdan Carbunar
2024 A* conf
SP
Sandeep Kiran Pinjala, Bogdan Carbunar, Anrin Chakraborti, Radu Sion
2023 A* conf
USENIX Security Symposium
Yuzhou Feng, Ruyu Zhai, Radu Sion, Bogdan Carbunar
2023 J jnl
CoRR
Yuzhou Feng, Ruyu Zhai, Radu Sion, Bogdan Carbunar
2023 A* conf
USENIX Security Symposium
Anrin Chakraborti, Darius Suciu, Radu Sion
2022 conf
CPSS@AsiaCCS
Antonio Ken Iannillo, Sean Rivera, Darius Suciu, Radu Sion, Radu State
2022 conf
ESORICS (2)
Darius Suciu, Radu Sion, Michael Ferdman
2022 J jnl
Found. Trends Priv. Secur.
Anrin Chakraborti, Reza Curtmola, Jonathan Katz, Jason Nieh, Ahmad-Reza Sadeghi, Radu Sion, Yinqian Zhang
2022 J jnl
Proc. Priv. Enhancing Technol.
Chen Chen, Xiao Liang, Bogdan Carbunar, Radu Sion
2022 J jnl
CoRR
Anrin Chakraborti, Darius Suciu, Radu Sion
2021 J jnl
IEEE Trans. Knowl. Data Eng.
Sumeet Bajaj, Anrin Chakraborti, Radu Sion
2021 A* conf
USENIX Security Symposium
Chen Chen, Anrin Chakraborti, Radu Sion
2021 J jnl
CoRR
Chen Chen, Xiao Liang, Bogdan Carbunar, Radu Sion
2021 J jnl
IACR Cryptol. ePrint Arch.
Chen Chen, Xiao Liang, Bogdan Carbunar, Radu Sion
2020 ed.
CCSW
Yinqian Zhang, Radu Sion
2020 A* conf
CCS
Radu Sion, Yinqian Zhang
2020 A* conf
USENIX Security Symposium
Jake Christensen, Ionut Mugurel Anghel, Rob Taglang, Mihai Chiroiu, Radu Sion
2020 A* conf
USENIX Security Symposium
Darius Suciu, Stephen E. McLaughlin, Laurent Simon, Radu Sion
2020 J jnl
Proc. Priv. Enhancing Technol.
Chen Chen, Anrin Chakraborti, Radu Sion
2020 J jnl
CoRR
Chen Chen, Anrin Chakraborti, Radu Sion
2020 J jnl
Proc. Priv. Enhancing Technol.
Anrin Chakraborti, Radu Sion
2019 A* conf
CCS
Radu Sion, Charalampos Papamanthou
2019 A* conf
NDSS
Anrin Chakraborti, Radu Sion
2019 J jnl
IEEE Trans. Cloud Comput.
Moussa Ehsan, Karthiek Chandrasekaran, Yao Chen, Radu Sion
2019 J jnl
Proc. Priv. Enhancing Technol.
Chen Chen, Anrin Chakraborti, Radu Sion
2019 ed.
CCSW
Radu Sion, Charalampos Papamanthou
2019 conf
CCSW
Yinqian Zhang, Radu Sion
2019 A* conf
NDSS
Anrin Chakraborti, Adam J. Aviv, Seung Geol Choi, Travis Mayberry, Daniel S. Roche, Radu Sion
2018 A* conf
CCS
Jan Kasiak, Bogdan Carbunar, Jake Christensen, Maria Lyukova, Sumeet Bajaj, Mike Boruta, Radu Sion, Viorel Popescu, Alex Sorodoc, Gabriel Stan
2018 J jnl
CoRR
Anrin Chakraborti, Radu Sion
2018 ch.
Encyclopedia of Database Systems (2nd ed.)
Radu Sion
2018 J jnl
IACR Cryptol. ePrint Arch.
Anrin Chakraborti, Adam J. Aviv, Seung Geol Choi, Travis Mayberry, Daniel S. Roche, Radu Sion
2018 ch.
Encyclopedia of Database Systems (2nd ed.)
Radu Sion, Sumeet Bajaj
2018 ch.
Encyclopedia of Database Systems (2nd ed.)
Radu Sion
2018 ch.
Encyclopedia of Database Systems (2nd ed.)
Radu Sion
2017 J jnl
CoRR
Anrin Chakraborti, Chen Chen, Radu Sion
2017 J jnl
Proc. Priv. Enhancing Technol.
Anrin Chakraborti, Chen Chen, Radu Sion
2017 conf
CSCS
Darius Andrei Suciu, Radu Sion
2017 J jnl
CoRR
Anrin Chakraborti, Radu Sion
2017 conf
APSys
Anrin Chakraborti, Bhushan Jain, Jan Kasiak, Tao Zhang, Donald E. Porter, Radu Sion
2016 J jnl
Dagstuhl Reports
Kristin E. Lauter, Radu Sion, Nigel P. Smart
2016 A* conf
CCS
Anrin Chakraborti, Radu Sion
2016 A* conf
CCS
Anrin Chakraborti, Chen Chen, Radu Sion
2016 A* conf
CCS
Darius Suciu, Radu Sion
2016 A* conf
CCS
Chen Chen, Darius Suciu, Radu Sion
2016 J jnl
IEEE Trans. Inf. Forensics Secur.
Sumeet Bajaj, Anrin Chakraborti, Radu Sion
2015 J jnl
CoRR
Bo Chen, Radu Sion
2015 J jnl
IEEE Secur. Priv.
Bhushan Jain, Mirza Basim Baig, Dongli Zhang, Donald E. Porter, Radu Sion
2015 J jnl
CoRR
Sumeet Bajaj, Anrin Chakraborti, Radu Sion
2015 B conf
CCGRID
Chen Chen, Moussa Ehsan, Radu Sion
2014 B conf
IC2E
Mirza Basim Baig, Connor Fitzsimons, Suryanarayanan Balasubramanian, Radu Sion, Donald E. Porter
2014 ch.
Secure Cloud Computing
Yao Chen, Radu Sion
2014 conf
SoCC
Dongli Zhang, Moussa Ehsan, Michael Ferdman, Radu Sion
2014 J jnl
IEEE Trans. Mob. Comput.
Bogdan Carbunar, Radu Sion, Rahul Potharaju, Moussa Ehsan
2014 A* conf
IEEE Symposium on Security and Privacy
Bhushan Jain, Mirza Basim Baig, Dongli Zhang, Donald E. Porter, Radu Sion
2014 J jnl
IEEE Trans. Knowl. Data Eng.
Sumeet Bajaj, Radu Sion
2013 J jnl
ACM Trans. Inf. Syst. Secur.
Peter Williams, Radu Sion
2013 J jnl
Proc. VLDB Endow.
Sumeet Bajaj, Radu Sion
2013 A* conf
ICDE
Sumeet Bajaj, Radu Sion
2013 A* conf
CCS
Sumeet Bajaj, Radu Sion
2013 conf
IPDPS Workshops
Moussa Ehsan, Radu Sion
2013 Misc conf
HiPC
Moussa Ehsan, Yao Chen, Hui Kang, Radu Sion, Jennifer L. Wong
2013 conf
Secure Data Management
Radu Sion
2013 conf
ScienceCloud@HPDC
Radu Sion
2012 J jnl
IEEE Trans. Inf. Forensics Secur.
Radu Sion, Yao Chen
2012 J jnl
IEEE Data Eng. Bull.
Yao Chen, Radu Sion
2012 A* conf
CCS
Peter Williams, Radu Sion, Alin Tomescu
2012 A* conf
CCS
Peter Williams, Radu Sion
2012 B conf
ACNS
Bogdan Carbunar, Radu Sion, Rahul Potharaju, Moussa Ehsan
2012 J jnl
IEEE Trans. Inf. Forensics Secur.
Bogdan Carbunar, Yao Chen, Radu Sion
2012 J jnl
IEEE Trans. Knowl. Data Eng.
Bogdan Carbunar, Radu Sion
2011 J jnl
J. Parallel Distributed Comput.
Bogdan Carbunar, Weidong Shi, Radu Sion
2011 A conf
HPDC
Hui Kang, Yao Chen, Jennifer L. Wong, Radu Sion, Jason Wu
2011 conf
Financial Cryptography
Martin Franz, Peter Williams, Bogdan Carbunar, Stefan Katzenbeisser, Andreas Peter, Radu Sion, Miroslava Sotáková
2011 A* conf
CCS
Rishab Nithyanand, Radu Sion, John Solis
2011 J jnl
ACM Trans. Inf. Syst. Secur.
Peter Williams, Radu Sion, Miroslava Sotáková
2011 conf
GIS
Bogdan Carbunar, Radu Sion
2011 ch.
Encyclopedia of Cryptography and Security (2nd Ed.)
Radu Sion
2011 conf
SoCC
Yao Chen, Radu Sion
2011 J jnl
Proc. VLDB Endow.
Sumeet Bajaj, Radu Sion
2011 conf
SIGMOD Conference
Sumeet Bajaj, Radu Sion
2011 J jnl
IEEE Trans. Inf. Forensics Secur.
Bogdan Carbunar, Radu Sion
2010 J jnl
ACM Trans. Sens. Networks
Jie Gao, Radu Sion, Sol Lederer
2010 ed.
Financial Cryptography
Radu Sion
2010 ed.
Financial Cryptography Workshops
Radu Sion, Reza Curtmola, Sven Dietrich, Aggelos Kiayias, Josep M. Miret, Kazue Sako, Francesc Sebé
2010 conf
Secure Data Management
Bogdan Carbunar, Radu Sion
2010 conf
WPES
Yao Chen, Radu Sion
2010 ed.
CCSW
Adrian Perrig, Radu Sion
2010 ch.
Handbook of Financial Cryptography and Security
Radu Sion, Marianne Winslett
2010 B conf
ACNS
Bogdan Carbunar, Radu Sion
2010 conf
TRUST
Heike Busch, Miroslava Sotáková, Stefan Katzenbeisser, Radu Sion
2010 conf
TaPP
Patrick D. McDaniel, Kevin R. B. Butler, Stephen E. McLaughlin, Radu Sion, Erez Zadok, Marianne Winslett
2009 J jnl
Comput. Secur.
Siddharth Bhatt, Radu Sion, Bogdan Carbunar
2009 ch.
Encyclopedia of Database Systems
Radu Sion
2009 J jnl
ACM Trans. Storage
Ragib Hasan, Radu Sion, Marianne Winslett
2009 ed.
CCSW
Radu Sion, Dawn Song
2009 ch.
Encyclopedia of Database Systems
Radu Sion
2009 J jnl
CoRR
Ragib Hasan, Radu Sion, Marianne Winslett
2009 A conf
CIDR
Ragib Hasan, Radu Sion, Marianne Winslett
2009 J jnl
login Usenix Mag.
Ragib Hasan, Radu Sion, Marianne Winslett
2009 ch.
Encyclopedia of Database Systems
Radu Sion
2009 A* conf
NDSS
Peter Williams, Radu Sion, Dennis E. Shasha
2009 A conf
FAST
Ragib Hasan, Radu Sion, Marianne Winslett
2009 ch.
Encyclopedia of Database Systems
Radu Sion
2009 conf
WPES
Yao Chen, Radu Sion, Bogdan Carbunar
2008 A* conf
CCS
Peter Williams, Radu Sion, Bogdan Carbunar
2008 ch.
Handbook of Database Security
Radu Sion
2008 A conf
ICDCS
Radu Sion
2008 ch.
Handbook of Database Security
Radu Sion
2008 ch.
Handbook of Database Security
Ragib Hasan, Marianne Winslett, Soumyadeb Mitra, Windsor W. Hsu, Radu Sion
2008 A* conf
NDSS
Peter Williams, Radu Sion
2007 J jnl
Future Gener. Comput. Syst.
Ramesh Natarajan, Radu Sion, Thomas Phan
2007 conf
Financial Cryptography
Larry Shi, Bogdan Carbunar, Radu Sion
2007 conf
StorageSS
Ragib Hasan, Radu Sion, Marianne Winslett
2007 A* conf
VLDB
Radu Sion, Sumeet Bajaj, Bogdan Carbunar, Stefan Katzenbeisser
2007 A* conf
NDSS
Radu Sion, Bogdan Carbunar
2007 conf
Financial Cryptography
Siddharth Bhatt, Bogdan Carbunar, Radu Sion, Venu Vasudevan
2007 A* conf
VLDB
Radu Sion, Marianne Winslett
2007 conf
Secure Data Management
Ragib Hasan, Marianne Winslett, Radu Sion
2007 ch.
Secure Data Management in Decentralized Systems
Radu Sion
2007 A* conf
VLDB
Radu Sion
2006 J jnl
IEEE Trans. Knowl. Data Eng.
Radu Sion, Mikhail J. Atallah, Sunil Prabhakar
2006 Misc conf
COMAD
Radu Sion
2006 conf
Financial Cryptography
Bogdan Carbunar, Radu Sion
2006 B conf
EDBT
Radu Sion, Ramesh Natarajan, Inderpal Narang, Thomas Phan
2005 A conf
ICWS
Radu Sion, Jun'ichi Tatemura
2005 C conf
JSSPP
Thomas Phan, Kavitha Ranganathan, Radu Sion
2005 A* conf
VLDB
Radu Sion
2005 J jnl
IEEE Trans. Knowl. Data Eng.
Radu Sion, Mikhail J. Atallah, Sunil Prabhakar
2005 C conf
DEXA
Radu Sion, Ramesh Natarajan, Inderpal Narang, Wen-Syan Li, Thomas Phan
2004 conf
Security, Steganography, and Watermarking of Multimedia Contents
Radu Sion, Mikhail J. Atallah
2004 J jnl
IEEE Data Eng. Bull.
Mikhail J. Atallah, Sunil Prabhakar, Keith B. Frikken, Radu Sion
2004 A* conf
ICDE
Radu Sion
2004 B conf
EDBT
Yi-Cheng Tu, Sunil Prabhakar, Ahmed K. Elmagarmid, Radu Sion
2004 A* conf
VLDB
Radu Sion, Mikhail J. Atallah, Sunil Prabhakar
2004 J jnl
IEEE Trans. Knowl. Data Eng.
Radu Sion, Mikhail J. Atallah, Sunil Prabhakar
2004
Radu Sion
2004 A* conf
ICDE
Radu Sion, Mikhail J. Atallah, Sunil Prabhakar
2003 conf
ITCC
Radu Sion, Mikhail J. Atallah, Sunil Prabhakar
2003 C conf
IWDW
Radu Sion, Mikhail J. Atallah, Sunil Prabhakar
2003 conf
SIGMOD Conference
Radu Sion, Mikhail J. Atallah, Sunil Prabhakar
2002 A* conf
VLDB
Wen-Syan Li, Wang-Pin Hsiung, Dmitri V. Kalashnikov, Radu Sion, Oliver Po, Divyakant Agrawal, K. Selçuk Candan
2002 conf
Information Hiding
Mikhail J. Atallah, Victor Raskin, Christian Hempelmann, Mercan Karahan, Radu Sion, Umut Topkara, Katrina E. Triezenberg
2002 C conf
IWDW
Radu Sion, Mikhail J. Atallah, Sunil Prabhakar
2002 conf
ITCC
Radu Sion
2000 conf
ASA/MA
Ladislau Bölöni, Kyungkoo Jun, Krzysztof Palacz, Radu Sion, Dan C. Marinescu
redb/extractors/apk_extractors/apk_resources.py
← Index redb/extractors/apk_extractors/apk_resources.py python
import hashlib
import inspect
import os
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 APKResource


# ─── Suspicious file types ──────────────────────────────────────────────
# File types that are suspicious when found inside res/ or assets/.
# Excludes javascript/html (extremely common in legitimate hybrid apps)
# and common media/font types that are normal APK content.
SUSPICIOUS_TYPES = {
    # Executables — no legitimate reason in assets/res
    "elf", "pebin", "macho", "dex", "apk",
    # Java containers — DexClassLoader target
    "jar",
    # Archives — rare in legitimate assets (~135:1 malware-to-benign ratio)
    "zip", "gzip", "7z", "xz", "tar", "bzip2", "rar", "7zip", "lzma",
    # Scripts with system execution capability
    "shell", "python", "powershell", "batch",
}

# ─── Entropy thresholds ─────────────────────────────────────────────────
# For unrecognized/unknown types: encrypted payloads typically land > 7.0
ENTROPY_HIGH_UNKNOWN = 7.0
# For recognized-but-non-image types: stricter threshold
ENTROPY_EXTREME = 7.85

# ─── Android-specific binary format magic bytes ─────────────────────────
# These formats are common in legitimate APKs but unknown to Magika,
# causing misclassification (e.g., AXML → "gzip", profm → "unknown").
AXML_MAGIC = b'\x03\x00\x08\x00'       # Android Binary XML (compiled res/*.xml)
ARSC_MAGIC = b'\x02\x00\x0c\x00'       # Android compiled resource table
ART_PROF_MAGIC = b'pro\x00'            # ART baseline profile
ART_PROFM_MAGIC = b'prm\x00'           # ART baseline profile metadata

# ─── Allowlisted paths ──────────────────────────────────────────────────
# Fixed, hardcoded paths in the Android build system that are always benign.
# ART profiles at these exact paths are shipped by Jetpack ProfileInstaller.
ALLOWLISTED_PATHS = {
    "assets/dexopt/baseline.prof",
    "assets/dexopt/baseline.profm",
}

# ─── Image handling ─────────────────────────────────────────────────────
# Magika-confirmed image types: high entropy is expected (lossy codecs
# like VP8/JPEG arithmetic-code toward entropy ~7.95-8.0 by design).
IMAGE_MAGIKA_TYPES = {"png", "webp", "jpeg", "gif", "bmp", "tiff", "ico"}
IMAGE_EXTENSIONS = {".png", ".webp", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".ico"}

# ─── Types Magika assigns when it can't identify the content ────────────
UNRECOGNIZED_MAGIKA_TYPES = {"unknown", "empty"}

# ─── Resource scan limits ───────────────────────────────────────────────
MAX_RESOURCE_FILES = 5000


class APKResourceExtractor(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.resources = []
        self.suspicious_files = []
        self.log.debug(inspect.currentframe().f_code.co_name)

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

    # ─── Core classification logic ──────────────────────────────────────

    def _identify_android_format(self, header: bytes) -> str | None:
        """
        Identify Android-specific binary formats that Magika doesn't know.
        Returns a corrected type label, or None to fall through to Magika.
        """
        if len(header) < 4:
            return None

        magic4 = header[:4]

        # Android Binary XML — all res/*.xml in a compiled APK.
        # Magika often misclassifies this as "gzip".
        if magic4 == AXML_MAGIC:
            return "android_binary_xml"

        # Android compiled resource table (resources.arsc chunks)
        if magic4 == ARSC_MAGIC:
            return "android_resource_table"

        # ART baseline profiles — high entropy (zlib inside) but benign.
        # The format is inert (method reference bitmaps/metadata, not
        # executable code) and some build configs place them at varying paths.
        if magic4 == ART_PROF_MAGIC:
            return "android_art_profile"
        if magic4 == ART_PROFM_MAGIC:
            return "android_art_profile_metadata"

        return None

    def _is_suspicious_resource(
        self, path: str, magika_type: str, entropy: float,
        android_type: str | None,
    ) -> bool:
        """
        Determine if a resource file is suspicious.

        Detection layers:
        1. Allowlisted paths → always benign
        2. Android-specific format override → reclassify Magika mislabels
        3. Image extension vs Magika type mismatch → encrypted blob detection
        4. Magika-confirmed images → benign regardless of entropy
        5. Suspicious type match → flag known-dangerous types
        6. High-entropy unknown blobs → likely encrypted payloads
        """

        # ── Layer 1: Allowlisted paths (hardcoded Android build artifacts) ──
        if path in ALLOWLISTED_PATHS:
            return False

        # ── Layer 2: Android-specific format detection ──────────────────────
        # Override Magika's label for formats it doesn't recognize.
        # All Android-specific formats (AXML, ARSC, ART profiles) are
        # legitimate build artifacts — never suspicious.
        if android_type is not None:
            return False

        # ── Layer 3: Image extension / Magika type mismatch ─────────────────
        # If the file extension claims "image" but Magika's content analysis
        # disagrees, this is a strong signal for an encrypted payload with
        # a fake image extension (e.g., ErrorFather's "rbyypivsnw.png").
        ext = os.path.splitext(path)[1].lower()
        if ext in IMAGE_EXTENSIONS and magika_type not in IMAGE_MAGIKA_TYPES:
            # Exception: Magika might label a valid image as "unknown" if
            # the file is very small (< ~16 bytes). Don't flag tiny files.
            if entropy > 5.0:
                return True

        # ── Layer 4: Magika-confirmed images → benign ───────────────────────
        # Lossy codecs (VP8, JPEG) produce entropy up to ~8.0 by design.
        # If Magika confirms image structure, high entropy is expected.
        if magika_type in IMAGE_MAGIKA_TYPES:
            return False

        # ── Layer 5: Known suspicious file types ────────────────────────────
        if magika_type in SUSPICIOUS_TYPES:
            return True

        # ── Layer 6: High-entropy unrecognized blobs ────────────────────────
        # Files Magika can't identify with high entropy are likely encrypted
        # payloads. Most Android malware packers store encrypted DEX/SO
        # payloads as opaque blobs with random names and no valid magic.
        if magika_type in UNRECOGNIZED_MAGIKA_TYPES and entropy > ENTROPY_HIGH_UNKNOWN:
            return True

        # ── Layer 7: Extreme entropy on any non-image recognized type ───────
        # Catches edge cases where Magika assigns a benign label (e.g.,
        # "xml", "txt") but the entropy is impossibly high for that format.
        if magika_type not in IMAGE_MAGIKA_TYPES and entropy > ENTROPY_EXTREME:
            return True

        return False

    # ─── Extraction pipeline ────────────────────────────────────────────

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

        try:
            from magika import Magika
            magika = Magika()
        except Exception as e:
            self.log.error(f"Failed to initialize Magika for {self.hash.sha256}: {e}")
            magika = None

        self.resources = []
        self.suspicious_files = []
        scanned = 0

        zf = self._get_zip_file()
        if not zf:
            return None

        with zf:
            for info in zf.infolist():
                if info.is_dir():
                    continue
                if not (info.filename.startswith("res/") or
                        info.filename.startswith("assets/")):
                    continue

                if scanned >= MAX_RESOURCE_FILES:
                    self.log.warning(
                        f"Resource scan limit reached ({MAX_RESOURCE_FILES}), "
                        f"stopping resource enumeration"
                    )
                    break
                scanned += 1

                try:
                    data = zf.read(info.filename)
                except Exception as e:
                    self.log.warning(
                        f"Error reading resource {info.filename}: {e}"
                    )
                    continue

                try:
                    file_sha256 = hashlib.sha256(data).hexdigest()
                    file_entropy = round(self.calculate_entropy(data), 3)

                    # Read first bytes for Android-specific format detection
                    header = data[:16] if len(data) >= 16 else data

                    if magika:
                        try:
                            filetype = magika.identify_bytes(data).output.label
                        except Exception:
                            filetype = "unknown"
                    else:
                        filetype = "unknown"

                    # Identify Android-specific formats once, reuse for
                    # both stored type and suspicion classification
                    android_type = self._identify_android_format(header)
                    stored_type = android_type if android_type else filetype

                    suspicious = self._is_suspicious_resource(
                        path=info.filename,
                        magika_type=filetype,
                        entropy=file_entropy,
                        android_type=android_type,
                    )

                    resource = APKResource(
                        path=info.filename,
                        size=info.file_size,
                        sha256=file_sha256,
                        filetype_magika=stored_type,
                        entropy=file_entropy,
                    )

                    if suspicious:
                        resource.is_suspicious = True
                        self.suspicious_files.append(resource)

                    self.resources.append(resource)
                except Exception as e:
                    self.log.warning(
                        f"Error processing resource {info.filename}: {e}"
                    )
                    continue

        if not self.resources:
            return None

        return {
            "total_resource_count": len(self.resources),
            "total_resource_size": sum(r.size for r in self.resources),
            "suspicious_file_count": len(self.suspicious_files),
            "resources": self.resources,
            "suspicious_files": self.suspicious_files,
        }

    # ─── Export ──────────────────────────────────────────────────────────

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

            current_time = datetime.now(timezone.utc)
            data = []
            for res in self.resources:
                data.append([
                    self.sha256,
                    res.path,
                    res.size,
                    res.sha256,
                    res.filetype_magika,
                    res.entropy,
                    int(res.is_suspicious),
                    current_time,
                ])

            column_names = [
                'sha256', 'resource_path', 'resource_size',
                'resource_sha256', 'resource_magika', 'resource_entropy',
                'is_suspicious', 'analysis_date',
            ]

            column_type_names = [
                'FixedString(64)', 'String', 'UInt64',
                'FixedString(64)', 'LowCardinality(String)', 'Float32',
                'UInt8', "DateTime64(3, 'UTC')",
            ]

            return (data, column_names, column_type_names)

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