Ion Necoara

119 papers A* 1C 7Journal 55Unranked 56
YearRankTypeTitle / Venue / Authors
2026 J jnl
Comput. Optim. Appl.
Lahcen El Bourkhissi, Ion Necoara
2026 J jnl
SIAM J. Optim.
Yassine Nabou, Ion Necoara
2025 J jnl
SIAM J. Optim.
Ion Necoara, Daniela Lupu
2025 conf
MED
Nitesh Kumar Singh, Daniela Lupu, Ion Necoara
2025 J jnl
CoRR
Lionel Tondji, Dirk A. Lorenz, Ion Necoara
2025 J jnl
J. Glob. Optim.
Lahcen El Bourkhissi, Ion Necoara
2025 conf
CDC
Lahcen El Bourkhissi, Ion Necoara
2025 conf
MED
Daniela Lupu, Ion Necoara, Lucian Toma
2025 J jnl
Math. Oper. Res.
Ion Necoara, Flávia Chorobura
2025 J jnl
Math. Oper. Res.
Ion Necoara, Olivier Fercoq
2025 conf
CDC
Tudor C. Ionescu, Orest V. Iftime, Ion Necoara
2025 J jnl
Optim. Lett.
Yassine Nabou, François Glineur, Ion Necoara
2025 J jnl
IEEE Trans. Computational Imaging
Daniela Lupu, Joseph L. Garrett, Tor Arne Johansen, Milica Orlandic, Ion Necoara
2025 J jnl
IEEE Trans. Autom. Control.
Nitesh Kumar Singh, Ion Necoara
2024 J jnl
CoRR
Jon Álvarez Justo, Daniela Lupu, Milica Orlandic, Ion Necoara, Tor Arne Johansen
2024 J jnl
Comput. Optim. Appl.
Nitesh Kumar Singh, Ion Necoara
2024 J jnl
Optim. Methods Softw.
Daniela Lupu, Ion Necoara
2024 J jnl
Comput. Optim. Appl.
Flávia Chorobura, Ion Necoara
2024 conf
MED
Tudor C. Ionescu, Orest V. Iftime, Ion Necoara
2024 J jnl
Comput. Optim. Appl.
Yassine Nabou, Ion Necoara
2024 J jnl
Syst. Control. Lett.
Daniela Lupu, Ion Necoara
2024 conf
CDC
X. Cheng, Tudor C. Ionescu, Orest V. Iftime, Ion Necoara
2024 conf
ECC
Nitesh Kumar Singh, Ion Necoara
2023 J jnl
CoRR
Lionel Tondji, Ion Necoara, Dirk A. Lorenz
2023 conf
ECC
Lionel Tondji, Dirk A. Lorenz, Ion Necoara
2023 conf
ECC
Flávia Chorobura, François Glineur, Ion Necoara
2023 C conf
ETFA
Liliana Maria Ghinea, Daniela Lupu, Marian Barbu, Ion Necoara
2023 conf
ECC
Daniela Lupu, Ion Necoara
2023 conf
ECC
Daniela Lupu, Ion Necoara, Tudor C. Ionescu, Liliana Maria Ghinea, Joseph L. Garrett, Tor Arne Johansen
2023 conf
CDC
Lahcen El Bourkhissi, Ion Necoara, Panagiotis Patrinos
2023 conf
ECC
Yassine Nabou, Lucian Toma, Ion Necoara
2023 J jnl
SIAM J. Optim.
Flávia Chorobura, Ion Necoara
2022 conf
IVMSP
Jon Álvarez Justo, Daniela Lupu, Milica Orlandic, Ion Necoara, Tor Arne Johansen
2022 conf
WHISPERS
Joseph L. Garrett, Nitesh Kumar Singh, Tor Arne Johansen, Ion Necoara
2022 conf
CDC
Flávia Chorobura, Daniela Lupu, Ion Necoara
2022 conf
ICSTCC
Tudor C. Ionescu, Lahcen El Bourkhissi, Ion Necoara
2022 J jnl
Math. Oper. Res.
Ion Necoara, Olivier Fercoq
2022 J jnl
Autom.
Tudor C. Ionescu, Orest V. Iftime, Ion Necoara
2022 J jnl
IEEE Trans. Computational Imaging
Daniela Lupu, Ion Necoara, Joseph L. Garrett, Tor Arne Johansen
2022 J jnl
Optim. Methods Softw.
Ion Necoara
2022 J jnl
J. Mach. Learn. Res.
Ion Necoara, Nitesh Kumar Singh
2021 J jnl
J. Optim. Theory Appl.
Ion Necoara
2021 conf
ECC
Daniela Lupu, Ion Necoara
2021 J jnl
Comput. Optim. Appl.
Ion Necoara, Angelia Nedic
2021 conf
ECC
Liliana Maria Ghinea, Ion Necoara, Marian Barbu
2020 J jnl
IEEE Trans. Autom. Control.
Ion Necoara, Tudor C. Ionescu
2020 conf
ECC
Xiaodong Cheng, Ion Necoara
2020 J jnl
Comput. Optim. Appl.
Tianxiao Sun, Ion Necoara, Quoc Tran-Dinh
2020 conf
ECC
Tudor C. Ionescu, Orest V. Iftime, Ion Necoara
2019 A* conf
ICML
Olivier Fercoq, Ahmet Alacaoglu, Ion Necoara, Volkan Cevher
2019 J jnl
Optim. Methods Softw.
Ion Necoara, Andrei Patrascu, François Glineur
2019 J jnl
SIAM J. Matrix Anal. Appl.
Ion Necoara
2019 J jnl
Math. Program.
Ion Necoara, Yurii E. Nesterov, François Glineur
2019 conf
ECC
Ion Necoara, Tudor C. Ionescu
2019 conf
ECC
Ion Necoara
2019 conf
CDC
Angelia Nedic, Ion Necoara
2019 J jnl
SIAM J. Optim.
Ion Necoara, Peter Richtárik, Andrei Patrascu
2018 conf
ECC
Ion Necoara, Andrei Patrascu
2018 J jnl
IEEE Trans. Autom. Control.
Andrei Patrascu, Ion Necoara
2017 J jnl
Optim. Lett.
Andrei Patrascu, Ion Necoara, Quoc Tran-Dinh
2017 J jnl
J. Optim. Theory Appl.
Ngoc Anh Nguyen, Sorin Olaru, Pedro Rodríguez-Ayerbe, Morten Hovd, Ion Necoara
2017 J jnl
J. Mach. Learn. Res.
Andrei Patrascu, Ion Necoara
2017 J jnl
J. Optim. Theory Appl.
Ion Necoara, Yurii E. Nesterov, François Glineur
2016 conf
MED
Andrei Patrascu, Ion Necoara
2016 J jnl
Optim. Methods Softw.
Ion Necoara, Andrei Patrascu
2016 conf
ISGT Europe
Ion Necoara, Valentin Nedelcu, Dragos N. Clipici, Lucian Toma, Constantin Bulac
2016 J jnl
SIAM J. Optim.
Ion Necoara, Dragos N. Clipici
2015 conf
ECC
Ion Necoara, Angelia Nedich
2015 J jnl
Syst. Control. Lett.
Ion Necoara
2015 conf
CDC
Ion Necoara
2015 conf
CDC
Ion Necoara, Sverre Kvamme
2015 J jnl
J. Glob. Optim.
Andrei Patrascu, Ion Necoara
2015 J jnl
Autom.
Ion Necoara, Valentin Nedelcu
2015 conf
CDC
Ion Necoara, Andrei Patrascu
2015 C conf
ACC
Ion Necoara, Rolf Findeisen
2015 conf
CSCS
Andrei Patrascu, Ion Necoara
2015 J jnl
IEEE Trans. Autom. Control.
Andrei Patrascu, Ion Necoara
2015 conf
CDC
Andrei Patrascu, Ion Necoara, Rolf Findeisen
2014 conf
CDC
Andrei Patrascu, Ion Necoara, Panagiotis Patrinos
2014 J jnl
Comput. Optim. Appl.
Ion Necoara, Andrei Patrascu
2014 J jnl
SIAM J. Control. Optim.
Valentin Nedelcu, Ion Necoara, Quoc Tran-Dinh
2014 conf
ECC
Ngoc Anh Nguyen, Sorin Olaru, Pedro Rodríguez-Ayerbe, Morten Hovd, Ion Necoara
2014 J jnl
J. Glob. Optim.
Dinh Quoc Tran, Ion Necoara, Moritz Diehl
2014 J jnl
IEEE Trans. Autom. Control.
Ion Necoara, Valentin Nedelcu
2013 conf
ECC
Ion Necoara, Dragos N. Clipici
2013 conf
CDC
Dinh Quoc Tran, Ion Necoara, Moritz Diehl
2013 conf
ECC
Andrei Patrascu, Ion Necoara
2013 J jnl
SIAM J. Optim.
Dinh Quoc Tran, Ion Necoara, Carlo Savorgnan, Moritz Diehl
2013 C conf
ACC
Ion Necoara, Dragos N. Clipici, Sorin Olaru
2013 conf
ASCC
Ion Necoara, Valentin Nedelcu, Dragos N. Clipici
2013 conf
CDC
Ion Necoara, Valentin Nedelcu, Tamás Keviczky, Minh Dang Doan, Bart De Schutter
2013 J jnl
IEEE Trans. Autom. Control.
Ion Necoara
2012 conf
CDC
Ion Necoara
2012 C conf
CCA
Mihai Cornoiu, Ion Necoara
2012 conf
CDC
Valentin Nedelcu, Ion Necoara
2012 C conf
CCA
Adrian-Bogdan Hanchevici, Ion Necoara
2012 conf
CDC
Ion Necoara
2010 conf
CDC
Ion Necoara, Ioan Dumitrache, Johan A. K. Suykens
2010 J jnl
IEEE Trans. Signal Process.
Paschalis Tsiaflakis, Ion Necoara, Johan A. K. Suykens, Marc Moonen
2009 conf
ECC
Ion Necoara, Johan A. K. Suykens
2009 conf
EUSIPCO
Paschalis Tsiaflakis, Ion Necoara, Johan A. K. Suykens, Marc Moonen
2009 conf
ICANN (2)
Ion Necoara
2009 conf
CDC
Ion Necoara, Carlo Savorgnan, Dinh Quoc Tran, Johan A. K. Suykens, Moritz Diehl
2008 conf
CDC
Ion Necoara, Johan A. K. Suykens
2008 J jnl
IEEE Trans. Autom. Control.
Ion Necoara, Johan A. K. Suykens
2008 conf
CDC
Ion Necoara, Minh Dang Doan, Johan A. K. Suykens
2008 J jnl
IEEE Trans. Autom. Control.
Michel Baes, Moritz Diehl, Ion Necoara
2008 J jnl
Int. J. Control
Ion Necoara, Bart De Schutter, Ton J. J. van den Boom, Hans Hellendoorn
2008 J jnl
Autom.
Ion Necoara, Ton J. J. van den Boom, Bart De Schutter, Hans Hellendoorn
2007 J jnl
IEEE Trans. Autom. Control.
Ion Necoara, Eric C. Kerrigan, Bart De Schutter, Ton J. J. van den Boom
2007 J jnl
Discret. Event Dyn. Syst.
Ion Necoara, Bart De Schutter, Ton J. J. van den Boom, Hans Hellendoorn
2006 conf
CDC
Daniele Corona, Ion Necoara, Bart De Schutter, Ton J. J. van den Boom
2006 conf
ADHS
Ion Necoara, Ton J. J. van den Boom, Bart De Schutter, Johannes Hellendoorn
2006 C conf
ACC
Ion Necoara, Bart De Schutter, Ton J. J. van den Boom, Johannes Hellendoorn
2006 conf
CDC
Ion Necoara, Eric C. Kerrigan, Bart De Schutter, Ton J. J. van den Boom
2005 conf
CDC/ECC
Ton J. J. van den Boom, Bart De Schutter, Ion Necoara
2005 conf
CDC/ECC
Ion Necoara, Bart De Schutter, Ton J. J. van den Boom, Johannes Hellendoorn
2004 conf
CDC
Ion Necoara, Bart De Schutter, Ton J. J. van den Boom, Johannes Hellendoorn
2004 C conf
ACC
Ion Necoara, Bart De Schutter, Hans Hellendoorn
redb/extractors/decompiler/DecompileAPK.py
← Index redb/extractors/decompiler/DecompileAPK.py python
"""APK Code Analysis Extractor.

Decompiles and disassembles APK DEX bytecode at the method level,
producing per-method content and reference records analogous to
the Binary Ninja code_binja_* tables.

Uses androguard + JADX + apktool to replicate Binary Ninja analysis
depth for Android applications.
"""

