Rajshekar Kalayappan

21 papers A 1B 2Misc 1Journal 12Unranked 5
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Chirantan Hebballi, Akash Poptani, Amrutha Benny, Rajshekar Kalayappan, Sandeep Chandran, Ramchandra Phawade
2025 J jnl
ACM Trans. Archit. Code Optim.
Shruthi Karunakar, Rajshekar Kalayappan, Sandeep Chandran
2024 conf
ACM Great Lakes Symposium on VLSI
Shruthi Karunakar, Meenakshi Atkade, Akash Poptani, Rajshekar Kalayappan, Sandeep Chandran
2024 conf
HIPCW
Shruthi Karunakar, Rajshekar Kalayappan
2024 B conf
ASPDAC
C. Harshitha, Sundarapalli Harikrishna, Peddakotla Rohith, Sandeep Chandran, Rajshekar Kalayappan
2024 B conf
RV
Amrutha Benny, Sandeep Chandran, Rajshekar Kalayappan, Ramchandra Phawade, Piyush P. Kurur
2023 J jnl
CoRR
Rajshekar Kalayappan, Sandeep Chandran
2023 Misc conf
VLSID
Akash Poptani, Abhishek Mittal, Rishit Saiya, Rajshekar Kalayappan, Sandeep Chandran
2021 J jnl
IEEE Trans. Dependable Secur. Comput.
Rajshekar Kalayappan, Smruti R. Sarangi
2021 J jnl
ACM Comput. Surv.
Hadi Brais, Rajshekar Kalayappan, Preeti Ranjan Panda
2020 J jnl
ACM Trans. Model. Comput. Simul.
Rajshekar Kalayappan, Avantika Chhabra, Smruti R. Sarangi
2018 J jnl
ACM Trans. Embed. Comput. Syst.
Rajshekar Kalayappan, Smruti R. Sarangi
2017 A conf
DATE
Srishty Patel, Rajshekar Kalayappan, Ishani Mahajan, Smruti R. Sarangi
2017 J jnl
ACM Trans. Model. Comput. Simul.
Geetika Malhotra, Rajshekar Kalayappan, Seep Goel, Pooja Aggarwal, Abhishek Sagar, Smruti R. Sarangi
2016 J jnl
ACM Trans. Archit. Code Optim.
Rajshekar Kalayappan, Smruti R. Sarangi
2016 conf
ISVLSI
Rajshekar Kalayappan, Smruti R. Sarangi
2015 conf
ISVLSI
Rajshekar Kalayappan, Smruti R. Sarangi
2015 J jnl
CoRR
Smruti R. Sarangi, Rajshekar Kalayappan, Prathmesh Kallurkar, Seep Goel
2015 conf
PATMOS
Smruti R. Sarangi, Rajshekar Kalayappan, Prathmesh Kallurkar, Seep Goel, Eldhose Peter
2014 J jnl
Secur. Commun. Networks
Amitabha Bagchi, Rajshekar Kalayappan, Surabhi Sankhla
2013 J jnl
ACM Comput. Surv.
Rajshekar Kalayappan, Smruti R. Sarangi
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"