Camilla Forsell

38 papers B 2C 7Misc 1Journal 9Unranked 17
YearRankTypeTitle / Venue / Authors
2024 conf
EuroVis (Posters)
Ivar Gorenko, Lonni Besançon, Camilla Forsell, Niklas Rönnberg
2021 conf
ECCE
Åsa Svensson, Jonas Lundberg, Camilla Forsell, Niklas Rönnberg
2020 J jnl
Comput. Graph. Forum
Daniel Jönsson, Albin Bergström, Camilla Forsell, Rozalyn Simon, Maria Engström, Susanna Walter, Anders Ynnerman, Ingrid Hotz
2019 conf
IV (1)
Kahin Akram Hassan, Niklas Rönnberg, Camilla Forsell, Matthew Cooper, Jimmy Johansson
2019 conf
VCBM
Daniel Jönsson, Albin Bergström, Camilla Forsell, Rozalyn Simon, Maria Engström, Anders Ynnerman, Ingrid Hotz
2016 J jnl
IEEE Trans. Vis. Comput. Graph.
Jimmy Johansson, Camilla Forsell
2016 conf
BELIV
Prithiviraj K. Muthumanickam, Camilla Forsell, Katerina Vrotsou, Jimmy Johansson, Matthew Cooper
2015 conf
Eurographics (Dirk Bartz Prize)
Anders Ynnerman, Thomas Rydell, Anders Persson, Aron Ernvik, Camilla Forsell, Patric Ljung, Claes Lundström
2014 ch.
Handbook of Human Centric Visualization
Camilla Forsell, Matthew Cooper
2014 J jnl
Inf. Vis.
Jimmy Johansson, Camilla Forsell, Matthew Cooper
2014 conf
BELIV
Alvin Tarrell, Ann L. Fruhling, Rita Borgo, Camilla Forsell, Georges G. Grinstein, Jean Scholtz
2012 C ed.
IV
Ebad Banissi, Stefan Bertschi, Camilla Forsell, Jimmy Johansson, Sarah Kenderdine, Francis T. Marchese, Muhammad Sarfraz, Liz J. Stuart, Anna Ursyn, Theodor G. Wyeld, Hanane Azzag, Mustapha Lebbah, Gilles Venturini
2012 B conf
AVI
Camilla Forsell, Matthew Cooper
2012 C conf
IV
Camilla Forsell
2012 J jnl
IEEE Trans. Vis. Comput. Graph.
Christian Tominski, Camilla Forsell, Jimmy Johansson
2012 conf
BELIV
Camilla Forsell, Matthew Cooper
2012 conf
EuroHaptics (1)
Umut Koçak, Karljohan E. Lundin Palmerius, Camilla Forsell, Matthew Cooper
2011 C ed.
IV
Ebad Banissi, Stefan Bertschi, Remo Aslak Burkhard, Urska Cvek, Martin J. Eppler, Camilla Forsell, Georges G. Grinstein, Jimmy Johansson, Sarah Kenderdine, Francis T. Marchese, Carsten Maple, Marjan Trutschl, Muhammad Sarfraz, Liz J. Stuart, Anna Ursyn, Theodor G. Wyeld
2011 conf
HCI (11)
Katerina Vrotsou, Camilla Forsell
2011 conf
HAID
Umut Koçak, Karljohan E. Lundin Palmerius, Camilla Forsell, Anders Ynnerman, Matthew Cooper
2011 J jnl
IEEE Trans. Vis. Comput. Graph.
Claes Lundström, Thomas Rydell, Camilla Forsell, Anders Persson, Anders Ynnerman
2011 conf
Eurographics (Tutorials)
Camilla Forsell, Matthew Cooper
2010 C ed.
IV
Ebad Banissi, Stefan Bertschi, Remo Aslak Burkhard, John Counsell, Mohammad Dastbaz, Martin J. Eppler, Camilla Forsell, Georges G. Grinstein, Jimmy Johansson, Mikael Jern, Farzad Khosrowshahi, Francis T. Marchese, Carsten Maple, Richard Laing, Urska Cvek, Marjan Trutschl, Muhammad Sarfraz, Liz J. Stuart, Anna Ursyn, Theodor G. Wyeld
2010 J jnl
Inf. Vis.
Katerina Vrotsou, Camilla Forsell, Matthew Cooper
2010 C conf
IV
Camilla Forsell
2010 conf
MedInfo
Isabella Scandurra, Camilla Forsell, Anders Ynnerman, Patric Ljung, Claes Lundström, Anders Persson
2010 B conf
AVI
Camilla Forsell, Jimmy Johansson
2010 conf
VG@Eurographics
Tan Khoa Nguyen, Anders Eklund, Henrik Ohlsson, Frida Hernell, Patric Ljung, Camilla Forsell, Mats T. Andersson, Hans Knutsson, Anders Ynnerman
2009 C ed.
IV
Ebad Banissi, Liz J. Stuart, Theodor G. Wyeld, Mikael Jern, Gennady L. Andrienko, Nasrullah Memon, Reda Alhajj, Remo Aslak Burkhard, Georges G. Grinstein, Dennis P. Groth, Anna Ursyn, Jimmy Johansson, Camilla Forsell, Urska Cvek, Marjan Trutschl, Francis T. Marchese, Carsten Maple, Andrew J. Cowell, Andrew Vande Moere
2009 conf
WHC
Karljohan E. Lundin Palmerius, Camilla Forsell
2008 J jnl
Inf. Vis.
Jimmy Johansson, Camilla Forsell, Mats Lind, Matthew Cooper
2008 C conf
IV
Patrik Lundblad, Mikael Jern, Camilla Forsell
2007
Camilla Forsell
2007 Misc conf
Visualization and Data Analysis
Camilla Forsell, Jimmy Johansson
2006 J jnl
Inf. Vis.
Camilla Forsell, Stefan Seipel, Mats Lind
2005 conf
INFOVIS
Camilla Forsell, Stefan Seipel, Mats Lind
2003 J jnl
Inf. Vis.
Mats Lind, Geoffrey P. Bingham, Camilla Forsell
2002 conf
INFOVIS
Mats Lind, Geoffrey P. Bingham, Camilla Forsell
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"