J. A. Tenreiro Machado

135 papers A* 1A 2B 6C 5Journal 114Unranked 7
YearRankTypeTitle / Venue / Authors
2025 J jnl
Neural Comput. Appl.
Mercedes Alonso, Vitor M. R. Cunha, Alexandra M. S. F. Galhano, António M. Lopes, J. A. Tenreiro Machado
2023 J jnl
Eng. Comput.
Omid Nikan, Zakieh Avazzadeh, J. A. Tenreiro Machado, Mohammad Navaz Rasoulizadeh
2023 J jnl
Eng. Comput.
Hossein Hassani, J. A. Tenreiro Machado, Eskandar Naraghirad, Zakieh Avazzadeh
2022 J jnl
Appl. Math. Comput.
Juan P. Ugarte, J. A. Tenreiro Machado, Catalina Tobón
2022 J jnl
SN Comput. Sci.
J. A. Tenreiro Machado, S. Hamid Mehdipour
2022 J jnl
Iran J. Comput. Sci.
S. Hamid Mehdipour, J. A. Tenreiro Machado
2022 J jnl
Eng. Comput.
Omid Nikan, Ahmad Golbabai, J. A. Tenreiro Machado, Touraj Nikazad
2022 J jnl
J. Comput. Biol.
Hossein Hassani, Zakieh Avazzadeh, J. A. Tenreiro Machado, Praveen Agarwal, Maryam Bakhtiar
2021 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Behrouz Parsa Moghaddam, Zeinab Salamat Mostaghim, Athanasios A. Pantelous, J. A. Tenreiro Machado
2021 C conf
ACC
Arman Dabiri, Laya Karimi Chahrogh, J. A. Tenreiro Machado
2021 J jnl
Commun. Nonlinear Sci. Numer. Simul.
J. A. Tenreiro Machado, Seyed Mehdi Abedi Pahnehkolaei, Alireza Alfi
2021 C conf
ACC
Arman Dabiri, Laya Karimi Chahrogh, J. A. Tenreiro Machado
2021 J jnl
Signal Process. Image Commun.
Liping Chen, Hao Yin, Liguo Yuan, J. A. Tenreiro Machado, Ranchao Wu, Zeeshan Alam
2021 J jnl
Eng. Appl. Artif. Intell.
Dalia Yousri, Seyedali Mirjalili, J. A. Tenreiro Machado, Thanikanti Sudhakar Babu, Osama Elbaksawi, Ahmed Fathy
2021 J jnl
Comput. Appl. Math.
Zahra Sadat Aghayan, Alireza Alfi, J. A. Tenreiro Machado
2021 J jnl
Commun. Nonlinear Sci. Numer. Simul.
António M. Lopes, J. A. Tenreiro Machado
2021 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Omid Nikan, Zakieh Avazzadeh, J. A. Tenreiro Machado
2021 J jnl
J. Comput. Phys.
Omid Nikan, J. A. Tenreiro Machado, Ahmad Golbabai, Jalil Rashidinia
2021 J jnl
Eng. Comput.
Omid Nikan, Ahmad Golbabai, J. A. Tenreiro Machado, Touraj Nikazad
2021 J jnl
J. Comput. Sci.
Omid Nikan, Zakieh Avazzadeh, J. A. Tenreiro Machado
2021 J jnl
Appl. Soft Comput.
Seyed Mehdi Abedi Pahnehkolaei, Alireza Alfi, J. A. Tenreiro Machado
2021 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Juan P. Ugarte, Catalina Tobón, Javier Saiz, António Mendes Lopes, J. A. Tenreiro Machado
2021 J jnl
Frontiers Inf. Technol. Electron. Eng.
Zahra Sadat Aghayan, Alireza Alfi, J. A. Tenreiro Machado
2020 J jnl
Numer. Algorithms
P. Mokhtary, Behrouz Parsa Moghaddam, António M. Lopes, J. A. Tenreiro Machado
2020 J jnl
Frontiers Inf. Technol. Electron. Eng.
Liping Chen, Hao Yin, Liguo Yuan, António M. Lopes, J. A. Tenreiro Machado, Ranchao Wu
2020 J jnl
Entropy
Marcin Bakala, Piotr Duch, J. A. Tenreiro Machado, Piotr Ostalczyk, Dominik Sankowski
2020 J jnl
Comput. Appl. Math.
Seyed Mehdi Abedi Pahnehkolaei, Alireza Alfi, J. A. Tenreiro Machado
2020 J jnl
J. Sci. Comput.
Hossein Hassani, J. A. Tenreiro Machado, Zakieh Avazzadeh, Eskandar Naraghirad, Mohammad Shafie Dahaghin
2020 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Hossein Hassani, J. A. Tenreiro Machado, Zakieh Avazzadeh, Eskandar Naraghirad
2020 J jnl
Eng. Comput.
Hossein Hassani, Zakieh Avazzadeh, J. A. Tenreiro Machado
2020 J jnl
Comput. Appl. Math.
Liping Chen, Tingting Li, Ranchao Wu, António M. Lopes, J. A. Tenreiro Machado, Kehan Wu
2020 J jnl
Mob. Networks Appl.
Shuai Liu, Weiling Bai, Gautam Srivastava, J. A. Tenreiro Machado
2020 J jnl
Comput. Appl. Math.
Hossein Hassani, J. A. Tenreiro Machado, Eskandar Naraghirad, B. Sadeghi
2020 J jnl
Comput. Appl. Math.
José Vanterler da Costa Sousa, J. A. Tenreiro Machado, E. Capelas De Oliveira
2019 J jnl
Comput. Appl. Math.
Hais Azin, F. Mohammadi, J. A. Tenreiro Machado
2019 J jnl
J. Comput. Phys.
G. Sales Teodoro, J. A. Tenreiro Machado, E. Capelas De Oliveira
2019 J jnl
Entropy
António M. Lopes, J. A. Tenreiro Machado
2019 J jnl
Appl. Math. Comput.
Seyed Mehdi Abedi Pahnehkolaei, Alireza Alfi, J. A. Tenreiro Machado
2019 J jnl
Neural Networks
Liping Chen, Tingwen Huang, J. A. Tenreiro Machado, António M. Lopes, Yi Chai, Ranchao Wu
2019 J jnl
Neural Networks
Seyed Mehdi Abedi Pahnehkolaei, Alireza Alfi, J. A. Tenreiro Machado
2019 J jnl
Symmetry
Ramandeep Behl, Ioannis K. Argyros, Fouad Othman Mallawi, J. A. Tenreiro Machado
2019 J jnl
Entropy
E. J. Solteiro Pires, J. A. Tenreiro Machado, P. B. de Moura Oliveira
2019 J jnl
Symmetry
Rania A. Alharbey, Munish Kansal, Ramandeep Behl, J. A. Tenreiro Machado
2019 J jnl
Entropy
António M. Lopes, J. A. Tenreiro Machado
2019 J jnl
Appl. Soft Comput.
Esmat Sadat Alaviyan Shahri, Alireza Alfi, J. A. Tenreiro Machado
2019 J jnl
Commun. Nonlinear Sci. Numer. Simul.
J. A. Tenreiro Machado, António M. Lopes
2019 J jnl
Symmetry
Ramandeep Behl, Ioannis K. Argyros, J. A. Tenreiro Machado, Ali Saleh Alshomrani
2019 J jnl
Appl. Math. Comput.
Ioannis K. Argyros, Ramandeep Behl, J. A. Tenreiro Machado, Ali Saleh Alshomrani
2019 J jnl
Comput. Appl. Math.
Behrouz Parsa Moghaddam, Arman Dabiri, António M. Lopes, J. A. Tenreiro Machado
2019 J jnl
Entropy
António M. Lopes, J. A. Tenreiro Machado
2019 J jnl
Comput. Chem. Eng.
Abolfazl Simorgh, Abolhassan Razminia, J. A. Tenreiro Machado
2019 J jnl
Comput. Math. Appl.
Yong Zhou, Michal Feckan, Fawang Liu, J. A. Tenreiro Machado
2019 J jnl
Neurocomputing
Seyed Mehdi Abedi Pahnehkolaei, Alireza Alfi, J. A. Tenreiro Machado
2019 J jnl
Soft Comput.
Wen Zhong, Yunchuan Deng, J. A. Tenreiro Machado, Chao Zhang, Kui Zhao, Xiaojun Wang
2019 J jnl
Entropy
António M. Lopes, J. A. Tenreiro Machado
2019 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Daniel Cao Labora, António M. Lopes, J. A. Tenreiro Machado
2018 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Samer S. Ezz-Eldien, Eid H. Doha, Ali H. Bhrawy, Ahmed A. El-Kalaawy, J. A. Tenreiro Machado
2018 J jnl
Entropy
António M. Lopes, J. A. Tenreiro Machado
2018 J jnl
Entropy
António M. Lopes, J. A. Tenreiro Machado
2018 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Manuel Duarte Ortigueira, António M. Lopes, J. A. Tenreiro Machado
2018 J jnl
J. Comput. Appl. Math.
Sergio Adriani David, Derick D. Quintino, Cláudio M. C. Inácio, J. A. Tenreiro Machado
2018 J jnl
J. Comput. Appl. Math.
Arman Dabiri, Behrouz Parsa Moghaddam, J. A. Tenreiro Machado
2018 C conf
HIS
E. J. Solteiro Pires, J. A. Tenreiro Machado, P. B. de Moura Oliveira
2018 J jnl
Entropy
António M. Lopes, J. A. Tenreiro Machado
2018 J jnl
J. Frankl. Inst.
Penghua Li, Liping Chen, Ranchao Wu, J. A. Tenreiro Machado, António M. Lopes, Liguo Yuan
2018 J jnl
Int. J. Control
E. J. Solteiro Pires, P. B. de Moura Oliveira, J. A. Tenreiro Machado
2017 J jnl
Fundam. Informaticae
Xiaojun Yang, J. A. Tenreiro Machado, Juan J. Nieto
2017 J jnl
Comput. Math. Appl.
Yong Zhou, Michal Feckan, Fawang Liu, J. A. Tenreiro Machado
2017 J jnl
Entropy
J. A. Tenreiro Machado, António M. Lopes
2017 J jnl
Entropy
J. A. Tenreiro Machado, António M. Lopes
2017 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Seyed Mehdi Abedi Pahnehkolaei, Alireza Alfi, J. A. Tenreiro Machado
2017 J jnl
Fundam. Informaticae
Sergio Adriani David, J. A. Tenreiro Machado, Lucas R. Trevisan, Cláudio M. C. Inácio, António M. Lopes
2017 J jnl
Int. J. Control
António M. Lopes, J. A. Tenreiro Machado
2017 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Xiaojun Yang, J. A. Tenreiro Machado, Carlo Cattani, Feng Gao
2017 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Manuel Duarte Ortigueira, António M. Lopes, J. A. Tenreiro Machado
2017 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Mahmoud A. Zaky, J. A. Tenreiro Machado
2017 J jnl
Commun. Nonlinear Sci. Numer. Simul.
J. A. Tenreiro Machado, António M. Lopes
2017 J jnl
Neural Networks
Liping Chen, Jinde Cao, Ranchao Wu, J. A. Tenreiro Machado, António M. Lopes, Hejun Yang
2017 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Clara M. Ionescu, António M. Lopes, Dana Copot, J. A. Tenreiro Machado, Jason H. T. Bates
2017 J jnl
Inf. Sci.
Seyed Mehdi Abedi Pahnehkolaei, Alireza Alfi, J. A. Tenreiro Machado
2016 J jnl
Appl. Math. Comput.
Xiaojun Yang, J. A. Tenreiro Machado, H. M. Srivastava
2016 J jnl
Int. J. Syst. Sci.
Ricardo Enrique Gutiérrez-Carvajal, Leonimer Flavio de Melo, João Maurício Rosário, J. A. Tenreiro Machado
2016 J jnl
Commun. Nonlinear Sci. Numer. Simul.
J. A. Tenreiro Machado
2016 J jnl
Commun. Nonlinear Sci. Numer. Simul.
J. A. Tenreiro Machado
2016 C conf
ISDA
E. J. Solteiro Pires, J. A. Tenreiro Machado, P. B. de Moura Oliveira
2016 J jnl
Comput. Methods Programs Biomed.
António M. Lopes, José P. Andrade, J. A. Tenreiro Machado
2015 J jnl
Signal Process.
J. A. Tenreiro Machado, Carla M. A. Pinto, António Mendes Lopes
2015 J jnl
Appl. Math. Lett.
Esmat Sadat Alaviyan Shahri, Alireza Alfi, J. A. Tenreiro Machado
2015 J jnl
Signal Image Video Process.
J. A. Tenreiro Machado, Erdal Dinç, Dumitru Baleanu
2015 J jnl
Signal Image Video Process.
Erdal Dinç, Fernando B. Duarte, J. A. Tenreiro Machado, Dumitru Baleanu
2015 J jnl
Entropy
J. A. Tenreiro Machado, Maria Eugénia Mata, António M. Lopes
2015 J jnl
Appl. Math. Comput.
J. A. Tenreiro Machado
2015 J jnl
Commun. Nonlinear Sci. Numer. Simul.
J. A. Tenreiro Machado
2015 conf
nDS
E. J. Solteiro Pires, P. B. de Moura Oliveira, J. A. Tenreiro Machado
2015 J jnl
Int. J. Bifurc. Chaos
António M. Lopes, J. A. Tenreiro Machado, Alexandra M. S. F. Galhano
2015 J jnl
Commun. Nonlinear Sci. Numer. Simul.
J. A. Tenreiro Machado, Maria Eugénia Mata
2015 J jnl
J. Comput. Phys.
Manuel Duarte Ortigueira, J. A. Tenreiro Machado
2014 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Kambiz Razminia, Abolhassan Razminia, J. A. Tenreiro Machado
2014 J jnl
Commun. Nonlinear Sci. Numer. Simul.
António M. Lopes, J. A. Tenreiro Machado
2014 conf
NaBIC
E. J. Solteiro Pires, J. A. Tenreiro Machado, Paulo B. de Moura Oliveira
2014 J jnl
Scientometrics
J. A. Tenreiro Machado, Alexandra M. S. F. Galhano, Juan J. Trujillo
2013 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Clara M. Ionescu, J. A. Tenreiro Machado, Robin De Keyser
2013 J jnl
Comput. Math. Appl.
Dumitru Baleanu, J. A. Tenreiro Machado, Wen Chen
2013 J jnl
Comput. Math. Appl.
António M. Lopes, J. A. Tenreiro Machado, Carla M. A. Pinto, Alexandra M. S. F. Galhano
2013 J jnl
Comput. Math. Appl.
Carla M. A. Pinto, J. A. Tenreiro Machado
2013 J jnl
J. Optim. Theory Appl.
J. A. Tenreiro Machado
2013 J jnl
IEEE J. Emerg. Sel. Topics Circuits Syst.
J. A. Tenreiro Machado, Alexandra M. S. F. Galhano
2012 J jnl
Robotics Auton. Syst.
Micael S. Couceiro, J. A. Tenreiro Machado, Rui P. Rocha, Nuno M. F. Ferreira
2012 J jnl
Appl. Soft Comput.
Maria da Graça Marcos, J. A. Tenreiro Machado, T.-P. Azevedo-Perdicoúlis
2012 J jnl
Signal Process.
J. A. Tenreiro Machado
2012 J jnl
Signal Image Video Process.
Micael S. Couceiro, Rui P. Rocha, Nuno M. Fonseca Ferreira, J. A. Tenreiro Machado
2012 J jnl
Signal Image Video Process.
Clara M. Ionescu, Jocelyn Sabatier, J. A. Tenreiro Machado
2012 J jnl
Comput. Math. Appl.
J. A. Tenreiro Machado
2011 J jnl
Signal Process.
Maria da Graça Marcos, J. A. Tenreiro Machado, T.-P. Azevedo-Perdicoúlis
2011 J jnl
Int. J. Bifurc. Chaos
Carla M. A. Pinto, J. A. Tenreiro Machado
2011 J jnl
Signal Process.
Manuel Duarte Ortigueira, J. A. Tenreiro Machado, Juan J. Trujillo, Blas M. Vinagre
2010 J jnl
IEEE Trans. Biomed. Eng.
Clara M. Ionescu, Ionut Muntean, J. A. Tenreiro Machado, Robin De Keyser, Mihail Abrudean
2010 B conf
SMC
Viriato M. Marques, Cecília Reis, J. A. Tenreiro Machado
2010 B conf
IEEE Congress on Evolutionary Computation
E. J. Solteiro Pires, Luís Mendes, António M. Lopes, Paulo B. de Moura Oliveira, J. A. Tenreiro Machado, João Caldinhas Vaz, Maria João Rosário
2010 conf
SOCO
E. J. Solteiro Pires, Paulo B. de Moura Oliveira, J. A. Tenreiro Machado
2010 J jnl
Comput. Math. Appl.
Wen Chen, Dumitru Baleanu, J. A. Tenreiro Machado
2007 C conf
ISDA
Isabel S. Jesus, J. A. Tenreiro Machado, Ramiro S. Barbosa, E. S. Solteiro Pires
2005 conf
CLAWAR
M. F. da Silva, J. A. Tenreiro Machado
2004 J jnl
IEEE Trans. Intell. Transp. Syst.
Lino Figueiredo, J. A. Tenreiro Machado, José Rui Ferreira
2003 B conf
SMC
Lino Figueiredo, J. A. Tenreiro Machado, José Rui Ferreira
2001 conf
ECC
Carlos M. B. Rodrigues, J. A. Tenreiro Machado
2001 conf
ECC
Lino Figueiredo, Isabel S. Jesus, J. A. Tenreiro Machado, José Rui Ferreira, J. L. Martins de Carvalho
2000 B conf
CEC
E. J. Solteiro Pires, J. A. Tenreiro Machado
1998 B conf
SMC
Abílio Azenha, J. A. Tenreiro Machado
1998 B conf
SMC
J. A. Tenreiro Machado, Abílio Azenha
1998 conf
ICECS
Fernando B. M. Duarte, J. A. Tenreiro Machado
1998 A conf
IROS
Filipe M. Silva, J. A. Tenreiro Machado
1996 A* conf
ICRA
Abílio Azenha, J. A. Tenreiro Machado
1989 J jnl
J. Field Robotics
J. A. Tenreiro Machado, Jorge Leite Martins de Carvalho
1988 A conf
IROS
J. A. Tenreiro Machado, J. L. Martins de Carvalho
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