Wai-Choong Wong

132 papers A* 2A 3B 22C 14Misc 9Journal 51Unranked 31
YearRankTypeTitle / Venue / Authors
2024 J jnl
IEEE Trans. Intell. Transp. Syst.
Zhixiang Zhang, Wai-Choong Wong, Biplab Sikdar
2023 J jnl
IEEE Trans. Veh. Technol.
Zhixiang Zhang, Tianyi Feng, Wai-Choong Wong, Biplab Sikdar
2022 J jnl
IEEE Internet Things J.
Jiange Wang, Wai-Choong Wong, Xiaoyuan Luo, Xiaolei Li, Xinping Guan
2021 conf
ICC
Zhixiang Zhang, Tianyi Feng, Biplab Sikdar, Wai-Choong Wong
2021 B conf
PIMRC
Tianyi Feng, Zhixiang Zhang, Wai-Choong Wong, Sumei Sun, Biplab Sikdar
2021 J jnl
IEEE Internet Things J.
Yonghao Zhao, Zhixiang Zhang, Tianyi Feng, Wai-Choong Wong, Hari Krishna Garg
2020 J jnl
IEEE Trans. Wirel. Commun.
Yonghao Zhao, Wai-Choong Wong, Tianyi Feng, Hari Krishna Garg
2020 J jnl
IEEE Internet Things J.
Yonghao Zhao, Wai-Choong Wong, Tianyi Feng, Hari Krishna Garg
2019 conf
ICSPCS
Lin Tang, Zhixiang Zhang, Yonghao Zhao, Tianyi Feng, Wai-Choong Wong, Hari Krishna Garg
2019 B conf
GLOBECOM
Yonghao Zhao, Wai-Choong Wong, Hari Krishna Garg, Tianyi Feng, Zhixiang Zhang, Lin Tang
2019 conf
WPNC
Tianyi Feng, Wai-Choong Wong, Sumei Sun, Yonghao Zhao, Zhixiang Zhang
2019 J jnl
IEEE Trans. Veh. Technol.
Jiange Wang, Xiaoyuan Luo, Wai-Choong Wong, Xinping Guan
2018 C conf
TENCON
Shuangyao Huang, Wai-Choong Wong
2018 C conf
IPIN
Yonghao Zhao, Wai-Choong Wong, Hari Krishna Garg, Tianyi Feng
2017 J jnl
Wirel. Pers. Commun.
Jinqiang Yu, Wai-Choong Wong
2017 C conf
IPIN
Yonghao Zhao, Wai-Choong Wong, Hari Krishna Garg
2017 J jnl
IEEE Trans. Inf. Forensics Secur.
Jing Yang Koh, Derek Leong, Gareth W. Peters, Ido Nevat, Wai-Choong Wong
2017 conf
ICC
Jing Yang Koh, Gareth W. Peters, Derek Leong, Ido Nevat, Wai-Choong Wong
2016 J jnl
IEEE/ACM Trans. Netw.
Yu Lu, Mehul Motani, Wai-Choong Wong
2016 J jnl
IEEE Trans. Veh. Technol.
Jiangbin Lyu, Yong Huat Chew, Wai-Choong Wong
2016 J jnl
IEEE Trans. Veh. Technol.
Wen Sun, Yu Ge, Zhiqiang Zhang, Wai-Choong Wong
2016 J jnl
CoRR
Jiangbin Lyu, Yong Huat Chew, Wai-Choong Wong
2016 J jnl
IEEE Trans. Veh. Technol.
Jiangbin Lyu, Yong Huat Chew, Wai-Choong Wong
2016 J jnl
IEEE Internet Things J.
Jing Yang Koh, Ido Nevat, Derek Leong, Wai-Choong Wong
2016 J jnl
CoRR
Jing Yang Koh, Ido Nevat, Derek Leong, Wai-Choong Wong
2016 J jnl
Comput. Networks
Ke Wang, Teck Yoong Chai, Wai-Choong Wong
2015 J jnl
CoRR
Jiangbin Lyu, Yong Huat Chew, Wai-Choong Wong
2015 B conf
WCNC
Wen Sun, Yu Ge, Wai-Choong Wong
2015 J jnl
IEEE Trans. Cogn. Commun. Netw.
Amna Jamal, Chen-Khong Tham, Wai-Choong Wong
2015 conf
VTC Spring
Jiangbin Lyu, Yong Huat Chew, Wai-Choong Wong
2015 J jnl
IEEE Trans. Veh. Technol.
Jinqiang Yu, Wai-Choong Wong
2015 J jnl
Sensors
Wen Sun, Yu Ge, Zhiqiang Zhang, Wai-Choong Wong
2015 conf
ICC
Jing Yang Koh, Joseph Chee Ming Teo, Derek Leong, Wai-Choong Wong
2014 J jnl
J. Sens. Actuator Networks
Haitao Bao, Wai-Choong Wong
2014 B conf
WCNC
Ke Wang, Teck Yoong Chai, Wai-Choong Wong
2014 conf
CrownCom
Amna Jamal, Chen-Khong Tham, Wai-Choong Wong
2014 Misc conf
ICCS
Jing Yang Koh, Joseph Chee Ming Teo, Wai-Choong Wong
2014 conf
ICT
Jin Wang, Teck Yoong Chai, Wai-Choong Wong
2014 J jnl
J. Comput. Networks Commun.
Jin Wang, Cenzhe Zhu, Teck Yoong Chai, Wai-Choong Wong
2014 J jnl
IEEE Trans. Biomed. Eng.
Xiaoli Meng, Zhiqiang Zhang, Jian-Kang Wu, Wai-Choong Wong, Haoyong Yu
2014 conf
INFOCOM Workshops
Amna Jamal, Chen-Khong Tham, Wai-Choong Wong
2014 Misc conf
ICCS
Jinqiang Yu, Wai-Choong Wong
2013 conf
ICON
Ke Wang, Teck Yoong Chai, Wai-Choong Wong
2013 J jnl
IEEE Trans. Mob. Comput.
Yunye Jin, Wee-Seng Soh, Mehul Motani, Wai-Choong Wong
2013 J jnl
Comput. Networks
Wen Sun, Yu Ge, Wai-Choong Wong
2013 B conf
IWCMC
Li Zhang, Yong Huat Chew, Wai-Choong Wong
2013 J jnl
CoRR
Jiangbin Lyu, Yong Huat Chew, Wai-Choong Wong
2013 J jnl
IEEE Trans. Wirel. Commun.
Jiangbin Lyu, Yong Huat Chew, Wai-Choong Wong
2013 J jnl
Sensors
Wen Sun, Zhiqiang Zhang, Lianying Ji, Wai-Choong Wong
2013 conf
ICSPCS
Ke Wang, Wai-Choong Wong, Teck Yoong Chai
2013 B conf
PIMRC
Jiangbin Lyu, Yong Huat Chew, Wai-Choong Wong
2013 B conf
IWCMC
Haitao Bao, Wai-Choong Wong
2013 J jnl
IEEE Trans. Biomed. Eng.
Xiaoli Meng, Zhiqiang Zhang, Jian-Kang Wu, Wai-Choong Wong
2013 conf
CyberC
Haitao Bao, Wai-Choong Wong
2013 J jnl
IEEE J. Sel. Areas Commun.
Qian Chen, Wai-Choong Wong, Mehul Motani, Ying-Chang Liang
2013 B conf
PIMRC
Jinqiang Yu, Wai-Choong Wong
2013 J jnl
IEEE Commun. Surv. Tutorials
Abror Abduvaliyev, Al-Sakib Khan Pathan, Jianying Zhou, Rodrigo Roman, Wai-Choong Wong
2013 conf
ICDP
Zhi Gao, Mo Shan, Wai-Choong Wong, Qingquan Li, Peigen He
2013 conf
PerCom Workshops
Yu Lu, Wai-Choong Wong
2013 J jnl
Signal Process.
Li Zhang, Yong Huat Chew, Wai-Choong Wong
2012 Misc conf
ICCS
Ke Wang, Wai-Choong Wong, Teck Yoong Chai
2012 Misc conf
ICCS
Li Zhang, Yong Huat Chew, Wai-Choong Wong
2012 conf
ICSPCS
Lei Wang, Wai-Choong Wong
2012 B conf
WiMob
Wen Sun, Yu Ge, Wai-Choong Wong
2012 Misc conf
ICCS
Haitao Bao, Wai-Choong Wong, T. T. Tay
2012 C conf
FUSION
Xiaoli Meng, Guanhong Tao, Zhiqiang Zhang, Shuyan Sun, Jiankang Wu, Wai-Choong Wong
2012 J jnl
Int. J. Wirel. Inf. Networks
Li Zhang, Yong Huat Chew, Wai-Choong Wong
2012 Misc conf
ICCS
Amna Jamal, Chen-Khong Tham, Wai-Choong Wong
2012 conf
ICSPCS
Li Zhang, Yong Huat Chew, Wai-Choong Wong
2012 C conf
Healthcom
Wen Sun, Yu Ge, Wai-Choong Wong
2012 Misc conf
ICCS
Jinqiang Yu, Wai-Choong Wong
2012 conf
ICON
Alok Pathak, Wai-Choong Wong, Huaqun Guo, Yongdong Wu
2012 conf
ICSPCS
Jin Wang, Cenzhe Zhu, Qinfeng Guo, Teck Yoong Chai, Wai-Choong Wong
2012 Misc conf
ICCS
Qinfeng Guo, Wai-Choong Wong
2012 J jnl
Comput. Networks
Yu Lu, Mehul Motani, Wai-Choong Wong
2011 J jnl
IEEE Trans. Veh. Technol.
Qian Chen, Ying-Chang Liang, Mehul Motani, Wai-Choong Wong
2011 B conf
IWCMC
Xi Yu, Huaqun Guo, Wai-Choong Wong
2011 A* conf
PerCom
Yunye Jin, Hong-Song Toh, Wee-Seng Soh, Wai-Choong Wong
2011 J jnl
IEEE J. Sel. Top. Signal Process.
Qian Chen, Mehul Motani, Wai-Choong Wong, Arumugam Nallanathan
2011 C conf
ICICS
Qingqing Yi, Huaqun Guo, Wai-Choong Wong
2011 C conf
BSN
Xiaoli Meng, Shuyan Sun, Lianying Ji, Jiankang Wu, Wai-Choong Wong
2011 C conf
ICICS
Lei Wang, Wai-Choong Wong
2011 conf
ICC
Huaqun Guo, Fan Yu, Zonghua Zhang, Wai-Choong Wong, Maode Ma, Yongdong Wu
2011 conf
ANT/MobiWIS
Wen Sun, Lianying Ji, Wai-Choong Wong
2011 B conf
IWCMC
Huaqun Guo, Shen-Tat Goh, Nicholas C. S. Foo, Qian Zhang, Wai-Choong Wong
2011 B conf
PIMRC
Li Zhang, Yong Huat Chew, Wai-Choong Wong
2011 conf
ANT/MobiWIS
Yu Lu, Mehul Motani, Wai-Choong Wong
2011 J jnl
IEEE Trans. Inf. Technol. Biomed.
Zhiqiang Zhang, Wai-Choong Wong, Jian-Kang Wu
2010 C conf
FUSION
Shuyan Sun, Xiaoli Meng, Lianying Ji, Jiankang Wu, Wai-Choong Wong
2010 B conf
SMC
Xiaoli Meng, Shuyan Sun, Lianying Ji, Jiankang Wu, Wai-Choong Wong
2010 J jnl
IEEE Commun. Lett.
Yunye Jin, Wee-Seng Soh, Wai-Choong Wong
2010 J jnl
IEEE Trans. Wirel. Commun.
Yunye Jin, Wee-Seng Soh, Wai-Choong Wong
2010 B conf
SMC
Yu Lu, Mehul Motani, Wai-Choong Wong
2010 J jnl
Wirel. Networks
Yew Fai Wong, Lek Heng Ngoh, Wai-Choong Wong
2010 B conf
IWCMC
Huaqun Guo, Fan Yu, Wai-Choong Wong, Vivy Suhendra, Yongdong Wu
2010 C conf
EUC
Yu Lu, Mehul Motani, Wai-Choong Wong
2009 B conf
AINA
Huaqun Guo, Lek Heng Ngoh, Wai-Choong Wong, Ping Yang, Nazreen Beevi
2009 J jnl
Comput. Commun.
Yew Fai Wong, Lek Heng Ngoh, Winston Khoon Guan Seah, Wai-Choong Wong
2009 conf
ISWCS
Hui Wang, Wai-Choong Wong, Wee-Seng Soh, Mehul Motani
2009 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Zhishou Zhang, Qibin Sun, John G. Apostolopoulos, Wai-Choong Wong
2009 conf
ICC
Ho Huat Peh, Athanassios Manikas, Tjeng Thiang Tjhung, Wai-Choong Wong
2008 B conf
ICIP
Zhishou Zhang, Qibin Sun, John G. Apostolopoulos, Wai-Choong Wong
2007 J jnl
IEEE Trans. Multim.
Zhishou Zhang, Qibin Sun, Wai-Choong Wong, John G. Apostolopoulos, Susie J. Wee
2007 J jnl
IEEE Trans. Veh. Technol.
Wai-Leong Yeow, Chen-Khong Tham, Wai-Choong Wong
2007 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Zhishou Zhang, Qibin Sun, Wai-Choong Wong, John G. Apostolopoulos, Susie J. Wee
2007 conf
ICASSP (2)
Zhishou Zhang, Qibin Sun, Wai-Choong Wong, John G. Apostolopoulos, Susie J. Wee
2007 conf
ICIP (6)
Zhishou Zhang, John G. Apostolopoulos, Qibin Sun, Susie J. Wee, Wai-Choong Wong
2006 A conf
ICME
Zhishou Zhang, Qibin Sun, Wai-Choong Wong, John G. Apostolopoulos, Susie J. Wee
2006 conf
ICASSP (2)
Zhishou Zhang, Qibin Sun, Susie J. Wee, Wai-Choong Wong
2006 C conf
ISCC
Huaqun Guo, D. Q. Zhang, Lek Heng Ngoh, Wai-Choong Wong, S. Zheng, Y. K. Koh
2006 J jnl
Multim. Tools Appl.
Huaqun Guo, Lek Heng Ngoh, Wai-Choong Wong, Joo Geok Tan
2006 A* conf
AAAI
Wai-Leong Yeow, Chen-Khong Tham, Wai-Choong Wong
2006 B conf
ICIP
Zhishou Zhang, Qibin Sun, Wai-Choong Wong, John G. Apostolopoulos, Susie J. Wee
2005 conf
ICIP (2)
Rong Zhang, Qibin Sun, Wai-Choong Wong
2005 C conf
ISCC
Huaqun Guo, Lek Heng Ngoh, Wai-Choong Wong
2005 A conf
ICME
Rong Zhang, Rongshan Yu, Qibin Sun, Wai-Choong Wong
2005 A conf
ICME
Zhishou Zhang, Qibin Sun, Wai-Choong Wong
2005 conf
PE-WASUN
Yew Fai Wong, Lek Heng Ngoh, Wai-Choong Wong
2005 conf
ICN (2)
Huaqun Guo, Lek Heng Ngoh, Wai-Choong Wong
2005 J jnl
Future Gener. Comput. Syst.
Huaqun Guo, Lek Heng Ngoh, Wai-Choong Wong, Joo Geok Tan
2005 Misc conf
PDPTA
Huaqun Guo, Lek Heng Ngoh, Wai-Choong Wong
2005 conf
ICOIN
Huaqun Guo, Lek Heng Ngoh, Wai-Choong Wong, Ligang Dong
2005 C conf
IPCCC
Huaqun Guo, Lek Heng Ngoh, Wai-Choong Wong
2005 B conf
GLOBECOM
Wai-Leong Yeow, Chen-Khong Tham, Wai-Choong Wong
2005 conf
ICN (2)
Huaqun Guo, Lek Heng Ngoh, Wai-Choong Wong
2004 B conf
ICIP
Zhishou Zhang, Qibin Sun, Wai-Choong Wong
2004 B conf
LCN
Yew Fai Wong, J. K. Wu, Lek Heng Ngoh, Wai-Choong Wong
2003 C conf
ISCC
Yew Fai Wong, C. Y. Wong, Lek Heng Ngoh, Wai-Choong Wong
1994 B conf
VTC
Wai-Choong Wong, Carl-Erik W. Sundberg, Nambi Seshadri
1993 J jnl
IEEE J. Sel. Areas Commun.
Wai-Choong Wong
1989 J jnl
IEEE J. Sel. Areas Commun.
Sami A. El-Dolil, Wai-Choong Wong, Raymond Steele
1986 J jnl
IEEE Trans. Acoust. Speech Signal Process.
David J. Goodman, Gordon B. Lockhart, Ondria J. Wasem, Wai-Choong Wong
redb/extractors/apk_extractors/apk_inconsistency_tests.py
← Index redb/extractors/apk_extractors/apk_inconsistency_tests.py python
import inspect
import re
from datetime import datetime, timezone
from typing import Any

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

