Hannes Frey

95 papers A* 2A 4B 16C 12Misc 2Journal 19Unranked 36
YearRankTypeTitle / Venue / Authors
2025 B conf
GLOBECOM
Manuel Utsch, Björn Böckling, Konrad Junkes, Sebastian Treib, Wolfgang Kiess, Hannes Frey, Thomas Bauschert, Andreas Baumgartner
2025 C conf
WoWMoM
Iftikhar Ahmed Saeed, Arnova Abdullah, Daniel Schneider, Melanie Reinelt, Simon Pannek, Tim Farnschläder, Hannes Frey, Wolfgang Kiess, Maria A. Wimmer
2025 J jnl
Future Internet
Hamed Khalili, Hannes Frey, Maria A. Wimmer
2024 conf
WMNC
Steffen Böhmer, Sven-Niklas Wollny, Hannes Frey
2024 conf
VMCAI (1)
Lucas Böltz, Viorica Sofronie-Stokkermans, Hannes Frey
2023 A conf
MSWiM
Daniel Schneider, Hannes Frey
2023 C conf
ACC
Christian Hespe, Adwait Datar, Daniel Schneider, Hamideh Saadabadi, Herbert Werner, Hannes Frey
2023 J jnl
CoRR
Lucas Böltz, Viorica Sofronie-Stokkermans, Hannes Frey
2023 conf
ICC
Steffen Böhmer, Hannes Frey
2022 J jnl
Inf.
Lucas Böltz, Hannes Frey
2022 conf
SysCon
Mahdi Razzaghpour, Adwait Datar, Daniel Schneider, Mahdi Zaman, Herbert Werner, Hannes Frey, Javad Mohammadpour Velni, Yaser P. Fallah
2022 B conf
WCNC
Eike Lyczkowski, Tobias W. Weber, Hannes Frey, Wolfgang Kiess
2022 C conf
WoWMoM
Steffen Böhmer, Lucas Böltz, Hannes Frey
2021 conf
CCCG
Hannes Frey, Lucas Böltz
2021 A conf
MSWiM
Hannes Frey, Daniel Schneider
2021 J jnl
CoRR
Mahdi Razzaghpour, Adwait Datar, Daniel Schneider, Mahdi Zaman, Herbert Werner, Hannes Frey, Javad Mohammadpour Velni, Yaser P. Fallah
2021 C conf
LAGOS
Lucas Böltz, Benjamin Becker, Hannes Frey
2021 conf
SOQE@KR
Lucas Böltz, Hannes Frey, Dennis Peuter, Viorica Sofronie-Stokkermans
2021 C conf
ETFA
Eike Lyczkowski, Konrad Junkes, Wolfgang Kiess, Hannes Frey
2021 B conf
PIMRC
Eike Lyczkowski, Christian Sauer, Felix Reichert, Hannes Frey
2021 conf
WMNC
Ahmed Nader al-Dulaimy, Hannes Frey
2020 B conf
PIMRC
Daniel Schneider, Hannes Frey
2020 J jnl
CoRR
Daniel Schneider, Hannes Frey
2020 B conf
WiOpt
Steffen Böhmer, Lucas Böltz, Hannes Frey
2019 C conf
ALGOSENSORS
Lucas Böltz, Hannes Frey
2019 B conf
ICCCN
Daniel Schneider, Hannes Frey
2019 conf
WMNC
Jovan Radak, Daniel Schneider, Christian Henke, Hannes Frey
2019 A conf
MSWiM
Steffen Böhmer, Daniel Schneider, Hannes Frey
2019 conf
WMNC
Ahmed Nader al-Dulaimy, Hannes Frey
2018 J jnl
IEEE Commun. Surv. Tutorials
Dennis Grewe, Marco Wagner, Hannes Frey
2018 C conf
ACC
Adwait Datar, Daniel Schneider, Furugh Mirali, Herbert Werner, Hannes Frey
2018 conf
EuCNC
Dennis Grewe, Andong Tan, Marco Wagner, Sebastian Schildt, Hannes Frey
2018 conf
VTC Spring
Dennis Grewe, Sebastian Schildt, Marco Wagner, Hannes Frey
2018 conf
VNC
Dennis Grewe, Marco Wagner, Sebastian Schildt, Mayutan Arumaithurai, Hannes Frey
2017 conf
NOF
Dennis Grewe, K. P. Pavithra Rao, Sebastian Schildt, Marco Wagner, Dominik Schoop, Hannes Frey
2017 conf
ICC Workshops
Dennis Grewe, Marco Wagner, Hannes Frey
2017 conf
PE-WASUN
Jovan Radak, Lukas Baulig, Dawid Bijak, Christian Schowalter, Hannes Frey
2016 conf
VNC
Dennis Grewe, Marco Wagner, Hannes Frey
2016 conf
ADHOC-NOW
Florentin Neumann, Daniel Vivas Estevao, Frank Ockenfeld, Jovan Radak, Hannes Frey
2015 J jnl
IEEE Commun. Lett.
Florentin Neumann, Hannes Frey
2015 B conf
MASS
Florentin Neumann, Hannes Frey
2015 conf
NetSys
Florentin Neumann, Hannes Frey
2015 Misc conf
SAC
Frank Bohdanowicz, Hannes Frey, Rafael Funke, Dominik Mosen, Florentin Neumann, Ivan Stojmenovic
2014 J jnl
Pervasive Mob. Comput.
Adrian Loch, Hannes Frey, Matthias Hollick
2014 J jnl
Peer-to-Peer Netw. Appl.
Marcus Autenrieth, Hannes Frey
2014 conf
ADHOC-NOW
Florentin Neumann, Christian Botterbusch, Hannes Frey
2013 B conf
DCOSS
Rafael Funke, Hannes Frey
2013 J jnl
IEEE Trans. Parallel Distributed Syst.
Hannes Frey
2013 conf
NetSys
Marcus Autenrieth, Hannes Frey
2013 conf
MSN
Florentin Neumann, Hannes Frey
2013 A* conf
INFOCOM
Markus Benter, Florentin Neumann, Hannes Frey
2012 Misc conf
ICDCN
Emi Mathews, Hannes Frey
2012 C conf
WOWMOM
Hannes Frey, Matthias Hollick, Adrian Loch
2012 B conf
DCOSS
Juergen Eckert, Hermann S. Lichte, Falko Dressler, Hannes Frey
2012 B conf
MASS
Florentin Neumann, Hannes Frey
2012 J jnl
Comput. Commun.
Jiming Chen, Hannes Frey, Xu Li
2012 J jnl
Int. J. Distributed Sens. Networks
Jiming Chen, Hannes Frey, Pedro M. Ruiz, David Simplot-Ryl
2011 conf
KiVS
Hannes Frey, Ranjith Pillay
2011 C conf
WOWMOM
Emi Mathews, Hannes Frey
2011 ed.
ADHOC-NOW
Hannes Frey, Xu Li, Stefan Rührup
2011 B conf
MASS
Hannes Frey, Matthias Hollick, Adrian Loch
2011 C conf
WOWMOM
Hannes Frey
2011 conf
ADHOC-NOW
Marcus Autenrieth, Hannes Frey
2011 J jnl
IEEE Trans. Mob. Comput.
Xu Li, Hannes Frey, Nicola Santoro, Ivan Stojmenovic
2010 conf
PerCom Workshops
Nico Loose, Hannes Frey
2010 A conf
MSWiM
Hannes Frey
2010 B conf
MobiHoc
Hermann S. Lichte, Hannes Frey, Holger Karl
2010 C conf
WOWMOM
Hannes Frey
2010 J jnl
IEEE Trans. Computers
Hannes Frey, Ivan Stojmenovic
2010 conf
ADHOC-NOW
Rafael Funke, Hannes Frey
2009 B conf
EWSN
Hannes Frey, Kristen Pind
2009 B conf
MASS
Xu Li, Hannes Frey, Nicola Santoro, Ivan Stojmenovic
2009 conf
ICC
Xu Li, Hannes Frey, Nicola Santoro, Ivan Stojmenovic
2009 conf
KiVS
Hannes Frey, Stefan Rührup
2009 ch.
Guide to Wireless Sensor Networks
Hannes Frey, Stefan Rührup, Ivan Stojmenovic
2008 conf
ICUIMC
Matthias R. Brust, Hannes Frey, Steffen Rothkugel
2008 C conf
WOWMOM
Hannes Frey, François Ingelrest, David Simplot-Ryl
2008 J jnl
ACM SIGMOBILE Mob. Comput. Commun. Rev.
Xu Li, Hannes Frey, Nicola Santoro, Ivan Stojmenovic
2007 conf
Mobility Conference
Matthias R. Brust, Hannes Frey, Steffen Rothkugel
2007 conf
GI Jahrestagung (1)
Alexander Höhfeld, Hannes Frey, Peter Sturm
2007 conf
Annual Simulation Symposium
Daniel Görgen, Hannes Frey, Christian Hiedels
2006 J jnl
IEEE Trans. Parallel Distributed Syst.
Hannes Frey, Daniel Görgen
2006
Hannes Frey
2006 A* conf
MobiCom
Hannes Frey, Ivan Stojmenovic
2005 ch.
Handbook of Sensor Networks
Hannes Frey, Ivan Stojmenovic
2005 conf
ICDCS Workshops
Hannes Frey, Daniel Görgen
2005 B conf
MASS
Hannes Frey
2005 conf
KiVS
Daniel Görgen, Hannes Frey, Christian Hutter
2005 J jnl
Ad Hoc Networks
Hannes Frey, Daniel Görgen
2004 J jnl
A Generic Background Dissemination Service for Mobile Ad-Hoc Networks
Universität Trier, Mathematik/Informatik, Forschungsbericht
Hannes Frey, Johannes K. Lehnert, Daniel Görgen, Peter Sturm
2004 conf
Wireless Information Systems
Hannes Frey, Daniel Görgen, Johannes K. Lehnert, Peter Sturm
2004 J jnl
IEEE Netw.
Hannes Frey
2004 B conf
KES
Peter Sturm, Hannes Frey, Daniel Görgen, Johannes K. Lehnert
2003 conf
FIDJI
Hannes Frey, Daniel Görgen, Johannes K. Lehnert, Peter Sturm
2003 conf
KiVS
Daniel Görgen, Hannes Frey, Johannes K. Lehnert, Peter Sturm
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"