Xiaojing Yan

18 papers Misc 1Journal 14Unranked 3
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Commun. Lett.
Xiaojing Yan, Saeed Razavikia, Carlo Fischione
2025 J jnl
Quantum Inf. Process.
Xiaojing Yan, Xiao Sun, Mingming Du, Jiashan Tang
2025 J jnl
Int. J. Appl. Earth Obs. Geoinformation
Yang Liu, Xiaoyang Ma, Lulu An, Hong Sun, Fangkui Zhao, Xiaojing Yan, Yuntao Ma, Minzan Li
2025 J jnl
IEEE Trans. Commun.
Xiaojing Yan, Saeed Razavikia, Carlo Fischione
2025 J jnl
Quantum Inf. Process.
Haojian Li, Xiaojing Yan
2024 conf
ICC
Xiaojing Yan, Saeed Razavikia, Carlo Fischione
2024 J jnl
Briefings Bioinform.
Xin Liu, Yu Pang, Junqi Shan, Yunfei Wang, Yanhua Zheng, Yuhang Xue, Xuerong Zhou, Wenjun Wang, Yanlai Sun, Xiaojing Yan, Jiantao Shi, Xiaoxue Wang, Hongcang Gu, Fan Zhang
2024 J jnl
Comput. Electron. Agric.
Yang Liu, Mingjia Liu, Guohui Liu, Hong Sun, Lulu An, Ruomei Zhao, Weijie Tang, Fangkui Zhao, Xiaojing Yan, Yuntao Ma, Minzan Li
2024 J jnl
Comput. Electron. Agric.
Yang Liu, Guohui Liu, Hong Sun, Lulu An, Ruomei Zhao, Mingjia Liu, Weijie Tang, Minzan Li, Xiaojing Yan, Yuntao Ma, Fangkui Zhao
2024 J jnl
Educ. Inf. Technol.
Ahmad Affandi Supli, Xiaojing Yan
2024 J jnl
Comput. Electron. Agric.
Peng Wei, Xiaojing Yan, Wentao Yan, Lina Sun, Jun Xu, Huizhu Yuan
2023 J jnl
Earth Sci. Informatics
Qingbo Yan, Haowen Yan, Liming Zhang, Xiaolong Wang, Pengbo Li, Xiaojing Yan
2022 J jnl
Soft Comput.
Xiaojing Yan, Xiangfeng Yang, Peng Zhang, Ziqian Zhang
2020 J jnl
Quantum Inf. Process.
Xiaojing Yan, Zhi Yin, Longsuo Li
2019 Misc conf
ISKE
Xiaojing Yan, Huawei Wang, Qiang Fu, Jianhua Zhao
2018 J jnl
IEEE Commun. Lett.
Xiaojing Yan, Hui Tian, Cheng Qin, Arogyswami Paul
2017 conf
VTC Spring
Xiaojing Yan, Hui Tian, Cheng Qin
2008 conf
CSSE (1)
Hua Dong, Xiaojing Yan, Fengqin Chao, Ying Li
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"