Washington Mio

62 papers A* 2A 1B 14C 2Journal 16Unranked 26
YearRankTypeTitle / Venue / Authors
2024 A* conf
SoCG
Justin Curry, Washington Mio, Tom Needham, Osman Berat Okutan, Florian Russold
2023 J jnl
CoRR
Justin Curry, Washington Mio, Tom Needham, Osman Berat Okutan, Florian Russold
2023 conf
TAG-ML
Justin Curry, Washington Mio, Tom Needham, Osman Berat Okutan, Florian Russold
2023 J jnl
CoRR
Justin Curry, Washington Mio, Tom Needham, Osman Berat Okutan, Florian Russold
2022 J jnl
J. Appl. Comput. Topol.
Justin Curry, Haibin Hang, Washington Mio, Tom Needham, Osman Berat Okutan
2020 B conf
IJCNN
Shaeke Salman, Canlin Zhang, Xiuwen Liu, Washington Mio
2019 J jnl
J. Appl. Comput. Topol.
Haibin Hang, Facundo Mémoli, Washington Mio
2019 J jnl
J. Comput. Appl. Math.
Serdar Cellat, Yu Fan, Washington Mio, Giray Ökten
2019 J jnl
CoRR
Shaeke Salman, Canlin Zhang, Xiuwen Liu, Washington Mio
2014 J jnl
J. Math. Imaging Vis.
Jonathan Bates, Washington Mio
2013 conf
GSI
Diego H. Diaz Martinez, Facundo Mémoli, Washington Mio
2012 J jnl
Comput. J.
Mariano Rivera, Oscar Dalmau Cedeño, Washington Mio, Alonso Ramirez-Manzanares
2011 B conf
IJCNN
Nan Zhao, Washington Mio, Xiuwen Liu
2011 conf
BIBM Workshops
Prabesh Kanel, Xiuwen Liu, Washington Mio
2011 conf
ISBI
Jonathan Bates, Dominic Pafundi, Prabesh Kanel, Xiuwen Liu, Washington Mio
2010 J jnl
Int. J. Comput. Vis.
Xiuwen Liu, Yonggang Shi, Ivo D. Dinov, Washington Mio
2010 conf
ECCV (3)
Xinyang Liu, Xiuwen Liu, Yonggang Shi, Paul M. Thompson, Washington Mio
2010 conf
ISBI
Xiuwen Liu, Yonggang Shi, Ying Wang, Paul M. Thompson, Washington Mio
2010 B conf
ICPR
Yu Fan, David Houle, Washington Mio
2010 conf
CSIIRW
Josef D. Allen, Xiuwen Liu, Liam M. Mayron, Washington Mio
2010 B conf
ICPR
Jonathan Bates, Xiuwen Liu, Washington Mio
2010 conf
ISCIS
Mariano Rivera, Oscar Dalmau Cedeño, Washington Mio
2009 B conf
IJCNN
Yuhua Zhu, Xiuwen Liu, Washington Mio
2009 C conf
ICMLA
Yiming Wu, Xiuwen Liu, Washington Mio
2009 conf
ISBI
Xinyang Liu, Yonggang Shi, Jonathan H. Morra, Xiuwen Liu, Paul M. Thompson, Washington Mio
2009 B conf
IJCNN
Yuhua Zhu, Washington Mio, Xiuwen Liu
2009 conf
ISBI
Jonathan Bates, Ying Wang, Xiuwen Liu, Washington Mio
2009 J jnl
Int. J. Comput. Vis.
Washington Mio, John Christopher Bowers, Xiuwen Liu
2009 conf
ISBI
Yue Qiu, Ying Wang, Xiuwen Liu, Washington Mio
2008 B conf
ICPR
Xiuwen Liu, Arturo Donate, Matthew Jemison, Washington Mio
2008 J jnl
Neural Networks
Yiming Wu, Xiuwen Liu, Washington Mio
2008 conf
MICCAI (2)
Xinyang Liu, Washington Mio, Yonggang Shi, Ivo D. Dinov, Xiuwen Liu, Natasha Leporé, Franco Lepore, Madeleine Fortin, Patrice Voss, Maryse Lassonde, Paul M. Thompson
2008 B conf
ICPR
Yuhua Zhu, Yiming Wu, Xiuwen Liu, Washington Mio
2008 J jnl
Comput. Vis. Image Underst.
Yiming Wu, Xiuwen Liu, Washington Mio, Kyle A. Gallivan
2007 conf
VISAPP (2)
Washington Mio, Yuhua Zhu, Xiuwen Liu
2007 A conf
ICME
Yuhua Zhu, Xiuwen Liu, Washington Mio
2007 A* conf
ICCV
Washington Mio, John Christopher Bowers, Monica K. Hurdal, Xiuwen Liu
2007 B conf
IJCNN
Yiming Wu, Xiuwen Liu, Washington Mio
2007 J jnl
Int. J. Comput. Vis.
Washington Mio, Anuj Srivastava, Shantanu H. Joshi
2007 conf
VISIGRAPP (Selected Papers)
Yuhua Zhu, Washington Mio, Xiuwen Liu
2007 conf
VISAPP (1)
Xiuwen Liu, John Bowers, Washington Mio
2007 C conf
ICMLA
Yiming Wu, Xiuwen Liu, Washington Mio
2006 J jnl
Int. J. Comput. Vis.
Washington Mio, Anuj Srivastava, Xiuwen Liu
2006 B conf
ICIP
Washington Mio, Xiuwen Liu
2006 B conf
ICIP
Keith Haynes, Xiuwen Liu, Washington Mio
2006 ch.
Statistics and Analysis of Shapes
Shantanu H. Joshi, David Kaziska, Anuj Srivastava, Washington Mio
2006 B conf
ICIP
Xiuwen Liu, Washington Mio
2006 B conf
ICIP
Yiming Wu, Xiuwen Liu, Washington Mio, Kyle A. Gallivan
2005 conf
ICIP (2)
Sajjad Baloch, Hamid Krim, Washington Mio, Anuj Srivastava
2005 conf
EMMCVPR
Washington Mio, Dennis Badlyans, Xiuwen Liu
2005 conf
IPMI
Shantanu H. Joshi, Anuj Srivastava, Washington Mio
2005 conf
EMMCVPR
Xiuwen Liu, Washington Mio
2005 conf
EUSIPCO
Washington Mio, Dennis Badlyans, Xiuwen Liu
2005 B conf
IJCNN
Washington Mio, Qiang Zhang, Xiuwcn Liu
2005 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Anuj Srivastava, Shantanu H. Joshi, Washington Mio, Xiuwen Liu
2004 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Eric Klassen, Anuj Srivastava, Washington Mio, Shantanu H. Joshi
2004 conf
CVPR (2)
Washington Mio, Anuj Srivastava
2004 conf
ECCV (3)
Shantanu H. Joshi, Anuj Srivastava, Washington Mio, Xiuwen Liu
2004 conf
ECCV (4)
Washington Mio, Anuj Srivastava, Xiuwen Liu
2004 conf
EUSIPCO
Anuj Srivastava, Washington Mio
2003 conf
NIPS
Anuj Srivastava, Xiuwen Liu, Washington Mio, Eric Klassen
2003 conf
EMMCVPR
Anuj Srivastava, Washington Mio, Eric Klassen, Shantanu H. Joshi
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"