Kai Jia

81 papers A* 3A 4B 3C 1Journal 59Unranked 11
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Trans. Software Eng.
Chen Zhang, Jianwen Xiang, Rui Hao, Kai Jia, Jing Tian, Roberto Natella, Roberto Pietrantuono, Domenico Cotroneo
2026 J jnl
CoRR
Guoxin Chen, Fanzhe Meng, Jiale Zhao, Minghao Li, Daixuan Cheng, Huatong Song, Jie Chen, Yuzhi Lin, Hui Chen, Xin Zhao, Ruihua Song, Chang Liu, Cheng Chen, Kai Jia, Ji-Rong Wen
2026 J jnl
J. Vis. Commun. Image Represent.
Da Ai, Yunqiao Wang, Kai Jia, Zhike Ji, Ying Liu
2026 J jnl
CoRR
Jiale Zhao, Guoxin Chen, Fanzhe Meng, Minghao Li, Jie Chen, Hui Xu, Yongshuai Sun, Xin Zhao, Ruihua Song, Yuan Zhang, Peng Wang, Cheng Chen, Jirong Wen, Kai Jia
2025 J jnl
IEEE Trans. Dependable Secur. Comput.
Bin Xu, Dongdong Zhao, Junwei Zhou, Wenzhi Xie, Kai Jia, Jing Tian, Jianwen Xiang
2025 J jnl
CoRR
Siyao Song, Cong Ma, Zhihao Cheng, Shiye Lei, Minghao Li, Ying Zeng, Huaixiao Tou, Kai Jia
2025 J jnl
IEEE Trans. Ind. Informatics
Xue Gao, Kai Jia, Zhe Gao, Shasha Xiao
2025 J jnl
CoRR
Zirun Guo, Feng Zhang, Kai Jia, Tao Jin
2025 J jnl
CoRR
Yichen Han, Xiaoyang Hao, Keming Chen, Weibo Xiong, Jun He, Ruonan Zhang, Junjie Cao, Yue Liu, Bowen Li, Dongrui Zhang, Hui Xia, Huilei Fu, Kai Jia, Kaixuan Guo, Mingli Jin, Qingyun Meng, Ruidong Ma, Ruiqian Fang, Shaotong Guo, Xuhui Li, Yang Xiang, Ying Zhang, Yulong Liu, Yunfeng Li, Yuyi Zhang, Yuze Zhou, Zhen Wang, Zhaowen Chen
2025 J jnl
IEICE Electron. Express
Duoli Zhang, Huanyu Zhou, Feiyang Zhang, Kai Jia, Zhenmin Li, Wei Ni, Yukun Song
2025 J jnl
CoRR
Minghao Li, Ying Zeng, Zhihao Cheng, Cong Ma, Kai Jia
2025 J jnl
CoRR
Shiye Lei, Zhihao Cheng, Kai Jia, Dacheng Tao
2025 J jnl
CoRR
Huaixiao Tou, Ying Zeng, Cong Ma, Muzhi Li, Minghao Li, Weijie Yuan, He Zhang, Kai Jia
2025 J jnl
Ecol. Informatics
Jiapeng Dong, Kai Jia, Chongyang Wang, Guorong Yu, Dan Li, Shuisen Chen, Xingda Chen, Ni Wen, Zitong Zhao
2025 J jnl
CoRR
Zirun Guo, Minjie Hong, Feng Zhang, Kai Jia, Tao Jin
2024 J jnl
J. Glob. Optim.
Kai Jia, Xiaojun Duan, Zhengming Wang, Taihe Yi, Liang Yan, Xuan Chen
2024 J jnl
Peer Peer Netw. Appl.
Xiaohui Yang, Kun Zhang, Kai Jia, Peiyin Zhao
2024 J jnl
IEEE Trans. Circuits Syst. II Express Briefs
Kai Jia, Zhe Gao, Xue Gao
2024 J jnl
IEEE Trans. Ind. Informatics
Kai Jia, Zhe Gao, Ruicheng Ma, Haoyu Chai, Siqi Sun
2024 J jnl
Signal Process.
Zhiyuan Jiao, Zhe Gao, Haoyu Chai, Shasha Xiao, Kai Jia
2024 J jnl
Energy Inform.
Xi Yang, Kai Jia, Zirui Peng
2024 J jnl
Energy Inform.
Kai Jia, Xi Yang, Zirui Peng
2024 J jnl
Int. J. Appl. Earth Obs. Geoinformation
Kai Jia, Umut Hasan, Hao Jiang, Boxiong Qin, Shuisen Chen, Dan Li, Chongyang Wang, Yue Deng, Jie Shen
2024 J jnl
CoRR
Kai Jia, Martin C. Rinard
2024 A conf
ICME
Da Ai, Kai Jia, Yunqiao Wang, Ying Liu
2024 J jnl
J. Syst. Softw.
Kai Jia, Xiao Yu, Chen Zhang, Wenzhi Xie, Dongdong Zhao, Jianwen Xiang
2024 J jnl
Expert Syst. Appl.
Kai Jia, Zhe Gao, Shasha Xiao
2024 J jnl
Softw. Qual. J.
Kai Jia, Xiao Yu, Chen Zhang, Wenzhi Xie, Dongdong Zhao, Jianwen Xiang
2023 J jnl
Entropy
Zhiwei Fan, Kai Jia, Lei Zhang, Fengshan Zou, Zhenjun Du, Mingmin Liu, Yuting Cao, Qiang Zhang
2023 J jnl
Remote. Sens.
Xuemei Dai, Shuisen Chen, Kai Jia, Hao Jiang, Yishan Sun, Dan Li, Qiong Zheng, Jianxi Huang
2023 conf
IFTC (1)
Shuqi Wang, Da Pan, Yangrui Zhao, Kai Jia, Yichun Zhang, Tianyu Liang
2023 J jnl
CoRR
Kai Jia, Martin C. Rinard
2023 conf
IFTC (2)
Kai Jia, Zelu Qi, Yunchao Xie, Da Pan, Shuqi Wang, Xin Xiong, Fei Zhao, Yichun Zhang, Tianyu Liang
2023 conf
ISSREW
Xiaolei Yu, Kai Jia, Wenhua Hu, Jing Tian, Jianwen Xiang
2023 conf
ISSREW
Wenzhi Xie, Chen Zhang, Kai Jia, Dongdong Zhao, Junwei Zhou, Jing Tian, Jianwen Xiang
2023 A* conf
AAAI
Kai Jia, Hongwen Zhang, Liang An, Yebin Liu
2023 J jnl
CoRR
Kai Jia, Hongwen Zhang, Liang An, Yebin Liu
2023 J jnl
CoRR
Kai Jia, Martin C. Rinard
2023 J jnl
Remote. Sens.
Kai Jia, Ailin Huang, Xiaoling Yin, Ji Yang, Liming Deng, Zhuoling Lin
2023 J jnl
IEEE Trans. Emerg. Top. Comput.
Kai Jia, Xiao Yu, Chen Zhang, Wenhua Hu, Dongdong Zhao, Jianwen Xiang
2023 J jnl
CoRR
Kai Jia, Pasapol Saowakon, Limor Appelbaum, Martin C. Rinard
2022 conf
SSPS
Da Ai, Weixin Fan, Kai Jia, Mingyue Lu, Ying Liu
2022 conf
ISSRE Workshops
Yancai Zhou, Chen Zhang, Kai Jia, Dongdong Zhao, Jianwen Xiang
2022 J jnl
Entropy
Hongyan Liu, Daokui Qu, Fang Xu, Zhenjun Du, Kai Jia, Mingmin Liu
2022 J jnl
Electron. Mark.
Kai Jia, Nan Zhang
2022 conf
RCAR
Hongyan Liu, Daokui Qu, Fang Xu, Zhenjun Du, Kai Jia, Mingmin Liu
2022 J jnl
CoRR
Kai Jia, Martin C. Rinard, Yichen Yang
2022 B conf
SAGT
Yichen Yang, Kai Jia, Martin C. Rinard
2022 J jnl
CoRR
Yichen Yang, Kai Jia, Martin C. Rinard
2022 J jnl
J. Intell. Robotic Syst.
Hongyan Liu, Daokui Qu, Fang Xu, Zhenjun Du, Kai Jia, Jilai Song, Mingmin Liu
2022 A conf
ISSRE
Kai Jia, Xiao Yu, Chen Zhang, Wenhua Hu, Dongdong Zhao, Jianwen Xiang
2022 J jnl
Remote. Sens.
Yue Deng, Weiguo Jiang, Xuchun Ye, Lin Zhang, Kai Jia
2021 J jnl
Int. J. Digit. Crime Forensics
Xintao Duan, Baoxia Li, Daidou Guo, Kai Jia, En Zhang, Chuan Qin
2021 B conf
SAS
Kai Jia, Martin C. Rinard
2021 A conf
CIKM
Weihao Gao, Xiangjun Fan, Chong Wang, Jiankai Sun, Kai Jia, Wenzhi Xiao, Ruofan Ding, Xingyan Bin, Hui Yang, Xiaobing Liu
2021 J jnl
CoRR
Kai Jia
2021 J jnl
ACM Trans. Graph.
Kai Jia
2021 B conf
SAS
Kai Jia, Martin C. Rinard
2021 J jnl
CoRR
Kai Jia, Martin C. Rinard
2020 A conf
ISSRE
Bin Xu, Dongdong Zhao, Kai Jia, Junwei Zhou, Jing Tian, Jianwen Xiang
2020 J jnl
CoRR
Weihao Gao, Xiangjun Fan, Jiankai Sun, Kai Jia, Wenzhi Xiao, Chong Wang, Xiaobing Liu
2020 A* conf
NeurIPS
Kai Jia, Martin C. Rinard
2020 J jnl
CoRR
Kai Jia, Martin C. Rinard
2020 J jnl
CoRR
Kai Jia, Martin C. Rinard
2019 J jnl
IEEE Access
Xintao Duan, Kai Jia, Baoxia Li, Daidou Guo, En Zhang, Chuan Qin
2019 J jnl
IEEE Access
Kai Jia, Yong Hou, Kai Niu, Chao Dong, Zhiqiang He
2018 J jnl
Remote. Sens.
Pinzeng Rao, Weiguo Jiang, Yukun Hou, Zheng Chen, Kai Jia
2018 conf
ICCCS (3)
Xintao Duan, Jingjing Liu, En Zhang, Haoxian Song, Kai Jia
2018 conf
GCCE
Renwei Chen, Kai Jia, Xiaoying Zhao, Qi Qi, Jie Zhu
2018 A* conf
CVPR
Chao Peng, Tete Xiao, Zeming Li, Yuning Jiang, Xiangyu Zhang, Kai Jia, Gang Yu, Jian Sun
2018 conf
ISR
Hengle Ren, Fang Xu, Fengshan Zou, Kai Jia, Pei Di, Jie Kang
2018 J jnl
Remote. Sens.
Zheng Chen, Weiguo Jiang, Wenjie Wang, Yue Deng, Bin He, Kai Jia
2017 J jnl
CoRR
Chao Peng, Tete Xiao, Zeming Li, Yuning Jiang, Xiangyu Zhang, Kai Jia, Gang Yu, Jian Sun
2017 J jnl
Remote. Sens.
Yue Deng, Weiguo Jiang, Zhenghong Tang, Jiahong Li, Jinxia Lv, Zheng Chen, Kai Jia
2016 J jnl
J. Sensors
Qiang Zhang, Daokui Qu, Fang Xu, Kai Jia, Xueying Sun
2016 J jnl
CoRR
Rami Al-Rfou, Guillaume Alain, Amjad Almahairi, Christof Angermüller, Dzmitry Bahdanau, Nicolas Ballas, Frédéric Bastien, Justin Bayer, Anatoly Belikov, Alexander Belopolsky, Yoshua Bengio, Arnaud Bergeron, James Bergstra, Valentin Bisson, Josh Bleecher Snyder, Nicolas Bouchard, Nicolas Boulanger-Lewandowski, Xavier Bouthillier, Alexandre de Brébisson, Olivier Breuleux, Pierre Luc Carrier, Kyunghyun Cho, Jan Chorowski, Paul F. Christiano, Tim Cooijmans, Marc-Alexandre Côté, Myriam Côté, Aaron C. Courville, Yann N. Dauphin, Olivier Delalleau, Julien Demouth, Guillaume Desjardins, Sander Dieleman, Laurent Dinh, Melanie Ducoffe, Vincent Dumoulin, Samira Ebrahimi Kahou, Dumitru Erhan, Ziye Fan, Orhan Firat, Mathieu Germain, Xavier Glorot, Ian J. Goodfellow, Matthew Graham, Çaglar Gülçehre, Philippe Hamel, Iban Harlouchet, Jean-Philippe Heng, Balázs Hidasi, Sina Honari, Arjun Jain, Sébastien Jean, Kai Jia, Mikhail Korobov, Vivek Kulkarni, Alex Lamb, Pascal Lamblin, Eric Larsen, César Laurent, Sean Lee, Simon Lefrançois, Simon Lemieux, Nicholas Léonard, Zhouhan Lin, Jesse A. Livezey, Cory Lorenz, Jeremiah Lowin, Qianli Ma, Pierre-Antoine Manzagol, Olivier Mastropietro, Robert McGibbon, Roland Memisevic, Bart van Merriënboer, Vincent Michalski, Mehdi Mirza, Alberto Orlandi, Christopher Joseph Pal, Razvan Pascanu, Mohammad Pezeshki, Colin Raffel, Daniel Renshaw, Matthew Rocklin, Adriana Romero, Markus Roth, Peter Sadowski, John Salvatier, François Savard, Jan Schlüter, John Schulman, Gabriel Schwartz, Iulian Vlad Serban, Dmitriy Serdyuk, Samira Shabanian, Étienne Simon, Sigurd Spieckermann, S. Ramana Subramanyam, Jakub Sygnowski, Jérémie Tanguay, Gijs van Tulder, Joseph P. Turian, Sebastian Urban, Pascal Vincent, Francesco Visin, Harm de Vries, David Warde-Farley, Dustin J. Webb, Matthew Willson, Kelvin Xu, Lijun Xue, Li Yao, Saizheng Zhang, Ying Zhang
2015 J jnl
Remote. Sens.
Weiguo Jiang, Kai Jia, Jianjun Wu, Zheng-Hong Tang, Wenjie Wang, Xiaofu Liu
2015 conf
ROBIO
Jilai Song, Ning Xi, Fang Xu, Kai Jia, Fengshan Zou
2013 J jnl
IEEE Trans. Instrum. Meas.
Haiming Shao, Bo Liang, Feipeng Lin, Hongtao Huang, Yanqiang Li, Kai Jia, Wenfeng Li, Huanghui Zhang
2013 J jnl
IEEE Trans. Instrum. Meas.
Haiming Shao, Kaifeng Qu, Feipeng Lin, Bo Liang, Kai Jia, Qiang Ren, Yanqiang Li, Wenfeng Li
2012 C conf
ISCAS
Shuai Chen, Hao Li, Kai Jia, Yue Wang, Xiaobing Shi, Feng Zhang
redb/extractors/apk_extractors/apk_dex.py
← Index redb/extractors/apk_extractors/apk_dex.py python
import hashlib
import inspect
import json
from collections import Counter
from datetime import datetime, timezone
from typing import Any

