Weiliang Zhao

116 papers A* 3A 13B 9C 5Misc 1Journal 35Unranked 49
YearRankTypeTitle / Venue / Authors
2025 conf
NAACL (Long Papers)
Weiliang Zhao, Daniel Ben-Levi, Wei Hao, Junfeng Yang, Chengzhi Mao
2025 conf
ACL (1)
Wei Hao, Ran Li, Weiliang Zhao, Junfeng Yang, Chengzhi Mao
2025 J jnl
CoRR
Weiliang Zhao, Jinjun Peng, Daniel Ben-Levi, Zhou Yu, Junfeng Yang
2025 J jnl
Symmetry
Weiliang Zhao, Helin Gong
2025 conf
OFC
Weiliang Zhao, Xiangpeng Xiao, Jianbiao Wu, Zhengqi Sun, Hanlin Liu, Yijie Zhang, Peng Wang, Qizhen Sun, Zhijun Yan
2024 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Luke Rosenberg, Weiliang Zhao, Anthony Heng, Len Hamey, Si Tran Nguyen, Mehmet A. Orgun
2024 J jnl
CoRR
Weiliang Zhao, Daniel Ben-Levi, Junfeng Yang, Chengzhi Mao
2024 J jnl
CoRR
Wei Hao, Ran Li, Weiliang Zhao, Junfeng Yang, Chengzhi Mao
2024 conf
OFC
Xiangpeng Xiao, Weiliang Zhao, Yibo Liu, Ke Ai, Peng Wang, Lei Deng, Chen Liu, Qi Yang, Qizhen Sun, Zhijun Yan
2023 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Qi Wang, Weiliang Zhao, Jian Yang, Jia Wu, Shan Xue, Qianli Xing, Philip S. Yu
2023 conf
OFC
Cunzheng Fan, Xiangpeng Xiao, Hao Li, Weiliang Zhao, Zhijun Yan, Qizhen Sun
2023 conf
OFC
Xiangpeng Xiao, Qingguo Song, Weiliang Zhao, Hao Li, Qizhen Sun, Zhijun Yan
2023 J jnl
Future Gener. Comput. Syst.
Naime Ranjbar Kermany, Weiliang Zhao, Tseesuren Batsuuri, Jian Yang, Jia Wu
2023 B conf
WISE
Wei Huang, Guohao Sun, Mei Wang, Weiliang Zhao, Jian Yang
2022 J jnl
IEEE Trans. Serv. Comput.
Bin Cao, Jiaxing Wang, Jing Fan, Shuiguang Deng, Jian Yang, Weiliang Zhao, Jianwei Yin, MengChu Zhou
2021 J jnl
IEEE Trans. Intell. Transp. Syst.
Junling Shi, Liang Zhao, Xingwei Wang, Weiliang Zhao, Ammar Hawbani, Min Huang
2021 J jnl
World Wide Web
Naime Ranjbar Kermany, Weiliang Zhao, Jian Yang, Jia Wu, Luiz Pizzato
2021 conf
BIBM
Dehua Chen, Hongjin Zhao, Jianrong He, Qiao Pan, Weiliang Zhao
2021 J jnl
IEEE Intell. Syst.
Peiyao Li, Weiliang Zhao, Jian Yang, Jia Wu
2021 conf
SmartWorld/SCALCOM/UIC/ATC/IOP/SCI
Dehua Chen, Liping Zhang, Wei Zhang, Kun Shao, Weiliang Zhao, Xiaokang Zhou
2021 conf
CAIBDA
Dehua Chen, Wei Zhang, Kun Shao, Weiliang Zhao
2021 J jnl
IEEE Trans. Wirel. Commun.
Liang Zhao, Weiliang Zhao, Ammar Hawbani, Ahmed Al-Dubai, Geyong Min, Albert Y. Zomaya, Changqing Gong
2021 A conf
ICWS
Qianli Xing, Weiliang Zhao, Jian Yang, Jia Wu, Qi Wang
2021 A conf
ICWS
Qianli Xing, Weiliang Zhao, Jian Yang, Jia Wu, Qi Wang
2020 J jnl
Knowl. Inf. Syst.
Robertus Nugroho, Cécile Paris, Surya Nepal, Jian Yang, Weiliang Zhao
2020 conf
SCC
Naime Ranjbar Kermany, Weiliang Zhao, Jian Yang, Jia Wu, Luiz Pizzato
2020 A* conf
ICDM
Qi Wang, Weiliang Zhao, Jian Yang, Jia Wu, Chuan Zhou, Qianli Xing
2020 conf
SCC
Yang Guo, Weiliang Zhao, Jian Yang, Zizhu Zhang, Jia Wu, Tarique Anwar
2020 conf
APWeb/WAIM (2)
Haiqin Lu, Mei Wang, Weiliang Zhao, Tingwei Su, Jian Yang
2020 J jnl
World Wide Web
Peiyao Li, Weiliang Zhao, Jian Yang, Quan Z. Sheng, Jia Wu
2020 A conf
ICWS
Qianli Xing, Weiliang Zhao, Jian Yang, Jia Wu, Qi Wang
2020 J jnl
IEEE Trans. Knowl. Data Eng.
Lei Han, Jian Yang, Weiliang Zhao, Quan Z. Sheng
2020 J jnl
IEEE Trans. Serv. Comput.
Robertus Nugroho, Jian Yang, Weiliang Zhao, Cécile Paris, Surya Nepal
2019 conf
ICC
Liang Zhao, Weiliang Zhao, Ahmed Yassin Al-Dubai, Geyong Min
2019 J jnl
Serv. Oriented Comput. Appl.
Pengbo Xiu, Jian Yang, Weiliang Zhao
2019 A* conf
IJCAI
Peiyao Li, Weiliang Zhao, Jian Yang, Jia Wu
2019 A* conf
ICDM
Qi Wang, Weiliang Zhao, Jian Yang, Jia Wu, Wenbin Hu, Qianli Xing
2019 B conf
WISE
Qianli Xing, Weiliang Zhao, Jian Yang, Jia Wu, Qi Wang, Mei Wang
2019 conf
WWW (Companion Volume)
Zizhu Zhang, Weiliang Zhao, Jian Yang, Cécile Paris, Surya Nepal
2019 conf
WISE Workshops
Naime Ranjbar Kermany, Weiliang Zhao, Jian Yang, Jia Wu
2018 conf
WISE (1)
Peiyao Li, Weiliang Zhao, Jian Yang
2018 conf
ICSOC Workshops
Pengbo Xiu, Jian Yang, Weiliang Zhao
2017 conf
ACSW
Pengbo Xiu, Jian Yang, Weiliang Zhao
2017 A conf
ICWS
Lei Han, Weiliang Zhao, Jian Yang
2017 A conf
ICWS
Pengbo Xiu, Weiliang Zhao, Jian Yang
2017 conf
WISE (2)
Zizhu Zhang, Weiliang Zhao, Jian Yang, Surya Nepal, Cécile Paris, Bing Li
2017 conf
ICC
Yan Mei, Weiliang Zhao, Jian Yang
2017 conf
BigData Congress
Yan Mei, Weiliang Zhao, Jian Yang
2017 A conf
ICDCS
Robertus Nugroho, Weiliang Zhao, Jian Yang, Cécile Paris, Surya Nepal
2017 J jnl
World Wide Web
Robertus Nugroho, Weiliang Zhao, Jian Yang, Cécile Paris, Surya Nepal
2016 J jnl
ACM Trans. Web
Huiyuan Zheng, Jian Yang, Weiliang Zhao
2016 A conf
ICSOC
Lei Han, Weiliang Zhao, Jian Yang
2015 conf
WISE (1)
Yan Mei, Zizhu Zhang, Weiliang Zhao, Jian Yang, Robertus Nugroho
2015 conf
CBD
Zizhu Zhang, Bing Li, Weiliang Zhao, Jian Yang
2015 conf
WISE (1)
Robertus Nugroho, Weiliang Zhao, Jian Yang, Cécile Paris, Surya Nepal, Yan Mei
2014 ch.
Web Services Foundations
Huiyuan Zheng, Jian Yang, Weiliang Zhao
2013 conf
GreenCom/iThings/CPScom
Yun Li, Yafei Ma, Yong Wang, Weiliang Zhao
2013 J jnl
IEEE Trans. Veh. Technol.
Yun Li, Zhenghua Zhang, Chonggang Wang, Weiliang Zhao, Hsiao-Hwa Chen
2013 J jnl
IEEE Wirel. Commun.
Yun Li, Haluk Çelebi, Mahmoud Daneshmand, Chonggang Wang, Weiliang Zhao
2013 J jnl
IEEE Trans. Serv. Comput.
Huiyuan Zheng, Weiliang Zhao, Jian Yang, Athman Bouguettaya
2012 B conf
CEC
Hien Trang Nguyen, Jian Yang, Weiliang Zhao
2012 J jnl
Serv. Oriented Comput. Appl.
Yi Wang, Jian Yang, Weiliang Zhao, Jianwen Su
2012 A conf
ICSOC
Haiyang Sun, Weiliang Zhao, Surya Nepal
2012 C conf
ICCC
Yun Li, Xin Chen, Weiliang Zhao, Bin Cao
2012 conf
IEEE SCC
Haiyang Sun, Jian Yang, Weiliang Zhao, Surya Nepal
2012 B conf
GLOBECOM
Yun Li, Yaozhang Guo, Weiliang Zhao, Jihong Yu, Mahmoud Daneshmand
2012 J jnl
IEEE Trans. Serv. Comput.
Haiyang Sun, Jian Yang, Weiliang Zhao
2012 J jnl
Discret. Math. Theor. Comput. Sci.
Gerard Jennhwa Chang, Paul Dorbec, Hye Kyung Kim, André Raspaud, Haichao Wang, Weiliang Zhao
2011 B conf
WISE
Yi Wang, Jian Yang, Weiliang Zhao
2011 conf
ICSOC Workshops
Huiyuan Zheng, Jian Yang, Weiliang Zhao
2011 conf
WOCN
Yun Li, Xiaofen Zhu, Weiliang Zhao
2011 conf
OTM Conferences (1)
Youliang Zhong, Weiliang Zhao, Jian Yang, Lai Xu
2011 A conf
ICSOC
Youliang Zhong, Weiliang Zhao, Jian Yang
2011 A conf
ICSOC
Huiyuan Zheng, Jian Yang, Weiliang Zhao, Athman Bouguettaya
2011 B conf
WISE
Haiyang Sun, Weiliang Zhao, Jian Yang, Guizhi Shi
2011 conf
ICEBE
Yi Wang, Jian Yang, Weiliang Zhao
2011 J jnl
Wirel. Networks
Yun Li, Chonggang Wang, Xiaohu You, Weiliang Zhao, Kazem Sohraby
2010 conf
OTM Workshops
Huiyuan Zheng, Jian Yang, Weiliang Zhao
2010 A conf
ICWS
Hien Trang Nguyen, Weiliang Zhao, Jian Yang
2010 conf
SOCA
Yi Wang, Jian Yang, Weiliang Zhao
2010 C conf
APSCC
Yi Wang, Jian Yang, Weiliang Zhao
2010 conf
OTM Conferences (1)
Haiyang Sun, Weiliang Zhao, Jian Yang
2010 conf
WISE Workshops
Huiyuan Zheng, Jian Yang, Weiliang Zhao
2010 conf
IEEE CLOUD
Mahbub Hassan, Weiliang Zhao, Jian Yang
2010 conf
IEEE SCC
Huiyuan Zheng, Jian Yang, Weiliang Zhao
2010 conf
SOCA
Huiyuan Zheng, Jian Yang, Weiliang Zhao
2010 C conf
APSCC
Huiyuan Zheng, Jian Yang, Weiliang Zhao
2010 conf
IEEE SCC
Haiyang Sun, Weiliang Zhao, Jian Yang
2010 J jnl
Int. J. Organ. Collect. Intell.
Weiliang Zhao, Jian Yang
2009 J jnl
RITA
Haiyang Sun, Jian Yang, Weiliang Zhao
2009 conf
IEEE SCC
Huiyuan Zheng, Weiliang Zhao, Jian Yang, Athman Bouguettaya
2009 J jnl
Int. J. Commun. Syst.
Yun Li, Chonggang Wang, Weiliang Zhao, Xiaohu You
2008 C conf
ICIW
Weiliang Zhao, Vijay Varadharajan
2008 J jnl
Wirel. Pers. Commun.
Yun Li, Chonggang Wang, Keping Long, Weiliang Zhao
2008 conf
ICNSC
Lin Wang, Weiliang Zhao, Yun Li, Yi Qu, Zhanjun Liu, Qianbin Chen
2008 A conf
ICWS
Weiliang Zhao, Vijay Varadharajan
2007 conf
MMNS
Xian Zhou, Yun Li, Weiliang Zhao, Zhanjun Liu, Qianbin Chen
2006 J jnl
Wirel. Pers. Commun.
Yun Li, Keping Long, Weiliang Zhao, Qianbin Chen
2006 C conf
SecureComm
Weiliang Zhao, Vijay Varadharajan, George Bryan
2006 B conf
IWCMC
Feng Li, Yun Li, Weiliang Zhao, Qianbin Chen, Weiwen Tang
2006 J jnl
Int. J. Commun. Syst.
Yun Li, Keping Long, Weiliang Zhao
2006 J jnl
J. Comput.
Weiliang Zhao, Vijay Varadharajan, George Bryan
2005 conf
MSN
Yun Li, Weiliang Zhao, Keping Long, Qianbin Chen
2005 conf
MSN
Yun Li, Keping Long, Weiliang Zhao, Chonggang Wang, Kazem Sohraby
2005 conf
MMNS
Yun Li, Keping Long, Weiliang Zhao, Qianbin Chen, Yujun Kuang
2005 Misc conf
ICISS
Weiliang Zhao, Vijay Varadharajan, George Bryan
2005 B conf
GLOBECOM
Yun Li, Keping Long, Weiliang Zhao, Chonggang Wang
2005 conf
ICC
Yun Li, Keping Long, Weiliang Zhao, Feng-Rui Yang, Qianbin Chen
2005 conf
ITCC (1)
Weiliang Zhao, Vijay Varadharajan
2005 J jnl
J. Comput. Sci. Technol.
Yun Li, Keping Long, Weiliang Zhao, Feng-Rui Yang
2005 conf
ICEIS (3)
Weiliang Zhao, Vijay Varadharajan, George Bryan
2004 conf
WOSIS
Weiliang Zhao, Vijay Varadharajan, George Bryan
2004 J jnl
Inf. Secur. J. A Glob. Perspect.
Weiliang Zhao, Vijay Varadharajan, George Bryan
2004 B conf
TrustBus
Weiliang Zhao, Vijay Varadharajan, George Bryan
2003 conf
ACSW
Weiliang Zhao, Vijay Varadharajan, Yi Mu
2000 A conf
ACSAC
Weiliang Zhao, Vijay Varadharajan, Yi Mu
redb/extractors/decompiler/apk/method_extractor.py
← Index redb/extractors/decompiler/apk/method_extractor.py python
"""Per-method content extraction, hashing, and similarity computation.

Handles SHA-256 content hashing, ssdeep/TLSH fuzzy hashing, MinHash
computation, and obfuscation indicator detection for APK methods.
"""

