Rahul Thakur

52 papers A* 1A 1B 5C 3Misc 4Journal 27Unranked 11
YearRankTypeTitle / Venue / Authors
2026 J jnl
Veh. Commun.
Srishti Sharma, Rahul Thakur
2026 J jnl
Future Gener. Comput. Syst.
Akshay Singh, Rahul Thakur
2026 J jnl
Int. J. Data Sci. Anal.
Rahul Thakur, J. P. Teshan Kavindu Jayasinghe, Preeti Mehta
2026 J jnl
Future Gener. Comput. Syst.
Akshay Singh, Rahul Thakur
2025 J jnl
IEEE Internet Things J.
Akshay Singh, Rahul Thakur
2025 conf
CCNC
Kanhu Charan Gouda, Rahul Thakur
2025 J jnl
Multim. Tools Appl.
Rahul Thakur, Geeta Sikka, Urvashi Bansal, Jayant P. Giri, Saurav Mallik
2025 C conf
IoTBDS
Srishti Sharma, Rahul Thakur
2025 J jnl
Ad Hoc Networks
Kanhu Charan Gouda, Rahul Thakur
2025 J jnl
Signal Image Video Process.
Kartik Bindra, Hitesh Gupta, Devyansh Bhattacharya, Rahul Thakur
2025 J jnl
Comput. Biol. Chem.
Rahul Thakur, Vibhor Joshi, Ganesh Chandra Sahoo, Rajnarayan R. Tiwari, Sindhuprava Rana
2025 C conf
IoTBDS
Khadijah Febriana R., Rahul Thakur, Sudip Roy
2025 J jnl
Signal Image Video Process.
Rahul Thakur, Rajesh Rohilla
2025 Misc conf
COMSNETS
Harrithha B, Vijeth J. Kotagi, Rahul Thakur
2025 J jnl
J. Internet Serv. Inf. Secur.
R. Karthikeyan, Kanishka Jha, Rahul Thakur, Alakananda Tripathy, Julie Sunil, P. S. Raghavendra Rao
2025 A conf
MSWiM
Sangya Shrivastava, Sreenivasa Reddy Yeduri, Rahul Thakur, Linga Reddy Cenkeramaddi
2024 B conf
WCNC
Kanhu Charan Gouda, Rahul Thakur
2024 J jnl
Signal Image Video Process.
Rahul Thakur, Rajesh Rohilla
2024 B conf
GLOBECOM
Sangya Shrivastava, Rahul Thakur
2024 Misc conf
ICDCN
Kanhu Charan Gouda, Rahul Thakur
2024 C conf
IoTBDS
Khadijah Febriana R., Rahul Thakur, Sudip Roy
2024 conf
NAACL-HLT
Akshay Singh, Rahul Thakur
2024 conf
ICCCNT
Rahul Thakur, Rajesh Rohilla
2024 Misc conf
ICDCN
Sangya Shrivastava, Rahul Thakur
2024 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Arpit Mahajan, Rahul Thakur, Ruchi Das
2024 J jnl
Veh. Commun.
Kanhu Charan Gouda, Sangya Shrivastava, Rahul Thakur
2023 J jnl
IEEE Access
Geraldo F. Oliveira, Saugata Ghose, Juan Gómez-Luna, Amirali Boroumand, Alexis Savery, Sonny Rao, Salman Qazi, Gwendal Grignou, Rahul Thakur, Eric Shiu, Onur Mutlu
2022 conf
CCNC
Rahul Thakur, Swati Agarwal
2022 conf
VTC Fall
Kanhu Charan Gouda, Sangya Shrivastava, Rahul Thakur
2021 J jnl
CoRR
Geraldo F. Oliveira, Saugata Ghose, Juan Gómez-Luna, Amirali Boroumand, Alexis Savery, Sonny Rao, Salman Qazi, Gwendal Grignou, Rahul Thakur, Eric Shiu, Onur Mutlu
2021 conf
HICSS
Bhavye Jain, Kaustubh Trivedi, Swati Agarwal, Rahul Thakur
2021 conf
VTC Spring
Shourya Shukla, Rahul Thakur, Swati Agarwal
2020 conf
VTC Spring
Swati Agarwal, Rahul Thakur, Utkarsh Yadav, Hemant Rathore
2020 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Rahul Thakur, Ruchi Das
2020 J jnl
CoRR
Jason Lowe-Power, Abdul Mutaal Ahmad, Ayaz Akram, Mohammad Alian, Rico Amslinger, Matteo Andreozzi, Adrià Armejach, Nils Asmussen, Srikant Bharadwaj, Gabe Black, Gedare Bloom, Bobby R. Bruce, Daniel Rodrigues Carvalho, Jerónimo Castrillón, Lizhong Chen, Nicolas Derumigny, Stephan Diestelhorst, Wendy Elsasser, Marjan Fariborz, Amin Farmahini Farahani, Pouya Fotouhi, Ryan Gambord, Jayneel Gandhi, Dibakar Gope, Thomas Grass, Bagus Hanindhito, Andreas Hansson, Swapnil Haria, Austin Harris, Timothy Hayes, Adrian Herrera, Matthew Horsnell, Syed Ali Raza Jafri, Radhika Jagtap, Hanhwi Jang, Reiley Jeyapaul, Timothy M. Jones, Matthias Jung, Subash Kannoth, Hamidreza Khaleghzadeh, Yuetsu Kodama, Tushar Krishna, Tommaso Marinelli, Christian Menard, Andrea Mondelli, Tiago Mück, Omar Naji, Krishnendra Nathella, Hoa Nguyen, Nikos Nikoleris, Lena E. Olson, Marc S. Orr, Binh Pham, Pablo Prieto, Trivikram Reddy, Alec Roelke, Mahyar Samani, Andreas Sandberg, Javier Setoain, Boris Shingarov, Matthew D. Sinclair, Tuan Ta, Rahul Thakur, Giacomo Travaglini, Michael Upton, Nilay Vaish, Ilias Vougioukas, Zhengrong Wang, Norbert Wehn, Christian Weis, David A. Wood, Hongil Yoon, Éder F. Zulian
2019 Misc conf
TRIDENTCOM
Swati Agarwal, Rahul Thakur, Sudeepta Mishra
2018 J jnl
IEEE Syst. J.
Rahul Thakur, Siba Narayan Swain, C. Siva Ram Murthy
2018 A* conf
ASPLOS
Amirali Boroumand, Saugata Ghose, Youngsok Kim, Rachata Ausavarungnirun, Eric Shiu, Rahul Thakur, Daehyun Kim, Aki Kuusela, Allan Knies, Parthasarathy Ranganathan, Onur Mutlu
2017 J jnl
IEEE Trans. Green Commun. Netw.
Rahul Thakur, Sudeepta Mishra, C. Siva Ram Murthy
2017 J jnl
Comput. Commun.
Rahul Thakur, Siba Narayan Swain, C. Siva Ram Murthy
2017 J jnl
IEEE Trans. Mob. Comput.
Siba Narayan Swain, Rahul Thakur, Chebiyyam Siva Ram Murthy
2017 J jnl
Comput. Networks
Siba Narayan Swain, Rahul Thakur, C. Siva Ram Murthy
2017 J jnl
IEEE Trans. Veh. Technol.
Moumita Patra, Rahul Thakur, C. Siva Ram Murthy
2017 J jnl
Comput. Networks
Rahul Thakur, Vijeth J. Kotagi, C. Siva Ram Murthy
2016 J jnl
Comput. Commun.
Rahul Thakur, Rajkarn Singh, C. Siva Ram Murthy
2016 J jnl
IEEE Commun. Lett.
Vijeth J. Kotagi, Rahul Thakur, Sudeepta Mishra, Chebiyyam Siva Ram Murthy
2015 B conf
PIMRC
Rahul Thakur, Vijeth J. Kotagi, C. Siva Ram Murthy
2014 conf
VTC Spring
Sudeepta Mishra, Rahul Thakur, C. Siva Ram Murthy
2013 B conf
PIMRC
Rahul Thakur, Sudeepta Mishra, C. Siva Ram Murthy
2013 conf
ICON
Anik Sengupta, Rahul Thakur, C. Siva Ram Murthy
2013 B conf
WiOpt
Rahul Thakur, Anik Sengupta, C. Siva Ram Murthy
2013 conf
ICON
Rahul Thakur, Anik Sengupta, C. Siva Ram Murthy
redb/extractors/apk_extractors/apk_resources.py
← Index redb/extractors/apk_extractors/apk_resources.py python
import hashlib
import inspect
import os
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 APKResource


