Kai Geissdoerfer

18 papers A* 2A 1Misc 6Journal 3Unranked 6
YearRankTypeTitle / Venue / Authors
2025 A conf
MobiSys
Kai Geissdoerfer, Ingmar Splitt, Matthias Sokolowski, Carsten Herrmann, Jonas Kubicki, Jasper de Winkel, Marco Zimmerling
2024 Misc conf
SenSys
Kai Geissdoerfer, Marco Zimmerling
2024 Misc conf
SenSys
Kai Geissdoerfer, Marco Zimmerling
2023 conf
IPSN
Kai Geissdoerfer, Ingmar Splitt, Marco Zimmerling
2022 Misc conf
NSDI
Kai Geissdoerfer, Marco Zimmerling
2021 Misc conf
NSDI
Kai Geissdoerfer, Marco Zimmerling
2021 A* conf
PerCom
Muhammad Moid Sandhu, Sara Khalifa, Kai Geissdoerfer, Raja Jurdak, Marius Portmann
2020 conf
IPSN
Kai Geissdoerfer, Friedrich Schmidt, Brano Kusy, Marco Zimmerling
2020 J jnl
IEEE Trans. Mob. Comput.
Philipp Sommer, Kai Geissdoerfer, Raja Jurdak, Branislav Kusy, Jiajun Liu, Kun Zhao, Adam McKeown, David Westcott
2020 J jnl
GetMobile Mob. Comput. Commun.
Kai Geissdoerfer, Mikolaj Chwalisz, Marco Zimmerling
2020 A* conf
PerCom
Muhammad Moid Sandhu, Kai Geissdoerfer, Sara Khalifa, Raja Jurdak, Marius Portmann, Brano Kusy
2020 conf
PerCom Workshops
Muhammad Moid Sandhu, Kai Geissdoerfer, Sara Khalifa, Raja Jurdak, Marius Portmann, Brano Kusy
2019 Misc conf
SenSys
Kai Geissdoerfer, Mikolaj Chwalisz, Marco Zimmerling
2019 conf
IPSN
Kai Geissdoerfer, Raja Jurdak, Brano Kusy, Marco Zimmerling
2019 Misc conf
SenSys
Kai Geissdoerfer, Mikolaj Chwalisz, Marco Zimmerling
2019 conf
INFOCOM Workshops
Mikolaj Chwalisz, Kai Geissdoerfer, Adam Wolisz
2018 conf
IPSN
Kai Geissdoerfer, Raja Jurdak, Brano Kusy
2017 J jnl
Sensors
Maik Pflugradt, Kai Geissdoerfer, Matthias Goernig, Reinhold Orglmeister
tests/unit/test_decompile_strings.py
← Index tests/unit/test_decompile_strings.py python
"""Unit tests for bninja/analysis/strings.py — StringAnalysis."""
import pytest
import math
from unittest.mock import MagicMock


# StringAnalysis has no binaryninja imports, just collections and math
from redb.extractors.decompiler.bninja.analysis.strings import StringAnalysis


# ============================================================================
# Helper mocks
# ============================================================================

class MockStringEntry:
    """Mock for a Binary Ninja string reference."""
    def __init__(self, value, raw=None, start=0, length=0, type_name="Utf8String"):
        self.value = value
        self.raw = raw if raw is not None else (value.encode("utf-8") if isinstance(value, str) else value)
        self.start = start
        self.length = length if length else len(self.raw)
        self.type = MagicMock()
        self.type.name = type_name


class MockBinaryView:
    """Mock binary view with a strings list."""
    def __init__(self, strings=None):
        self.strings = strings or []


# ============================================================================
# 6a. StringAnalysis
# ============================================================================


class TestStringAnalysisEntropy:
    def setup_method(self):
        self.sa = StringAnalysis(bv=MockBinaryView(), functions=[])

    def test_entropy_empty_string(self):
        assert self.sa.entropy("") == 0.0

    def test_entropy_single_char(self):
        assert self.sa.entropy("aaaa") == 0.0

    def test_entropy_uniform_distribution(self):
        # "abcd" -> 4 unique chars, each p=1/4, entropy = log2(4) = 2.0
        result = self.sa.entropy("abcd")
        assert result == pytest.approx(2.0)

    def test_entropy_binary_string(self):
        # "ab" -> 2 unique chars, each p=1/2, entropy = log2(2) = 1.0
        result = self.sa.entropy("ab")
        assert result == pytest.approx(1.0)


class TestStringAnalysisAnalyze:
    def test_analyze_deduplication(self):
        """Duplicate (string, encoding) pairs -> only first kept."""
        entries = [
            MockStringEntry("hello", start=100, type_name="Utf8String"),
            MockStringEntry("hello", start=200, type_name="Utf8String"),
        ]
        bv = MockBinaryView(strings=entries)
        sa = StringAnalysis(bv=bv, functions=[])
        result = sa.analyze()
        assert len(result) == 1
        assert result[0]["string_offset"] == 100

    def test_analyze_sorted_by_address(self):
        """First occurrence (lowest offset) is the one kept."""
        entries = [
            MockStringEntry("world", start=500, type_name="Utf8String"),
            MockStringEntry("world", start=100, type_name="Utf8String"),
        ]
        bv = MockBinaryView(strings=entries)
        sa = StringAnalysis(bv=bv, functions=[])
        result = sa.analyze()
        assert len(result) == 1
        # The analyze() sorts by start, so 100 comes first
        assert result[0]["string_offset"] == 100

    def test_analyze_empty_bv(self):
        bv = MockBinaryView(strings=[])
        sa = StringAnalysis(bv=bv, functions=[])
        result = sa.analyze()
        assert result == []

    def test_analyze_output_schema(self):
        entries = [MockStringEntry("test_string", start=0, type_name="Utf8String")]
        bv = MockBinaryView(strings=entries)
        sa = StringAnalysis(bv=bv, functions=[])
        result = sa.analyze()
        assert len(result) == 1
        r = result[0]
        required_keys = [
            "string",
            "string_raw",
            "string_encoding",
            "string_offset",
            "string_length",
            "string_raw_length",
            "string_entropy",
        ]
        for key in required_keys:
            assert key in r, f"Missing key: {key}"