Nadine Martin

34 papers A 1Misc 8Journal 15Unranked 10
YearRankTypeTitle / Venue / Authors
2018 J jnl
Signal Process.
Nadine Martin, Corinne Mailhes
2016 J jnl
IEEE Trans. Signal Process.
Zhongyang Li, Nadine Martin
2015 J jnl
IEEE Trans. Ind. Electron.
Timothée Gerber, Nadine Martin, Corinne Mailhes
2014 J jnl
IEEE Trans. Signal Process.
Julien Huillery, Fabien Millioz, Nadine Martin
2013 J jnl
IEEE Trans. Signal Process.
Matthieu Sanquer, Florent Chatelain, Mabrouka El-Guedri, Nadine Martin
2013 Misc conf
ICASSP
Matthieu Sanquer, Florent Chatelain, Mabrouka El-Guedri, Nadine Martin
2012 Misc conf
ICASSP
Jan Jagla, Julien Maillard, Nadine Martin
2011 Misc conf
ICASSP
Matthieu Sanquer, Florent Chatelain, Mabrouka El-Guedri, Nadine Martin
2011 J jnl
IEEE Trans. Signal Process.
Fabien Millioz, Nadine Martin
2010 Misc conf
ICASSP
Fabien Millioz, Nadine Martin
2008 J jnl
Signal Process.
Meryem Jabloun, Nadine Martin, François Léonard, Michelle Vieira
2008 J jnl
IEEE Trans. Signal Process.
Julien Huillery, Fabien Millioz, Nadine Martin
2007 J jnl
IEEE Trans. Signal Process.
Meryem Jabloun, François Léonard, Michelle Vieira, Nadine Martin
2006 conf
EUSIPCO
Corinne Mailhes, Nadine Martin, Kheira Sahli, Gerard Lejeune
2006 conf
ICASSP (3)
Julien Huillery, Fabien Millioz, Nadine Martin
2006 conf
ICASSP (3)
Fabien Millioz, Julien Huillery, Nadine Martin
2005 conf
EUSIPCO
Meryem Jabloun, Nadine Martin, Michelle Vieira, François Léonard
2004 conf
EUSIPCO
Michelle Vieira, François Léonard, Meryem Jabloun, Nadine Martin
2002 J jnl
Signal Process.
Benoit Leprettre, Nadine Martin
2002 Misc conf
ICASSP
Cyril Hory, Nadine Martin
2002 conf
EUSIPCO
Cyril Hory, Nadine Martin
2002 conf
EUSIPCO
Francois Combet, Nadine Martin, Pierre Jaussaud
2002 J jnl
IEEE Trans. Signal Process.
Cyril Hory, Nadine Martin, Alain Chéhikian
2000 J jnl
Signal Process.
Matthieu Durnerin, Nadine Martin
2000 A conf
INTERSPEECH
Nadine Martin, Eleanor M. Saffran, Gary S. Dell, Myrna F. Schwartz, Prahlad Gupta
2000 conf
EUSIPCO
Cyril Hory, Nadine Martin, Alain Chéhikian, Lars Erik Solberg
2000 conf
EUSIPCO
Hélène Cottereau, Manuel Davy, Christian Doncarli, Nadine Martin
1998 J jnl
IEEE Trans. Signal Process.
Benoit Leprettre, Nadine Martin, F. Glangeaud, J.-P. Navarre
1998 conf
EUSIPCO
Manuel Davy, Benoit Leprettre, Christian Doncarli, Nadine Martin
1995 J jnl
IEEE Trans. Signal Process.
Nadine Martin, Jérôme I. Mars, Jacques Martin, Cecile Chorier
1992 J jnl
Signal Process.
Jérôme I. Mars, Nadine Martin, Jean-Louis Lacoume, M. Dubesset
1987 Misc conf
ICASSP
M. A. Pallas, Nadine Martin, J. Martin
1982 Misc conf
ICASSP
J. P. Benoist, F. Glangeaud, Nadine Martin, Jean-Louis Lacoume, C. Lorius, A. Ait Ouahman
1982 Misc conf
ICASSP
F. Glangeaud, Mohamed Gharbi, Nadine Martin, Jean-Louis Lacoume
redb/extractors/apk_extractors/apk_permissions.py
← Index redb/extractors/apk_extractors/apk_permissions.py python
import inspect
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 APKPermissions, APKPermission

