Walid Gomaa

117 papers A* 3A 1B 11C 13Misc 6Journal 42Unranked 40
YearRankTypeTitle / Venue / Authors
2026 conf
VISAPP (2)
Mohamed Awad, Mahmoud Mohamed, Walid Gomaa
2026 J jnl
CoRR
Samy Shaawat, Adham Hammad, Karim Farhat, Mina Thabet, Walid Gomaa
2025 conf
ICINCO (2)
Ahmed Hassan, Abdelaziz Serour, Ahmed Gamea, Walid Gomaa
2025 J jnl
Int. J. Data Sci. Anal.
Mohamed A. Khamis, Walid Gomaa
2025 A conf
IROS
Ahmed Shokry, Walid Gomaa, Tobias Zaenker, Murad Dawood, Rohit U. Menon, Shady A. Maged, Mohammed I. Awad, Maren Bennewitz
2025 J jnl
CoRR
Mohamed Awad, Mahmoud Akrm, Walid Gomaa
2025 J jnl
CoRR
Mariam Ayman, Sohaila Kandil, Alaa Moheb, Ahmed Abdelkader, Mohanned Ahmed, Walid Gomaa
2025 J jnl
CoRR
Amr Almorsi, Mohanned Ahmed, Walid Gomaa
2025 J jnl
CoRR
Alhossien Waly, Bassant Tarek, Ali Feteha, Rewan Yehia, Gasser Amr, Walid Gomaa, Ahmed Fares
2025 conf
CHIRA (2)
Ahmed Gamea, Ahmed Hasan, Abdelaziz Serour, Moustafa Rezk, Walid Gomaa
2025 conf
ICINCO (1)
Walid Gomaa, Abdelrahman Wael Ammar, Ismael Abbo, Mohamed Galal Nassef, Tetsuji Ogawa, Mohab Hossam
2024 J jnl
Neural Comput. Appl.
Mohamed Zaytoon, Muhannad Bashar, Mohamed Abdelaziz Khamis, Walid Gomaa
2024 conf
NILES
Omar Essam, Omar A. Bakr, Mervat T. Abassy, Ali Taha, Walid Gomaa
2024 J jnl
CoRR
Mohamed Elshaarawy, Ashrakat Saeed, Mariam Sheta, Abdelrahman Said, Asem Bakr, Omar Bahaa, Walid Gomaa
2024 conf
ACLING
Ahmed Heakl, Youssef Zaghloul, Mennatullah Ali, Rania Hossam, Walid Gomaa
2024 J jnl
CoRR
Ahmed Heakl, Youssef Zaghloul, Mennatullah Ali, Rania Hossam, Walid Gomaa
2024 conf
ICINCO (2)
Toqa Alaa, Mostafa Kotb, Arwa Zakaria, Mariam Diab, Walid Gomaa
2024 J jnl
CoRR
Toqa Alaa, Mostafa Kotb, Arwa Zakaria, Mariam Diab, Walid Gomaa
2024 C conf
CloudCom
Muhammad Sharshar, Kareem Elzeky, Menna Othman, SeifALdin Khaled, Hosam Moubarak, Walid Gomaa
2024 J jnl
CoRR
Ahmed Shokry, Walid Gomaa, Tobias Zaenker, Murad Dawood, Shady A. Maged, Mohammed I. Awad, Maren Bennewitz
2024 J jnl
CoRR
Ahmed Heakl, Fatma Youssef, Victor Parque, Walid Gomaa
2024 Misc conf
QCE
Mostafa Fathi, Walid Gomaa, Yasutaka Wada, Keiji Kimura, Kazunori Ueda, Ahmed El-Mahdy
2024 C conf
ICINCO (1)
Rania Hossam, Ahmed Heakl, Walid Gomaa
2024 J jnl
CoRR
Rania Hossam, Ahmed Heakl, Walid Gomaa
2024 conf
ICINCO (2)
Toqa Alaa, Ahmad Mongy, Assem Bakr, Mariam Diab, Walid Gomaa
2024 J jnl
CoRR
Toqa Alaa, Ahmad Mongy, Assem Bakr, Mariam Diab, Walid Gomaa
2023 J jnl
Neural Comput. Appl.
Walid Gomaa, Mohamed Abdelaziz Khamis
2023 J jnl
EPJ Data Sci.
Moayadeldin Tamer, Mohamed Abdelaziz Khamis, Abdallah Yahia, SeifALdin Khaled, Abdelrahman Ashraf, Walid Gomaa
2023 J jnl
CoRR
Mariam Ayman, Youssef El-harty, Ahmed Rashed, Ahmed Fathy, Ahmed Abdullah, Omar Wassim, Walid Gomaa
2023 B conf
IJCNN
Ahmed Sharshar, Ahmed Abo Eitta, Ahmed Fayez, Mohamed Abdelaziz Khamis, Ahmed Bayoumy Zaki, Walid Gomaa
2023 J jnl
ACM Trans. Asian Low Resour. Lang. Inf. Process.
Walid Gomaa
2023 conf
ICINCO (2)
Ahmed Hammad Azab, Ahmed Bayoumy Zaki, Tetsuji Ogawa, Walid Gomaa
2023 conf
ICINCO (2)
Samy Shaawat, Adham Hammad, Karim Farhat, Mina Thabet, Walid Gomaa
2023 conf
ICINCO (2)
Mohamed Elsayed, Sama Hadhoud, Alaa Elsetohy, Menna Osman, Walid Gomaa
2023 B conf
IJCNN
Fatma Youssef, Ahmed El-Mahdy, Tetsuji Ogawa, Walid Gomaa
2023 conf
INNS DLIA@IJCNN
Fatma Youssef, Victor Parque, Walid Gomaa
2022 conf
IMCOM
Omar Alaaeldein, Omar Sayed El Ahl, Lamiaa Elmahy, Martin Ihab, Walid Gomaa
2022 C conf
ICINCO
Fatma Youssef, Ahmed Bayoumy Zaki, Walid Gomaa
2022 conf
IMCOM
Abdulrahman Hussien Mustafa, Farah Mahmoud AbdelMoneim, Magy Gamal Matta, Toka Ossama Barghash, Walid Gomaa
2022 J jnl
Pattern Recognit. Lett.
Mubarak G. Abdu-Aguye, Walid Gomaa, Yasushi Makihara, Yasushi Yagi
2022 B conf
IJCNN
Ahmed Sharshar, Ahmed Fayez, Ahmed Abo Eitta, Walid Gomaa
2022 conf
IMCOM
Mazen Khodier, Ahmed Abdelaziz, Maria Gadelkarim, Abdelrahman Abdelkhalek, Walid Gomaa
2022 conf
IMCOM
Ahmed Fayez, Ahmed Sharshar, Ahmed Hesham, Islam Eldifrawi, Walid Gomaa
2022 B conf
IJCNN
Maria Gadelkarim, Mazen Khodier, Walid Gomaa
2021 conf
IMCOM
Ahmed Sharshar, Ahmed Fayez, Yasser Ashraf, Walid Gomaa
2021 conf
AMLTA
Walid Gomaa
2021 conf
HEALTHINF
Mohamed A. Gomaa, Mustafa Wassel, Rouzan M. Abdelmawla, Nihal Ibrahim, Khaled Nasser, Nermin A. Osman, Walid Gomaa
2021 B conf
IJCNN
Ahmed Abo Eitta, Toka Barabash, Yousef Nafea, Walid Gomaa
2021 J jnl
CoRR
Akthem Rehab, Islam Ali, Walid Gomaa, M. Nashat Fors
2021 C conf
ICINCO
Abeer Mostafa, Samir A. Elsagheer, Walid Gomaa
2021 B conf
IJCNN
Osama Adel, Mostafa Soliman, Walid Gomaa
2021 C conf
ICINCO
Hisham Madcor, Osama Adel, Walid Gomaa
2020 B conf
IJCNN
Mubarak G. Abdu-Aguye, Walid Gomaa, Yasushi Makihara, Yasushi Yagi
2020 J jnl
CoRR
Osama T. Ibrahim, Walid Gomaa, Moustafa Youssef
2020 Misc conf
ICASSP
Mubarak G. Abdu-Aguye, Walid Gomaa, Yasushi Makihara, Yasushi Yagi
2020 J jnl
IEEE J. Biomed. Health Informatics
Amr Elkholy, Mohamed E. Hussein, Walid Gomaa, Dima Damen, Emmanuel Saba
2020 C conf
ICINCO
Osama Adel, Yousef Nafea, Ahmed Hesham, Walid Gomaa
2020 J jnl
Multim. Tools Appl.
Abdullah N. Moustafa, Walid Gomaa
2020 J jnl
Comput. Vis. Image Underst.
Allam S. Hassanein, Mohamed E. Hussein, Walid Gomaa, Yasushi Makihara, Yasushi Yagi
2020 C conf
ICINCO
Sara Ashry Mohammed, Walid Gomaa, Mubarak G. Abdu-Aguye, Nahla El-borae
2020 C conf
ICINCO
Abeer Mostafa, Toka Ossama Barghash, Asmaa Al-Sayed Assaf, Walid Gomaa
2019 conf
AMLTA
Reda Elbasiony, Walid Gomaa
2019 B conf
IJCNN
Mubarak G. Abdu-Aguye, Walid Gomaa
2019 B conf
ICTAI
Norhan Elsayed Amer Abdelgawad, Ahmed El-Mahdy, Walid Gomaa, Amin A. Shoukry
2019 conf
ICINCO (1)
Mubarak G. Abdu-Aguye, Walid Gomaa, Yasushi Makihara, Yasushi Yagi
2019 conf
ICINCO (1)
Mubarak G. Abdu-Aguye, Walid Gomaa
2019 conf
AISI
Walid Gomaa
2019 B conf
SECON
Ali Mohamed AbdelAziz, Amin A. Shoukry, Walid Gomaa, Moustafa Youssef
2019 J jnl
CoRR
Ali Mohamed AbdelAziz, Amin A. Shoukry, Walid Gomaa, Moustafa Youssef
2019 conf
EMBC
Amr Elkholy, Yasushi Makihara, Walid Gomaa, Md Atiqur Rahman Ahad, Yasushi Yagi
2019 conf
ICINCO (1)
Mubarak G. Abdu-Aguye, Walid Gomaa
2019 conf
AMLTA
Walid Gomaa, Reda Elbasiony
2019 J jnl
CoRR
Osama T. Ibrahim, Walid Gomaa, Moustafa Youssef
2018 conf
ICINCO (1)
Sara Ashry Mohammed, Reda Elbasiony, Walid Gomaa
2018 J jnl
CoRR
Walid Gomaa
2018 conf
ICANN (3)
Reda Elbasiony, Walid Gomaa, Tetsuya Ogata
2018 J jnl
Intell. Serv. Robotics
Reda Elbasiony, Walid Gomaa
2018 J jnl
CoRR
Ahmed Fares, Walid Gomaa, Mohamed Abdelaziz Khamis
2018 C conf
ICMLA
Mubarak G. Abdu-Aguye, Walid Gomaa
2018 J jnl
Theor. Comput. Sci.
Hugo Bazille, Olivier Bournez, Walid Gomaa, Amaury Pouly
2018 B conf
GLOBECOM
Osama T. Ibrahim, Walid Gomaa, Moustafa Youssef
2017 conf
EMBC
Amr Elkholy, Mohamed E. Hussein, Walid Gomaa, Dima Damen, Emmanuel Saba
2017 C conf
ICMLA
Walid Gomaa, Reda Elbasiony, Sara Ashry Mohammed
2017 conf
ICINCO (2)
Sara Ashry Mohammed, Walid Gomaa
2017 Misc conf
DICTA
Abdullah N. Moustafa, Mohamed E. Hussein, Walid Gomaa
2017 A* conf
LICS
Mathieu Hoyrup, Walid Gomaa
2016 J jnl
CoRR
Olivier Bournez, Walid Gomaa, Emmanuel Hainry
2016 conf
ICINCO (2)
Sara Ashry Mohammed, Walid Gomaa
2016 J jnl
CoRR
Hugo Bazille, Olivier Bournez, Walid Gomaa, Amaury Pouly
2016 A* conf
IJCAI
Allam S. Hassanein, Mohamed E. Hussein, Walid Gomaa
2015 C conf
ICMLA
Ahmed Bayoumy Zaky, Walid Gomaa, Mohamed Abdelaziz Khamis
2014 J jnl
Eng. Appl. Artif. Intell.
Mohamed K. Gunady, Walid Gomaa, Ikuo Takeuchi
2014 J jnl
J. Complex.
Hugo Férée, Walid Gomaa, Mathieu Hoyrup
2014 conf
ITSC
Ahmed Bayoumy Zaky, Walid Gomaa
2014 conf
ICINCO (2)
Walaa Gouda, Walid Gomaa
2014 J jnl
CoRR
Walid Gomaa
2014 conf
ICCA
Ahmed Fares, Walid Gomaa
2014 conf
ICCSA (1)
Islam A. Elshaarawy, Walid Gomaa
2014 C conf
ICSEng
Ahmed Fares, Walid Gomaa
2014 Misc conf
MMAR
Walaa Gouda, Walid Gomaa
2014 conf
RP
Hugo Bazille, Olivier Bournez, Walid Gomaa, Amaury Pouly
2014 C conf
ICMLA
Reda Elbasiony, Walid Gomaa
2013 Misc conf
SYNASC
Islam A. Elshaarawy, Walid Gomaa
2013 A* conf
LICS
Hugo Férée, Mathieu Hoyrup, Walid Gomaa
2013 J jnl
Int. J. Softw. Informatics
Walid Gomaa
2013 J jnl
IEEE Internet Comput.
Helmut Prendinger, Kugamoorthy Gajananan, Ahmed Bayoumy Zaki, Ahmed Fares, Reinaert Molenaar, Daniel Urbano, Hans van Lint, Walid Gomaa
2012 J jnl
Nat. Comput.
Walid Gomaa
2012 Misc conf
AIMSA
Mohamed K. Gunady, Walid Gomaa, Ikuo Takeuchi
2012 conf
ITSC
Mohamed Abdelaziz Khamis, Walid Gomaa, Hisham El-Shishiny
2011 J jnl
Int. J. Unconv. Comput.
Olivier Bournez, Walid Gomaa, Emmanuel Hainry
2011 J jnl
Int. J. Unconv. Comput.
Walid Gomaa
2011 conf
ICA3PP (1)
Sameh Samra, Ahmed El-Mahdy, Walid Gomaa, Yasutaka Wada, Amin A. Shoukry
2010 J jnl
Int. J. Algebra Comput.
Walid Gomaa
2009 conf
DCM
Walid Gomaa
2009 J jnl
Electron. Colloquium Comput. Complex.
Walid Gomaa
2009 conf
FOPARA
Walid Gomaa
2007
Walid Gomaa
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