# ─── Suspicious file types ──────────────────────────────────────────────
# File types that are suspicious when found inside res/ or assets/.
# Excludes javascript/html (extremely common in legitimate hybrid apps)
# and common media/font types that are normal APK content.
SUSPICIOUS_TYPES = {
    # Executables — no legitimate reason in assets/res
    "elf", "pebin", "macho", "dex", "apk",
    # Java containers — DexClassLoader target
    "jar",
    # Archives — rare in legitimate assets (~135:1 malware-to-benign ratio)
    "zip", "gzip", "7z", "xz", "tar", "bzip2", "rar", "7zip", "lzma",
    # Scripts with system execution capability
    "shell", "python", "powershell", "batch",
}

# ─── Entropy thresholds ─────────────────────────────────────────────────
# For unrecognized/unknown types: encrypted payloads typically land > 7.0
ENTROPY_HIGH_UNKNOWN = 7.0
# For recognized-but-non-image types: stricter threshold
ENTROPY_EXTREME = 7.85

# ─── Android-specific binary format magic bytes ─────────────────────────
# These formats are common in legitimate APKs but unknown to Magika,
# causing misclassification (e.g., AXML → "gzip", profm → "unknown").
AXML_MAGIC = b'\x03\x00\x08\x00'       # Android Binary XML (compiled res/*.xml)
ARSC_MAGIC = b'\x02\x00\x0c\x00'       # Android compiled resource table
ART_PROF_MAGIC = b'pro\x00'            # ART baseline profile
ART_PROFM_MAGIC = b'prm\x00'           # ART baseline profile metadata