import gc
import hashlib
import inspect
import logging
import os
import threading
import time
from datetime import datetime, timezone
from typing import Any, Dict, Optional

from redb.extractors.decompiler.apk.analyzer import APKCodeAnalyzer
from redb.extractors.enum import Tag
from redb.extractors.extractor import Extractor


class DecompileAPK(Extractor):
    """APK code analysis extractor — produces multi-table ClickHouse export.

    Follows the same pattern as DecompileBinja for consistency.
    """

    def __init__(
        self,
        filepath,
        log,
        exporters=None,
        index_prefix=None,
        known_benign=False,
        known_malicious=False,
        filetype=None,
        decompile_modules=None,
    ):
        super().__init__(
            filepath,
            log,
            exporters,
            index_prefix,
            known_benign=known_benign,
            known_malicious=known_malicious,
        )
        self.log.debug(inspect.currentframe().f_code.co_name)
        self.analysis_results = None
        self.analyzer = None
        self.filetype = filetype or "apk"
        self.decompile_modules = decompile_modules or {"all"}

        try:
            self.APK_DECOMPILE_TIMEOUT = int(
                os.getenv("APK_DECOMPILE_TIMEOUT", "600")
            )
        except ValueError:
            self.log.warning(
                "Invalid APK_DECOMPILE_TIMEOUT value, using default of 600 seconds"
            )
            self.APK_DECOMPILE_TIMEOUT = 600

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.cleanup_run()

    def calculate_md5(self, input_str):
        """Calculate MD5 hash of a string."""
        return hashlib.md5(input_str.encode("utf-8")).hexdigest()

    def cleanup_run(self):
        """Clean up after analysis."""
        try:
            if self.analyzer:
                self.analyzer.cleanup()
                self.analyzer = None
            gc.collect()
        except Exception as e:
            self.log.error(f"Error in cleanup: {e}")

    def analyze_apk(self) -> Optional[Dict[str, Any]]:
        """Run APK code analysis and return results."""
        self.log.debug("Starting APK code analysis")
        try:
            self.analyzer = APKCodeAnalyzer(
                filepath=self.filepath,
                timeout=self.APK_DECOMPILE_TIMEOUT,
                log=self.log,
                decompile_modules=self.decompile_modules,
            )
            results = self.analyzer.extract()
            return results
        except Exception as e:
            self.log.error(f"Error in APK code analysis: {e}")
            import traceback
            self.log.error(f"Traceback: {traceback.format_exc()}")
            return None
        finally:
            self.cleanup_run()

    def extract(self):
        """Extract and process all analysis results.

        Uses daemon thread with timeout, same pattern as DecompileBinja.
        """
        self.log.debug(inspect.currentframe().f_code.co_name)

        extraction_completed = False
        extraction_result = False
        extraction_error = None

        def do_extraction():
            nonlocal extraction_completed, extraction_result, extraction_error
            try:
                results = self.analyze_apk()
                if not results:
                    extraction_result = False
                else:
                    self.analysis_results = results
                    self.analysis_results["sha256"] = self.sha256
                    self.analysis_results["sha1"] = self.sha1
                    self.analysis_results["md5"] = self.md5
                    extraction_result = True
            except Exception as e:
                extraction_error = e
                extraction_result = False
            finally:
                extraction_completed = True

        extraction_thread = threading.Thread(target=do_extraction)
        extraction_thread.daemon = True
        extraction_thread.start()

        start_time = time.time()
        while (
            not extraction_completed
            and (time.time() - start_time) < self.APK_DECOMPILE_TIMEOUT
        ):
            time.sleep(1)

        if not extraction_completed:
            self.log.error(
                f"APK extraction timed out after {self.APK_DECOMPILE_TIMEOUT} seconds"
            )
            self.cleanup_run()
            return None

        if extraction_error:
            self.log.error(f"Error in APK extraction: {extraction_error}")
            return None

        return self.analysis_results if extraction_result else None

    def prepare_export_data(self, exporter_type: str) -> Any:
        """Prepare data for database export."""
        self.log.debug(inspect.currentframe().f_code.co_name)
        if not self.analysis_results:
            return None

        if exporter_type == "ClickHouseExporter":
            now = datetime.now(timezone.utc)
            export = {"multi_table": True}

            # Table 1: Decompiled method content
            if self.analysis_results.get("decompiled_content"):
                export["decompiled_content"] = {
                    "table": "code_apk_decompiled_methods_content",
                    "data": [
                        [
                            f["decompiled_method_hash"],
                            f["decompiled_method"],
                            f.get("decompiled_method_type", "UNKNOWN"),
                            1 if f.get("decompiled_has_string_encryption") else 0,
                            1 if f.get("decompiled_has_reflection_calls") else 0,
                            1 if f.get("decompiled_excessive_goto_count") else 0,
                            now,
                        ]
                        for f in self.analysis_results["decompiled_content"]
                    ],
                    "column_names": [
                        "decompiled_method_hash",
                        "decompiled_method",
                        "decompiled_method_type",
                        "decompiled_has_string_encryption",
                        "decompiled_has_reflection_calls",
                        "decompiled_excessive_goto_count",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "String",
                        "Enum8('USER'=1, 'LIBRARY'=2, 'UNKNOWN'=5)",
                        "UInt8",
                        "UInt8",
                        "UInt8",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Table 2: Decompiled method references
            if self.analysis_results.get("decompiled_refs"):
                export["decompiled_refs"] = {
                    "table": "code_apk_decompiled_methods_references",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            f["decompiled_method_hash"],
                            f.get("smali_method_hash"),
                            f.get("decompiled_class_name", ""),
                            f.get("decompiled_method_name", ""),
                            f.get("decompiled_method_signature", ""),
                            f.get("decompiled_method_prototype", ""),
                            f.get("functions_caller", []),
                            f.get("functions_call", []),
                            now,
                        ]
                        for f in self.analysis_results["decompiled_refs"]
                    ],
                    "column_names": [
                        "sha256",
                        "decompiled_method_hash",
                        "smali_method_hash",
                        "decompiled_class_name",
                        "decompiled_method_name",
                        "decompiled_method_signature",
                        "decompiled_method_prototype",
                        "functions_caller",
                        "functions_call",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "FixedString(64)",
                        "Nullable(FixedString(64))",
                        "LowCardinality(String)",
                        "LowCardinality(String)",
                        "String",
                        "String",
                        "Array(String)",
                        "Array(String)",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Table 3: Smali method content
            if self.analysis_results.get("smali_content"):
                export["smali_content"] = {
                    "table": "code_apk_smali_methods_content",
                    "data": [
                        [
                            f["smali_method_hash"],
                            f["smali_method"],
                            f.get("smali_method_type", "UNKNOWN"),
                            f.get("smali_instructions_count", 0),
                            f.get("smali_register_count", 0),
                            1 if f.get("smali_has_string_encryption") else 0,
                            1 if f.get("smali_has_reflection_calls") else 0,
                            1 if f.get("smali_excessive_goto_count") else 0,
                            f.get("smali_flattened_score", 0.0),
                            f.get("smali_mba_score", 0.0),
                            now,
                        ]
                        for f in self.analysis_results["smali_content"]
                    ],
                    "column_names": [
                        "smali_method_hash",
                        "smali_method",
                        "smali_method_type",
                        "smali_instructions_count",
                        "smali_register_count",
                        "smali_has_string_encryption",
                        "smali_has_reflection_calls",
                        "smali_excessive_goto_count",
                        "smali_flattened_score",
                        "smali_mba_score",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "String",
                        "Enum8('USER'=1, 'LIBRARY'=2, 'UNKNOWN'=5)",
                        "UInt32",
                        "UInt16",
                        "UInt8",
                        "UInt8",
                        "UInt8",
                        "Float64",
                        "Float64",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Table 4: Smali method references
            if self.analysis_results.get("smali_refs"):
                export["smali_refs"] = {
                    "table": "code_apk_smali_methods_references",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            f["smali_method_hash"],
                            f.get("decompiled_method_hash"),
                            f.get("smali_class_name", ""),
                            f.get("smali_method_name", ""),
                            f.get("smali_method_signature", ""),
                            now,
                        ]
                        for f in self.analysis_results["smali_refs"]
                    ],
                    "column_names": [
                        "sha256",
                        "smali_method_hash",
                        "decompiled_method_hash",
                        "smali_class_name",
                        "smali_method_name",
                        "smali_method_signature",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "FixedString(64)",
                        "Nullable(FixedString(64))",
                        "LowCardinality(String)",
                        "LowCardinality(String)",
                        "String",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Table 5: Method similarity metrics (content-based fuzzy matching)
            if self.analysis_results.get("similarity_metrics"):
                export["method_similarity_metrics"] = {
                    "table": "code_apk_method_similarity_metrics",
                    "data": [
                        [
                            f["smali_method_hash"],
                            f.get("ssdeep_smali"),
                            f.get("tlsh_smali"),
                            f.get("ssdeep_smali_normalized"),
                            f.get("tlsh_smali_normalized"),
                            f.get("minhash", []),
                            now,
                        ]
                        for f in self.analysis_results["similarity_metrics"]
                    ],
                    "column_names": [
                        "smali_method_hash",
                        "ssdeep_smali",
                        "tlsh_smali",
                        "ssdeep_smali_normalized",
                        "tlsh_smali_normalized",
                        "minhash",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "Nullable(String)",
                        "Nullable(FixedString(72))",
                        "Nullable(String)",
                        "Nullable(FixedString(72))",
                        "Array(UInt8)",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Table 5b: CFG method features (structural/topological)
            if self.analysis_results.get("cfg"):
                export["cfg_methods"] = {
                    "table": "code_apk_cfg_methods",
                    "data": [
                        [
                            cfg["smali_method_hash"],
                            cfg["cfg_topology_hash"],
                            cfg["block_count"],
                            cfg["edge_count"],
                            cfg.get("cfg_instructions_count", 0),
                            cfg.get("call_count", 0),
                            cfg["cyclomatic_complexity"],
                            cfg.get("loop_count", 0),
                            cfg.get("max_depth", 0),
                            cfg.get("max_fan_out", 0),
                            cfg.get("md_index_topdown", 0),
                            cfg.get("md_index_bottomup", 0),
                            cfg.get("prime_product_smali", 0),
                            cfg.get("cfg_feature_tlsh"),
                            cfg.get("wl_minhash", []),
                            cfg.get("bb_features", []),
                            cfg.get("cfg_adjacency", []),
                            now,
                        ]
                        for cfg in self.analysis_results["cfg"]
                        if cfg is not None
                    ],
                    "column_names": [
                        "smali_method_hash",
                        "cfg_topology_hash",
                        "block_count",
                        "edge_count",
                        "cfg_instructions_count",
                        "call_count",
                        "cyclomatic_complexity",
                        "loop_count",
                        "max_depth",
                        "max_fan_out",
                        "md_index_topdown",
                        "md_index_bottomup",
                        "prime_product_smali",
                        "cfg_feature_tlsh",
                        "wl_minhash",
                        "bb_features",
                        "cfg_adjacency",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "FixedString(16)",
                        "UInt16",
                        "UInt16",
                        "UInt32",
                        "UInt16",
                        "UInt16",
                        "UInt16",
                        "UInt16",
                        "UInt16",
                        "UInt64",
                        "UInt64",
                        "UInt64",
                        "Nullable(FixedString(72))",
                        "Array(UInt8)",
                        "Array(Array(UInt16))",
                        "Array(UInt32)",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Table 6: Strings — reuse code_binja_strings_raw for cross-format correlation
            # DEX strings are MUTF-8; string_raw = string since no encoding difference
            if self.analysis_results.get("strings"):
                export["strings_raw"] = {
                    "table": "code_binja_strings_raw",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            s["string"],
                            s["string"],  # string_raw = string (MUTF-8 decoded to UTF-8)
                            s.get("string_encoding", "UTF8"),
                            s.get("string_offset", 0),
                            s.get("string_length", len(s["string"])),
                            s.get("string_length", len(s["string"])),  # string_raw_length = string_length
                            s.get("string_entropy", 0.0),
                        ]
                        for s in self.analysis_results["strings"]
                    ],
                    "column_names": [
                        "sha256",
                        "string",
                        "string_raw",
                        "string_encoding",
                        "string_offset",
                        "string_length",
                        "string_raw_length",
                        "string_entropy",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "String",
                        "String",
                        "LowCardinality(String)",
                        "UInt64",
                        "UInt32",
                        "UInt32",
                        "Float32",
                    ],
                }

            # Table 7: Analysis errors
            if self.analysis_results.get("analysis_errors"):
                export["analysis_errors"] = {
                    "table": "code_apk_analysis_errors",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            f.get("class_name"),
                            f.get("method_name"),
                            f.get("error_location", "unknown"),
                            f.get("error_message", ""),
                            f.get("error_type", "unknown"),
                            self.calculate_md5(
                                f"{f.get('error_message', '')}"
                                f"{f.get('class_name', '')}"
                                f"{f.get('method_name', '')}"
                                f"{f.get('error_location', 'unknown')}"
                            ),
                            "new",
                            now,
                        ]
                        for f in self.analysis_results["analysis_errors"]
                    ],
                    "column_names": [
                        "sha256",
                        "class_name",
                        "method_name",
                        "error_location",
                        "error_message",
                        "error_type",
                        "error_hash",
                        "status",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "Nullable(String)",
                        "Nullable(String)",
                        "LowCardinality(String)",
                        "Nullable(String)",
                        "Nullable(String)",
                        "FixedString(32)",
                        "Enum8('new'=1, 'investigating'=2, 'fixed'=3, 'wontfix'=4)",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            return export

        return None

    def tag(self) -> str:
        """Return the tag for this extractor."""
        return Tag.APK_DECOMPILED.value

    def get_clickhouse_table(self) -> str:
        """Not used directly as we're handling multiple tables."""
        pass