James R. Hopgood

69 papers B 4C 5Misc 8Journal 27Unranked 24
YearRankTypeTitle / Venue / Authors
2025 conf
SSP
Qing Li, Runze Gan, James R. Hopgood, Michael E. Davies, Simon J. Godsill
2025 J jnl
CoRR
Qing Li, Runze Gan, James R. Hopgood, Michael E. Davies, Simon J. Godsill
2025 J jnl
Comput. Biol. Medicine
Mehmet Demirel, Bethany Mills, Erin Gaughan, Kevin Dhaliwal, James R. Hopgood
2025 B conf
WCNC
Muhammad Nafees, Mohammadamin Baniasadi, James R. Hopgood, Majid Safari, John S. Thompson
2025 B conf
PIMRC
Muhammad Nafees, Mohammadamin Baniasadi, James R. Hopgood, Majid Safari, John S. Thompson
2025 C conf
FUSION
Runze Gan, Qing Li, James R. Hopgood, Mike E. Davies, Simon J. Godsill
2024 J jnl
IEEE Trans. Biomed. Eng.
Ali Taimori, Bethany Mills, Erin Gaughan, Ali Aysha, Kevin Dhaliwal, Gareth O. S. Williams, Neil Finlayson, James R. Hopgood
2024 conf
EUSIPCO
Mehmet Demirel, Bethany Mills, Erin Gaughan, Kevin Dhaliwal, James R. Hopgood
2024 conf
EMBC
Mehmet Demirel, Bethany Mills, Erin Gaughan, Kevin Dhaliwal, James R. Hopgood
2024 J jnl
IEEE Trans. Image Process.
Mehmet Demirel, Bethany Mills, Erin Gaughan, Kevin Dhaliwal, James R. Hopgood
2024 J jnl
CoRR
Isabel Schlangen, André Brandenburger, Mengwei Sun, James R. Hopgood
2024 conf
VTC Fall
Muhammad Nafees, John S. Thompson, James R. Hopgood
2024 conf
ICBBT
Qiang Wang, James R. Hopgood, Marta Vallejo
2024 C conf
FUSION
James S. Wright, Mengwei Sun, Mike E. Davies, Ian K. Proudler, James R. Hopgood
2024 conf
EMBC
Tarek Haloubi, Spencer A. Thomas, Catherine Hines, Kevin Dhaliwal, James R. Hopgood
2023 J jnl
IEEE Trans. Signal Process.
Mengwei Sun, Mike E. Davies, Ian K. Proudler, James R. Hopgood
2022 J jnl
CoRR
Mengwei Sun, Mike E. Davies, Ian K. Proudler, James R. Hopgood
2022 J jnl
Neural Comput. Appl.
Qiang Wang, James R. Hopgood, Susan Fernandes, Neil Finlayson, Gareth O. S. Williams, Ahsan R. Akram, Kevin Dhaliwal, Marta Vallejo
2022 J jnl
IEEE Signal Process. Lett.
Mengwei Sun, Mike E. Davies, Ian K. Proudler, James R. Hopgood
2022 J jnl
CoRR
Qiang Wang, Susan Fernandes, Gareth O. S. Williams, Neil Finlayson, Ahsan R. Akram, Kevin Dhaliwal, James R. Hopgood, Marta Vallejo
2022 J jnl
IEEE Trans. Biomed. Eng.
Ali Taimori, Duncan Humphries, Gareth O. S. Williams, Kevin Dhaliwal, Neil Finlayson, James R. Hopgood
2022 conf
MFI
Sofie Macdonald, Ian K. Proudler, Michael E. Davies, James R. Hopgood
2021 C conf
FUSION
Mengwei Sun, Michael E. Davies, James R. Hopgood, Ian K. Proudler
2021 conf
Computer-Aided Diagnosis
Qiang Wang, James R. Hopgood, Marta Vallejo
2021 J jnl
IEEE Trans. Aerosp. Electron. Syst.
David Cormack, James R. Hopgood
2021 conf
EMBC
Qiang Wang, James R. Hopgood, Marta Vallejo
2021 J jnl
IEEE ACM Trans. Audio Speech Lang. Process.
Elizabeth Vargas, James R. Hopgood, Keith E. Brown, Kartic Subr
2020 conf
EMBC
Qiang Wang, James R. Hopgood, Neil Finlayson, Gareth O. S. Williams, Susan Fernandes, Elvira Williams, Ahsan R. Akram, Kevin Dhaliwal, Marta Vallejo
2020 J jnl
IEEE Trans. Aerosp. Electron. Syst.
David Cormack, Isabel Schlangen, James R. Hopgood, Daniel E. Clark
2019 J jnl
IEEE Trans. Mob. Comput.
Saurav Sthapit, John Thompson, Neil M. Robertson, James R. Hopgood
2019 J jnl
IEEE Trans. Biomed. Eng.
James R. Hopgood, Matthew Connelly, Barry McHoull, Darren Troy
2019 C conf
FUSION
David Cormack, James R. Hopgood
2018 conf
EUSIPCO
Elizabeth Vargas, James R. Hopgood, Keith E. Brown, Kartic Subr
2018 J jnl
IEEE Trans. Signal Process.
Steven Herbert, James R. Hopgood, Bernard Mulgrew
2018 J jnl
IEEE Trans. Signal Process.
Steven Herbert, James R. Hopgood, Bernard Mulgrew
2018 Misc conf
ICASSP
Steven Herbert, James R. Hopgood, Bernard Mulgrew
2018 J jnl
IEEE Access
Konstantinos Diamantis, Aris Dermitzakis, James R. Hopgood, Vassilis Sboros
2017 conf
EUSIPCO
Saurav Sthapit, James R. Hopgood, John Thompson
2016 conf
EUSIPCO
Ebtihal H. G. Yousif, James R. Hopgood, John S. Thompson, Mike E. Davies
2016 J jnl
CoRR
Puneet S. Chhabra, Andrew M. Wallace, James R. Hopgood
2016 conf
EUSIPCO
James R. Hopgood
2016 conf
EUSIPCO
Saurav Sthapit, James R. Hopgood, Neil M. Robertson, John Thompson
2016 J jnl
Signal Process.
Eleonora D'Arca, Neil M. Robertson, James R. Hopgood
2016 Misc conf
ICASSP
Konstantinos Diamantis, Maruf A. Dhali, Gavin Gibson, Yan Yan, James R. Hopgood, Vassilis Sboros
2015 J jnl
IEEE ACM Trans. Audio Speech Lang. Process.
Xionghu Zhong, James R. Hopgood
2014 Misc conf
ICASSP
Eleonora D'Arca, Neil M. Robertson, James R. Hopgood
2014 J jnl
Signal Process.
Xionghu Zhong, James R. Hopgood
2013 conf
EUSIPCO
Ashley Hughes, James R. Hopgood, Neil M. Robertson
2013 Misc conf
ICASSP
Eleonora D'Arca, Neil M. Robertson, James R. Hopgood
2013 B conf
ICIP
Eleonora D'Arca, Ashley Hughes, Neil M. Robertson, James R. Hopgood
2011 J jnl
EURASIP J. Adv. Signal Process.
Yan Yan, James R. Hopgood, Vassilis Sboros
2011 J jnl
J. Signal Process. Syst.
Christine Evers, James R. Hopgood
2010 conf
EUSIPCO
Christine Evers, James R. Hopgood
2010 ch.
Speech Dereverberation
James R. Hopgood, Christine Evers, Steven A. Fortune
2009 conf
EUSIPCO
Christine Evers, James R. Hopgood
2008 Misc conf
ICASSP
Yan Yan, James R. Hopgood, Vassilis Sboros
2008 Misc conf
ICASSP
Christine Evers, James R. Hopgood, Jerome Bell
2008 B conf
ICIP
Tom E. Bishop, Rafael Molina, James R. Hopgood
2008 C conf
ISCAS
Christine Evers, James R. Hopgood, Judith Bell
2008 conf
EUSIPCO
Sharad Nagappa, James R. Hopgood
2008 Misc conf
ICASSP
Xionghu Zhong, James R. Hopgood
2008 conf
EUSIPCO
Steven A. Fortune, James R. Hopgood
2007 conf
ICIP (1)
Tom E. Bishop, Rafael Molina, James R. Hopgood
2006 conf
ICASSP (2)
Tom E. Bishop, James R. Hopgood
2005 conf
EUSIPCO
James R. Hopgood
2003 conf
ICASSP (6)
James R. Hopgood, Peter J. W. Rayner
2003 J jnl
IEEE Trans. Speech Audio Process.
James R. Hopgood, Peter J. W. Rayner
2003 J jnl
IEEE Trans. Signal Process.
James R. Hopgood, Peter J. W. Rayner
1999 Misc conf
ICASSP
James R. Hopgood, Peter J. W. Rayner
redb/extractors/apk_extractors/apk_features.py
← Index redb/extractors/apk_extractors/apk_features.py python
import inspect
import zipfile
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 APKFeatures


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

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

    def _extract_zip_timestamps(self):
        """Extract earliest and latest content modification from ZIP entries."""
        earliest = None
        latest = None
        try:
            zf = self._get_zip_file()
            if zf:
                with zf:
                    for info in zf.infolist():
                        try:
                            dt = datetime(*info.date_time)
                            if earliest is None or dt < earliest:
                                earliest = dt
                            if latest is None or dt > latest:
                                latest = dt
                        except (ValueError, TypeError):
                            continue
        except Exception as e:
            self.log.warning(f"Error extracting ZIP timestamps: {e}")
        return (
            earliest.isoformat() if earliest else None,
            latest.isoformat() if latest else None,
        )

    def _extract_supported_abis(self):
        """Determine supported ABIs from lib/ directory."""
        abis = set()
        for f in self._list_files():
            if f.startswith("lib/") and f.endswith(".so"):
                parts = f.split("/")
                if len(parts) >= 3:
                    abis.add(parts[1])
        return sorted(abis)

    def _count_dex_files(self):
        """Count DEX files and compute total size."""
        dex_count = 0
        total_size = 0
        try:
            zf = self._get_zip_file()
            if zf:
                with zf:
                    for info in zf.infolist():
                        if info.filename.endswith(".dex"):
                            dex_count += 1
                            total_size += info.file_size
        except Exception as e:
            self.log.warning(f"Error counting DEX files: {e}")
        return dex_count, total_size

    def _check_embedded_apk(self):
        """Check if the archive contains nested APK files."""
        for f in self._list_files():
            if f.lower().endswith(".apk"):
                return True
        return False

    def _safe_extract(self, field_name, func, default=None):
        """Extract a single field, logging and returning default on failure."""
        try:
            return func()
        except Exception as e:
            self.log.warning(
                f"Error extracting APK field '{field_name}' for "
                f"{self.hash.sha256}: {e}"
            )
            return default

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

        package_name = self._safe_extract(
            "package_name", lambda: self.apk.get_package()
        )
        app_name = self._safe_extract(
            "app_name", lambda: self.apk.get_app_name()
        )

        def _get_version_code():
            try:
                return int(self.apk.get_androidversion_code() or 0)
            except (ValueError, TypeError):
                return 0

        version_code = self._safe_extract("version_code", _get_version_code)
        version_name = self._safe_extract(
            "version_name", lambda: self.apk.get_androidversion_name()
        )

        def _get_sdk(getter):
            val = getter()
            return int(val) if val else None

        min_sdk = self._safe_extract(
            "min_sdk_version", lambda: _get_sdk(self.apk.get_min_sdk_version)
        )
        target_sdk = self._safe_extract(
            "target_sdk_version", lambda: _get_sdk(self.apk.get_target_sdk_version)
        )
        compile_sdk = self._safe_extract(
            "compile_sdk_version",
            lambda: _get_sdk(self.apk.get_effective_target_sdk_version),
        )

        main_activity = self._safe_extract(
            "main_activity", lambda: self.apk.get_main_activity()
        )

        is_debuggable = self._safe_extract(
            "is_debuggable",
            lambda: self.apk.get_attribute_value(
                "application", "debuggable"
            ) == "true",
            False,
        )
        allow_backup = self._safe_extract(
            "allow_backup",
            lambda: self.apk.get_attribute_value(
                "application", "allowBackup"
            ) != "false",
            True,
        )
        uses_cleartext = self._safe_extract(
            "uses_cleartext_traffic",
            lambda: self.apk.get_attribute_value(
                "application", "usesCleartextTraffic"
            ) == "true",
            False,
        )

        supported_abis = self._safe_extract(
            "supported_abis", self._extract_supported_abis, []
        )
        dex_count, total_dex_size = self._safe_extract(
            "dex_files", self._count_dex_files, (0, 0)
        )
        all_files = self._safe_extract("file_list", self._list_files, [])
        total_file_count = len(all_files)
        has_native_code = any(
            f.startswith("lib/") and f.endswith(".so") for f in all_files
        )
        has_assets = any(f.startswith("assets/") for f in all_files)
        contains_embedded_apk = self._safe_extract(
            "contains_embedded_apk", self._check_embedded_apk, False
        )

        uses_libraries = self._safe_extract(
            "uses_libraries",
            lambda: list(self.apk.get_libraries() or []),
            [],
        )

        earliest_mod, latest_mod = self._safe_extract(
            "zip_timestamps", self._extract_zip_timestamps, (None, None)
        )

        self.apk_features = APKFeatures(
            package_name=package_name,
            app_name=app_name,
            version_code=version_code,
            version_name=version_name,
            min_sdk_version=min_sdk,
            target_sdk_version=target_sdk,
            compile_sdk_version=compile_sdk,
            main_activity=main_activity,
            is_debuggable=is_debuggable,
            allow_backup=allow_backup,
            uses_cleartext_traffic=uses_cleartext,
            supported_abis=supported_abis,
            dex_count=dex_count,
            total_dex_size=total_dex_size,
            total_file_count=total_file_count,
            has_native_code=has_native_code,
            has_assets=has_assets,
            uses_libraries=uses_libraries,
            earliest_content_modification=earliest_mod,
            latest_content_modification=latest_mod,
            contains_embedded_apk=contains_embedded_apk,
        )
        return self.apk_features

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

            f = self.apk_features
            current_time = datetime.now(timezone.utc)
            data = [[
                self.sha256,
                f.package_name,
                f.app_name,
                f.version_code,
                f.version_name,
                f.min_sdk_version,
                f.target_sdk_version,
                f.compile_sdk_version,
                f.main_activity,
                int(f.is_debuggable),
                int(f.allow_backup),
                int(f.uses_cleartext_traffic),
                f.supported_abis,
                f.dex_count,
                f.total_dex_size,
                f.total_file_count,
                int(f.has_native_code),
                int(f.has_assets),
                f.uses_libraries,
                f.earliest_content_modification,
                f.latest_content_modification,
                int(f.contains_embedded_apk),
                current_time,
            ]]

            column_names = [
                "sha256",
                "package_name", "app_name", "version_code", "version_name",
                "min_sdk_version", "target_sdk_version", "compile_sdk_version",
                "main_activity",
                "is_debuggable", "allow_backup", "uses_cleartext_traffic",
                "supported_abis",
                "dex_count", "total_dex_size", "total_file_count",
                "has_native_code", "has_assets",
                "uses_libraries",
                "earliest_content_modification", "latest_content_modification",
                "contains_embedded_apk",
                "analysis_date",
            ]

            column_type_names = [
                "FixedString(64)",
                "Nullable(String)", "Nullable(String)", "Nullable(UInt32)", "Nullable(String)",
                "Nullable(UInt16)", "Nullable(UInt16)", "Nullable(UInt16)",
                "Nullable(String)",
                "UInt8", "UInt8", "UInt8",
                "Array(String)",
                "UInt16", "UInt64", "UInt32",
                "UInt8", "UInt8",
                "Array(String)",
                "Nullable(String)", "Nullable(String)",
                "UInt8",
                "DateTime64(3, 'UTC')",
            ]

            return (data, column_names, column_type_names)

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