Incheon Paik

132 papers A 12B 5C 14Misc 3Journal 35Unranked 63
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
T. H. Akila S. Siriweera, Janani Rangila, Keitaro Naruse, Incheon Paik, Isuru Jayanada
2026 J jnl
CoRR
Janani Rangila, Akila Siriweera, Incheon Paik, Keitaro Naruse, Isuru Jayanada, Vishmika Devindi
2025 J jnl
IEEE Trans. Serv. Comput.
T. H. Akila S. Siriweera, Incheon Paik
2025 J jnl
IEEE Access
Hong N. Dao, Yasuhiro Hashimoto, Incheon Paik, Truong Cong Thang
2024 J jnl
IEEE Access
Hong N. Dao, Tuyen Nguyen, Chérubin Mugisha, Incheon Paik
2024 J jnl
Expert Syst. Appl.
Kungan Zeng, Incheon Paik
2023 conf
ICCE-Berlin
Jean Flaherty, Chibuike Onuoha, Incheon Paik, Truong Cong Thang
2023 J jnl
IEEE Trans. Big Data
T. H. Akila S. Siriweera, Incheon Paik, Huawei Huang
2023 J jnl
IEEE Access
Hong N. Dao, Penugonda Ravikumar, Palla Likhitha, Rage Uday Kiran, Yutaka Watanobe, Incheon Paik
2023 conf
MCSoC
Hong N. Dao, Incheon Paik
2023 conf
iCAST
Zheqi Shen, Incheon Paik
2022 J jnl
IEEE Access
Chérubin Mugisha, Incheon Paik
2022 conf
BIBM
Chérubin Mugisha, Incheon Paik
2022 Misc conf
QCE
Tuyen Nguyen, Incheon Paik, Hiroyuki Sagawa, Truong Cong Thang
2022 conf
ICSC
Incheon Paik
2022 C conf
IEA/AIE
Hong N. Dao, Penugonda Ravikumar, Palla Likhitha, Bathala Venus Vikranth Raj, R. Uday Kiran, Yutaka Watanobe, Incheon Paik
2022 conf
KSE
Truong Cong Thang, Yutaka Watanobe, Rage Uday Kiran, Incheon Paik
2022 Misc conf
QCE
Tuyen Nguyen, Incheon Paik, Hiroyuki Sagawa, Truong Cong Thang
2022 conf
CSE
Incheon Paik, Kungan Zeng, Munhan Bae
2021 conf
IEA/AIE (1)
Atsushi Oba, Incheon Paik, Ayato Kuwana
2021 conf
TALE
Md. Mostafizer Rahman, Yutaka Watanobe, Rage Uday Kiran, Truong Cong Thang, Incheon Paik
2021 conf
MCSoC
Haklin Kimm, Incheon Paik
2021 conf
MCSoC
Kungan Zeng, Incheon Paik
2021 J jnl
IEEE Access
Md. Mostafizer Rahman, Yutaka Watanobe, Rage Uday Kiran, Truong Cong Thang, Incheon Paik
2021 conf
MCSoC
Haklin Kimm, Incheon Paik, Hanke Kimm
2021 J jnl
IEEE Trans. Engineering Management
Wuhui Chen, Baichuan Liu, Incheon Paik, Zhenni Li, Zibin Zheng
2021 J jnl
IEEE Access
Kungan Zeng, Incheon Paik
2020 conf
iCAST
Kungan Zeng, Incheon Paik
2020 J jnl
Int. J. Web Serv. Res.
Banage T. G. S. Kumara, Incheon Paik, Yuichi Yaguchi
2020 conf
IEEE BigData
R. Uday Kiran, Sadanori Ito, Minh-Son Dao, Koji Zettsu, Cheng-Wei Wu, Yutaka Watanobe, Incheon Paik, Truong Cong Thang
2020 conf
iCAST
Ty V. Nguyen, Incheon Paik
2020 conf
BIBM
Chérubin Mugisha, Incheon Paik
2020 conf
AICCC
Quang-Minh Do, Kungan Zeng, Incheon Paik
2020 J jnl
Int. J. Syst. Serv. Oriented Eng.
Banujan Kuhaneswaran, Banage T. G. S. Kumara, Incheon Paik
2020 conf
BigDataSE
Kungan Zeng, Incheon Paik
2019 A conf
ICWS
Incheon Paik, Ryo Ataka
2019 B conf
DSAA
Incheon Paik, T. H. Akila S. Siriweera
2019 C conf
ICCC
Atsushi Oba, Incheon Paik
2019 J jnl
IEEE Trans. Serv. Comput.
Wuhui Chen, Incheon Paik, Patrick C. K. Hung
2018 C ed.
ICCC
Jeffrey Tsai, Ernesto Damiani, Xiaoqing (Frank) Liu, Incheon Paik
2018 J jnl
J. Parallel Distributed Comput.
Wuhui Chen, Incheon Paik, Zhenni Li, Neil Y. Yen
2018 conf
iCAST
Takeyuki Miyagi, Rupasingha A. H. M. Rupasingha, Incheon Paik
2018 C conf
ICCC
Kazuki Omine, Incheon Paik
2018 J jnl
Digit. Signal Process.
Benying Tan, Yujie Li, Shuxue Ding, Incheon Paik, Atsunori Kanemura
2018 conf
iCAST
Rupasingha A. H. M. Rupasingha, Incheon Paik
2018 A conf
ICWS
Rupasingha A. H. M. Rupasingha, Incheon Paik
2018 conf
MCSoC
Incheon Paik, Yuji Ishizuka, Quang-Minh Do, Wuhui Chen
2018 J jnl
IEEE Access
T. H. Akila S. Siriweera, Incheon Paik
2018 J jnl
IEICE Trans. Inf. Syst.
Rupasingha A. H. M. Rupasingha, Incheon Paik, Banage T. G. S. Kumara
2018 conf
iCAST
K. Banujan, Banage T. G. S. Kumara, Incheon Paik
2017 conf
iCAST
Sheng Zhang, Incheon Paik
2017 A conf
ICWS
Thenuwara Hannadige Akila Sanjaya Siriweera, Incheon Paik, Banage Thanne Gedara Samantha Kumara
2017 J jnl
IEEE Trans. Computers
Wuhui Chen, Incheon Paik, Zhenni Li
2017 J jnl
Multim. Tools Appl.
Wuhui Chen, Incheon Paik, Neil Y. Yen
2017 conf
MCSoC
Incheon Paik, Yutaka Koshiba, T. H. Akila S. Siriweera
2017 A conf
ICWS
Rupasingha A. H. M. Rupasingha, Incheon Paik, Banage T. G. S. Kumara
2017 conf
MCSoC
Yujie Li, Benying Tan, Shuxue Ding, Incheon Paik, Atsunori Kanemura
2017 conf
SCC
Banage T. G. S. Kumara, Incheon Paik, T. H. A. S. Siriweera, Koswatte R. C. Koswatte
2017 conf
SCC
T. H. Akila S. Siriweera, Incheon Paik, Banage T. G. S. Kumara
2017 conf
iCAST
Chungho Lee, Incheon Paik
2016 B conf
SMC
Incheon Paik, Satoshi Hotta, Wuhui Chen
2016 A conf
ICWS
T. H. Akila S. Siriweera, Incheon Paik, Jia Zhang, Banage T. G. S. Kumara
2016 conf
SCC
Banage T. G. S. Kumara, Incheon Paik, T. H. A. S. Siriweera, Koswatte R. C. Koswatte
2016 conf
SCC
Yutaka Koshiba, Incheon Paik, Wuhui Chen
2016 C conf
CIT
T. H. Akila S. Siriweera, Incheon Paik, Banage T. G. S. Kumara
2016 Misc conf
ICMLC
Incheon Paik
2016 J jnl
IEEE Trans. Computers
Wuhui Chen, Incheon Paik, Zhenni Li
2016 conf
BigData Congress
Yuji Ishizuka, Wuhui Chen, Incheon Paik
2015 J jnl
IEEE Trans. Serv. Comput.
Wuhui Chen, Incheon Paik, Patrick C. K. Hung
2015 J jnl
Int. J. Inf. Retr. Res.
Koswatte R. C. Koswatte, Incheon Paik, Wonhee Park, Banage T. G. S. Kumara
2015 conf
BigData Congress
T. H. A. S. Siriweera, Incheon Paik, Banage T. G. S. Kumara, Koswatte R. C. Koswatta
2015 conf
iCAST
Yutaka Koshiba, Wuhui Chen, Yuichi Yamada, Takazumi Tanaka, Incheon Paik
2015 conf
iCAST
T. H. Akila S. Siriweera, Incheon Paik, Banage T. G. S. Kumara
2015 A conf
ICWS
Banage T. G. S. Kumara, Incheon Paik, Jia Zhang, T. H. A. S. Siriweera, Koswatte R. C. Koswatte
2015 J jnl
Fundam. Informaticae
Wuhui Chen, Incheon Paik, Patrick C. K. Hung
2015 conf
BigDataService
Wuhui Chen, Banage T. G. S. Kumara, Incheon Paik, Zhenni Li
2015 J jnl
IEEE Trans. Parallel Distributed Syst.
Wuhui Chen, Incheon Paik
2014 conf
WAIM Workshops
Hyeongsoo Kim, Hyun Woo Park, Wonwoo Cho, Incheon Paik, Keun Ho Ryu
2014 J jnl
IEEE Trans. Serv. Comput.
Incheon Paik, Wuhui Chen, Michael N. Huhns
2014 conf
IEEE SCC
Banage T. G. S. Kumara, Incheon Paik, Hiroki Ohashi, Wuhui Chen, Koswatte R. C. Koswatte
2014 A conf
ICWS
Banage T. G. S. Kumara, Incheon Paik, Hiroki Ohashi, Yuichi Yaguchi, Wuhui Chen
2014 conf
ISIC
Koswatte R. C. Koswatte, Incheon Paik, Banage T. G. S. Kumara
2014 conf
iCAST
Dingkun Li, Minghao Piao, Ho-Sun Shon, Keun Ho Ryu, Incheon Paik
2014 C conf
CIDM
Banage T. G. S. Kumara, Incheon Paik, Koswatte R. C. Koswatte, Wuhui Chen
2014 C conf
CIDM
Banage T. G. S. Kumara, Incheon Paik, Koswatte R. C. Koswatte, Wuhui Chen
2014 J jnl
Int. J. Web Serv. Res.
Banage T. G. S. Kumara, Incheon Paik, Wuhui Chen, Keun Ho Ryu
2013 conf
IEEE SCC
Wuhui Chen, Incheon Paik, Takazumi Tanaka, Banage T. G. S. Kumara
2013 conf
CYBCONF
Wuhui Chen, Incheon Paik, Junbo Wang, Banage T. G. S. Kumara, Takazumi Tanaka
2013 conf
BigData Congress
Incheon Paik, Takazumi Tanaka, Hiroki Ohashi, Wuhui Chen
2013 conf
iCAST/UMEDIA
Hiroki Ohashi, Incheon Paik, Banage T. G. S. Kumara
2013 conf
IEEE SCC
Banage T. G. S. Kumara, Yuichi Yaguchi, Incheon Paik, Wuhui Chen
2013 conf
iCAST/UMEDIA
Tetsuya Tashiro, Wuhui Chen, Incheon Paik
2013 conf
iCAST/UMEDIA
Ryohei Komiya, Incheon Paik, Keun Ho Ryu
2013 J jnl
Inf. Syst. Frontiers
Wuhui Chen, Incheon Paik
2013 J jnl
J. Adv. Comput. Intell. Intell. Informatics
Wuhui Chen, Incheon Paik, Tetsuya Tashiro
2013 J jnl
Int. J. Bus. Process. Integr. Manag.
Incheon Paik, Wuhui Chen
2013 conf
IEEE SCC
Victor W. Chu, Raymond K. Wong, Wuhui Chen, Incheon Paik, Chi-Hung Chi
2013 conf
iCAST/UMEDIA
Banage T. G. S. Kumara, Incheon Paik, Hiroki Ohashi, Yuichi Yaguchi
2013 A conf
ICWS
Banage T. G. S. Kumara, Incheon Paik, Wuhui Chen
2012 conf
ICHIT (1)
Eonseok Shin, Tsendsuren Munkhdalai, Meijing Li, Incheon Paik, Keun Ho Ryu
2012 conf
iCAST
Incheon Paik, Ryohei Komiya, Wuhui Chen, Kyeongmu Lee
2012 conf
iCAST
Wuhui Chen, Ryusuke Tashiro, Incheon Paik, Takazumi Tanaka
2012 conf
IEEE SCC
Wuhui Chen, Incheon Paik, Ryohei Komiya
2012 conf
iCAST
Wuhui Chen, Incheon Paik, Tetsuya Tashiro, Daeyong Kang
2012 C conf
APSCC
Wuhui Chen, Incheon Paik, Patrick C. K. Hung
2012 A conf
ICWS
Wuhui Chen, Incheon Paik, Ryohei Komiya
2012 conf
DEXA (2)
Xiuming Yu, Meijing Li, Incheon Paik, Keun Ho Ryu
2012 conf
iCAST
Wuhui Chen, Incheon Paik, Daeyong Kang, Takazumi Tanaka
2011 B conf
SERVICES
Incheon Paik, Wuhui Chen, Ryohei Komiya
2011 conf
iCAST
Ryohei Komiya, Incheon Paik, Masayuki Hisada
2011 A conf
ICWS
Incheon Paik, Wuhui Chen, Ryohei Komiya
2011 conf
iCAST
Incheon Paik, Kyubo Kim, Wonhee Park, Ryohei Komiya
2010 B conf
SMC
Incheon Paik, Wuhui Chen
2010 J jnl
J. Adv. Comput. Intell. Intell. Informatics
Incheon Paik, Hiroshi Mizugai
2010 C conf
CIT
Hiroshi Mizugai, Incheon Paik, Wuhui Chen
2010 B conf
SMC
Incheon Paik, Shinsuke Mori, Wuhui Chen
2009 conf
CIT (2)
Incheon Paik, Haruhiko Takada
2009 conf
ICSOC/ServiceWave Workshops
Haruhiko Takada, Incheon Paik
2008 conf
FCST
Haruhiko Takada, Incheon Paik
2008 A conf
ICWS
Incheon Paik, Haruhiko Takada, Michael N. Huhns
2007 C conf
CIT
Incheon Paik, Daisuke Maruyama
2007 J jnl
Int. J. Agent Oriented Softw. Eng.
Incheon Paik, Hiroyuki Akimoto
2007 conf
AINA Workshops (2)
Incheon Paik, Hiroto Suzuki
2006 C conf
CIT
Daisuke Maruyama, Incheon Paik, Mitsuteru Shinozawa
2006 A conf
ICWS
Incheon Paik, Daisuke Maruyama, Michael N. Huhns
2005 conf
ICITA (1)
Incheon Paik, Hiroyuki Akimoto
2005 C conf
CIT
Ken Nariai, Incheon Paik, Mitsuteru Shinozawa
2005 J jnl
J. Organ. Comput. Electron. Commer.
Incheon Paik, Wonhee Park
2004 C conf
CIT
Incheon Paik, Md. Saidul Hossain, Md. Tofazzal Hossain
2004 conf
WWW Workshop on Application Design, Development and Implementation Issues in the Semantic Web
Incheon Paik, Hiroyuki Akimoto, Shinjirou Takami
2004 C conf
HIS
Incheon Paik, Shinjirou Takami, Yuu Watanabe
2003 J jnl
Inf. Softw. Technol.
Incheon Paik, Tongwon Han, Dongik Oh, Sangho Ha, Donggue Park
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