Caitlin Martin

12 papers B 1Journal 3Unranked 8
YearRankTypeTitle / Venue / Authors
2026 J jnl
Interactions
Jessa Dickinson, Sheena Erete, Natasha Smith-Walker, Caitlin Martin, Nichole Pinkard
2025 J jnl
CoRR
Jiasong Chen, Linchen Qian, Ruonan Gong, Christina Sun, Tongran Qin, Thuy Pham, Caitlin Martin, Mohammad Zafar, John A. Elefteriades, Wei Sun, Liang Liang
2025 J jnl
CoRR
Jiasong Chen, Linchen Qian, Ruonan Gong, Christina Sun, Tongran Qin, Thuy Pham, Caitlin Martin, Mohammad Zafar, John A. Elefteriades, Wei Sun, Liang Liang
2020 conf
ICLS
Peter Samuelson Wardrip, Stephanie Chang, Lauren Penney, Samuel Abramovich, Rebecca Millerjohn, Vishesh Kumar, Caitlin Martin, Sari Widman, William R. Penuel, Josephina Chang-Order, Erica Halverson
2020 conf
ICLS
Sheena Lewis Erete, Jessa Dickinson, Caitlin Martin, Anna Bethune, Nichole Pinkard
2020 conf
ICLS
Brigid Barron, Caitlin Martin, Rose K. Pozos
2016 B conf
Image Processing
Liang Liang, Caitlin Martin, Qian Wang, Wei Sun, James S. Duncan
2008 conf
ICLS (3)
Nichole Pinkard, Brigid Barron, Caitlin Martin
2007 conf
CHI Extended Abstracts
Sarah E. Walter, Karin Forssell, Brigid Barron, Caitlin Martin
2006 conf
ICLS
Brigid Barron, Yasmin B. Kafai, Diana M. Joseph, Nichole Pinkard, Mitchel Resnick, Caitlin Martin, Colin Schatz, R. Benjamin Shapiro, Amon Millner, Kylie Peppler, Grace Chiu, Shiu Desai
2004 conf
ICLS
Brigid Barron, Jennifer Tackman, Caitlin Martin, Emma Mercier, Aditja Johri, Zanette Johnson, Susie Wise, Marie White, Sara McPhee, Peter Worth
2002 conf
CSCL
Brigid Barron, Caitlin Martin, Eric Roberts, Alex Osipovich, Michael Ross
redb/extractors/apk_extractors/apk_native_libs.py
← Index redb/extractors/apk_extractors/apk_native_libs.py python
import fnmatch
import hashlib
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 APKNativeLib

# Known packer/protector native library names
KNOWN_PACKER_LIBS = {
    # Jiagu (360/Qihoo)
    "libjiagu.so", "libjiagu_a64.so", "libjiagu_x86.so", "libjiagu_x64.so",
    # Bangcle/SecNeo
    "libsecexe.so", "libsecmain.so", "libSecShell.so",
    # Baidu
    "libbaiduprotect.so",
    # Tencent (Legu)
    "libtxAppProtect.so", "libBugly.so",
    # iJiami
    "libexec.so", "libexecmain.so",
    # Alibaba
    "libmobisec.so", "libaliprotect.so",
    # APKProtect
    "libAPKProtect.so",
    # Pangxie (Pangolin)
    "libdexjni.so",
    # DexProtector
    "libdexprotector.so",
    # AppSolid
    "libAppSolid.so",
    # Kiwisec
    "libkwscmm.so",
    # DingXiang
    "libx3g.so",
    # NQ Shield
    "libnqshield.so",
    # Generic / other
    "libprotectClass.so",
    "libDexHelper.so",
    "libdexloader.so",
    "libfdog.so",
}

# Glob-style patterns for packer libs (e.g. libshella-*.so)
KNOWN_PACKER_PATTERNS = [
    "libshella-*.so",
    "libshell-super.*.so",
]


def is_known_packer_lib(filename):
    """Check if a native library filename matches known packer signatures."""
    if filename in KNOWN_PACKER_LIBS:
        return True
    for pattern in KNOWN_PACKER_PATTERNS:
        if fnmatch.fnmatch(filename, pattern):
            return True
    return False


class APKNativeLibExtractor(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.native_libs = []
        self.abis = set()
        self.log.debug(inspect.currentframe().f_code.co_name)

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

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

        self.native_libs = []
        self.abis = set()

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

        with zf:
            for info in zf.infolist():
                if not (info.filename.startswith("lib/") and info.filename.endswith(".so")):
                    continue
                parts = info.filename.split("/")
                if len(parts) < 3:
                    continue

                abi = parts[1]
                filename = parts[-1]
                self.abis.add(abi)

                try:
                    data = zf.read(info.filename)
                    lib_sha256 = hashlib.sha256(data).hexdigest()
                except Exception as e:
                    self.log.warning(f"Error reading native lib {info.filename}: {e}")
                    continue

                self.native_libs.append(APKNativeLib(
                    abi=abi,
                    filename=filename,
                    size=info.file_size,
                    sha256=lib_sha256,
                    is_known_packer=is_known_packer_lib(filename),
                ))

        if not self.native_libs:
            return None

        return {
            "native_lib_count": len(self.native_libs),
            "abis": sorted(self.abis),
            "native_libs": self.native_libs,
            "known_packer_libs": [
                lib for lib in self.native_libs if lib.is_known_packer
            ],
        }

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

            current_time = datetime.now(timezone.utc)
            data = []
            for lib in self.native_libs:
                data.append([
                    self.sha256,
                    lib.abi,
                    lib.filename,
                    lib.size,
                    lib.sha256,
                    int(lib.is_known_packer),
                    current_time,
                ])

            column_names = [
                'sha256', 'lib_abi', 'lib_filename', 'lib_size',
                'lib_sha256', 'lib_is_known_packer', 'analysis_date',
            ]

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

            return (data, column_names, column_type_names)

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