Wanjun Zhong

95 papers A* 8A 3B 1Journal 61Unranked 22
YearRankTypeTitle / Venue / Authors
2026 J jnl
Trans. Mach. Learn. Res.
Shijue Huang, Hongru Wang, Wanjun Zhong, Zhaochen Su, Jiazhan Feng, Bowen Cao, Yi R. Fung
2025 J jnl
CoRR
Shijue Huang, Hongru Wang, Wanjun Zhong, Zhaochen Su, Jiazhan Feng, Bowen Cao, Yi R. (May) Fung
2025 J jnl
Inf. Process. Manag.
Jianpeng Zhou, Wanjun Zhong, Yanlin Wang, Jiahai Wang
2025 J jnl
Autom. Softw. Eng.
Yanlin Wang, Wanjun Zhong, Yanxian Huang, Ensheng Shi, Min Yang, Jiachi Chen, Hui Li, Yuchi Ma, Qianxiang Wang, Zibin Zheng
2025 J jnl
Image Vis. Comput.
Peng Zan, Yuerong Wang, Haohao Hu, Wanjun Zhong, Tianyu Han, Jingwei Yue
2025 J jnl
CoRR
Shuangshuang Ying, Yunwen Li, Xingwei Qu, Xin Li, Sheng Jin, Minghao Liu, Zhoufutu Wen, Xeron Du, Tianyu Zheng, Yichi Zhang, Letian Ni, Yuyang Cheng, Qiguang Chen, Jingzhe Ding, Shengda Long, Wangchunshu Zhou, Jiazhan Feng, Wanjun Zhong, Libo Qin, Ge Zhang, Wenhao Huang, Wanxiang Che, Chenghua Lin
2025 J jnl
CoRR
Yunwen Li, Shuangshuang Ying, Xingwei Qu, Xin Li, Sheng Jin, Minghao Liu, Zhoufutu Wen, Tianyu Zheng, Xeron Du, Qiguang Chen, Jiajun Shi, Wangchunshu Zhou, Jiazhan Feng, Wanjun Zhong, Libo Qin, Stephen Huang, Wanxiang Che, Chenghua Lin, Eli Zhang
2025 A* conf
AAAI
Shijue Huang, Wanjun Zhong, Deng Cai, Fanqi Wan, Chengyi Wang, Mingxuan Wang, Mu Qiao, Ruifeng Xu
2025 A* conf
AAAI
Qiming Bao, Juho Leinonen, Alex Yuxuan Peng, Wanjun Zhong, Gaël Gendron, Timothy Pistotti, Alice Huang, Paul Denny, Michael Witbrock, Jiamou Liu
2025 A* conf
ICLR
Jiahui Gao, Renjie Pi, Jipeng Zhang, Jiacheng Ye, Wanjun Zhong, Yufei Wang, Lanqing Hong, Jianhua Han, Hang Xu, Zhenguo Li, Lingpeng Kong
2025 J jnl
CoRR
Zihao Wang, Xujing Li, Yining Ye, Junjie Fang, Haoming Wang, Longxiang Liu, Shihao Liang, Junting Lu, Zhiyong Wu, Jiazhan Feng, Wanjun Zhong, Zili Li, Yu Wang, Yu Miao, Bo Zhou, Yuanfan Li, Hao Wang, Zhongkai Zhao, Faming Wu, Zhengxuan Jiang, Weihao Tan, Heyuan Yao, Shi Yan, Xiangyang Li, Yitao Liang, Yujia Qin, Guang Shi
2025 J jnl
Int. J. Comput. Vis.
Haohao Hu, Tianyu Han, Yuerong Wang, Wanjun Zhong, Jingwei Yue, Peng Zan
2025 J jnl
Vis. Comput.
Wanjun Zhong, Haohao Hu, Yuerong Wang, Li Li, Tianyu Han, Chunyong Li, Peng Zan
2025 J jnl
Proc. ACM Softw. Eng.
Ziyao Zhang, Chong Wang, Yanlin Wang, Ensheng Shi, Yuchi Ma, Wanjun Zhong, Jiachi Chen, Mingzhi Mao, Zibin Zheng
2025 J jnl
CoRR
Hongru Wang, Cheng Qian, Wanjun Zhong, Xiusi Chen, Jiahao Qiu, Shijue Huang, Bowen Jin, Mengdi Wang, Kam-Fai Wong, Heng Ji
2025 J jnl
CoRR
Jiazhan Feng, Shijue Huang, Xingwei Qu, Ge Zhang, Yujia Qin, Baoquan Zhong, Chengquan Jiang, Jinxin Chi, Wanjun Zhong
2025 J jnl
CoRR
Haozhe Wang, Haoran Que, Qixin Xu, Minghao Liu, Wangchunshu Zhou, Jiazhan Feng, Wanjun Zhong, Wei Ye, Tong Yang, Wenhao Huang, Ge Zhang, Fangzhen Lin
2025 conf
ACL (Findings)
Hongru Wang, Deng Cai, Wanjun Zhong, Shijue Huang, Jeff Z. Pan, Zeming Liu, Kam-Fai Wong
2025 J jnl
CoRR
Hongru Wang, Deng Cai, Wanjun Zhong, Shijue Huang, Jeff Z. Pan, Zeming Liu, Kam-Fai Wong
2025 J jnl
CoRR
Yujia Qin, Yining Ye, Junjie Fang, Haoming Wang, Shihao Liang, Shizuo Tian, Junda Zhang, Jiahao Li, Yunxin Li, Shijue Huang, Wanjun Zhong, Kuanye Li, Jiale Yang, Yu Miao, Woyu Lin, Longxiang Liu, Xu Jiang, Qianli Ma, Jingyu Li, Xiaojun Xiao, Kai Cai, Chuang Li, Yaowei Zheng, Chaolin Jin, Chen Li, Xiao Zhou, Minchao Wang, Haoli Chen, Zhaojian Li, Haihua Yang, Haifeng Liu, Feng Lin, Tao Peng, Xin Liu, Guang Shi
2024 conf
NAACL-HLT (Findings)
Wanjun Zhong, Ruixiang Cui, Yiduo Guo, Yaobo Liang, Shuai Lu, Yanlin Wang, Amin Saied, Weizhu Chen, Nan Duan
2024 conf
ACL (Findings)
Qiming Bao, Alex Yuxuan Peng, Zhenyun Deng, Wanjun Zhong, Gaël Gendron, Timothy Pistotti, Neset Tan, Nathan Young, Yang Chen, Yonghua Zhu, Paul Denny, Michael Witbrock, Jiamou Liu
2024 J jnl
CoRR
Yanlin Wang, Wanjun Zhong, Yanxian Huang, Ensheng Shi, Min Yang, Jiachi Chen, Hui Li, Yuchi Ma, Qianxiang Wang, Zibin Zheng
2024 conf
ICONIP (10)
Qiming Bao, Gaël Gendron, Alex Yuxuan Peng, Wanjun Zhong, Neset Tan, Yang Chen, Michael Witbrock, Jiamou Liu
2024 J jnl
CoRR
Ziming Li, Qianbo Zang, David Ma, Jiawei Guo, Tuney Zheng, Minghao Liu, Xinyao Niu, Yue Wang, Jian Yang, Jiaheng Liu, Wanjun Zhong, Wangchunshu Zhou, Wenhao Huang, Ge Zhang
2024 J jnl
Pattern Recognit. Lett.
Qiqi Gao, Wanjun Zhong, Jie Li, Tiejun Zhao
2024 conf
EMNLP (Findings)
Zexuan Qiu, Jingjing Li, Shijue Huang, Xiaoqi Jiao, Wanjun Zhong, Irwin King
2024 J jnl
CoRR
Zexuan Qiu, Jingjing Li, Shijue Huang, Wanjun Zhong, Irwin King
2024 conf
ACL (Findings)
Yang Xu, Yunlong Feng, Honglin Mu, Yutai Hou, Yitong Li, Xinghao Wang, Wanjun Zhong, Zhongyang Li, Dandan Tu, Qingfu Zhu, Min Zhang, Wanxiang Che
2024 J jnl
CoRR
Yang Xu, Yunlong Feng, Honglin Mu, Yutai Hou, Yitong Li, Xinghao Wang, Wanjun Zhong, Zhongyang Li, Dandan Tu, Qingfu Zhu, Min Zhang, Wanxiang Che
2024 conf
ACL (1)
Yuxin Jiang, Yufei Wang, Xingshan Zeng, Wanjun Zhong, Liangyou Li, Fei Mi, Lifeng Shang, Xin Jiang, Qun Liu, Wei Wang
2024 conf
ACL (1)
Yuxin Jiang, Yufei Wang, Chuhan Wu, Wanjun Zhong, Xingshan Zeng, Jiahui Gao, Liangyou Li, Xin Jiang, Lifeng Shang, Ruiming Tang, Qun Liu, Wei Wang
2024 J jnl
CoRR
Yuxin Jiang, Yufei Wang, Chuhan Wu, Wanjun Zhong, Xingshan Zeng, Jiahui Gao, Liangyou Li, Xin Jiang, Lifeng Shang, Ruiming Tang, Qun Liu, Wei Wang
2024 A* conf
AAAI
Wanjun Zhong, Lianghong Guo, Qiqi Gao, He Ye, Yanlin Wang
2024 J jnl
CoRR
Yiming Du, Hongru Wang, Zhengyi Zhao, Bin Liang, Baojun Wang, Wanjun Zhong, Zezhong Wang, Kam-Fai Wong
2024 conf
ACL (Findings)
Shijue Huang, Wanjun Zhong, Jianqiao Lu, Qi Zhu, Jiahui Gao, Weiwen Liu, Yutai Hou, Xingshan Zeng, Yasheng Wang, Lifeng Shang, Xin Jiang, Ruifeng Xu, Qun Liu
2024 J jnl
CoRR
Shijue Huang, Wanjun Zhong, Jianqiao Lu, Qi Zhu, Jiahui Gao, Weiwen Liu, Yutai Hou, Xingshan Zeng, Yasheng Wang, Lifeng Shang, Xin Jiang, Ruifeng Xu, Qun Liu
2024 A conf
ISSTA
Lianghong Guo, Yanlin Wang, Ensheng Shi, Wanjun Zhong, Hongyu Zhang, Jiachi Chen, Ruikai Zhang, Yuchi Ma, Zibin Zheng
2024 J jnl
CoRR
Lianghong Guo, Yanlin Wang, Ensheng Shi, Wanjun Zhong, Hongyu Zhang, Jiachi Chen, Ruikai Zhang, Yuchi Ma, Zibin Zheng
2024 J jnl
CoRR
Jianqiao Lu, Wanjun Zhong, Yufei Wang, Zhijiang Guo, Qi Zhu, Wenyong Huang, Yanlin Wang, Fei Mi, Baojun Wang, Yasheng Wang, Lifeng Shang, Xin Jiang, Qun Liu
2024 J jnl
CoRR
Yanlin Wang, Lianghong Guo, Ensheng Shi, Wenqing Chen, Jiachi Chen, Wanjun Zhong, Menghan Wang, Hui Li, Hongyu Zhang, Ziyu Lyu, Zibin Zheng
2023 J jnl
CoRR
Qiming Bao, Gaël Gendron, Alex Yuxuan Peng, Wanjun Zhong, Neset Tan, Yang Chen, Michael Witbrock, Jiamou Liu
2023 J jnl
CoRR
Wanjun Zhong, Ruixiang Cui, Yiduo Guo, Yaobo Liang, Shuai Lu, Yanlin Wang, Amin Saied, Weizhu Chen, Nan Duan
2023 J jnl
CoRR
Jianpeng Zhou, Wanjun Zhong, Yanlin Wang, Jiahai Wang
2023 J jnl
CoRR
Yufei Wang, Wanjun Zhong, Liangyou Li, Fei Mi, Xingshan Zeng, Wenyong Huang, Lifeng Shang, Xin Jiang, Qun Liu
2023 conf
ACL (1)
Zhijian Hou, Wanjun Zhong, Lei Ji, Difei Gao, Kun Yan, Wing Kwong Chan, Chong-Wah Ngo, Mike Zheng Shou, Nan Duan
2023 J jnl
CoRR
Qiming Bao, Alex Yuxuan Peng, Zhenyun Deng, Wanjun Zhong, Neset Tan, Nathan Young, Yang Chen, Yonghua Zhu, Michael Witbrock, Jiamou Liu
2023 A conf
ICME
Zenan Xu, Wanjun Zhong, Qinliang Su, Fuwei Zhang
2023 J jnl
CoRR
Zige Wang, Wanjun Zhong, Yufei Wang, Qi Zhu, Fei Mi, Baojun Wang, Lifeng Shang, Xin Jiang, Qun Liu
2023 conf
ACL (Findings)
Wanjun Zhong, Tingting Ma, Jiahai Wang, Jian Yin, Tiejun Zhao, Chin-Yew Lin, Nan Duan
2023 J jnl
CoRR
Qiming Bao, Juho Leinonen, Alex Yuxuan Peng, Wanjun Zhong, Tim Pistotti, Alice Huang, Paul Denny, Michael Witbrock, Jiamou Liu
2023 J jnl
CoRR
Yuxin Jiang, Yufei Wang, Xingshan Zeng, Wanjun Zhong, Liangyou Li, Fei Mi, Lifeng Shang, Xin Jiang, Qun Liu, Wei Wang
2023 J jnl
CoRR
Jiahui Gao, Renjie Pi, Jipeng Zhang, Jiacheng Ye, Wanjun Zhong, Yufei Wang, Lanqing Hong, Jianhua Han, Hang Xu, Zhenguo Li, Lingpeng Kong
2023 J jnl
CoRR
Zhijian Hou, Lei Ji, Difei Gao, Wanjun Zhong, Kun Yan, Chao Li, Wing-Kwong Chan, Chong-Wah Ngo, Nan Duan, Mike Zheng Shou
2023 J jnl
AI Open
Wanjun Zhong, Yifan Gao, Ning Ding, Zhiyuan Liu, Ming Zhou, Jiahai Wang, Jian Yin, Nan Duan
2023 B conf
ICIP
Qiqi Gao, Wanjun Zhong, Jie Li, Tiejun Zhao
2023 J jnl
CoRR
Wanjun Zhong, Lianghong Guo, Qiqi Gao, He Ye, Yanlin Wang
2023 J jnl
CoRR
Jianqiao Lu, Wanjun Zhong, Wenyong Huang, Yufei Wang, Fei Mi, Baojun Wang, Weichao Wang, Lifeng Shang, Qun Liu
2023 A conf
ICSME
Yanlin Wang, Lianghong Guo, Ensheng Shi, Wenqing Chen, Jiachi Chen, Wanjun Zhong, Menghan Wang, Hui Li, Hongyu Zhang, Ziyu Lyu, Zibin Zheng
2022 J jnl
CoRR
Zhijian Hou, Wanjun Zhong, Lei Ji, Difei Gao, Kun Yan, Wing Kwong Chan, Chong-Wah Ngo, Zheng Shou, Nan Duan
2022 conf
NAACL-HLT (Findings)
Wanjun Zhong, Siyuan Wang, Duyu Tang, Zenan Xu, Daya Guo, Yining Chen, Jiahai Wang, Jian Yin, Ming Zhou, Nan Duan
2022 J jnl
CoRR
Zhijian Hou, Wanjun Zhong, Lei Ji, Difei Gao, Kun Yan, Wing Kwong Chan, Chong-Wah Ngo, Zheng Shou, Nan Duan
2022 J jnl
CoRR
Wanjun Zhong, Tingting Ma, Jiahai Wang, Jian Yin, Tiejun Zhao, Chin-Yew Lin, Nan Duan
2022 J jnl
IEEE ACM Trans. Audio Speech Lang. Process.
Siyuan Wang, Zhongkun Liu, Wanjun Zhong, Ming Zhou, Zhongyu Wei, Zhumin Chen, Nan Duan
2022 J jnl
CoRR
Wanjun Zhong, Yifan Gao, Ning Ding, Zhiyuan Liu, Ming Zhou, Jiahai Wang, Jian Yin, Nan Duan
2022 A* conf
NeurIPS
Xinyu Pi, Wanjun Zhong, Yan Gao, Nan Duan, Jian-Guang Lou
2022 J jnl
CoRR
Xinyu Pi, Wanjun Zhong, Yan Gao, Nan Duan, Jian-Guang Lou
2022 conf
ACL (Findings)
Siyuan Wang, Wanjun Zhong, Duyu Tang, Zhongyu Wei, Zhihao Fan, Daxin Jiang, Ming Zhou, Nan Duan
2022 conf
EMNLP (Findings)
Junjie Huang, Wanjun Zhong, Qian Liu, Ming Gong, Daxin Jiang, Nan Duan
2022 J jnl
CoRR
Junjie Huang, Wanjun Zhong, Qian Liu, Ming Gong, Daxin Jiang, Nan Duan
2022 J jnl
CoRR
Zenan Xu, Wanjun Zhong, Qinliang Su, Zijing Ou, Fuwei Zhang
2022 conf
NAACL-HLT
Wanjun Zhong, Yifan Gao, Ning Ding, Yujia Qin, Zhiyuan Liu, Ming Zhou, Jiahai Wang, Jian Yin, Nan Duan
2022 J jnl
CoRR
Wanjun Zhong, Yifan Gao, Ning Ding, Yujia Qin, Zhiyuan Liu, Ming Zhou, Jiahai Wang, Jian Yin, Nan Duan
2022 J jnl
CoRR
Wanjun Zhong, Junjie Huang, Qian Liu, Ming Zhou, Jiahai Wang, Jian Yin, Nan Duan
2022 A* conf
IJCAI
Wanjun Zhong, Junjie Huang, Qian Liu, Ming Zhou, Jiahai Wang, Jian Yin, Nan Duan
2021 J jnl
CoRR
Wanjun Zhong, Siyuan Wang, Duyu Tang, Zenan Xu, Daya Guo, Jiahai Wang, Jian Yin, Ming Zhou, Nan Duan
2021 conf
ACL/IJCNLP (1)
Linmei Hu, Tianchi Yang, Luhao Zhang, Wanjun Zhong, Duyu Tang, Chuan Shi, Nan Duan, Ming Zhou
2021 J jnl
CoRR
Siyuan Wang, Zhongkun Liu, Wanjun Zhong, Ming Zhou, Zhongyu Wei, Zhumin Chen, Nan Duan
2021 J jnl
CoRR
Siyuan Wang, Wanjun Zhong, Duyu Tang, Zhongyu Wei, Zhihao Fan, Daxin Jiang, Ming Zhou, Nan Duan
2021 conf
ACL/IJCNLP (1)
Zenan Xu, Daya Guo, Duyu Tang, Qinliang Su, Linjun Shou, Ming Gong, Wanjun Zhong, Xiaojun Quan, Daxin Jiang, Nan Duan
2021 conf
ACL/IJCNLP (Findings)
Wanjun Zhong, Duyu Tang, Jiahai Wang, Jian Yin, Nan Duan
2021 conf
EMNLP (Findings)
Junjie Huang, Duyu Tang, Wanjun Zhong, Shuai Lu, Linjun Shou, Ming Gong, Daxin Jiang, Nan Duan
2021 J jnl
CoRR
Junjie Huang, Duyu Tang, Wanjun Zhong, Shuai Lu, Linjun Shou, Ming Gong, Daxin Jiang, Nan Duan
2020 J jnl
CoRR
Wanjun Zhong, Duyu Tang, Nan Duan, Ming Zhou, Jiahai Wang, Jian Yin
2020 conf
EMNLP (1)
Ruize Wang, Duyu Tang, Nan Duan, Wanjun Zhong, Zhongyu Wei, Xuanjing Huang, Daxin Jiang, Ming Zhou
2020 J jnl
CoRR
Ruize Wang, Duyu Tang, Nan Duan, Wanjun Zhong, Zhongyu Wei, Xuanjing Huang, Daxin Jiang, Ming Zhou
2020 A* conf
ACL
Wanjun Zhong, Duyu Tang, Zhangyin Feng, Nan Duan, Ming Zhou, Ming Gong, Linjun Shou, Daxin Jiang, Jiahai Wang, Jian Yin
2020 J jnl
CoRR
Wanjun Zhong, Duyu Tang, Zhangyin Feng, Nan Duan, Ming Zhou, Ming Gong, Linjun Shou, Daxin Jiang, Jiahai Wang, Jian Yin
2020 conf
EMNLP (1)
Wanjun Zhong, Duyu Tang, Zenan Xu, Ruize Wang, Nan Duan, Ming Zhou, Jiahai Wang, Jian Yin
2020 J jnl
CoRR
Wanjun Zhong, Duyu Tang, Zenan Xu, Ruize Wang, Nan Duan, Ming Zhou, Jiahai Wang, Jian Yin
2020 A* conf
ACL
Wanjun Zhong, Jingjing Xu, Duyu Tang, Zenan Xu, Nan Duan, Ming Zhou, Jiahai Wang, Jian Yin
2020 J jnl
CoRR
Zenan Xu, Daya Guo, Duyu Tang, Qinliang Su, Linjun Shou, Ming Gong, Wanjun Zhong, Xiaojun Quan, Nan Duan, Daxin Jiang
2019 conf
NLPCC (1)
Wanjun Zhong, Duyu Tang, Nan Duan, Ming Zhou, Jiahai Wang, Jian Yin
2019 J jnl
CoRR
Wanjun Zhong, Jingjing Xu, Duyu Tang, Zenan Xu, Nan Duan, Ming Zhou, Jiahai Wang, Jian Yin
2018 J jnl
CoRR
Wanjun Zhong, Duyu Tang, Nan Duan, Ming Zhou, Jiahai Wang, Jian Yin
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