import tlsh

from redb.extractors.enum import Tag
from redb.extractors.apk_extractor import APKExtractor
from redb.models.dataclasses import APKDexFile

# Sensitive API patterns categorized for malware analysis
SENSITIVE_API_CATEGORIES = {
    "reflection": [
        "Ljava/lang/reflect/Method;->invoke",
        "Ljava/lang/reflect/Field;->get",
        "Ljava/lang/reflect/Field;->set",
        "Ljava/lang/reflect/Constructor;->newInstance",
        "Ljava/lang/Class;->forName",
        "Ljava/lang/Class;->getMethod",
        "Ljava/lang/Class;->getDeclaredMethod",
        "Ljava/lang/Class;->getDeclaredField",
        "Ljava/lang/ClassLoader;->loadClass",
    ],
    "crypto": [
        "Ljavax/crypto/Cipher;->getInstance",
        "Ljavax/crypto/Cipher;->init",
        "Ljavax/crypto/spec/SecretKeySpec;-><init>",
        "Ljavax/crypto/spec/IvParameterSpec;-><init>",
        "Ljava/security/MessageDigest;->getInstance",
        "Ljava/security/KeyStore;->getInstance",
        "Ljavax/crypto/Mac;->getInstance",
    ],
    "dynamic_loading": [
        "Ldalvik/system/DexClassLoader;-><init>",
        "Ldalvik/system/PathClassLoader;-><init>",
        "Ldalvik/system/InMemoryDexClassLoader;-><init>",
        "Ldalvik/system/BaseDexClassLoader;-><init>",
        "Ljava/lang/Runtime;->exec",
        "Ljava/lang/ProcessBuilder;->start",
    ],
    "telephony": [
        "Landroid/telephony/TelephonyManager;->getDeviceId",
        "Landroid/telephony/TelephonyManager;->getSubscriberId",
        "Landroid/telephony/TelephonyManager;->getLine1Number",
        "Landroid/telephony/TelephonyManager;->getSimSerialNumber",
        "Landroid/telephony/TelephonyManager;->getNetworkOperator",
        "Landroid/telephony/TelephonyManager;->getSimOperator",
    ],
    "sms": [
        "Landroid/telephony/SmsManager;->sendTextMessage",
        "Landroid/telephony/SmsManager;->sendMultipartTextMessage",
        "Landroid/telephony/SmsManager;->sendDataMessage",
    ],
    "network": [
        "Ljava/net/HttpURLConnection;->connect",
        "Ljava/net/URL;->openConnection",
        "Lokhttp3/OkHttpClient;-><init>",
        "Lokhttp3/Request$Builder;->build",
        "Lorg/apache/http/client/HttpClient;->execute",
        "Landroid/webkit/WebView;->loadUrl",
        "Landroid/webkit/WebView;->setWebViewClient",
    ],
    "native": [
        "Ljava/lang/System;->loadLibrary",
        "Ljava/lang/System;->load",
        "Ljava/lang/Runtime;->loadLibrary",
    ],
    "device_info": [
        "Landroid/os/Build;->FINGERPRINT",
        "Landroid/os/Build;->MODEL",
        "Landroid/os/Build;->MANUFACTURER",
        "Landroid/os/Build;->PRODUCT",
        "Landroid/os/Build;->BRAND",
        "Landroid/os/Build;->DEVICE",
        "Landroid/os/Build;->HARDWARE",
        "Landroid/os/Build;->SERIAL",
        "Landroid/os/Build$VERSION;->SDK_INT",
        "Landroid/provider/Settings$Secure;->getString",
    ],
    "file_io": [
        "Ljava/io/FileOutputStream;-><init>",
        "Ljava/io/FileInputStream;-><init>",
        "Landroid/content/SharedPreferences;->edit",
        "Landroid/database/sqlite/SQLiteDatabase;->execSQL",
        "Landroid/database/sqlite/SQLiteDatabase;->rawQuery",
    ],
    "ipc": [
        "Landroid/content/ContentResolver;->query",
        "Landroid/content/ContentResolver;->insert",
        "Landroid/content/ContentResolver;->delete",
        "Landroid/content/Intent;-><init>",
        "Landroid/content/Context;->sendBroadcast",
        "Landroid/content/Context;->startService",
        "Landroid/content/Context;->bindService",
    ],
}


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

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

    def _analyze_api_usage(self, dex):
        """Categorize sensitive API calls found in DEX bytecode."""
        api_usage = {cat: set() for cat in SENSITIVE_API_CATEGORIES}

        try:
            for method in dex.get_encoded_methods():
                code = method.get_code()
                if not code:
                    continue
                try:
                    bytecode = code.get_bc()
                    if not bytecode:
                        continue
                    for instruction in bytecode.get_instructions():
                        op_name = instruction.get_name()
                        if not op_name or not op_name.startswith("invoke"):
                            continue
                        output = instruction.get_output()
                        if not output:
                            continue
                        for category, patterns in SENSITIVE_API_CATEGORIES.items():
                            for pattern in patterns:
                                if pattern in output:
                                    api_usage[category].add(output.strip())
                                    break
                except Exception:
                    continue
        except Exception as e:
            self.log.warning(f"Error analyzing API usage: {e}")

        # Convert sets to sorted lists
        return {cat: sorted(calls) for cat, calls in api_usage.items() if calls}

    def _compute_obfuscation_indicators(self, classes, methods):
        """Compute obfuscation indicators from class/method names."""
        class_names = []
        for cls in classes:
            try:
                name = cls.get_name()
                if name:
                    class_names.append(name)
            except Exception:
                continue

        method_names = []
        for m in methods:
            try:
                name = m.get_name()
                if name and name not in ("<init>", "<clinit>"):
                    method_names.append(name)
            except Exception:
                continue

        if not class_names:
            return None

        # Short class names: extract just the class part from Dalvik notation
        short_class = 0
        for n in class_names:
            simple = n.split("/")[-1].rstrip(";")
            if len(simple) <= 2:
                short_class += 1

        short_method = sum(1 for n in method_names if len(n) <= 2)

        return {
            "short_class_names_pct": round(short_class / max(len(class_names), 1), 4),
            "short_method_names_pct": round(short_method / max(len(method_names), 1), 4),
            "non_ascii_identifiers": sum(1 for n in class_names if not n.isascii()),
            "avg_class_name_length": round(
                sum(len(n) for n in class_names) / max(len(class_names), 1), 2
            ),
        }

    def _compute_top_packages(self, classes):
        """Compute top packages by class count."""
        package_counter = Counter()
        for cls in classes:
            try:
                name = cls.get_name()  # "Lcom/example/foo/Bar;"
                if not name:
                    continue
                parts = name[1:].replace("/", ".").rsplit(".", 1)
                if len(parts) > 1:
                    package = parts[0]
                else:
                    package = "(default)"
                package_counter[package] += 1
            except Exception:
                continue

        return [
            {"package": pkg, "class_count": count}
            for pkg, count in package_counter.most_common(20)
        ]

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

        from androguard.core.dex import DEX

        try:
            dex_names = list(self.apk.get_dex_names() or [])
        except Exception as e:
            self.log.warning(f"Error getting DEX names for {self.hash.sha256}: {e}")
            dex_names = []

        try:
            dex_buffers = list(self.apk.get_all_dex() or [])
        except Exception as e:
            self.log.error(f"Error getting DEX buffers for {self.hash.sha256}: {e}")
            return None

        if not dex_buffers:
            self.log.debug("No DEX files found in APK")
            return None

        self.dex_files = []
        for i, dex_data in enumerate(dex_buffers):
            dex_name = dex_names[i] if i < len(dex_names) else f"classes{i}.dex"

            dex_sha256 = hashlib.sha256(dex_data).hexdigest()
            dex_tlsh = None
            if len(dex_data) >= 50:
                try:
                    dex_tlsh = tlsh.hash(dex_data) or None
                except Exception:
                    pass

            try:
                d = DEX(dex_data)
            except Exception as e:
                self.log.warning(f"Failed to parse DEX {dex_name}: {e}")
                continue

            try:
                classes = list(d.get_classes() or [])
            except Exception as e:
                self.log.warning(f"Error getting classes from {dex_name}: {e}")
                classes = []
            try:
                methods = list(d.get_methods() or [])
            except Exception as e:
                self.log.warning(f"Error getting methods from {dex_name}: {e}")
                methods = []
            try:
                strings = list(d.get_strings() or [])
            except Exception as e:
                self.log.warning(f"Error getting strings from {dex_name}: {e}")
                strings = []

            try:
                top_packages = self._compute_top_packages(classes)
            except Exception as e:
                self.log.warning(f"Error computing top packages for {dex_name}: {e}")
                top_packages = []
            try:
                api_usage = self._analyze_api_usage(d)
            except Exception as e:
                self.log.warning(f"Error analyzing API usage for {dex_name}: {e}")
                api_usage = {}
            try:
                obfuscation_indicators = self._compute_obfuscation_indicators(classes, methods)
            except Exception as e:
                self.log.warning(f"Error computing obfuscation indicators for {dex_name}: {e}")
                obfuscation_indicators = None

            self.dex_files.append(APKDexFile(
                filename=dex_name,
                sha256=dex_sha256,
                class_count=len(classes),
                method_count=len(methods),
                string_count=len(strings),
                tlsh=dex_tlsh,
                top_packages=top_packages,
                api_usage=api_usage if api_usage else None,
                obfuscation_indicators=obfuscation_indicators,
            ))

        return self.dex_files if self.dex_files else None

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

            current_time = datetime.now(timezone.utc)

            # DEX table: one row per DEX file
            dex_data = []
            for dex in self.dex_files:
                dex_data.append([
                    self.sha256,
                    dex.sha256,
                    dex.filename,
                    dex.tlsh,
                    dex.class_count,
                    dex.method_count,
                    dex.string_count,
                    json.dumps(dex.top_packages) if dex.top_packages else None,
                    json.dumps(dex.obfuscation_indicators) if dex.obfuscation_indicators else None,
                    current_time,
                ])

            # API usage table: one row per category per DEX
            api_data = []
            for dex in self.dex_files:
                if dex.api_usage:
                    for category, api_calls in dex.api_usage.items():
                        api_data.append([
                            self.sha256,
                            dex.sha256,
                            category,
                            api_calls,
                            current_time,
                        ])

            return {
                'multi_table': True,
                'dex': {
                    'table': 'redb_apk_dex',
                    'data': dex_data,
                    'column_names': [
                        'sha256', 'dex_sha256', 'dex_filename', 'dex_tlsh',
                        'dex_class_count', 'dex_method_count', 'dex_string_count',
                        'dex_top_packages', 'dex_obfuscation_indicators',
                        'analysis_date',
                    ],
                    'column_type_names': [
                        'FixedString(64)', 'FixedString(64)', 'String', 'Nullable(String)',
                        'UInt32', 'UInt32', 'UInt32',
                        'Nullable(String)', 'Nullable(String)',
                        "DateTime64(3, 'UTC')",
                    ],
                },
                'api_usage': {
                    'table': 'redb_apk_dex_api_usage',
                    'data': api_data,
                    'column_names': [
                        'sha256', 'dex_sha256', 'api_category',
                        'api_calls', 'analysis_date',
                    ],
                    'column_type_names': [
                        'FixedString(64)', 'FixedString(64)', 'LowCardinality(String)',
                        'Array(String)', "DateTime64(3, 'UTC')",
                    ],
                },
            }

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