Kainam Thomas Wong

84 papers A 1B 6Misc 7Journal 59Unranked 11
YearRankTypeTitle / Venue / Authors
2025 A conf
INTERSPEECH
Dengjian Zhou, Jianghan Hai, Sijia Liao, Yue Ivan Wu, Kainam Thomas Wong, Xiujuan Zheng
2025 J jnl
IEEE Wirel. Commun. Lett.
Hasan Saeed Mir, Lutfi Albasha, Kainam Thomas Wong
2025 J jnl
IEEE Access
Dominic Makaa Kitavi, Kainam Thomas Wong, Yue Ivan Wu, Charles Hung Lee
2025 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Jia Sharon Zheng, Kainam Thomas Wong
2024 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Yue Ivan Wu, Kainam Thomas Wong
2024 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Jia Sharon Zheng, Kainam Thomas Wong, Chibuzo Joseph Nnonyelu, Yang Song
2023 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Abeer Nasir Chaudhry, Hasan Saeed Mir, Kainam Thomas Wong
2023 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Yazan Youssef, Hasan Saeed Mir, Lutfi Albasha, Kainam Thomas Wong
2023 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Junlong Chen, Kainam Thomas Wong, Zakayo Ndiku Morris
2023 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Hao Yang, Kainam Thomas Wong, Zakayo Ndiku Morris
2022 J jnl
IEEE Access
Muhammad Muaz, Shiu-Keung Tang, Tsair-Chuan Lin, Kainam Thomas Wong, Ho Ting Ng
2022 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Yi Zhang, Kainam Thomas Wong
2021 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Lin Yang, Kainam Thomas Wong, Zakayo Ndiku Morris
2021 J jnl
IET Signal Process.
Tsair-Chuan Lin, Kainam Thomas Wong
2021 J jnl
IET Signal Process.
Tsair-Chuan Lin, Kainam Thomas Wong
2021 J jnl
Circuits Syst. Signal Process.
Yue Ivan Wu, Kainam Thomas Wong
2019 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Zakayo Ndiku Morris, Kainam Thomas Wong
2018 J jnl
IEEE Trans. Signal Process.
Kainam Thomas Wong, Chibuzo Joseph Nnonyelu, Yue Ivan Wu
2018 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Dominic Makaa Kitavi, Kainam Thomas Wong, Chun-Chiu Hung
2016 J jnl
Signal Process.
Tsair-Chuan Lin, Kainam Thomas Wong
2015 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Yang Song, Yiu Lung Li, Kainam Thomas Wong
2015 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Yang Song, Kainam Thomas Wong
2015 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Hasan Saeed Mir, Kainam Thomas Wong
2015 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Sebastian Miron, Yang Song, David Brie, Kainam Thomas Wong
2015 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Andriy Yakovych Olenko, Kainam Thomas Wong
2015 J jnl
IEEE Veh. Technol. Mag.
Matthias Pätzold, Alain Sibille, Kainam Thomas Wong, Alenka G. Zajic
2014 J jnl
IEEE Trans. Signal Process.
Yang Song, Kainam Thomas Wong, Fangjiong Chen
2014 J jnl
IET Signal Process.
Yang Song, Kainam Thomas Wong, Yung-Fang Chen
2014 J jnl
IEEE Trans. Signal Process.
Ping Kwan Tam, Kainam Thomas Wong, Yang Song
2014 J jnl
IEEE Trans. Signal Process.
Yang Song, Xin Yuan, Kainam Thomas Wong
2013 conf
CAMSAP
Sebastian Miron, Yang Song, David Brie, Kainam Thomas Wong
2013 J jnl
Trans. Emerg. Telecommun. Technol.
Andriy Yakovych Olenko, Kainam Thomas Wong, Sajjad Ahmed Qasmi
2013 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Mohamad Khattar Awad, Kainam Thomas Wong
2013 J jnl
IET Commun.
Yeong-Tzay Su, Yang Song, Kainam Thomas Wong
2013 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Andriy Yakovych Olenko, Kainam Thomas Wong
2013 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Yang Song, Kainam Thomas Wong
2012 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Yang Song, Kainam Thomas Wong
2012 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Yue Ivan Wu, Kainam Thomas Wong
2012 J jnl
IEEE Trans. Commun.
Cheng-Siang Wang, Meihui Guo, Kainam Thomas Wong, Vladimir I. Piterbarg
2012 J jnl
Phys. Commun.
Khoa Le, Sebastian Miron, Kainam Thomas Wong
2012 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Mohamad Khattar Awad, Kainam Thomas Wong
2012 J jnl
IEEE Trans. Commun.
Liang-Ching Lin, Meihui Guo, Kainam Thomas Wong
2012 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Lina Yeh, Kainam Thomas Wong, Hasan Saeed Mir
2011 J jnl
IEEE Trans. Signal Process.
Kainam Thomas Wong, Xin Yuan
2010 J jnl
IEEE Trans. Veh. Technol.
Yue Ivan Wu, Siu-Kit Lau, Kainam Thomas Wong, Shiu-Keung Tang
2010 J jnl
IEEE Trans. Commun.
Yeong-Tzay Su, Kainam Thomas Wong, Keang-Po Ho
2010 J jnl
IEEE Trans. Veh. Technol.
Kainam Thomas Wong
2010 J jnl
IEEE Trans. Commun.
Jerry Chi-Ling Lam, Kainam Thomas Wong, Yue Ivan Wu
2010 J jnl
IEEE Trans. Signal Process.
Yue Ivan Wu, Kainam Thomas Wong, Siu-Kit Lau
2009 conf
EUSIPCO
Yin-Ray Huang, Carrson C. Fung, Kainam Thomas Wong
2009 J jnl
IEEE Signal Process. Lett.
Yin-Ray Huang, Carrson C. Fung, Kainam Thomas Wong
2009 J jnl
IEEE Trans. Commun.
Kainam Thomas Wong, Yue Ivan Wu
2007 J jnl
Eur. Trans. Telecommun.
Kainam Thomas Wong
2006 B conf
GLOBECOM
Andriy Yakovych Olenko, Kainam Thomas Wong, Sajjad Ahmed Qasmi
2006 J jnl
IEEE Trans. Wirel. Commun.
Kainam Thomas Wong, Petr Tichavský, Shun Keung Cheung, Guisheng Liao
2005 J jnl
IEEE Trans. Signal Process.
Petr Tichavský, Kainam Thomas Wong
2005 J jnl
IEEE Signal Process. Lett.
Andriy Yakovych Olenko, Kainam Thomas Wong, M. Abdulla
2005 conf
ICIP (3)
Edmund Hui-On Ng, Kainam Thomas Wong, Jerry Chi-Ling Lam
2004 J jnl
IEEE Commun. Lett.
Kainam Thomas Wong, Shun Keung Cheung
2004 B conf
GLOBECOM
Andriy Yakovych Olenko, Kainam Thomas Wong, Javad Ahmadi-Shokouh
2004 conf
ICC
Vladimir I. Piterbarg, Kainam Thomas Wong
2004 J jnl
IEEE Trans. Signal Process.
Petr Tichavský, Kainam Thomas Wong
2003 B conf
GLOBECOM
Kainam Thomas Wong, Petr Tichavský
2003 conf
ISCAS (2)
Kainam Thomas Wong, S. L. A. Chan, Rafael P. Torres
2003 conf
ICC
Petr Tichavský, Kainam Thomas Wong
2002 Misc conf
ICASSP
Kainam Thomas Wong, Shun Keung Cheung
2002 B conf
GLOBECOM
Kainam Thomas Wong
2002 Misc conf
ICASSP
Petr Tichavský, Kainam Thomas Wong
2001 conf
ICC
Kainam Thomas Wong, Guisheng Liao, Shun Keung Cheung, Michael D. Zoltowski, Javier Ramos, Pak-Chung Ching
2001 J jnl
IEEE Trans. Signal Process.
Petr Tichavský, Kainam Thomas Wong, Michael D. Zoltowski
2000 Misc conf
ICASSP
Kin-Fai To, Kainam Thomas Wong, Kon Max Wong
2000 J jnl
IEEE Trans. Signal Process.
Michael D. Zoltowski, Kainam Thomas Wong
2000 J jnl
IEEE Trans. Signal Process.
Michael D. Zoltowski, Kainam Thomas Wong
2000 B conf
GLOBECOM
Kainam Thomas Wong, Albert Lai
2000 Misc conf
ICASSP
Wing-Kit Chung, Kainam Thomas Wong
1999 conf
ISCAS (3)
Kainam Thomas Wong
1999 B conf
WCNC
Kainam Thomas Wong
1999 conf
ISCAS (3)
Kainam Thomas Wong
1999 J jnl
IEEE Trans. Signal Process.
Kainam Thomas Wong, Michael D. Zoltowski
1998 conf
ICC
Kainam Thomas Wong
1998 Misc conf
ICASSP
Kainam Thomas Wong, Michael D. Zoltowski
1997 Misc conf
ICASSP
Kainam Thomas Wong, Michael D. Zoltowski
1997 conf
ICC (1)
Kainam Thomas Wong, Michael D. Zoltowski
1996 Misc conf
ICASSP
Kainam Thomas Wong, Michael D. Zoltowski
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"