Magnus Steinby

37 papers A* 1B 3C 1Journal 24Unranked 5
YearRankTypeTitle / Venue / Authors
2024 J jnl
Int. J. Found. Comput. Sci.
Arto Salomaa, Magnus Steinby
2021 J jnl
CoRR
Magnus Steinby
2019 J jnl
CoRR
Eija Jurvanen, Magnus Steinby
2017 J jnl
CoRR
Magnus Steinby
2017 J jnl
Acta Cybern.
Magnus Steinby
2015 J jnl
Acta Cybern.
Magnus Steinby
2015 J jnl
CoRR
Ferenc Gécseg, Magnus Steinby
2015 J jnl
CoRR
Magnus Steinby, Eija Jurvanen, Antonio Cano
2011 J jnl
Fundam. Informaticae
Gabriela Martín, Magnus Steinby
2011 J jnl
Theor. Comput. Sci.
Zoltán Fülöp, Magnus Steinby
2009 J jnl
Theor. Comput. Sci.
Magnus Steinby, Catalin Ionut Tîrnauca
2009 conf
Automata, Formal Languages, and Related Topics
Zoltán Fülöp, Magnus Steinby
2007 C conf
CIAA
Magnus Steinby, Catalin Ionut Tîrnauca
2007 J jnl
Theor. Comput. Sci.
Saeed Salehi, Magnus Steinby
2003 conf
Grammars and Automata for String Processing
Balázs Imreh, Masami Ito, Magnus Steinby
2001 conf
Words, Semigroups, and Transductions
Ferenc Gécseg, Magnus Steinby
2001 J jnl
J. Autom. Lang. Comb.
Tatjana Petkovic, Magnus Steinby
2000 conf
Words, Languages & Combinatorics
Magnus Steinby
1999 J jnl
Acta Cybern.
Balázs Imreh, Magnus Steinby
1999 J jnl
Acta Cybern.
Zoltán Fülöp, Eija Jurvanen, Magnus Steinby, Sándor Vágvölgyi
1999 J jnl
Fundam. Informaticae
Stojan Bogdanovic, Miroslav Ciric, Tatjana Petkovic, Balázs Imreh, Magnus Steinby
1998 J jnl
Theor. Comput. Sci.
Magnus Steinby
1998 B conf
MFCS
Zoltán Fülöp, Eija Jurvanen, Magnus Steinby, Sándor Vágvölgyi
1997 ch.
Handbook of Formal Languages (3)
Ferenc Gécseg, Magnus Steinby
1995 J jnl
Acta Cybern.
Balázs Imreh, Magnus Steinby
1994 conf
Results and Trends in Theoretical Computer Science
Magnus Steinby
1994 J jnl
Theor. Comput. Sci.
Timo Knuutila, Magnus Steinby
1993 J jnl
Fundam. Informaticae
Magnus Steinby
1992 ch.
Tree Automata and Languages
Magnus Steinby
1992 J jnl
Bull. EATCS
Magnus Steinby
1990 J jnl
J. Inf. Process. Cybern.
Magnus Steinby
1989 B conf
FCT
Magnus Steinby
1984 book
Tree Automata
Ferenc Gécseg, Magnus Steinby
1983 J jnl
Theor. Comput. Sci.
Magnus Steinby
1981 B conf
FCT
Magnus Steinby
1978 J jnl
Acta Cybern.
Ferenc Gécseg, Magnus Steinby
1977 A* ed.
ICALP
Arto Salomaa, Magnus Steinby
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"