import hashlib
import re
from typing import Dict, List, Optional

from redb.extractors.decompiler.apk.smali_normalization import (
    categorize_opcode,
    normalize_method_body,
)
from redb.extractors.decompiler.apk.smali_parser import SmaliParser


# ---------------------------------------------------------------------------
# Smali Prime Product — semantic primes matching Binary Ninja's LLIL primes
# ---------------------------------------------------------------------------
# Each Dalvik semantic category maps to the same prime its LLIL counterpart
# uses in cfg_features.py. This makes prime products semantically comparable
# for APK-vs-APK similarity (not numerically comparable to Binja values).

SMALI_OP_PRIMES = {
    "ALU": 37,       # ADD/SUB → same prime as LLIL_ADD
    "CONV": 131,     # Type conversions → same as LLIL_SX
    "CMP": 103,      # Comparisons → same as LLIL_CMP_E
    "MOV": 2,        # Register moves → same as LLIL_SET_REG
    "CONST": 2,      # Constants → SET_REG equivalent
    "LOAD": 5,       # Field/array reads → same as LLIL_LOAD
    "STORE": 7,      # Field/array writes → same as LLIL_STORE
    "CALL": 17,      # invoke-* → same as LLIL_CALL
    "BRANCH": 29,    # if-* → same as LLIL_IF
    "JMP": 31,       # goto → same as LLIL_GOTO
    "SWITCH": 151,   # switch → same as LLIL_JUMP_TO
    "RET": 23,       # return → same as LLIL_RET
    "ALLOC": 5,      # new-instance/new-array → LOAD-adjacent (heap access)
    "TYPE": 1,       # check-cast/instance-of → identity (metadata)
    "ARR": 5,        # array-length/fill-array → LOAD-adjacent
    "EXC": 23,       # throw → RET-adjacent (control transfer out)
    "SYNC": 1,       # monitor → identity (no LLIL equivalent)
    "OTHER": 1,      # Unknown → identity
}


