Rainer Steinwandt

158 papers A* 2A 4B 9C 6Misc 6Journal 113Unranked 15
YearRankTypeTitle / Venue / Authors
2024 conf
ASIACRYPT (8)
Christopher Battarbee, Giacomo Borin, Julian Brough, Ryann Cartor, Tobias Hemmert, Nadia Heninger, David Jao, Delaram Kahrobaei, Laura Maddison, Edoardo Persichetti, Angela Robinson, Daniel Smith-Tone, Rainer Steinwandt
2024 J jnl
IACR Cryptol. ePrint Arch.
Christopher Battarbee, Giacomo Borin, Ryann Cartor, Nadia Heninger, David Jao, Laura Maddison, Edoardo Persichetti, Angela Robinson, Daniel Smith-Tone, Rainer Steinwandt
2023 J jnl
Dagstuhl Reports
Gorjan Alagic, María Naya-Plasencia, Rainer Steinwandt, Manasi Shingane
2021 J jnl
Dagstuhl Reports
Stacey Jeffery, Michele Mosca, María Naya-Plasencia, Rainer Steinwandt
2020 J jnl
Symmetry
Jens-Matthias Bohli, María Isabel González Vasco, Rainer Steinwandt
2020 J jnl
Informatica
María Isabel González Vasco, Angel L. Pérez del Pozo, Rainer Steinwandt
2019 J jnl
Symmetry
Kenneth Matheis, Rainer Steinwandt, Adriana Suárez Corona
2019 J jnl
Entropy
Edoardo Persichetti, Rainer Steinwandt, Adriana Suárez Corona
2019 J jnl
Entropy
Hai Pham, Rainer Steinwandt, Adriana Suárez Corona
2019 J jnl
Int. J. Appl. Math. Comput. Sci.
Jens-Matthias Bohli, María Isabel González Vasco, Rainer Steinwandt
2019 C ed.
PQCrypto
Jintai Ding, Rainer Steinwandt
2019 J jnl
Dagstuhl Reports
Michele Mosca, María Naya-Plasencia, Rainer Steinwandt
2019 J jnl
IACR Cryptol. ePrint Arch.
Brandon Langenberg, Hai Pham, Rainer Steinwandt
2018 J jnl
Cryptogr.
María Isabel González Vasco, Angela Robinson, Rainer Steinwandt
2018 J jnl
IACR Trans. Cryptogr. Hardw. Embed. Syst.
Okan Seker, Abraham Fernandez-Rubio, Thomas Eisenbarth, Rainer Steinwandt
2018 C ed.
PQCrypto
Tanja Lange, Rainer Steinwandt
2017 J jnl
IACR Cryptol. ePrint Arch.
Okan Seker, Thomas Eisenbarth, Rainer Steinwandt
2017 J jnl
Adv. Math. Commun.
Paolo D'Arco, María Isabel González Vasco, Angel L. Pérez del Pozo, Claudio Soriente, Rainer Steinwandt
2017 J jnl
Dagstuhl Reports
Michele Mosca, Nicolas Sendrier, Rainer Steinwandt, Krysta M. Svore
2016 C conf
PQCrypto
Markus Grassl, Brandon Langenberg, Martin Roetteler, Rainer Steinwandt
2016 J jnl
Inf. Comput.
María Isabel González Vasco, Florian Hess, Rainer Steinwandt
2016 J jnl
Cryptologia
Shane Kepley, David Russo, Rainer Steinwandt
2016 J jnl
IEEE Trans. Inf. Forensics Secur.
Cong Chen, Thomas Eisenbarth, Ingo von Maurich, Rainer Steinwandt
2015 J jnl
Inf. Process. Lett.
Martin Rötteler, Rainer Steinwandt
2015 J jnl
CoRR
Markus Grassl, Brandon Langenberg, Martin Roetteler, Rainer Steinwandt
2015 J jnl
Quantum Inf. Process.
Parshuram Budhathoki, Rainer Steinwandt
2015 J jnl
IACR Cryptol. ePrint Arch.
Shane Kepley, David Russo, Rainer Steinwandt
2015 B conf
ACNS
Cong Chen, Thomas Eisenbarth, Ingo von Maurich, Rainer Steinwandt
2015 book
María Isabel González Vasco, Rainer Steinwandt
2015 Misc conf
SAC
Cong Chen, Thomas Eisenbarth, Ingo von Maurich, Rainer Steinwandt
2015 J jnl
IACR Cryptol. ePrint Arch.
Cong Chen, Thomas Eisenbarth, Ingo von Maurich, Rainer Steinwandt
2015 J jnl
IACR Cryptol. ePrint Arch.
Thomas Eisenbarth, Aaron Meyerowitz, Rainer Steinwandt
2015 J jnl
Inf. Process. Lett.
Thomas Eisenbarth, Aaron Meyerowitz, Rainer Steinwandt
2015 J jnl
Dagstuhl Reports
Michele Mosca, Martin Roetteler, Nicolas Sendrier, Rainer Steinwandt
2015 J jnl
Quantum Inf. Process.
Shane Kepley, Rainer Steinwandt
2014 J jnl
Quantum Inf. Comput.
Martin Rötteler, Rainer Steinwandt
2014 J jnl
IACR Cryptol. ePrint Arch.
Cong Chen, Thomas Eisenbarth, Ingo von Maurich, Rainer Steinwandt
2014 Misc conf
SCN
David Naccache, Rainer Steinwandt, Adriana Suárez Corona, Moti Yung
2014 J jnl
Appl. Algebra Eng. Commun. Comput.
Rainer Steinwandt, Adriana Suárez Corona
2014 J jnl
Int. J. Inf. Sec.
Weizheng Gao, Kashi Neupane, Rainer Steinwandt
2013 J jnl
CoRR
Martin Roetteler, Rainer Steinwandt
2013 J jnl
IACR Cryptol. ePrint Arch.
Martin Roetteler, Rainer Steinwandt
2013 J jnl
CoRR
Martin Roetteler, Rainer Steinwandt
2013 J jnl
Quantum Inf. Comput.
Brittanney Amento, Martin Rötteler, Rainer Steinwandt
2013 J jnl
Theor. Comput. Sci.
Lee Klingler, Rainer Steinwandt, Dominique Unruh
2013 J jnl
Dagstuhl Reports
Serge Fehr, Michele Mosca, Martin Rötteler, Rainer Steinwandt
2013 J jnl
Quantum Inf. Comput.
Brittanney Amento, Martin Rötteler, Rainer Steinwandt
2012 J jnl
CoRR
Brittanney Amento, Rainer Steinwandt, Martin Roetteler
2012 B conf
CANS
Kashi Neupane, Rainer Steinwandt, Adriana Suárez Corona
2012 J jnl
Des. Codes Cryptogr.
Rainer Steinwandt, Adriana Suárez Corona
2012 J jnl
Int. J. Comput. Math.
Vladimir Bozovic, Daniel Socek, Rainer Steinwandt, Viktória I. Villányi
2012 J jnl
CoRR
Brittanney Amento, Martin Roetteler, Rainer Steinwandt
2012 conf
FPS
Kashi Neupane, Rainer Steinwandt, Adriana Suárez Corona
2012 J jnl
IACR Cryptol. ePrint Arch.
Kashi Neupane, Rainer Steinwandt, Adriana Suárez Corona
2012 J jnl
Des. Codes Cryptogr.
Madeline González Muñiz, Rainer Steinwandt
2011 B conf
CT-RSA
Kashi Neupane, Rainer Steinwandt
2011 J jnl
Adv. Math. Commun.
Rainer Steinwandt, Adriana Suárez Corona
2011 J jnl
J. Cryptol.
Markus Grassl, Ivana Ilic, Spyros S. Magliveras, Rainer Steinwandt
2011 J jnl
Integr.
Kris Gaj, Rainer Steinwandt
2011 J jnl
Dagstuhl Reports
Serge Fehr, Michele Mosca, Martin Rötteler, Rainer Steinwandt
2010 J jnl
Appl. Algebra Eng. Commun. Comput.
Rainer Steinwandt
2010 J jnl
Adv. Math. Commun.
Rainer Steinwandt, Adriana Suárez Corona
2010 J jnl
IACR Cryptol. ePrint Arch.
Rainer Steinwandt, Adriana Suárez Corona
2010 J jnl
Trans. Comput. Sci.
Willi Geiselmann, Kenneth Matheis, Rainer Steinwandt
2010 C conf
SECRYPT
Kashi Neupane, Rainer Steinwandt
2010 J jnl
Des. Codes Cryptogr.
Ronald C. Mullin, Rainer Steinwandt
2009 Misc conf
ICISC
Madeline González Muñiz, Rainer Steinwandt
2009 J jnl
IACR Cryptol. ePrint Arch.
Madeline González Muñiz, Rainer Steinwandt
2009 J jnl
Inf. Process. Lett.
Markus Grassl, Rainer Steinwandt
2009 J jnl
IACR Cryptol. ePrint Arch.
Markus Grassl, Ivana Ilic, Spyros S. Magliveras, Rainer Steinwandt
2009 J jnl
IACR Cryptol. ePrint Arch.
Vladimir Bozovic, Daniel Socek, Rainer Steinwandt, Viktória I. Villányi
2009 J jnl
IACR Cryptol. ePrint Arch.
Willi Geiselmann, Kenneth Matheis, Rainer Steinwandt
2009 conf
BIOSIG
David Naccache, Rainer Steinwandt, Moti Yung
2008 conf
Theoretical Foundations of Practical Information Security
Ran Canetti, Shafi Goldwasser, Günter Müller, Rainer Steinwandt
2008 conf
Theoretical Foundations of Practical Information Security
Ran Canetti, Shafi Goldwasser, Günter Müller, Rainer Steinwandt
2008 J jnl
Inf. Process. Lett.
Rainer Steinwandt, Viktória I. Villányi
2008 J jnl
Discret. Appl. Math.
María Isabel González Vasco, Rainer Steinwandt
2008 J jnl
IACR Cryptol. ePrint Arch.
María Isabel González Vasco, Florian Hess, Rainer Steinwandt
2008 J jnl
IACR Cryptol. ePrint Arch.
Markus Grassl, Rainer Steinwandt
2008 ed.
Theoretical Foundations of Practical Information Security
Ran Canetti, Shafi Goldwasser, Günter Müller, Rainer Steinwandt
2007 B conf
TCC
Michel Abdalla, Jens-Matthias Bohli, María Isabel González Vasco, Rainer Steinwandt
2007 Misc conf
ICISC
Willi Geiselmann, Rainer Steinwandt
2007 J jnl
IACR Cryptol. ePrint Arch.
Willi Geiselmann, Rainer Steinwandt
2007 A* conf
EUROCRYPT
Willi Geiselmann, Rainer Steinwandt
2007 J jnl
Int. J. Inf. Sec.
Jens-Matthias Bohli, María Isabel González Vasco, Rainer Steinwandt
2007 J jnl
IEEE Secur. Priv.
Willi Geiselmann, Rainer Steinwandt
2006 Misc conf
ICISC
Willi Geiselmann, Fabian Januszewski, Hubert Köpfer, Jan Pelzl, Rainer Steinwandt
2006 J jnl
IACR Cryptol. ePrint Arch.
Willi Geiselmann, Fabian Januszewski, Hubert Köpfer, Jan Pelzl, Rainer Steinwandt
2006 conf
Information Hiding
Jens-Matthias Bohli, María Isabel González Vasco, Rainer Steinwandt
2006 conf
ETRICS
Dominik Raub, Rainer Steinwandt
2006 J jnl
J. Symb. Comput.
Thomas Beth, Jörn Müller-Quade, Rainer Steinwandt
2006 conf
VIETCRYPT
Jens-Matthias Bohli, Rainer Steinwandt
2006 J jnl
it Inf. Technol.
Willi Geiselmann, María Isabel González Vasco, Rainer Steinwandt
2006 J jnl
Int. J. Inf. Sec.
Jens-Matthias Bohli, Stefan Röhrich, Rainer Steinwandt
2006 J jnl
Appl. Algebra Eng. Commun. Comput.
Thomas Beth, Willi Geiselmann, Rainer Steinwandt
2006 J jnl
IACR Cryptol. ePrint Arch.
Willi Geiselmann, Rainer Steinwandt
2006 J jnl
IACR Cryptol. ePrint Arch.
Jens-Matthias Bohli, María Isabel González Vasco, Rainer Steinwandt
2006 J jnl
Appl. Math. Lett.
María Isabel González Vasco, Rainer Steinwandt
2006 conf
VIETCRYPT
Jens-Matthias Bohli, Benjamin Glas, Rainer Steinwandt
2006 J jnl
IACR Cryptol. ePrint Arch.
Jens-Matthias Bohli, Benjamin Glas, Rainer Steinwandt
2005 B conf
TCC
María Isabel González Vasco, Consuelo Martínez, Rainer Steinwandt, Jorge Luis Villar
2005 J jnl
IACR Cryptol. ePrint Arch.
Anja Groch, Dennis Hofheinz, Rainer Steinwandt
2005 J jnl
IACR Cryptol. ePrint Arch.
Jens-Matthias Bohli, María Isabel González Vasco, Rainer Steinwandt
2005 J jnl
Quantum Inf. Comput.
Thomas Beth, Jörn Müller-Quade, Rainer Steinwandt
2005 conf
ITCC (1)
Willi Geiselmann, Hubert Köpfer, Rainer Steinwandt, Eran Tromer
2005 B conf
SOFSEM
Dominik Raub, Rainer Steinwandt, Jörn Müller-Quade
2005 A conf
CHES
Willi Geiselmann, Adi Shamir, Rainer Steinwandt, Eran Tromer
2005 J jnl
IACR Cryptol. ePrint Arch.
Jens-Matthias Bohli, María Isabel González Vasco, Rainer Steinwandt
2005 J jnl
Des. Codes Cryptogr.
Jens-Matthias Bohli, Rainer Steinwandt, María Isabel González Vasco, Consuelo Martínez
2004 J jnl
Appl. Algebra Eng. Commun. Comput.
María Isabel González Vasco, Rainer Steinwandt
2004 A conf
ESORICS
Michael Backes, Markus Dürmuth, Rainer Steinwandt
2004 B conf
ISIT
Willi Geiselmann, Rainer Steinwandt
2004 Misc conf
ICISC
Jens-Matthias Bohli, Rainer Steinwandt
2004 J jnl
IACR Cryptol. ePrint Arch.
Dominik Raub, Rainer Steinwandt, Jörn Müller-Quade
2004 J jnl
Des. Codes Cryptogr.
María Isabel González Vasco, Dennis Hofheinz, Consuelo Martínez, Rainer Steinwandt
2004 J jnl
IACR Cryptol. ePrint Arch.
María Isabel González Vasco, Rainer Steinwandt
2004 J jnl
Inf. Process. Lett.
Willi Geiselmann, Rainer Steinwandt
2004 J jnl
Des. Codes Cryptogr.
María Isabel González Vasco, Consuelo Martínez, Rainer Steinwandt
2004 B conf
CT-RSA
Willi Geiselmann, Rainer Steinwandt
2003 conf
Public Key Cryptography
Willi Geiselmann, Rainer Steinwandt
2003 J jnl
IACR Cryptol. ePrint Arch.
Willi Geiselmann, Rainer Steinwandt
2003 conf
Public Key Cryptography
Dennis Hofheinz, Rainer Steinwandt
2003 J jnl
IEEE Trans. Computers
Willi Geiselmann, Rainer Steinwandt
2003 J jnl
IACR Cryptol. ePrint Arch.
Willi Geiselmann, Rainer Steinwandt
2003 J jnl
Int. J. Inf. Sec.
Willi Geiselmann, Willi Meier, Rainer Steinwandt
2003 J jnl
IACR Cryptol. ePrint Arch.
Willi Geiselmann, Rainer Steinwandt
2003 A conf
CHES
Willi Geiselmann, Rainer Steinwandt
2003 A conf
ESORICS
Dennis Hofheinz, Jörn Müller-Quade, Rainer Steinwandt
2003 J jnl
IACR Cryptol. ePrint Arch.
Dennis Hofheinz, Jörn Müller-Quade, Rainer Steinwandt
2003 J jnl
Exp. Math.
María Isabel González Vasco, Martin Rötteler, Rainer Steinwandt
2003 J jnl
IACR Cryptol. ePrint Arch.
Dennis Hofheinz, Jörn Müller-Quade, Rainer Steinwandt
2003 J jnl
Quantum Inf. Comput.
Jörn Müller-Quade, Rainer Steinwandt
2003 conf
GI Jahrestagung (1)
Willi Geiselmann, Rainer Steinwandt
2003 J jnl
IACR Cryptol. ePrint Arch.
Willi Geiselmann, Rainer Steinwandt
2002 J jnl
IACR Cryptol. ePrint Arch.
Willi Geiselmann, Willi Meier, Rainer Steinwandt
2002 J jnl
Int. J. Inf. Sec.
Rainer Steinwandt, Willi Geiselmann, Regine Endsuleit
2002 J jnl
IEEE Trans. Inf. Theory
Rainer Steinwandt, Willi Geiselmann
2002 J jnl
Period. Math. Hung.
Willi Geiselmann, Rainer Steinwandt
2002 J jnl
J. Symb. Comput.
Marcus Hausdorf, Werner M. Seiler, Rainer Steinwandt
2002 J jnl
IEEE Trans. Computers
Willi Geiselmann, Jörn Müller-Quade, Rainer Steinwandt
2002 J jnl
IACR Cryptol. ePrint Arch.
María Isabel González Vasco, Rainer Steinwandt
2002 J jnl
IACR Cryptol. ePrint Arch.
María Isabel González Vasco, Consuelo Martínez, Rainer Steinwandt
2002 J jnl
IACR Cryptol. ePrint Arch.
Jens-Matthias Bohli, María Isabel González Vasco, Consuelo Martínez, Rainer Steinwandt
2002 J jnl
Datenschutz und Datensicherheit
Willi Geiselmann, Jörn Müller-Quade, Rainer Steinwandt, Thomas Beth
2001 C conf
ISC
Rainer Steinwandt, Willi Geiselmann, Thomas Beth
2001 C conf
IMACC
Willi Geiselmann, Rainer Steinwandt, Thomas Beth
2001 J jnl
Inf. Process. Lett.
María Isabel González Vasco, Rainer Steinwandt
2001 conf
Public Key Cryptography
Feng Bao, Robert H. Deng, Willi Geiselmann, Claus-Peter Schnorr, Rainer Steinwandt, Hongjun Wu
2001 J jnl
Datenschutz und Datensicherheit
Willi Geiselmann, Rainer Steinwandt
2001 conf
Public Key Cryptography
Rainer Steinwandt
2001 J jnl
Quantum Inf. Comput.
Rainer Steinwandt, Dominik Janzing, Thomas Beth
2000 J jnl
J. Symb. Comput.
Jörn Müller-Quade, Rainer Steinwandt
2000 J jnl
SIGSAM Bull.
Rainer Steinwandt
2000 J jnl
Appl. Algebra Eng. Commun. Comput.
Jörn Müller-Quade, Rainer Steinwandt
2000 A* conf
CRYPTO
Rainer Steinwandt, Markus Grassl, Willi Geiselmann, Thomas Beth
2000
Zur algorithmischen Zerlegung polynomialer Gleichungssysteme.
Rainer Steinwandt
1999 J jnl
J. Symb. Comput.
Jörn Müller-Quade, Rainer Steinwandt
1999 B conf
CASC
Rainer Steinwandt
redb/extractors/decompiler/bninja/analysis/disassembly.py
← Index redb/extractors/decompiler/bninja/analysis/disassembly.py python
import re
import time

