Hadi Veisi

70 papers A 1C 3Misc 2Journal 51Unranked 13
YearRankTypeTitle / Venue / Authors
2025 J jnl
CoRR
Abdulhady Abas Abdullah, Arkaitz Zubiaga, Seyedali Mirjalili, Amir H. Gandomi, Fatemeh Daneshfar, Mohammad Sadra Amini, Alan Salam Mohammed, Hadi Veisi
2025 A conf
INTERSPEECH
Mina Serajian, Saeed Najafzadeh Rahaghi, Hadi Veisi, Saman Haratizadeh
2025 J jnl
CoRR
Kozhin Muhealddin Awlla, Hadi Veisi, Abdulhady Abas Abdullah
2025 J jnl
CoRR
Abdulhady Abas Abdullah, Hadi Veisi, Hussein M. Ali
2025 J jnl
Lang. Resour. Evaluation
Kozhin Muhealddin Awlla, Hadi Veisi, Abdulhady Abas Abdullah
2025 J jnl
CoRR
Aref Farhadipour, Homayoon Beigi, Volker Dellwo, Hadi Veisi
2025 J jnl
CoRR
Abdulhady Abas Abdullah, Amir H. Gandomi, Tarik A. Rashid, Seyedali Mirjalili, Laith Abualigah, Milena Zivkovic, Hadi Veisi
2024 J jnl
Neurocomputing
Mohammad Ali Jamshidi, Hadi Veisi, Mohammad Mahdi Mojahedian, Mohammad Reza Aref
2024 J jnl
CoRR
Abdulhady Abas Abdullah, Aram Mahmood Ahmed, Tarik A. Rashid, Hadi Veisi, Yassin Hussein Rassul, Bryar Ahmad Hassan, Polla Fattah, Sabat Abdulhameed Ali, Ahmed S. Shamsaldin
2024 J jnl
Circuits Syst. Signal Process.
Aref Farhadipour, Hadi Veisi
2024 J jnl
CoRR
Abdulhady Abas Abdullah, Shima Tabibian, Hadi Veisi, Aso Mahmudi, Tarik A. Rashid
2024 J jnl
CoRR
Abdulhady Abas Abdullah, Sabat Salih Muhamad, Hadi Veisi
2024 J jnl
Multim. Tools Appl.
Mahmood Farokhian, Vahid Rafe, Hadi Veisi
2024 J jnl
Iran J. Comput. Sci.
Aref Farhadipour, Hadi Veisi
2024 J jnl
Nat. Lang. Process. J.
Sabat Salih Muhamad, Hadi Veisi, Aso Mahmudi, Abdulhady Abas Abdullah, Farhad Rahimi
2024 J jnl
CoRR
Abdulhady Abas Abdullah, Srwa Hasan Abdulla, Dalia Mohammad Toufiq, Halgurd Sarhang Maghdid, Tarik A. Rashid, Pakshan F. Farho, Shadan Sh. Sabr, Akar H. Taher, Darya S. Hamad, Hadi Veisi, Aras T. Asaad
2023 J jnl
CoRR
Mohammad Ali Jamshidi, Hadi Veisi, Mohammad Mahdi Mojahedian, Mohammad Reza Aref
2023 J jnl
CoRR
Aref Farhadipour, Hadi Veisi
2022 J jnl
Knowl. Eng. Rev.
Mohammad Mirzanejad, Morteza Ebrahimi, Peter Vamplew, Hadi Veisi
2022 J jnl
IEEE Trans. Engineering Management
Sasan Azimi, Hadi Veisi, Mahdi Fateh-rad, Rouhollah Rahmani
2022 J jnl
CoRR
Mahmood Farokhian, Vahid Rafe, Hadi Veisi
2022 J jnl
Lang. Resour. Evaluation
Hadi Veisi, Hawre Hosseini, Mohammad MohammadAmini, Wirya Fathy, Aso Mahmudi
2022 J jnl
Iran J. Comput. Sci.
Hadi Veisi, Mahboobeh Golchinpour, Mostafa Salehi, Erfaneh Gharavi
2021 J jnl
Iran J. Comput. Sci.
Sara Besharati, Hadi Veisi, Ali Darzi, Seyed Habib Hosseini Saravani
2021 J jnl
Comput. Speech Lang.
Aso Mahmudi, Hadi Veisi
2021 J jnl
CoRR
Aso Mahmudi, Hadi Veisi
2021 J jnl
CoRR
Morteza Naserzade, Aso Mahmudi, Hadi Veisi, Hawre Hosseini, Mohammad MohammadAmini
2021 J jnl
CoRR
Hadi Veisi, Hawre Hosseini, Mohammad MohammadAmini, Wirya Fathy, Aso Mahmudi
2021 conf
SPECOM
Arash Amani, Mohammad MohammadAmini, Hadi Veisi
2021 J jnl
CoRR
Sara Shahmohammadi, Hadi Veisi, Ali Darzi
2020 J jnl
Int. J. Artif. Intell. Tools
Hadi Veisi, Hamed Fakour Shandi
2020 J jnl
Signal Image Video Process.
Sara Hashemi, Hadi Veisi, Ebrahim Jafarzadehpur, Rouhollah Rahmani, Zainabolhoda Heshmati
2020 J jnl
CoRR
Hamidreza Eivazi, Hadi Veisi, Mohammad Hossein Naderi, Vahid Esfahanian
2020 J jnl
Knowl. Based Syst.
Soheila Molaei, Hadi Zare, Hadi Veisi
2020 J jnl
CoRR
Erfaneh Gharavi, Hadi Veisi
2020 J jnl
Expert Syst. Appl.
Kayvan Bijari, Hadi Zare, Emad Kebriaei, Hadi Veisi
2020 J jnl
Medical Biol. Eng. Comput.
Sara Hashemi, Hadi Veisi, Ebrahim Jafarzadehpur, Rouhollah Rahmani, Zainabolhoda Heshmati
2020 J jnl
Int. J. Speech Technol.
Hadi Veisi, Armita Haji Mani
2020 J jnl
Neural Comput. Appl.
Erfaneh Gharavi, Hadi Veisi, Paolo Rosso
2020 J jnl
CoRR
Vahid Masoumi, Mostafa Salehi, Hadi Veisi, Golnoush Haddadian, Vahid Ranjbar, Mahsa Sahebdel
2020 J jnl
Digit. Scholarsh. Humanit.
Hadi Veisi, Mohammad MohammadAmini, Hawre Hosseini
2019 J jnl
Frontiers Comput. Neurosci.
Mohamad Khajezade, Sama Goliaei, Hadi Veisi
2019 J jnl
CoRR
Soheila Molaei, Hadi Zare, Hadi Veisi
2019 J jnl
CoRR
Kayvan Bijari, Hadi Zare, Hadi Veisi, Emad Kebriaei
2019 J jnl
Expert Syst. Appl.
Seyed Mahdi Rezaeinia, Rouhollah Rahmani, Ali Ghodsi, Hadi Veisi
2019 conf
ICSC
Erfaneh Gharavi, Rupesh Silwal, Matthew S. Gerber, Hadi Veisi
2018 J jnl
Neural Comput. Appl.
Kayvan Bijari, Hadi Zare, Hadi Veisi, Hossein Bobarshad
2018 conf
IST
Seyed Habib Hosseini Saravani, Mohammad Bahrani, Hadi Veisi, Sara Besharati
2017 J jnl
CoRR
Kayvan Bijari, Hadi Zare, Hadi Veisi, Hossein Bobarshad
2017 conf
BEA@EMNLP
Elham Mohammadi, Hadi Veisi, Hessam Amini
2016 conf
FIRE (Working Notes)
Erfaneh Gharavi, Kayvan Bijari, Kiarash Zahirnia, Hadi Veisi
2016 conf
FIRE Workshop
Erfaneh Gharavi, Hadi Veisi, Kayvan Bijari, Kiarash Zahirnia
2016 conf
FIRE (Working Notes)
Mozhgan Momtaz, Kayvan Bijari, Mostafa Salehi, Hadi Veisi
2015 J jnl
IET Signal Process.
Ali Aroudi, Hadi Veisi, Hossein Sameti
2015 J jnl
EURASIP J. Audio Speech Music. Process.
Ali Aroudi, Hadi Veisi, Hossein Sameti, Zahra Mafakheri
2013 J jnl
Speech Commun.
Hadi Veisi, Hossein Sameti
2012 C conf
ISDA
Hadi Veisi, Hossein Sameti
2012 conf
ISSPA
Soheil Khorram, Hossein Sameti, Hadi Veisi
2012 C conf
FedCSIS
Reza Haghmaram, Ali Aroudi, Mohammad Hossein Ghezel Aiagh, Hadi Veisi
2012 conf
ISSPA
Hadi Veisi, Hossein Sameti
2012 J jnl
IET Signal Process.
Hadi Veisi, Hossein Sameti
2012 conf
ISSPA
Ali Aroudi, Hadi Veisi, Hossein Sameti
2012 conf
ISSPA
Mahsa Sadat Elyasi Langarani, Hadi Veisi, Hossein Sameti
2011 J jnl
EURASIP J. Audio Speech Music. Process.
Hossein Sameti, Hadi Veisi, Mohammad Bahrani, Bagher BabaAli, Khosro Hosseinzadeh
2011 conf
DSP
Hadi Veisi, Hossein Sameti
2011 J jnl
Digit. Signal Process.
Hadi Veisi, Hossein Sameti
2009 C conf
ASRU
Hadi Veisi, Hossein Sameti
2008 Misc conf
CSICC
Hossein Sameti, Hadi Veisi, Mohammad Bahrani, Bagher BabaAli, Khosro Hosseinzadeh
2008 Misc conf
CSICC
Hadi Veisi, Hossein Sameti
2007 conf
ISSPA
Hadi Veisi, Hossein Sameti
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