Mahdi Zareei

85 papers C 2Journal 75Unranked 8
YearRankTypeTitle / Venue / Authors
2025 J jnl
IEEE Access
Faisal Alanazi, Mahdi Zareei, Moisés García Martínez
2025 conf
ICCSA (2)
Mahdi Zareei, Jesús Arturo Pérez Díaz
2025 J jnl
IEEE Access
Mahdi Zareei, Carlos Alonzo López Castañeda, Faisal Alanazi, Fausto Granda, Jesús Arturo Pérez Díaz
2025 J jnl
IEEE Access
Faisal Alanazi, Mahdi Zareei
2025 J jnl
IEEE Access
Faisal Alanazi, Mahdi Zareei, Alberto Rodriguez Arreola
2025 J jnl
IEEE Access
Alejandro De León Languré, Mahdi Zareei
2025 J jnl
IEEE Access
A. K. M. Muzahidul Islam, Rakin Bin Rabbani, Md Shadman Aadeeb, Mahdi Zareei, Nafees Mansoor, Molla Md Zubaer
2024 J jnl
IEEE Access
Zia Ullah, Abdul Waheed, Muhammad Ismail Mohmand, Sadia Basar, Mahdi Zareei, Fausto Granda
2024 J jnl
IEEE Access
Gullelala Jadoon, Adeel Ahmed, Ikram Ud Din, Ahmad Almogren, Mahdi Zareei, Rajesh Roshan Biswal, Ayman Altameem
2024 J jnl
IEEE Access
Zeenat Zulfiqar, Zubair Zulfiqar, Nauman Ali Khan, Mudassar Ali Khan, Ikram Ud Din, Ahmad Almogren, Mahdi Zareei, Moisés García Martínez
2024 J jnl
IEEE Access
Alejandro De León Languré, Mahdi Zareei
2024 J jnl
IEEE Access
Alejandro De León Languré, Mahdi Zareei
2024 J jnl
CoRR
Rodrigo Landa Andraca, Mahdi Zareei
2024 J jnl
IEEE Access
Wajahat Ali, Ikram Ud Din, Ahmad Almogren, Mahdi Zareei, Rajesh Roshan Biswal
2024 conf
MICAI (2)
Héctor Abel Gutiérrez, Mahdi Zareei, Alejandro De León Languré, Kellyton Brito
2024 J jnl
IEEE Access
Ikram Ud Din, Kamran Habib Khan, Ahmad Almogren, Mahdi Zareei, Jesús Arturo Pérez Díaz
2024 conf
ICEGOV
Héctor Abel Gutiérrez, Alejandro De León Languré, Mahdi Zareei, Kellyton dos Santos Brito
2024 conf
MICAI (1)
Iván Díaz de León Rodríguez, Mahdi Zareei, Alejandro De León Languré
2024 J jnl
IEEE Access
Carlos Javier García-Treviño, Jesús Arturo Pérez Díaz, Cesar Vargas-Rosales, Mahdi Zareei
2023 J jnl
IEEE Access
Nafees Mansoor, Md. Iqbal Hossain, Anatte Rozario, Mahdi Zareei, Alberto Rodriguez Arreola
2023 J jnl
IEEE Access
Nafees Mansoor, Kaniz Fatema Antora, Priyata Deb, Tarek Ahammed Arman, Azizah Abdul Manaf, Mahdi Zareei
2023 J jnl
IEEE Access
Alejandro De León Languré, Mahdi Zareei
2023 J jnl
IEEE Access
Kamran Ahmad Awan, Ikram Ud Din, Mahdi Zareei, Ahmad Almogren, Byung-Seo Kim, Jesús Arturo Pérez Díaz
2022 J jnl
Sensors
Sadia Basar, Abdul Waheed, Mushtaq Ali, Saleem Zahid, Mahdi Zareei, Rajesh Roshan Biswal
2022 J jnl
Sensors
Shahzad Khan, Waseem Iqbal, Abdul Waheed, Gulzar Mehmood, Shawal Khan, Mahdi Zareei, Rajesh Roshan Biswal
2022 J jnl
IEEE Access
Muhammad Amin, Khalil Ullah, Muhammad Asif, Abdul Waheed, Sana Ul Haq, Mahdi Zareei, Rajesh Roshan Biswal
2022 J jnl
Sensors
Saleem Zahid, Kifayat Ullah, Abdul Waheed, Sadia Basar, Mahdi Zareei, Rajesh Roshan Biswal
2022 J jnl
IEEE Access
Hassan Farooq, Uzair Iqbal Janjua, Tahir Mustafa Madni, Abdul Waheed, Mahdi Zareei, Faisal S. Alanazi
2022 J jnl
Sensors
Sidra Abid Syed, Munaf Rashid, Samreen Hussain, Choudhry Fahad Azim, Hira Zahid, Asif Umer, Abdul Waheed, Mahdi Zareei, Cesar Vargas-Rosales
2022 J jnl
Comput. Commun.
Noe Marcelo Yungaicela-Naula, Cesar Vargas-Rosales, Jesús Arturo Pérez Díaz, Mahdi Zareei
2022 conf
CARLA
Edgar León-Sandoval, Mahdi Zareei, Liliana Ibeth Barbosa-Santillán, Luis Eduardo Falcón-Morales
2021 J jnl
IEEE Access
Sadia Basar, Mushtaq Ali, Gilberto Ochoa-Ruiz, Abdul Waheed, Gerardo Rodriguez-Hernandez, Mahdi Zareei
2021 J jnl
IEEE Access
Mushtaq Ali, Amanullah Baloch, Abdul Waheed, Mahdi Zareei, Rimsha Manzoor, Hassam Sajid, Faisal S. Alanazi
2021 J jnl
Veh. Commun.
Seyed Ahmad Soleymani, Shidrokh Goudarzi, Mohammad Hossein Anisi, Mahdi Zareei, Abdul Hanan Abdullah, Nazri Kama
2021 J jnl
IEEE Access
Shawal Khan, Shahzad Khan, Mahdi Zareei, Faisal S. Alanazi, Nazri Kama, Masoom Alam, Adeel Anjum
2021 J jnl
Complex.
Maneela Shaheen, Rafiullah Khan, Rajesh Roshan Biswal, Mohib Ullah, Atif Khan, Muhammad Irfan Uddin, Mahdi Zareei, Abdul Waheed
2021 J jnl
Complex.
Gulzar Mehmood, Muhammad Sohail Khan, Abdul Waheed, Mahdi Zareei, Muhammad Fayaz, Tariq Sadad, Nazri Kama, Azri Azmi
2021 J jnl
IEEE Access
Nizamud Din, Abdul Waheed, Mahdi Zareei, Faisal S. Alanazi
2021 J jnl
IEEE Access
Fawad Saleem, Muhammad Nadeem Majeed, Jawaid Iqbal, Abdul Waheed, Abdul Rauf, Mahdi Zareei, Ehab Mahmoud Mohamed
2021 J jnl
J. Intell. Fuzzy Syst.
Jawaid Iqbal, Arif Iqbal Umar, Noor Ul Amin, Abdul Waheed, Saleem Abdullah, Mahdi Zareei, Muazzam Ali Khan Khattak
2021 J jnl
IEEE Access
Shahzad Khan, Mahdi Zareei, Shawal Khan, Faisal S. Alanazi, Masoom Alam, Abdul Waheed
2021 J jnl
Sensors
Muhammad Adnan, Jawaid Iqbal, Abdul Waheed, Noor Ul Amin, Mahdi Zareei, Shidrokh Goudarzi, Asif Umer
2021 J jnl
Sensors
Khola Anwar, Taj Rahman, Asim Zeb, Inayat Khan, Mahdi Zareei, Cesar Vargas-Rosales
2021 J jnl
Sensors
Muhammad Adnan, Jawaid Iqbal, Abdul Waheed, Noor Ul Amin, Mahdi Zareei, Asif Umer, Ehab Mahmoud Mohamed
2021 J jnl
IEEE Wirel. Commun. Lett.
Ehab Mahmoud Mohamed, Sherief Hashima, Kohei Hatano, Saud Alhajaj Aldossari, Mahdi Zareei, Mohamed Rihan
2020 J jnl
Symmetry
Seyed Ahmad Soleymani, Shidrokh Goudarzi, Nazri Kama, Saiful Adli Ismail, Mazlan Ali, Zaini M. D. Zainal, Mahdi Zareei
2020 J jnl
IEEE Access
Jawaid Iqbal, Abdul Waheed, Mahdi Zareei, Arif Iqbal Umar, Noor Ul Amin, Abdallah Aldosary, Ehab Mahmoud Mohamed
2020 J jnl
IEEE Access
Awais Manzoor, Malik Ali Judge, Ahmad Almogren, Adnan Akhunzada, Salmah Fattah, Abdullah Gani, Mahdi Zareei
2020 J jnl
Symmetry
Seyed Ahmad Soleymani, Shidrokh Goudarzi, Mohammad Hossein Anisi, Nazri Kama, Saiful Adli Ismail, Azri Azmi, Mahdi Zareei, Abdul Hanan Abdullah
2020 J jnl
IEEE Access
Gulzar Mehmood, Muhammad Zahid Khan, Abdul Waheed, Mahdi Zareei, Ehab Mahmoud Mohamed
2020 J jnl
IEEE Access
Misba Sikandar, Rafia Sohail, Yousaf Saeed, Asim Zeb, Mahdi Zareei, Muhammad Adnan Khan, Atif Khan, Abdallah Aldosary, Ehab Mahmoud Mohamed
2020 J jnl
Mob. Inf. Syst.
Zahid Ullah, Asim Zeb, Insaf Ullah, Khalid Mahmood Awan, Yousaf Saeed, Muhammad Irfan Uddin, Mahmoud Ahmad Al-Khasawneh, Marwan Mahmoud, Mahdi Zareei
2020 J jnl
IEEE Access
Abdul Waheed, Arif Iqbal Umar, Mahdi Zareei, Nizamud Din, Noor Ul Amin, Jawaid Iqbal, Yousaf Saeed, Ehab Mahmoud Mohamed
2020 J jnl
IEEE Access
Muhammad Adnan Khan, Shazia Saqib, Tahir Alyas, Anees Ur Rehman, Yousaf Saeed, Asim Zeb, Mahdi Zareei, Ehab Mahmoud Mohamed
2020 J jnl
IEEE Access
Hamid Asmat, Fasee Ullah, Mahdi Zareei, Atif Khan, Ehab Mahmoud Mohamed
2020 J jnl
IEEE Access
Sagheer Abbas, Muhammad Adnan Khan, Luis Eduardo Falcón-Morales, Abdur Rehman, Yousaf Saeed, Mahdi Zareei, Asim Zeb, Ehab Mahmoud Mohamed
2020 J jnl
J. Intell. Fuzzy Syst.
Anwar Khan, Atiq Ur Rahman, Mahdi Zareei, Najm Us Sama, Cesar Vargas-Rosales, Junaid Qadir, Ehab Mahmoud Mohamed
2020 J jnl
Comput. Intell. Neurosci.
Atif Khan, Muhammad Adnan Gul, Mahdi Zareei, Roshan Biswal Rajesh, Asim Zeb, Muhammad Naeem, Yousaf Saeed, Naomie Salim
2020 J jnl
IEEE Access
Ehab Mahmoud Mohamed, Basem M. ElHalawany, Haitham S. Khallaf, Mahdi Zareei, Asim Zeb, Mahmoud Ahmed Abdelghany
2020 J jnl
Complex.
Yasir Ahmad, Mohib Ullah, Rafiullah Khan, Bushra Shafi, Atif Khan, Mahdi Zareei, Abdallah Aldosary, Ehab Mahmoud Mohamed
2020 J jnl
IEEE Access
Rashid Jahangir, Ying Wah Teh, Nisar Ahmed Memon, Ghulam Mujtaba, Mahdi Zareei, Uzair Ishtiaq, Muhammad Zaheer Akhtar, Ihsan Ali
2019 J jnl
Symmetry
Insaf Ullah, Noor Ul Amin, Mahdi Zareei, Asim Zeb, Hizbullah Khattak, Ajab Khan, Shidrokh Goudarzi
2019 J jnl
IEEE Access
Ehab Mahmoud Mohamed, Mahmoud Ahmed Abdelghany, Mahdi Zareei
2019 conf
PIMRC Workshops
Mahdi Zareei, Cesar Vargas-Rosales, Rafaela Villalpando Hernandez, Leyre Azpilicueta
2019 J jnl
IEEE Access
Kamran Ahmad Awan, Ikram Ud Din, Mahdi Zareei, Muhammad Talha, Mohsen Guizani, Sultan Ullah Jadoon
2019 J jnl
IEEE Access
Yousaf Saeed, Khalil Ahmed, Mahdi Zareei, Asim Zeb, Cesar Vargas-Rosales, Khalid Mahmood Awan
2019 J jnl
IEEE Access
Kamran Sattar Awaisi, Assad Abbas, Mahdi Zareei, Hasan Ali Khattak, Muhammad Usman Shahid Khan, Mazhar Ali, Ikram Ud Din, Sajid Shah
2018 J jnl
Sensors
Dalhatu Muhammed, Mohammad Hossein Anisi, Mahdi Zareei, Cesar Vargas-Rosales, Anwar Khan
2018 J jnl
J. Netw. Comput. Appl.
Mahdi Zareei, Islam A. K. M. Muzahidul, Cesar Vargas-Rosales, Nafees Mansoor, Shidrokh Goudarzi, Mubashir Husain Rehmani
2018 J jnl
IEEE Access
Nafees Mansoor, Islam A. K. M. Muzahidul, Mahdi Zareei, Cesar Vargas-Rosales
2018 J jnl
Comput. Networks
Mahdi Zareei, Cesar Vargas-Rosales, Rafaela Villalpando Hernandez, Leyre Azpilicueta, Mohammad Hossein Anisi, Mubashir Husain Rehmani
2017 J jnl
IEEE Access
Seyed Ahmad Soleymani, Abdul Hanan Abdullah, Mahdi Zareei, Mohammad Hossein Anisi, Cesar Vargas-Rosales, Muhammad Khurram Khan, Shidrokh Goudarzi
2017 J jnl
Neurocomputing
Shidrokh Goudarzi, Wan Haslina Hassan, Mohammad Hossein Anisi, Seyed Ahmad Soleymani, Mehdi Sookhak, Muhammad Khurram Khan, Aisha-Hassan A. Hashim, Mahdi Zareei
2017 J jnl
Sensors
Mahdi Zareei, Islam A. K. M. Muzahidul, Sabariah Baharun, Cesar Vargas-Rosales, Leyre Azpilicueta, Nafees Mansoor
2017 J jnl
KSII Trans. Internet Inf. Syst.
Omar M. Zakaria, Aisha Hassan Abdalla Hashim, Wan Haslina Hassan, Othman Omran Khalifa, Mohammad Azram, Shidrokh Goudarzi, Lalitha Bhavani Jivanadham, Mahdi Zareei
2016 J jnl
EURASIP J. Wirel. Commun. Netw.
Mahdi Zareei, Islam A. K. M. Muzahidul, Nafees Mansoor, Sabariah Baharun, Ehab Mahmoud Mohamed, Seiichi Sampei
2016 J jnl
Int. J. Distributed Sens. Networks
Asim Zeb, A. K. M. Muzahidul Islam, Mahdi Zareei, Ishtiak Al Mamoon, Nafees Mansoor, Sabariah Baharun, Yoshiaki Katayama, Shozo Komaki
2016 J jnl
J. Comput. Networks Commun.
Omar M. Zakaria, Aisha-Hassan A. Hashim, Wan Haslina Hassan, Othman O. Khalifa, Mohammad Azram, Lalitha Bhavani Jivanadham, Mistura Laide Sanni, Mahdi Zareei
2016 J jnl
IEEE Access
Mahdi Zareei, Ehab Mahmoud Mohamed, Mohammad Hossein Anisi, Cesar Vargas-Rosales, Kazuya Tsukamoto, Muhammad Khurram Khan
2015 conf
ASCC
Nafees Mansoor, Islam A. K. M. Muzahidul, Mahdi Zareei, Sabariah Baharun, Shozo Komaki
2015 J jnl
Wirel. Pers. Commun.
Nafees Mansoor, Islam A. K. M. Muzahidul, Mahdi Zareei, Sabariah Baharun, Toshio Wakabayashi, Shozo Komaki
2015 conf
CrownCom
Nafees Mansoor, Islam A. K. M. Muzahidul, Mahdi Zareei, Sabariah Baharun, Shozo Komaki
2013 C conf
APCC
Mahdi Zareei, Islam A. K. M. Muzahidul, Sabariah Baharun, Shozo Komaki
2011 C conf
APCC
Mahdi Zareei, Azar Zarei, Rahmat Budiarto, Mohd. Adib Omar
2011 J jnl
Comput. J.
Mahdi Zareei, Alireza Taghizadeh, Rahmat Budiarto, Tat Chee Wan
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