Vincent Langenfeld

16 papers A 2B 7Journal 1Unranked 5
YearRankTypeTitle / Venue / Authors
2026 B conf
REFSQ
Nico Hauff, Elisabeth Henkel, Elisabeth Fünfgeld, Vincent Langenfeld, Andreas Podelski
2026 B conf
REFSQ
Tobias Kolzer, Vincent Langenfeld, Nico Hauff, Elisabeth Henkel, Andreas Podelski
2025 conf
REFSQ Workshops
Nico Hauff, Elisabeth Henkel, Tobias Kolzer, Vincent Langenfeld, Andreas Podelski
2024 A conf
RE
Elisabeth Henkel, Nico Hauff, Lena Funk, Vincent Langenfeld, Andreas Podelski
2024 J jnl
Requir. Eng.
Elisabeth Henkel, Nico Hauff, Vincent Langenfeld, Lukas Eber, Andreas Podelski
2023 B conf
REFSQ
Elisabeth Henkel, Nico Hauff, Lukas Eber, Vincent Langenfeld, Andreas Podelski
2023
Vincent Langenfeld
2022 conf
HICSS
Daniel Dietsch, Vincent Langenfeld
2021 B conf
CogSci
Vincent Langenfeld, Bernd Westphal, Andreas Podelski
2021 conf
REFSQ Workshops
Samuel Becker, Daniel Dietsch, Nico Hauff, Elisabeth Henkel, Vincent Langenfeld, Andreas Podelski, Bernd Westphal
2019 B conf
CogSci
Vincent Langenfeld, Bernd Westphal, Andreas Podelski
2019 A conf
RE
Vincent Langenfeld, Daniel Dietsch, Bernd Westphal, Jochen Hoenicke, Amalinda Post
2018 B conf
CogSci
Vincent Langenfeld, Bernd Westphal, Rebecca Albrecht, Andreas Podelski
2018 conf
Spatial Cognition
Rul von Stülpnagel, Vincent Langenfeld, Christoph Hölscher
2016 B conf
REFSQ
Vincent Langenfeld, Amalinda Post, Andreas Podelski
2015 conf
CAV (1)
Daniel Dietsch, Matthias Heizmann, Vincent Langenfeld, Andreas Podelski
redb/extractors/decompiler/apk/apktool_wrapper.py
← Index redb/extractors/decompiler/apk/apktool_wrapper.py python
"""Apktool disassembler subprocess wrapper.

Manages apktool subprocess execution for smali disassembly,
following the CAPA extractor subprocess pattern.
"""

import os
import signal
import subprocess
from typing import List, Optional


class ApktoolDisassembler:
    """Subprocess wrapper for apktool smali disassembly."""

    def __init__(
        self, apktool_path: str = None, timeout: int = None, log=None
    ):
        self.apktool_path = apktool_path or os.getenv("APKTOOL_PATH", "apktool")
        self.timeout = timeout or int(os.getenv("APKTOOL_TIMEOUT", "120"))
        self.log = log

    def disassemble(self, apk_path: str, output_dir: str) -> bool:
        """Run apktool disassembly on an APK file.

        Returns True on success, False on failure.
        """
        cmd = [
            self.apktool_path,
            "d",
            "--no-res",
            "--force",
            "--output", output_dir,
            apk_path,
        ]

        try:
            process = subprocess.Popen(
                cmd,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                preexec_fn=os.setsid,
            )

            try:
                stdout, stderr = process.communicate(timeout=self.timeout)
                if process.returncode != 0:
                    if self.log:
                        self.log.warning(
                            f"apktool returned non-zero exit code {process.returncode}: "
                            f"{stderr[:500] if stderr else 'no stderr'}"
                        )
                    return False
                return True

            except subprocess.TimeoutExpired:
                if self.log:
                    self.log.error(
                        f"apktool timed out after {self.timeout}s"
                    )
                try:
                    os.killpg(os.getpgid(process.pid), signal.SIGTERM)
                    process.wait(timeout=3)
                except (ProcessLookupError, subprocess.TimeoutExpired):
                    try:
                        os.killpg(os.getpgid(process.pid), signal.SIGKILL)
                    except ProcessLookupError:
                        pass
                return False

        except FileNotFoundError:
            if self.log:
                self.log.error(
                    f"apktool not found at '{self.apktool_path}'. "
                    "Install apktool or set APKTOOL_PATH env var."
                )
            return False
        except Exception as e:
            if self.log:
                self.log.error(f"apktool execution error: {e}")
            return False

    def get_smali_directories(self, output_dir: str) -> List[str]:
        """Return paths to all smali output directories.

        Handles multi-DEX: smali/, smali_classes2/, smali_classes3/, etc.
        """
        smali_dirs = []
        if not os.path.isdir(output_dir):
            return smali_dirs

        for entry in sorted(os.listdir(output_dir)):
            if entry == "smali" or entry.startswith("smali_classes"):
                full_path = os.path.join(output_dir, entry)
                if os.path.isdir(full_path):
                    smali_dirs.append(full_path)

        return smali_dirs