def compute_prime_product_smali(smali_body: str) -> int:
    """Multiplicative hash of normalized Dalvik opcodes. Mod 2^64.

    Same algorithm as cfg_features.compute_prime_product but using
    Dalvik semantic categories instead of LLIL operation enums.
    """
    if not smali_body:
        return 0

    product = 1
    for line in smali_body.splitlines():
        stripped = line.strip()
        if not stripped or stripped.startswith((".", ":", "#")):
            continue
        opcode = stripped.split()[0].split("/")[0] if stripped else ""
        category = categorize_opcode(opcode)
        prime = SMALI_OP_PRIMES.get(category, 1)
        product = (product * prime) % (2**64)

    return product


def count_call_instructions(smali_body: str) -> int:
    """Count invoke-* instructions in a smali method body."""
    if not smali_body:
        return 0
    count = 0
    for line in smali_body.splitlines():
        stripped = line.strip()
        if stripped.startswith("invoke-"):
            count += 1
    return count


def compute_sha256(content: str) -> str:
    """Compute SHA-256 hash of normalized content."""
    return hashlib.sha256(content.encode("utf-8")).hexdigest()


def compute_ssdeep(content: str) -> Optional[str]:
    """Compute ssdeep fuzzy hash of content."""
    try:
        import ppdeep
        data = content.encode("utf-8")
        if len(data) < 50:
            return None
        result = ppdeep.hash(data)
        return result if result else None
    except (ImportError, Exception):
        return None