# Known dangerous permissions (Android runtime permissions)
DANGEROUS_PERMISSIONS = {
    "android.permission.READ_CALENDAR",
    "android.permission.WRITE_CALENDAR",
    "android.permission.CAMERA",
    "android.permission.READ_CONTACTS",
    "android.permission.WRITE_CONTACTS",
    "android.permission.GET_ACCOUNTS",
    "android.permission.ACCESS_FINE_LOCATION",
    "android.permission.ACCESS_COARSE_LOCATION",
    "android.permission.ACCESS_BACKGROUND_LOCATION",
    "android.permission.RECORD_AUDIO",
    "android.permission.READ_PHONE_STATE",
    "android.permission.READ_PHONE_NUMBERS",
    "android.permission.CALL_PHONE",
    "android.permission.ANSWER_PHONE_CALLS",
    "android.permission.ADD_VOICEMAIL",
    "android.permission.USE_SIP",
    "android.permission.BODY_SENSORS",
    "android.permission.SEND_SMS",
    "android.permission.RECEIVE_SMS",
    "android.permission.READ_SMS",
    "android.permission.RECEIVE_WAP_PUSH",
    "android.permission.RECEIVE_MMS",
    "android.permission.READ_EXTERNAL_STORAGE",
    "android.permission.WRITE_EXTERNAL_STORAGE",
    "android.permission.READ_MEDIA_IMAGES",
    "android.permission.READ_MEDIA_VIDEO",
    "android.permission.READ_MEDIA_AUDIO",
    "android.permission.POST_NOTIFICATIONS",
    "android.permission.NEARBY_WIFI_DEVICES",
    "android.permission.ACTIVITY_RECOGNITION",
    "android.permission.BLUETOOTH_SCAN",
    "android.permission.BLUETOOTH_ADVERTISE",
    "android.permission.BLUETOOTH_CONNECT",
}


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

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

    def _get_protection_level(self, perm_name):
        """Determine the protection level of a permission.

        Uses androguard's permission mappings first, falls back to the
        known dangerous list.
        """
        try:
            from androguard.core.api_specific_resources import load_permission_mappings
            target_sdk = self.apk.get_target_sdk_version()
            sdk = int(target_sdk) if target_sdk else 30
            permission_map = load_permission_mappings(sdk)
            if perm_name in permission_map:
                info = permission_map[perm_name]
                if isinstance(info, dict):
                    return info.get("protectionLevel", "unknown")
                return "unknown"
        except Exception:
            pass

        # Fallback to known dangerous set
        if perm_name in DANGEROUS_PERMISSIONS:
            return "dangerous"
        if perm_name.startswith("android.permission."):
            return "normal"
        return "unknown"

    def _compute_permhash(self):
        """Compute permhash using the permhash library."""
        try:
            from permhash.functions import permhash_apk
            return permhash_apk(self.filepath)
        except Exception as e:
            self.log.warning(f"Failed to compute permhash: {e}")
            return None

    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 permissions 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

        requested_perms = self._safe_extract(
            "requested_permissions",
            lambda: list(self.apk.get_permissions() or []), []
        )
        custom_perms = self._safe_extract(
            "custom_permissions",
            lambda: list(self.apk.get_declared_permissions() or []), []
        )
        custom_perm_set = set(custom_perms)

        permission_details = []
        dangerous_permissions = []

        for perm in requested_perms:
            try:
                protection_level = self._get_protection_level(perm)
                is_custom = perm in custom_perm_set

                permission_details.append(APKPermission(
                    permission_name=perm,
                    protection_level=protection_level,
                    is_custom=is_custom,
                ))

                if protection_level == "dangerous":
                    dangerous_permissions.append(perm)
            except Exception as e:
                self.log.warning(
                    f"Error processing permission '{perm}' for "
                    f"{self.hash.sha256}: {e}"
                )
                permission_details.append(APKPermission(
                    permission_name=perm,
                    protection_level="unknown",
                    is_custom=perm in custom_perm_set,
                ))

        permhash_value = self._compute_permhash()

        self.permissions_data = APKPermissions(
            total_permission_count=len(requested_perms),
            dangerous_permission_count=len(dangerous_permissions),
            permissions=requested_perms,
            dangerous_permissions=dangerous_permissions,
            custom_permissions=custom_perms,
            permission_details=permission_details,
            permhash=permhash_value,
        )
        return self.permissions_data

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

            current_time = datetime.now(timezone.utc)

            # One row per permission
            data = []
            for detail in self.permissions_data.permission_details:
                data.append([
                    self.sha256,
                    detail.permission_name,
                    detail.protection_level,
                    int(detail.is_custom),
                    current_time,
                ])

            if not data:
                return None

            column_names = [
                'sha256', 'permission_name', 'protection_level',
                'is_custom', 'analysis_date',
            ]

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

            return (data, column_names, column_type_names)

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