Oded Maler

151 papers A* 16A 12B 15C 3Misc 2Journal 26Unranked 69
YearRankTypeTitle / Venue / Authors
2024 J jnl
ACM Trans. Embed. Comput. Syst.
Dogan Ulus, Thomas Ferrère, Eugene Asarin, Dejan Nickovic, Oded Maler
2020 J jnl
Int. J. Softw. Tools Technol. Transf.
Dejan Nickovic, Olivier Lebeltel, Oded Maler, Thomas Ferrère, Dogan Ulus
2019 J jnl
J. ACM
Thomas Ferrère, Oded Maler, Dejan Nickovic, Amir Pnueli
2019 conf
FORMATS
Thomas Ferrère, Oded Maler, Dejan Nickovic
2019 conf
FORMATS
Alexey Bakhirkin, Nicolas Basset, Oded Maler, José Ignacio Requeno Jarabo
2019 ch.
Automated Reasoning for Systems Biology and Medicine
Thao Dang, Tommaso Dreossi, Eric Fanchon, Oded Maler, Carla Piazza, Alexandre Rocca
2019 J jnl
Dagstuhl Reports
Jyotirmoy V. Deshmukh, Oded Maler, Dejan Nickovic
2018 conf
TACAS (2)
Dejan Nickovic, Olivier Lebeltel, Oded Maler, Thomas Ferrère, Dogan Ulus
2018 conf
HSCC
Alexey Bakhirkin, Thomas Ferrère, Oded Maler
2018 J jnl
Dagstuhl Reports
Yaakov Benenson, Neil Dalchau, Heinz Koeppl, Oded Maler
2018 conf
FORMATS
Alexey Bakhirkin, Thomas Ferrère, Dejan Nickovic, Oded Maler, Eugene Asarin
2018 ch.
Lectures on Runtime Verification
Ezio Bartocci, Jyotirmoy V. Deshmukh, Alexandre Donzé, Georgios Fainekos, Oded Maler, Dejan Nickovic, Sriram Sankaranarayanan
2018 conf
HSCC
Dogan Ulus, Oded Maler
2017 conf
Models, Algorithms, Logics and Tools
Oded Maler, Irini-Eleftheria Mens
2017 conf
FORMATS
Eugene Asarin, Oded Maler, Dejan Nickovic, Dogan Ulus
2017 conf
FORMATS
Alexey Bakhirkin, Thomas Ferrère, Oded Maler, Dogan Ulus
2016 conf
SSCI
Oded Maler, Abhinav Srivastav
2016 A conf
TACAS
Dogan Ulus, Thomas Ferrère, Eugene Asarin, Oded Maler
2016 B conf
RV
Oded Maler
2015 ed.
HSB
Oded Maler, Ádám M. Halász, Thao Dang, Carla Piazza
2015 J jnl
Log. Methods Comput. Sci.
Irini-Eleftheria Mens, Oded Maler
2015 conf
CAV (2)
Thomas Ferrère, Oded Maler, Dejan Nickovic, Dogan Ulus
2015 conf
Haifa Verification Conference
Jan Láník, Oded Maler
2015 C conf
MEMOCODE
Jan Láník, Julien Legriel, Erwan Piriou, Emmanuel Viaud, Fahim Rahim, Oded Maler, Solaiman Rahim
2015 B conf
ATVA
Jyotirmoy V. Deshmukh, Xiaoqing Jin, James Kapinski, Oded Maler
2015 B conf
ATVA
Thomas Ferrère, Oded Maler, Dejan Nickovic
2014 conf
HSB
Oded Maler, Ádám M. Halász, Olivier Lebeltel, Ouri Maler
2014 conf
QAPL
Jean-Francois Kempf, Olivier Lebeltel, Oded Maler
2014 A conf
TACAS
Oded Maler, Irini-Eleftheria Mens
2014 C conf
DSD
Pranav Tendulkar, Peter Poplavko, Ioannis Galanommatis, Oded Maler
2014 conf
FPS@ETAPS
Oded Maler
2014 conf
FORMATS
Dogan Ulus, Thomas Ferrère, Eugene Asarin, Oded Maler
2013 J jnl
CoRR
Moshe Ben-Bassat, Oded Maler
2013 conf
INFINITY
Oded Maler
2013 A conf
TACAS
Jean-Francois Kempf, Marius Bozga, Oded Maler
2013 A* conf
CAV
Alexandre Donzé, Thomas Ferrère, Oded Maler
2013 conf
HSB
Oded Maler, Ádám M. Halász, Olivier Lebeltel, Ouri Maler
2013 J jnl
Int. J. Softw. Tools Technol. Transf.
Oded Maler, Dejan Nickovic
2013 J jnl
Microprocess. Microsystems
Selma Saidi, Pranav Tendulkar, Thierry Lepley, Oded Maler
2013 J jnl
PLoS Comput. Biol.
Szymon Stoma, Alexandre Donzé, François Bertaux, Oded Maler, Grégory Batt
2013 conf
FORMATS
Pranav Tendulkar, Peter Poplavko, Oded Maler
2012 B conf
ATVA
Alexandre Donzé, Oded Maler, Ezio Bartocci, Dejan Nickovic, Radu Grosu, Scott A. Smolka
2012 C conf
DSD
Selma Saidi, Pranav Tendulkar, Thierry Lepley, Oded Maler
2012 J jnl
ACM Trans. Archit. Code Optim.
Selma Saidi, Pranav Tendulkar, Thierry Lepley, Oded Maler
2011 J jnl
Theor. Comput. Sci.
Thao Dang, Colas Le Guernic, Oded Maler
2011 B conf
ECRTS
Julien Legriel, Oded Maler
2011 conf
SIES
Scott Cotton, Oded Maler, Julien Legriel, Selma Saidi
2011 Misc conf
EMSOFT
Oded Maler
2011 B conf
IEEE Congress on Evolutionary Computation
Julien Legriel, Scott Cotton, Oded Maler
2011 B conf
RV
Eugene Asarin, Alexandre Donzé, Oded Maler, Dejan Nickovic
2011 conf
FORMATS
Jean-Francois Kempf, Marius Bozga, Oded Maler
2011 A* conf
CAV
Goran Frehse, Colas Le Guernic, Alexandre Donzé, Scott Cotton, Rajarshi Ray, Olivier Lebeltel, Rodolfo Ripado, Antoine Girard, Thao Dang, Oded Maler
2010 conf
HSCC
Thao Dang, Oded Maler, Romain Testylier
2010 conf
HSCC
Oded Maler
2010 A conf
TACAS
Julien Legriel, Colas Le Guernic, Scott Cotton, Oded Maler
2010 conf
INFINITY
Oded Maler, Kim G. Larsen, Bruce H. Krogh
2010 conf
Essays in Memory of Amir Pnueli
Oded Maler
2010 conf
FORMATS
John Havlicek, Scott Little, Oded Maler, Dejan Nickovic
2010 conf
FORMATS
Alexandre Donzé, Oded Maler
2010 B conf
ATVA
Eugene Asarin, Thao Dang, Oded Maler, Romain Testylier
2009 Misc conf
EMSOFT
Ramzi Ben Salah, Marius Bozga, Oded Maler
2009 A* ed.
CAV
Ahmed Bouajjani, Oded Maler
2009 conf
CMSB
Thao Dang, Colas Le Guernic, Oded Maler
2009 B conf
FoSSaCS
Rajeev Alur, Aldric Degorre, Oded Maler, Gera Weiss
2009 conf
RP
Oded Maler
2008 conf
FMSB
Oded Maler, Grégory Batt
2008 conf
Pillars of Computer Science
Oded Maler, Dejan Nickovic, Amir Pnueli
2008 conf
FORMATS
Aldric Degorre, Oded Maler
2008 conf
CDC
Thao Dang, Alexandre Donzé, Oded Maler, Noa Shalev
2007 conf
FORMATS
Dejan Nickovic, Oded Maler
2007 A* conf
CAV
Oded Maler, Dejan Nickovic, Amir Pnueli
2007 conf
FORMATS
Grégory Batt, Ramzi Ben Salah, Oded Maler
2007 J jnl
Annu. Rev. Control.
Oded Maler
2007 conf
SAVCBS
Ramzi Ben Salah, Marius Bozga, Oded Maler
2007 conf
HSCC
Goran Frehse, Oded Maler
2007 conf
HSCC
Alexandre Donzé, Oded Maler
2006 conf
HSCC
Antoine Girard, Colas Le Guernic, Oded Maler
2006 A conf
SAT
Scott Cotton, Oded Maler
2006 conf
FORMATS
Oded Maler, Dejan Nickovic, Amir Pnueli
2006 B conf
CONCUR
Ramzi Ben Salah, Marius Bozga, Oded Maler
2006 ed.
FAC
Oded Maler
2006 J jnl
Theor. Comput. Sci.
Yasmina Abdeddaïm, Eugene Asarin, Oded Maler
2005 conf
FAC
Oded Maler
2005 ch.
Handbook of Networked and Embedded Control Systems
Paul Caspi, Oded Maler
2005 conf
FAC
Oded Maler
2005 conf
FORMATS
Oded Maler, Dejan Nickovic, Amir Pnueli
2005 conf
FAC
Goran Frehse, Bruce H. Krogh, Rob A. Rutenbar, Oded Maler
2004 conf
FORMATS/FTRTFT
Oded Maler, Dejan Nickovic
2004 B conf
FoSSaCS
Oded Maler, Amir Pnueli
2004 A conf
RTSS
Marius Bozga, Abdelkarim Kerbaa, Oded Maler
2004 conf
FORMATS/FTRTFT
Scott Cotton, Eugene Asarin, Oded Maler, Peter Niebert
2004 B conf
FMCAD
Thao Dang, Alexandre Donzé, Oded Maler
2003 ed.
Oded Maler, Amir Pnueli
2003 A conf
TACAS
Yasmina Abdeddaïm, Eugene Asarin, Oded Maler
2003 conf
HSCC
James Kapinski, Bruce H. Krogh, Oded Maler, Olaf Stursberg
2003 conf
FORMATS
Ramzi Ben Salah, Marius Bozga, Oded Maler
2003 A conf
IPDPS
Yasmina Abdeddaïm, Abdelkarim Kerbaa, Oded Maler
2002 J jnl
Annu. Rev. Control.
Oded Maler
2002 conf
FTRTFT
Oded Maler, Bruce H. Krogh, Moez Mahfoudh
2002 A conf
TACAS
Yasmina Abdeddaïm, Oded Maler
2002 conf
Theory and Practice of Timed Systems @ ETAPS
Eugene Asarin, Oded Maler, Sergio Yovine
2002 A* conf
CAV
Eugene Asarin, Thao Dang, Oded Maler
2002 ed.
Theory and Practice of Timed Systems @ ETAPS
Eugene Asarin, Oded Maler, Sergio Yovine
2002 conf
AIPS Workshop on Planning for Temporal Domains
Oded Maler
2002 J jnl
J. ACM
Eugene Asarin, Paul Caspi, Oded Maler
2002 conf
Theory and Practice of Timed Systems @ ETAPS
Marius Bozga, Jianmin Hou, Oded Maler, Sergio Yovine
2002 conf
FTRTFT
Peter Niebert, Moez Mahfoudh, Eugene Asarin, Marius Bozga, Oded Maler, Navendu Jain
2001 J jnl
Eur. J. Control
Oded Maler
2001 conf
HSCC
Alberto L. Sangiovanni-Vincentelli, Thomas A. Henzinger, Bruce H. Krogh, Oded Maler, Manfred Morari, Costas C. Pantelides, George J. Pappas, Tunc Simsec, Janos Sztipanovits, Stavros Tripakis
2001 A* conf
CAV
Yasmina Abdeddaïm, Oded Maler
2001 conf
HSCC
Eugene Asarin, Sorav Bansal, Bernard Espiau, Thao Dang, Oded Maler
2001 J jnl
Theor. Comput. Sci.
Yonit Kesten, Oded Maler, Monica Marcus, Amir Pnueli, Elad Shahar
2001 conf
CDC
Eugene Asarin, Thao Dang, Oded Maler
2000 J jnl
Inf. Process. Lett.
Ahmed Bouajjani, Javier Esparza, Alain Finkel, Oded Maler, Peter Rossmanith, Bernard Willems, Pierre Wolper
2000 conf
HSCC
Eugene Asarin, Thao Dang, Oded Maler, Olivier Bournez
2000 J jnl
Proc. IEEE
Eugene Asarin, Olivier Bournez, Thao Dang, Oded Maler, Amir Pnueli
2000 A* conf
ICALP
Olivier Bournez, Oded Maler
1999 conf
HSCC
Eugene Asarin, Oded Maler
1999 conf
CHARME
Marius Bozga, Oded Maler, Stavros Tripakis
1999 A* conf
CAV
Marius Bozga, Oded Maler
1999 conf
HSCC
Olivier Bournez, Oded Maler, Amir Pnueli
1998 J jnl
J. Comput. Syst. Sci.
Eugene Asarin, Oded Maler
1998 conf
FTRTFT
Marius Bozga, Conrado Daws, Oded Maler, Alfredo Olivero, Stavros Tripakis, Sergio Yovine
1998 A* conf
CAV
Marius Bozga, Conrado Daws, Oded Maler, Alfredo Olivero, Stavros Tripakis, Sergio Yovine
1998 B conf
CONCUR
Eugene Asarin, Oded Maler, Amir Pnueli
1998 conf
HSCC
Thao Dang, Oded Maler
1997 A* conf
LICS
Eugene Asarin, Paul Caspi, Oded Maler
1997 conf
HART
Eugene Asarin, Marius Bozga, Alain Kerbrat, Oded Maler, Amir Pnueli, Anne Rasse
1997 ed.
HART
Oded Maler
1997 J jnl
Theor. Comput. Sci.
Oded Maler, Ludwig Staiger
1997 B conf
CONCUR
Ahmed Bouajjani, Javier Esparza, Oded Maler
1997 A* conf
CAV
Marius Bozga, Oded Maler, Amir Pnueli, Sergio Yovine
1997 A* conf
CAV
Yonit Kesten, Oded Maler, Monica Marcus, Amir Pnueli, Elad Shahar
1995 J jnl
Theor. Comput. Sci.
Oded Maler
1995 conf
FSTTCS
Eugene Asarin, Oded Maler
1995 J jnl
Inf. Comput.
Oded Maler, Amir Pnueli
1995 A conf
STACS
Oded Maler, Amir Pnueli, Joseph Sifakis
1995 J jnl
Theor. Comput. Sci.
Eugene Asarin, Oded Maler, Amir Pnueli
1995 conf
CHARME
Oded Maler, Amir Pnueli
1994 A* conf
ICALP
Eugene Asarin, Oded Maler
1994 J jnl
Theor. Comput. Sci.
Bernard Delyon, Oded Maler
1994 conf
Hybrid Systems
Eugene Asarin, Oded Maler, Amir Pnueli
1993 A conf
STACS
Oded Maler
1993 A conf
STACS
Oded Maler, Ludwig Staiger
1993 A* conf
CAV
Oded Maler, Amir Pnueli
1992 conf
FTRTFT
Bernard Delyon, Oded Maler
1991 conf
REX Workshop
Oded Maler, Zohar Manna, Amir Pnueli
1991 A* conf
COLT
Oded Maler, Amir Pnueli
1990 A* conf
FOCS
Oded Maler, Amir Pnueli
1989 conf
AII
Oded Maler, Amir Pnueli
1986 B conf
ICLP
Oded Maler, Zahava Scherz, Ehud Shapiro
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"