def compute_tlsh(content: str) -> Optional[str]:
    """Compute TLSH fuzzy hash of content."""
    try:
        import tlsh
        data = content.encode("utf-8")
        if len(data) < 50:
            return None
        result = tlsh.hash(data)
        return result if result else None
    except (ImportError, Exception):
        return None


def compute_minhash(
    content: str,
    n: int = 3,
    normalization_level: str = "opcode_api",
) -> Optional[List[int]]:
    """Compute MinHash signature from semantically normalized smali n-grams.

    Applies semantic normalization (analogous to Binary Ninja's LLIL) before
    computing the MinHash. This strips register allocation noise and
    instruction encoding variants while preserving operation semantics and
    API references.

    Uses the same algorithm and parameters as the Binary Ninja MinHasher
    (64 seeds from master seed 0xdeadbeef, 8-bit signature elements, mmh3)
    to ensure cross-platform similarity comparisons are compatible.

    Args:
        content: Raw smali method body.
        n: N-gram size (default 3).
        normalization_level: Normalization level for instructions.
            'opcode_api' (default) preserves API call/field references.
            'category' uses only semantic categories.
            'opcode' uses base opcodes without operands.
    """
    try:
        import mmh3
    except ImportError:
        return None

    HASH_MAX = 0xFFFFFFFF
    SIGNATURE_LENGTH = 64
    SIGNATURE_BITS = 8

    # Semantically normalize instructions (like LLIL for native code)
    lines = normalize_method_body(content, level=normalization_level)

    if len(lines) < n:
        return None

    # Build n-grams (tuples of normalized instruction strings)
    shingles = [tuple(lines[i:i + n]) for i in range(len(lines) - n + 1)]

    if not shingles:
        return None

    # Generate deterministic seeds matching the Binary Ninja pipeline
    import random
    rng = random.Random(0xDEADBEEF)
    seeds = [rng.randint(0, HASH_MAX) for _ in range(SIGNATURE_LENGTH)]

    # For each seed, hash all shingles and take the minimum
    signature = []
    for seed in seeds:
        min_val = HASH_MAX
        for shingle in shingles:
            text = "|".join(str(elem) for elem in shingle)
            h = mmh3.hash(text, seed) & HASH_MAX
            if h < min_val:
                min_val = h
        # Truncate to signature bits
        if SIGNATURE_BITS < 32:
            min_val %= (2 ** SIGNATURE_BITS)
        signature.append(min_val)

    return signature