# Emulator detection indicator strings
EMULATOR_INDICATORS = {
    "generic", "sdk", "google_sdk", "Emulator",
    "goldfish", "ranchu", "Andy", "Genymotion",
    "BlueStacks", "nox", "ttVM_Hdragon",
}

# Root detection indicator strings
ROOT_INDICATORS = {
    "/system/app/Superuser.apk",
    "/system/xbin/su",
    "/system/bin/su",
    "com.noshufou.android.su",
    "com.thirdparty.superuser",
    "eu.chainfire.supersu",
    "com.koushikdutta.superuser",
    "com.topjohnwu.magisk",
}

# Standard DEX filename pattern
STANDARD_DEX_PATTERN = re.compile(r"^classes\d*\.dex$")


class APKInconsistencyTestsExtractor(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.test_results = None
        self.log.debug(inspect.currentframe().f_code.co_name)

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

    def _test_zip_bomb(self):
        """Check if any ZIP entry has compression ratio > 100:1."""
        try:
            zf = self._get_zip_file()
            if not zf:
                return None
            with zf:
                for info in zf.infolist():
                    if info.compress_size > 0:
                        ratio = info.file_size / info.compress_size
                        if ratio > 100:
                            return True
            return False
        except Exception as e:
            self.log.warning(f"Error in zip bomb test: {e}")
            return None

    def _test_zip_duplicate_entries(self):
        """Check for duplicate filenames in ZIP directory."""
        try:
            zf = self._get_zip_file()
            if not zf:
                return None
            with zf:
                names = [info.filename for info in zf.infolist()]
                return len(names) != len(set(names))
        except Exception as e:
            self.log.warning(f"Error in duplicate entries test: {e}")
            return None

    def _test_zip_path_traversal(self):
        """Check for path traversal (../) in ZIP entry names."""
        try:
            for f in self._list_files():
                if ".." in f or f.startswith("/"):
                    return True
            return False
        except Exception as e:
            self.log.warning(f"Error in path traversal test: {e}")
            return None

    def _test_zip_suspicious_timestamps(self):
        """Check for timestamps at epoch (1980) or in the future."""
        try:
            zf = self._get_zip_file()
            if not zf:
                return None
            now = datetime.now()
            with zf:
                for info in zf.infolist():
                    try:
                        dt = datetime(*info.date_time)
                        if dt.year <= 1980 or dt > now:
                            return True
                    except (ValueError, TypeError):
                        continue
            return False
        except Exception as e:
            self.log.warning(f"Error in suspicious timestamps test: {e}")
            return None

    def _test_hidden_dex_files(self):
        """Check for DEX files not matching classes*.dex pattern."""
        try:
            for f in self._list_files():
                if f.endswith(".dex"):
                    basename = f.split("/")[-1]
                    if not STANDARD_DEX_PATTERN.match(basename):
                        return True
            return False
        except Exception as e:
            self.log.warning(f"Error in hidden DEX files test: {e}")
            return None

    def _test_manifest_component_mismatch(self):
        """Check for declared components that don't exist in DEX."""
        try:
            if not self._is_valid_apk():
                return None

            # Get all class names from DEX
            dex_classes = set()
            try:
                from androguard.core.dex import DEX
                for dex_data in (self.apk.get_all_dex() or []):
                    try:
                        d = DEX(dex_data)
                        for cls in d.get_classes():
                            name = cls.get_name()
                            if name:
                                # Convert "Lcom/example/Foo;" to "com.example.Foo"
                                dex_classes.add(
                                    name[1:-1].replace("/", ".") if name.startswith("L") else name
                                )
                    except Exception:
                        continue
            except Exception:
                return None

            if not dex_classes:
                return None

            # Check manifest components against DEX classes
            components = []
            try:
                components.extend(self.apk.get_activities() or [])
                components.extend(self.apk.get_services() or [])
                components.extend(self.apk.get_receivers() or [])
                components.extend(self.apk.get_providers() or [])
            except Exception:
                return None

            for comp in components:
                if comp and comp not in dex_classes:
                    # Component might use a shorthand; check with package prefix
                    package = self.apk.get_package() or ""
                    full_name = package + comp if comp.startswith(".") else comp
                    if full_name not in dex_classes:
                        return True

            return False
        except Exception as e:
            self.log.warning(f"Error in manifest component mismatch test: {e}")
            return None

    def _test_debuggable_release(self):
        """Check android:debuggable=true combined with a release signature."""
        try:
            if not self._is_valid_apk():
                return None

            is_debuggable = self.apk.get_attribute_value(
                "application", "debuggable"
            ) == "true"

            if not is_debuggable:
                return False

            # Check if it has a signing certificate (release builds have certs)
            try:
                certs = self.apk.get_certificates()
                if certs and len(certs) > 0:
                    return True
            except Exception:
                pass

            return False
        except Exception as e:
            self.log.warning(f"Error in debuggable release test: {e}")
            return None

    def _get_dex_strings(self):
        """Get all string constants from DEX files."""
        all_strings = set()
        try:
            from androguard.core.dex import DEX
            for dex_data in (self.apk.get_all_dex() or []):
                try:
                    d = DEX(dex_data)
                    for s in d.get_strings():
                        if s:
                            all_strings.add(s)
                except Exception:
                    continue
        except Exception:
            pass
        return all_strings

    def _test_emulator_detection_strings(self):
        """Check for emulator detection patterns in DEX strings."""
        try:
            if not self._is_valid_apk():
                return None

            dex_strings = self._get_dex_strings()
            for indicator in EMULATOR_INDICATORS:
                for s in dex_strings:
                    if indicator in s:
                        return True
            return False
        except Exception as e:
            self.log.warning(f"Error in emulator detection test: {e}")
            return None

    def _test_debugger_detection(self):
        """Check for debugger detection API calls in DEX."""
        try:
            if not self._is_valid_apk():
                return None

            dex_strings = self._get_dex_strings()
            debugger_patterns = {
                "isDebuggerConnected",
                "waitingForDebugger",
                "Debug.isDebuggerConnected",
            }
            for pattern in debugger_patterns:
                for s in dex_strings:
                    if pattern in s:
                        return True
            return False
        except Exception as e:
            self.log.warning(f"Error in debugger detection test: {e}")
            return None

    def _test_root_detection(self):
        """Check for root detection patterns in DEX."""
        try:
            if not self._is_valid_apk():
                return None

            dex_strings = self._get_dex_strings()
            for indicator in ROOT_INDICATORS:
                for s in dex_strings:
                    if indicator in s:
                        return True
            return False
        except Exception as e:
            self.log.warning(f"Error in root detection test: {e}")
            return None

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

        self.test_results = APKInconsistencyTests(
            test_zip_bomb=self._test_zip_bomb(),
            test_zip_duplicate_entries=self._test_zip_duplicate_entries(),
            test_zip_path_traversal=self._test_zip_path_traversal(),
            test_zip_suspicious_timestamps=self._test_zip_suspicious_timestamps(),
            test_hidden_dex_files=self._test_hidden_dex_files(),
            test_manifest_component_mismatch=self._test_manifest_component_mismatch(),
            test_debuggable_release=self._test_debuggable_release(),
            test_emulator_detection_strings=self._test_emulator_detection_strings(),
            test_debugger_detection=self._test_debugger_detection(),
            test_root_detection=self._test_root_detection(),
        )
        return self.test_results

    def _bool_to_nullable(self, val):
        """Convert bool/None to ClickHouse Nullable(UInt8)."""
        if val is None:
            return None
        return int(val)

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

            current_time = datetime.now(timezone.utc)
            t = self.test_results

            data = [[
                self.sha256,
                self._bool_to_nullable(t.test_zip_bomb),
                self._bool_to_nullable(t.test_zip_duplicate_entries),
                self._bool_to_nullable(t.test_zip_path_traversal),
                self._bool_to_nullable(t.test_zip_suspicious_timestamps),
                self._bool_to_nullable(t.test_hidden_dex_files),
                self._bool_to_nullable(t.test_manifest_component_mismatch),
                self._bool_to_nullable(t.test_debuggable_release),
                self._bool_to_nullable(t.test_emulator_detection_strings),
                self._bool_to_nullable(t.test_debugger_detection),
                self._bool_to_nullable(t.test_root_detection),
                current_time,
            ]]

            column_names = [
                'sha256',
                'test_zip_bomb', 'test_zip_duplicate_entries',
                'test_zip_path_traversal', 'test_zip_suspicious_timestamps',
                'test_hidden_dex_files', 'test_manifest_component_mismatch',
                'test_debuggable_release', 'test_emulator_detection_strings',
                'test_debugger_detection', 'test_root_detection',
                'analysis_date',
            ]

            column_type_names = [
                'FixedString(64)',
                'Nullable(UInt8)', 'Nullable(UInt8)',
                'Nullable(UInt8)', 'Nullable(UInt8)',
                'Nullable(UInt8)', 'Nullable(UInt8)',
                'Nullable(UInt8)', 'Nullable(UInt8)',
                'Nullable(UInt8)', 'Nullable(UInt8)',
                "DateTime64(3, 'UTC')",
            ]

            return (data, column_names, column_type_names)

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