# ─── Allowlisted paths ──────────────────────────────────────────────────
# Fixed, hardcoded paths in the Android build system that are always benign.
# ART profiles at these exact paths are shipped by Jetpack ProfileInstaller.
ALLOWLISTED_PATHS = {
    "assets/dexopt/baseline.prof",
    "assets/dexopt/baseline.profm",
}

# ─── Image handling ─────────────────────────────────────────────────────
# Magika-confirmed image types: high entropy is expected (lossy codecs
# like VP8/JPEG arithmetic-code toward entropy ~7.95-8.0 by design).
IMAGE_MAGIKA_TYPES = {"png", "webp", "jpeg", "gif", "bmp", "tiff", "ico"}
IMAGE_EXTENSIONS = {".png", ".webp", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".ico"}

# ─── Types Magika assigns when it can't identify the content ────────────
UNRECOGNIZED_MAGIKA_TYPES = {"unknown", "empty"}

# ─── Resource scan limits ───────────────────────────────────────────────
MAX_RESOURCE_FILES = 5000


class APKResourceExtractor(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.resources = []
        self.suspicious_files = []
        self.log.debug(inspect.currentframe().f_code.co_name)

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

    # ─── Core classification logic ──────────────────────────────────────

    def _identify_android_format(self, header: bytes) -> str | None:
        """
        Identify Android-specific binary formats that Magika doesn't know.
        Returns a corrected type label, or None to fall through to Magika.
        """
        if len(header) < 4:
            return None

        magic4 = header[:4]

        # Android Binary XML — all res/*.xml in a compiled APK.
        # Magika often misclassifies this as "gzip".
        if magic4 == AXML_MAGIC:
            return "android_binary_xml"

        # Android compiled resource table (resources.arsc chunks)
        if magic4 == ARSC_MAGIC:
            return "android_resource_table"

        # ART baseline profiles — high entropy (zlib inside) but benign.
        # The format is inert (method reference bitmaps/metadata, not
        # executable code) and some build configs place them at varying paths.
        if magic4 == ART_PROF_MAGIC:
            return "android_art_profile"
        if magic4 == ART_PROFM_MAGIC:
            return "android_art_profile_metadata"

        return None

    def _is_suspicious_resource(
        self, path: str, magika_type: str, entropy: float,
        android_type: str | None,
    ) -> bool:
        """
        Determine if a resource file is suspicious.

        Detection layers:
        1. Allowlisted paths → always benign
        2. Android-specific format override → reclassify Magika mislabels
        3. Image extension vs Magika type mismatch → encrypted blob detection
        4. Magika-confirmed images → benign regardless of entropy
        5. Suspicious type match → flag known-dangerous types
        6. High-entropy unknown blobs → likely encrypted payloads
        """

        # ── Layer 1: Allowlisted paths (hardcoded Android build artifacts) ──
        if path in ALLOWLISTED_PATHS:
            return False

        # ── Layer 2: Android-specific format detection ──────────────────────
        # Override Magika's label for formats it doesn't recognize.
        # All Android-specific formats (AXML, ARSC, ART profiles) are
        # legitimate build artifacts — never suspicious.
        if android_type is not None:
            return False

        # ── Layer 3: Image extension / Magika type mismatch ─────────────────
        # If the file extension claims "image" but Magika's content analysis
        # disagrees, this is a strong signal for an encrypted payload with
        # a fake image extension (e.g., ErrorFather's "rbyypivsnw.png").
        ext = os.path.splitext(path)[1].lower()
        if ext in IMAGE_EXTENSIONS and magika_type not in IMAGE_MAGIKA_TYPES:
            # Exception: Magika might label a valid image as "unknown" if
            # the file is very small (< ~16 bytes). Don't flag tiny files.
            if entropy > 5.0:
                return True

        # ── Layer 4: Magika-confirmed images → benign ───────────────────────
        # Lossy codecs (VP8, JPEG) produce entropy up to ~8.0 by design.
        # If Magika confirms image structure, high entropy is expected.
        if magika_type in IMAGE_MAGIKA_TYPES:
            return False

        # ── Layer 5: Known suspicious file types ────────────────────────────
        if magika_type in SUSPICIOUS_TYPES:
            return True

        # ── Layer 6: High-entropy unrecognized blobs ────────────────────────
        # Files Magika can't identify with high entropy are likely encrypted
        # payloads. Most Android malware packers store encrypted DEX/SO
        # payloads as opaque blobs with random names and no valid magic.
        if magika_type in UNRECOGNIZED_MAGIKA_TYPES and entropy > ENTROPY_HIGH_UNKNOWN:
            return True

        # ── Layer 7: Extreme entropy on any non-image recognized type ───────
        # Catches edge cases where Magika assigns a benign label (e.g.,
        # "xml", "txt") but the entropy is impossibly high for that format.
        if magika_type not in IMAGE_MAGIKA_TYPES and entropy > ENTROPY_EXTREME:
            return True

        return False

    # ─── Extraction pipeline ────────────────────────────────────────────

    def extract(self):
        if not self._is_valid_apk():
            self.log.error(f"Invalid APK for {self.hash.sha256}")
            return None

        try:
            from magika import Magika
            magika = Magika()
        except Exception as e:
            self.log.error(f"Failed to initialize Magika for {self.hash.sha256}: {e}")
            magika = None

        self.resources = []
        self.suspicious_files = []
        scanned = 0

        zf = self._get_zip_file()
        if not zf:
            return None

        with zf:
            for info in zf.infolist():
                if info.is_dir():
                    continue
                if not (info.filename.startswith("res/") or
                        info.filename.startswith("assets/")):
                    continue

                if scanned >= MAX_RESOURCE_FILES:
                    self.log.warning(
                        f"Resource scan limit reached ({MAX_RESOURCE_FILES}), "
                        f"stopping resource enumeration"
                    )
                    break
                scanned += 1

                try:
                    data = zf.read(info.filename)
                except Exception as e:
                    self.log.warning(
                        f"Error reading resource {info.filename}: {e}"
                    )
                    continue

                try:
                    file_sha256 = hashlib.sha256(data).hexdigest()
                    file_entropy = round(self.calculate_entropy(data), 3)

                    # Read first bytes for Android-specific format detection
                    header = data[:16] if len(data) >= 16 else data

                    if magika:
                        try:
                            filetype = magika.identify_bytes(data).output.label
                        except Exception:
                            filetype = "unknown"
                    else:
                        filetype = "unknown"

                    # Identify Android-specific formats once, reuse for
                    # both stored type and suspicion classification
                    android_type = self._identify_android_format(header)
                    stored_type = android_type if android_type else filetype

                    suspicious = self._is_suspicious_resource(
                        path=info.filename,
                        magika_type=filetype,
                        entropy=file_entropy,
                        android_type=android_type,
                    )

                    resource = APKResource(
                        path=info.filename,
                        size=info.file_size,
                        sha256=file_sha256,
                        filetype_magika=stored_type,
                        entropy=file_entropy,
                    )

                    if suspicious:
                        resource.is_suspicious = True
                        self.suspicious_files.append(resource)

                    self.resources.append(resource)
                except Exception as e:
                    self.log.warning(
                        f"Error processing resource {info.filename}: {e}"
                    )
                    continue

        if not self.resources:
            return None

        return {
            "total_resource_count": len(self.resources),
            "total_resource_size": sum(r.size for r in self.resources),
            "suspicious_file_count": len(self.suspicious_files),
            "resources": self.resources,
            "suspicious_files": self.suspicious_files,
        }

    # ─── Export ──────────────────────────────────────────────────────────

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

            current_time = datetime.now(timezone.utc)
            data = []
            for res in self.resources:
                data.append([
                    self.sha256,
                    res.path,
                    res.size,
                    res.sha256,
                    res.filetype_magika,
                    res.entropy,
                    int(res.is_suspicious),
                    current_time,
                ])

            column_names = [
                'sha256', 'resource_path', 'resource_size',
                'resource_sha256', 'resource_magika', 'resource_entropy',
                'is_suspicious', 'analysis_date',
            ]

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

            return (data, column_names, column_type_names)

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