def detect_obfuscation_indicators(
    method_name: str,
    class_name: str,
    smali_body: str,
    instruction_count: int,
) -> Dict[str, bool]:
    """Compute obfuscation indicators for a method.

    Returns dict with boolean indicators.
    """
    indicators = {}

    # Short method name (typical R8/ProGuard output)
    indicators["short_method_name"] = len(method_name) <= 2

    # Short class name — extract simple name from Dalvik descriptor
    simple_class = class_name
    if "/" in simple_class:
        simple_class = simple_class.rsplit("/", 1)[-1]
    simple_class = simple_class.rstrip(";")
    indicators["short_class_name"] = len(simple_class) <= 2

    # String encryption: const-string followed by decryption-pattern call
    indicators["has_string_encryption"] = _detect_string_encryption(smali_body)

    # Reflection calls
    indicators["has_reflection_calls"] = _detect_reflection_calls(smali_body)

    # Excessive goto count (control flow flattening)
    goto_count = _count_goto_instructions(smali_body)
    threshold = max(5, int(instruction_count * 0.15))
    indicators["excessive_goto_count"] = goto_count > threshold

    return indicators


def _detect_string_encryption(smali_body: str) -> bool:
    """Detect const-string followed by decryption-pattern calls."""
    lines = smali_body.split("\n")
    for i, line in enumerate(lines):
        stripped = line.strip()
        if stripped.startswith("const-string"):
            # Check the next 3 lines for invoke-* to potential decryption
            for j in range(i + 1, min(i + 4, len(lines))):
                next_line = lines[j].strip()
                if next_line.startswith("invoke-"):
                    # Common decryption patterns
                    if any(
                        pat in next_line
                        for pat in [
                            "decrypt",
                            "decode",
                            "Cipher",
                            "DES",
                            "AES",
                            "Base64",
                            "getBytes",
                        ]
                    ):
                        return True
    return False