import binaryninja
from binaryninja.enums import (
    InstructionTextTokenType,
)

# Support both package and standalone imports
try:
    from ..function_type import FunctionTypeAnalysis
    from ..utils.hashes import calculate_sha256
except ImportError:
    # Fallback to absolute imports (for multiprocessing spawned processes)
    from redb.extractors.decompiler.bninja.function_type import FunctionTypeAnalysis
    from redb.extractors.decompiler.bninja.utils.hashes import calculate_sha256


class DisassemblyAnalysis:
    INVALID_STACK_SIZE = -1

    def __init__(self, arch, function, bv, logger):
        self.arch = arch
        self.function = function
        self.bv = bv
        self.logger = logger
        if self.function is not None and hasattr(self.function, "instructions"):
            self.instructions = self.function.instructions
        else:
            self.instructions = []
        self.errors = []
        return

    def log_error(
        self, message, function_name, address, exception=None, error_location="unknown"
    ):
        """Log an error during processing."""
        error_msg = f"Error in function {function_name} at {address}: {message}"
        if exception:
            error_msg += f" - {str(exception)}"
        self.logger.error(error_msg)

        # Add to errors list
        error = {
            "function_name": function_name,
            "function_address": str(address),
            "error_location": error_location,
            "error_message": message,
            "error_details": str(exception) if exception else "",
            "error_type": type(exception).__name__ if exception else "Unknown",
            "timestamp": int(time.time() * 1000),
        }
        self.errors.append(error)

    def get_json(self):
        try:
            # Build disassembly string and normalized versions
            disassembly_builder = [[], []]  # Address and instruction text

            # Create a dictionary mapping addresses to instruction tokens
            instr_tokens_by_addr = {}
            for instr_tokens, addr in self.instructions:
                instr_tokens_by_addr[addr] = instr_tokens

            addresses = sorted(instr_tokens_by_addr.keys())
            for address in addresses:
                # Original disassembly with addresses
                # instr_tokens, address = instruction
                instr_tokens = instr_tokens_by_addr[address]
                disassembly_builder[0].append(address)
                disassembly_builder[1].append("".join(map(str, instr_tokens)))

            # Join with newlines
            disassembly_str = "\n".join(disassembly_builder[1])
            disassembly_with_addresses = "\n".join(
                f"{hex(address)}: {instr_text}"
                for address, instr_text in zip(
                    disassembly_builder[0], disassembly_builder[1], strict=False
                )
            )

            disassembly_json = {
                "disassembled_function_hash": calculate_sha256(disassembly_str),
                "disassembled_function": disassembly_with_addresses,
                "disassembled_function_no_addresses": disassembly_str,
                "disassembled_function_name": self.function.name,
                "disassembled_function_address": self.function.start,
                "instructions_count": len(instr_tokens_by_addr.keys()),
                "function_type": FunctionTypeAnalysis(self.function)
                .get_function_type()
                .name,
            }

            # Add additional metrics
            type_frequencies = self.collect_instruction_types()
            disassembly_json["instructions_types"] = list(type_frequencies.keys())
            disassembly_json["control_flow_count"] = (
                self.count_control_flow_instructions()
            )
            disassembly_json["memory_access_pattern"] = self.collect_memory_patterns()
            disassembly_json["register_usage"] = self.collect_register_usage()
            disassembly_json["data_references_count"] = self.count_data_references()
            disassembly_json["max_block_size"] = self.compute_max_block_size()
            disassembly_json["num_calls"] = self.compute_num_calls()
            disassembly_json["stack_size"] = self.estimate_stack_size()

            return disassembly_json, self.errors

        except Exception as e:
            self.log_error(
                "Failed to collect instruction types",
                self.function.name,
                self.function.start,
                e,
                "collect_instruction_types",
            )
            raise ValueError(e) from e

    def collect_instruction_types(self):
        """Collect instruction type frequencies from a function."""
        type_frequencies = {}

        try:
            # Iterate through all instructions in the function
            for instruction in self.instructions:
                instr_tokens = instruction[0]  # Get the instruction tokens

                # Extract the mnemonic from the instruction tokens
                mnemonic = None
                for token in instr_tokens:
                    if token.type == InstructionTextTokenType.InstructionToken:
                        mnemonic = token.text
                        break

                if not mnemonic:
                    continue

                # Use normalize_opcode to get standardized opcode
                normalized = self.normalize_opcode(mnemonic)

                # Get category from opcode_categories or use the instruction type directly
                category = self.arch.opcode_categories.get(normalized)
                if category:
                    self._increment_frequency(type_frequencies, category)

        except Exception as e:
            self.log_error(
                "Failed to collect instruction types",
                self.function.name,
                self.function.start,
                e,
                "collect_instruction_types",
            )

        return type_frequencies

    def normalize_opcode(self, opcode):
        return opcode.upper()

    def collect_memory_patterns(self):
        """Collect memory access patterns from a function."""
        patterns = []
        try:
            for instruction in self.instructions:
                instr_tokens = instruction[0]

                # We need to capture memory operands between BeginMemoryOperandToken and EndMemoryOperandToken
                in_memory_operand = False
                memory_operand_text = ""

                for token in instr_tokens:
                    if token.type == InstructionTextTokenType.BeginMemoryOperandToken:
                        in_memory_operand = True
                        memory_operand_text = ""
                    elif token.type == InstructionTextTokenType.EndMemoryOperandToken:
                        in_memory_operand = False

                        # Process the captured memory operand text
                        if memory_operand_text:
                            # Categorize memory access pattern
                            if (
                                "+" in memory_operand_text
                                and "*" in memory_operand_text
                            ):
                                if "MEM_SCALED_INDEX" not in patterns:
                                    patterns.append("MEM_SCALED_INDEX")
                            elif (
                                "+" in memory_operand_text or "-" in memory_operand_text
                            ):
                                if "MEM_BASE_OFFSET" not in patterns:
                                    patterns.append("MEM_BASE_OFFSET")
                            else:
                                if "MEM_DIRECT" not in patterns:
                                    patterns.append("MEM_DIRECT")

                            # Check for stack accesses
                            if any(
                                reg in memory_operand_text
                                for reg in ["SP", "BP", "ESP", "EBP", "RSP", "RBP"]
                            ):
                                if "MEM_STACK" not in patterns:
                                    patterns.append("MEM_STACK")
                            # Check for string operations
                            elif (
                                any(
                                    reg in memory_operand_text
                                    for reg in ["SI", "DI", "ESI", "EDI", "RSI", "RDI"]
                                )
                                and "MEM_STRING" not in patterns
                            ):
                                patterns.append("MEM_STRING")
                    elif in_memory_operand:
                        # Accumulate token text while inside a memory operand
                        memory_operand_text += token.text
        except Exception as e:
            self.log_error(
                "Failed to collect memory patterns",
                self.function.name,
                self.function.start,
                e,
                "collect_memory_patterns",
            )
        return patterns

    def collect_register_usage(self):
        """Collect register usage from a function."""
        registers = []
        try:
            # Define register groups we're interested in tracking
            register_groups = {
                "GPR": [
                    "RAX",
                    "RBX",
                    "RCX",
                    "RDX",
                    "R9",
                    "R10",
                    "R11",
                    "R12",
                    "R13",
                    "R14",
                    "R15",
                    "EAX",
                    "EBX",
                    "ECX",
                    "EDX",
                    "R9D",
                    "R10D",
                    "R11D",
                    "R12D",
                    "R13D",
                    "R14D",
                    "AX",
                    "BX",
                    "CX",
                    "DX",
                ],
                "GPR_INDEX": ["RSI", "RDI", "ESI", "EDI", "SI", "DI"],
                "GPR_STACK": ["RSP", "RBP", "ESP", "EBP", "SP", "BP"],
                "SIMD": ["XMM", "YMM", "ZMM"],
                "FPU": ["ST", "ST0", "ST1", "ST2", "ST3", "ST4", "ST5", "ST6", "ST7"],
                "FLAGS": ["FLAGS", "EFLAGS", "RFLAGS"],
                "CONTROL_REGISTER": ["CR0", "CR2", "CR3", "CR4", "CR8"],
                "DEBUG_REGISTER": ["DR0", "DR1", "DR2", "DR3", "DR6", "DR7"],
            }

            # Extract registers from instructions
            for instruction in self.instructions:
                instr_tokens = instruction[0]
                for token in instr_tokens:
                    if token.type == InstructionTextTokenType.RegisterToken:
                        reg = token.text.upper()
                        # Check which group this register belongs to
                        for group, regs in register_groups.items():
                            # if any(r in reg for r in regs) or any(reg.startswith(r) for r in regs):
                            if any(reg == r or reg.startswith(r) for r in regs):
                                if group not in registers:
                                    registers.append(group)
                                break
        except Exception as e:
            self.log_error(
                "Failed to collect register usage",
                self.function.name,
                self.function.start,
                e,
                "collect_register_usage",
            )
        return registers

    def count_data_references(self):
        """Count the number of data references in a function."""
        count = 0
        try:

            if self.function.mlil is None:
                return 0

            for block in self.function.mlil:
                for instr in block:
                    instr_str = str(instr)
                    logged = False
                    src = None

                    # Check for constant dereferencing or symbolic refs
                    if hasattr(instr, "src"):
                        src = instr.src
                        if isinstance(
                            src,
                            (
                                binaryninja.mediumlevelil.MediumLevelILConstPtr,
                                binaryninja.mediumlevelil.MediumLevelILConst,
                            ),
                        ):
                            count += 1
                            logged = True

                    # Check full string for hardcoded addresses or symbol-like tokens
                    if re.search(r"\b0x[0-9A-Fa-f]{3,}\b", instr_str) and not logged:
                        count += 1
                        logged = True

                    if "_" in instr_str and not logged:
                        count += 1
                        logged = True

                    # Only check for MediumLevelILConstPtr if src exists
                    if src is not None and isinstance(
                        src, binaryninja.mediumlevelil.MediumLevelILConstPtr
                    ):
                        addr = src.constant
                        # Check if address is in data sections
                        segment = self.bv.get_segment_at(addr)
                        if segment and segment.writable:
                            # print(f"[{function.name}] Matched data section reference in: {instr_str}")
                            count += 1
                            logged = True
        except Exception as e:
            self.logger.warning(
                f"Failed to use MLIL for counting data references in {self.function.name} at {self.function.start}: {e}"
            )
        return count

    def compute_max_block_size(self):
        """Compute the maximum basic block size in a function."""
        max_size = 0
        if self.function is None:
            return 0

        for block in self.function.basic_blocks:
            try:
                # Count instructions in this block using the direct length approach
                # This avoids UTF-8 decoding issues entirely
                block_size = block.instruction_count
                max_size = max(max_size, block_size)
            except Exception as e:
                self.log_error(
                    f"[HandledError] computing max block size: {e}",
                    self.function.name,
                    self.function.start,
                    e,
                    "compute_max_block_size",
                )
        return max_size

    def count_control_flow_instructions(self):
        """Count the number of control flow instructions in a function."""
        count = 0
        try:
            for instruction in self.instructions:
                instr_tokens = instruction[0]
                if self.arch.is_control_flow_instruction(instr_tokens):
                    count += 1
        except Exception as e:
            self.log_error(
                "Failed to count control flow instructions",
                self.function.name,
                self.function.start,
                e,
                "count_control_flow_instructions",
            )
        return count

    def compute_num_calls(self) -> int:
        """Compute the number of call instructions in a function."""
        num_calls = 0
        try:
            for instruction in self.instructions:
                instr_tokens = instruction[0]
                # Extract the mnemonic
                for token in instr_tokens:
                    if token.type == InstructionTextTokenType.InstructionToken:
                        if token.text.upper() == "CALL":
                            num_calls += 1
                        break
        except Exception as e:
            self.log_error(
                "Failed to compute number of calls",
                self.function.name,
                self.function.start,
                e,
                "compute_num_calls",
            )
        return num_calls

    def _increment_frequency(self, frequencies, type_name):
        """Increment the frequency count for an instruction type."""
        if type_name in frequencies:
            frequencies[type_name] += 1
        else:
            frequencies[type_name] = 1

    def estimate_stack_size(self):
        """Estimate the stack size used by a function."""
        try:
            # Binary Ninja provides a stack adjustment value for functions
            # Need to convert OffsetWithConfidence to a plain integer
            stack_adjust = self.function.stack_adjustment
            if hasattr(stack_adjust, "value"):  # Handle OffsetWithConfidence objects
                return stack_adjust.value
            return stack_adjust
        except Exception as e:
            self.log_error(
                "Failed to estimate stack size",
                self.function.name,
                self.function.start,
                e,
                "estimate_stack_size",
            )
            return self.INVALID_STACK_SIZE