def _detect_reflection_calls(smali_body: str) -> bool:
    """Detect use of Java reflection APIs."""
    reflection_patterns = [
        "Ljava/lang/reflect/",
        "Ljava/lang/Class;->forName",
        "Ljava/lang/Class;->getMethod",
        "Ljava/lang/Class;->getDeclaredMethod",
        "Ljava/lang/Class;->getField",
        "Ljava/lang/Class;->getDeclaredField",
    ]
    for pattern in reflection_patterns:
        if pattern in smali_body:
            return True
    return False


def _count_goto_instructions(smali_body: str) -> int:
    """Count goto/goto_16/goto_32 instructions."""
    count = 0
    for line in smali_body.split("\n"):
        stripped = line.strip()
        if stripped.startswith(("goto ", "goto/16 ", "goto/32 ")):
            count += 1
        elif stripped in ("goto", "goto/16", "goto/32"):
            count += 1
    return count


def dalvik_to_java_class(descriptor: str) -> str:
    """Convert Dalvik class descriptor to Java dot notation.

    Lcom/example/Foo; -> com.example.Foo
    """
    if descriptor.startswith("L") and descriptor.endswith(";"):
        return descriptor[1:-1].replace("/", ".")
    return descriptor.replace("/", ".")


def dalvik_type_to_java(type_desc: str) -> str:
    """Convert a Dalvik type descriptor to Java type name."""
    type_map = {
        "V": "void",
        "Z": "boolean",
        "B": "byte",
        "S": "short",
        "C": "char",
        "I": "int",
        "J": "long",
        "F": "float",
        "D": "double",
    }

    if not type_desc:
        return "void"

    if type_desc in type_map:
        return type_map[type_desc]

    if type_desc.startswith("["):
        return dalvik_type_to_java(type_desc[1:]) + "[]"

    if type_desc.startswith("L") and type_desc.endswith(";"):
        full = type_desc[1:-1].replace("/", ".")
        # Return simple name
        return full.rsplit(".", 1)[-1] if "." in full else full

    return type_desc


def dalvik_to_java_prototype(
    method_name: str, signature: str, class_name: str = ""
) -> str:
    """Convert Dalvik method signature to Java-style prototype.

    Input: method_name='onCreate', signature='(Landroid/os/Bundle;)V'
    Output: 'void onCreate(Bundle)'
    """
    # Parse return type and param types from signature
    if not signature or not signature.startswith("("):
        return f"void {method_name}()"

    close_paren = signature.find(")")
    if close_paren == -1:
        return f"void {method_name}()"

    params_str = signature[1:close_paren]
    return_type_str = signature[close_paren + 1:]

    return_type = dalvik_type_to_java(return_type_str)
    params = _parse_dalvik_params(params_str)
    param_java = ", ".join(dalvik_type_to_java(p) for p in params)

    return f"{return_type} {method_name}({param_java})"


def _parse_dalvik_params(params_str: str) -> List[str]:
    """Parse Dalvik parameter descriptor string into individual types."""
    params = []
    i = 0
    while i < len(params_str):
        ch = params_str[i]
        if ch in "VZBSCIJFD":
            params.append(ch)
            i += 1
        elif ch == "[":
            # Array — find the base type
            array_prefix = "["
            i += 1
            while i < len(params_str) and params_str[i] == "[":
                array_prefix += "["
                i += 1
            if i < len(params_str):
                if params_str[i] == "L":
                    end = params_str.find(";", i)
                    if end != -1:
                        params.append(array_prefix + params_str[i : end + 1])
                        i = end + 1
                    else:
                        break
                else:
                    params.append(array_prefix + params_str[i])
                    i += 1
        elif ch == "L":
            end = params_str.find(";", i)
            if end != -1:
                params.append(params_str[i : end + 1])
                i = end + 1
            else:
                break
        else:
            i += 1
    return params