Wei Wei

167 papers A* 16A 2B 2C 24Misc 1Journal 101Unranked 21
YearRankTypeTitle / Venue / Authors
2026 J jnl
Pattern Recognit.
Wei Wei, Haolie Wang, Yuduo Bian, Haijiao Xing, Chen Ding, Lei Zhang, Tao Zhou, Jiangbin Zheng, Yanning Zhang
2026 J jnl
Pattern Recognit.
Xiao Zhang, Zhen Zhang, Wei Wei, Lei Zhang, Yanning Zhang
2026 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Wei Wei, Chenxu Zhao, Shuyi Zhao, Lei Zhang, Yanning Zhang
2026 J jnl
Inf. Fusion
Jiangtao Nie, Lihao Lai, Wei Wei, Lei Zhang, Yanning Zhang
2026 A* conf
AAAI
Haoyu Wang, Lei Zhang, Wenrui Liu, Dengyang Jiang, Wei Wei, Chen Ding
2026 J jnl
Pattern Recognit.
Jiangtao Nie, Boxiong Wu, Wenyu Peng, Wei Wei, Lei Zhang, Chen Ding, Yan-Ning Zhang
2025 J jnl
Pattern Recognit. Lett.
Haijiao Xing, Wei Wei, Lei Zhang, Chen Ding
2025 J jnl
IEEE Trans. Big Data
Weijie Chen, Haoyu Wang, Shicai Yang, Lei Zhang, Wei Wei, Yanning Zhang, Luojun Lin, Di Xie, Yueting Zhuang
2025 J jnl
IEEE Trans. Geosci. Remote. Sens.
Bowen Fu, Jiangtao Nie, Wei Wei, Lei Zhang
2025 J jnl
IEEE Trans. Geosci. Remote. Sens.
Chen Ding, Sirui Zheng, Mengmeng Zheng, Yizhou Dong, Wenqiang Hua, Wei Wei, Lei Zhang, Yanning Zhang
2025 J jnl
Pattern Recognit.
Yanyu Ye, Wei Wei, Lei Zhang, Chen Ding, Yanning Zhang
2025 J jnl
Knowl. Based Syst.
Jiangtao Nie, Lei Zhang, Chongxing Song, Zhiqiang Lang, Weixin Ren, Wei Wei, Chen Ding, Yan-Ning Zhang
2025 J jnl
IEEE Trans. Geosci. Remote. Sens.
Jiangtao Nie, Wei Wei, Lei Zhang, Chen Ding, Yanning Zhang
2025 J jnl
CoRR
Haoyu Wang, Lei Zhang, Wenrui Liu, Dengyang Jiang, Wei Wei, Chen Ding
2025 J jnl
IEEE Signal Process. Lett.
Xiao Zhang, Wei Wei, Zhen Zhang, Lei Zhang
2025 A* conf
CVPR
Dengyang Jiang, Haoyu Wang, Lei Zhang, Wei Wei, Guang Dai, Mengmeng Wang, Jingdong Wang, Yanning Zhang
2025 J jnl
IEEE Trans. Multim.
Jiangtao Nie, Boxiong Wu, Wei Wei, Lei Zhang, Yanning Zhang
2025 J jnl
Pattern Recognit.
Haijiao Xing, Wei Wei, Lei Zhang, Yanning Zhang
2025 A* conf
IJCAI
Haoyu Wang, Lei Zhang, Wei Wei, Chen Ding, Yanning Zhang
2025 J jnl
CoRR
Haoyu Wang, Lei Zhang, Wei Wei, Chen Ding, Yanning Zhang
2025 J jnl
Neural Networks
Wei Wei, Yanyu Ye, Guochao Chen, Yuming Zhao, Xin Yang, Lei Zhang, Yanning Zhang
2025 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Yu Cao, Jingyi Chen, Haoyu Wang, Lei Zhang, Chen Ding, Wei Wei, Shiqi Cao, Meilin Xie
2024 C conf
IGARSS
Chenxu Zhao, Yizun Wang, Hongjian Wang, Lei Zhang, Chen Ding, Chunna Tian, Wei Wei
2024 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Boxiong Wu, Jiangtao Nie, Wei Wei, Lei Zhang, Yanning Zhang
2024 J jnl
IEEE Trans. Geosci. Remote. Sens.
Guochao Chen, Jiangtao Nie, Wei Wei, Lei Zhang, Yanning Zhang
2024 C conf
IGARSS
Weixin Ren, Ruiling Liu, Lei Zhang, Wei Wei, Chen Ding, Yanning Zhang
2024 J jnl
IEEE Geosci. Remote. Sens. Lett.
Junyuan Ding, Wei Wei, Lei Zhang
2024 J jnl
IEEE Trans. Geosci. Remote. Sens.
Xiao Zhang, Chongxing Song, Tao You, Qicheng Bai, Wei Wei, Lei Zhang
2024 J jnl
Neurocomputing
Xiao Zhang, Lei Zhang, Wei Wei, Yuxuan Sun, Chunna Tian, Yanning Zhang
2024 J jnl
IEEE Trans. Geosci. Remote. Sens.
Chen Ding, Zhicong Deng, Yaoyang Xu, Mengmeng Zheng, Lei Zhang, Yu Cao, Wei Wei, Yanning Zhang
2024 J jnl
IEEE Trans. Computational Imaging
Jiangtao Nie, Wei Wei, Lei Zhang, Chen Ding, Yanning Zhang
2024 J jnl
IEEE Trans. Geosci. Remote. Sens.
Chen Ding, Mengmeng Zheng, Sirui Zheng, Yaoyang Xu, Lei Zhang, Wei Wei, Yanning Zhang
2024 J jnl
Biomed. Signal Process. Control.
Yanyu Ye, Zhenxi Zhang, Chunna Tian, Wei Wei
2024 A* conf
NeurIPS
Fei Zhou, Peng Wang, Lei Zhang, Zhenghua Chen, Wei Wei, Chen Ding, Guosheng Lin, Yanning Zhang
2024 J jnl
CoRR
Fei Zhou, Peng Wang, Lei Zhang, Zhenghua Chen, Wei Wei, Chen Ding, Guosheng Lin, Yanning Zhang
2024 J jnl
Pattern Recognit.
Fei Zhou, Peng Wang, Lei Zhang, Wei Wei, Yanning Zhang
2024 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Lei Zhang, Jiangtao Nie, Wei Wei, Yanning Zhang
2023 J jnl
CoRR
Weijie Chen, Haoyu Wang, Shicai Yang, Lei Zhang, Wei Wei, Yanning Zhang, Luojun Lin, Di Xie, Yueting Zhuang
2023 C conf
IGARSS
Bowen Fu, Wei Li, Yuxuan Sun, Guochao Chen, Lei Zhang, Wei Wei
2023 J jnl
IEEE Trans. Geosci. Remote. Sens.
Cong Wang, Lei Zhang, Wei Wei, Yanning Zhang
2023 J jnl
IEEE Trans. Image Process.
Chongxing Song, Zhiqiang Lang, Wei Wei, Lei Zhang
2023 C conf
IGARSS
Qinglin Ran, Chenglong Zhang, Wei Wei, Lei Zhang
2023 A* conf
CVPR
Haoyu Wang, Guansong Pang, Peng Wang, Lei Zhang, Wei Wei, Yanning Zhang
2023 J jnl
CoRR
Haoyu Wang, Guansong Pang, Peng Wang, Lei Zhang, Wei Wei, Yanning Zhang
2023 C conf
IGARSS
Chenglong Zhang, Qinglin Ran, Wei Wei, Chen Ding, Lei Zhang
2023 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Fei Zhou, Wei Wei, Lei Zhang, Yanning Zhang
2023 J jnl
IEEE Trans. Geosci. Remote. Sens.
Wei Wei, Chongxing Song, Lei Zhang, Yanning Zhang
2023 J jnl
CoRR
Yanyu Ye, Zhengxi Zhang, Chunna Tian, Wei Wei
2023 J jnl
Pattern Recognit.
Lei Zhang, Fei Zhou, Wei Wei, Yanning Zhang
2023 J jnl
Pattern Recognit. Lett.
Xiao Zhang, Wei Wei, Zhen Zhang, Lei Zhang, Wei Li
2023 A* conf
AAAI
Lei Zhang, Yuxuan Sun, Wei Wei
2023 J jnl
CoRR
Yanyu Ye, Zhenxi Zhang, Wei Wei, Chunna Tian
2023 A* conf
CVPR
Fei Zhou, Peng Wang, Lei Zhang, Wei Wei, Yanning Zhang
2023 C conf
IGARSS
Junyuan Ding, Yue Wen, Weixin Ren, Lei Zhang, Wei Wei
2023 J jnl
IEEE Trans. Geosci. Remote. Sens.
Wei Wei, Shuyi Zhao, Songzheng Xu, Lei Zhang, Yanning Zhang
2023 J jnl
CoRR
Li Pengfei, Wei Wei, Yan Yu, Zhu Rong, Liguo Zhou
2023 C conf
IGARSS
Guochao Chen, Boxiong Wu, Haijiao Xing, Bowen Fu, Wei Wei, Lei Zhang
2023 C conf
IGARSS
Weixin Ren, Qianyue Duan, Tiange Huang, Lei Zhang, Wei Wei, Chen Ding, Yanning Zhang
2022 J jnl
IEEE Trans. Geosci. Remote. Sens.
Wei Wei, Songzheng Xu, Lei Zhang, Jinyang Zhang, Yanning Zhang
2022 J jnl
IEEE Trans. Geosci. Remote. Sens.
Jiangtao Nie, Wei Wei, Lei Zhang, Jianlong Yuan, Zhibin Wang, Hao Li
2022 C conf
IGARSS
Xinyuan Zhang, Lei Zhang, Wei Wei, Chen Ding, Yanning Zhang
2022 J jnl
CoRR
Zhiqiang Lang, Lei Zhang, Wei Wei
2022 C conf
IGARSS
Songzheng Xu, Wei Wei, Lei Zhang, Xiao Zhang
2022 J jnl
Remote. Sens.
Chen Ding, Mengmeng Zheng, Feixiong Chen, Yuankun Zhang, Xusi Zhuang, Enquan Fan, Dushi Wen, Lei Zhang, Wei Wei, Yanning Zhang
2022 J jnl
Remote. Sens.
Chen Ding, Youfa Chen, Runze Li, Dushi Wen, Xiaoyan Xie, Lei Zhang, Wei Wei, Yanning Zhang
2022 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Fei Zhou, Lei Zhang, Wei Wei
2022 J jnl
CoRR
Lei Zhang, Yuxuan Sun, Wei Wei
2022 conf
CVPR Workshops
Boaz Arad, Radu Timofte, Rony Yahel, Nimrod Morag, Amir Bernat, Yuanhao Cai, Jing Lin, Zudi Lin, Haoqian Wang, Yulun Zhang, Hanspeter Pfister, Luc Van Gool, Shuai Liu, Yongqiang Li, Chaoyu Feng, Lei Lei, Jiaojiao Li, Songcheng Du, Chaoxiong Wu, Yihong Leng, Rui Song, Mingwei Zhang, Chongxing Song, Shuyi Zhao, Zhiqiang Lang, Wei Wei, Lei Zhang, Renwei Dian, Tianci Shan, Anjing Guo, Chengguo Feng, Jinyang Liu, Mirko Agarla, Simone Bianco, Marco Buzzelli, Luigi Celona, Raimondo Schettini, Jiang He, Yi Xiao, Jiajun Xiao, Qiangqiang Yuan, Jie Li, Liangpei Zhang, Taesung Kwon, Dohoon Ryu, Hyokyoung Bae, Hao-Hsiang Yang, Hua-En Chang, Zhi-Kai Huang, Wei-Ting Chen, Sy-Yen Kuo, Junyu Chen, Haiwei Li, Song Liu, Sabari Nathan, K. Uma, B. Sathya Bama, S. Mohamed Mansoor Roomi
2022 C conf
IGARSS
Haoyu Wang, Lei Zhang, Wei Wei, Chen Ding, Yanning Zhang
2022 C conf
IGARSS
Zun Xu, Wei Wei, Lei Zhang, Jiangtao Nie
2022 J jnl
IEEE Trans. Geosci. Remote. Sens.
Cong Wang, Lei Zhang, Wei Wei, Yanning Zhang
2022 J jnl
IEEE Trans. Geosci. Remote. Sens.
Wei Wei, Jiangtao Nie, Lei Zhang, Yanning Zhang
2021 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Xian Sun, Peijin Wang, Zhiyuan Yan, Wenhui Diao, Xiaonan Lu, Zhujun Yang, Yidan Zhang, Deliang Xiang, Chen Yan, Jie Guo, Bo Dang, Wei Wei, Feng Xu, Cheng Wang, Ronny Hänsch, Martin Weinmann, Naoto Yokoya, Kun Fu
2021 J jnl
Remote. Sens.
Chen Ding, Yu Li, Yue Wen, Mengmeng Zheng, Lei Zhang, Wei Wei, Yanning Zhang
2021 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Lei Zhang, Jiangtao Nie, Wei Wei, Yong Li, Yanning Zhang
2021 J jnl
IEEE Trans. Image Process.
Lei Zhang, Zhiqiang Lang, Wei Wei, Yanning Zhang
2021 J jnl
IEEE Trans. Image Process.
Wei Li, Wei Wei, Lei Zhang
2021 C conf
IGARSS
Fei Zhou, Lei Zhang, Wei Wei, Zongwen Bai, Yanning Zhang
2021 C conf
IGARSS
Xiao Zhang, Wei Wei, Lei Zhang, Chen Ding
2020 conf
ECCV Workshops (3)
Kai Zhang, Martin Danelljan, Yawei Li, Radu Timofte, Jie Liu, Jie Tang, Gangshan Wu, Yu Zhu, Xiangyu He, Wenjie Xu, Chenghua Li, Cong Leng, Jian Cheng, Guangyang Wu, Wenyi Wang, Xiaohong Liu, Hengyuan Zhao, Xiangtao Kong, Jingwen He, Yu Qiao, Chao Dong, Xiaotong Luo, Liang Chen, Jiangtao Zhang, Maitreya Suin, Kuldeep Purohit, A. N. Rajagopalan, Xiaochuan Li, Zhiqiang Lang, Jiangtao Nie, Wei Wei, Lei Zhang, Abdul Muqeet, Jiwon Hwang, Subin Yang, Jung Heum Kang, Sung-Ho Bae, Yongwoo Kim, Yanyun Qu, Geun-Woo Jeon, Jun-Ho Choi, Jun-Hyuk Kim, Jong-Seok Lee, Steven Marty, Éric Marty, Dongliang Xiong, Siang Chen, Lin Zha, Jiande Jiang, Xinbo Gao, Wen Lu, Haicheng Wang, Vineeth Bhaskara, Alex Levinshtein, Stavros Tsogkas, Allan D. Jepson, Xiangzhen Kong, Tongtong Zhao, Shanshan Zhao, Hrishikesh P. S, Densen Puthussery, C. V. Jiji, Nan Nan, Shuai Liu, Jie Cai, Zibo Meng, Jiaming Ding, Chiu Man Ho, Xuehui Wang, Qiong Yan, Yuzhi Zhao, Long Chen, Long Sun, Wenhao Wang, Zhenbing Liu, Rushi Lan, Rao Muhammad Umer, Christian Micheloni
2020 J jnl
CoRR
Kai Zhang, Martin Danelljan, Yawei Li, Radu Timofte, Jie Liu, Jie Tang, Gangshan Wu, Yu Zhu, Xiangyu He, Wenjie Xu, Chenghua Li, Cong Leng, Jian Cheng, Guangyang Wu, Wenyi Wang, Xiaohong Liu, Hengyuan Zhao, Xiangtao Kong, Jingwen He, Yu Qiao, Chao Dong, Jiangtao Zhang, Maitreya Suin, Kuldeep Purohit, A. N. Rajagopalan, Xiaochuan Li, Zhiqiang Lang, Jiangtao Nie, Wei Wei, Lei Zhang, Abdul Muqeet, Jiwon Hwang, Subin Yang, Jung Heum Kang, Sung-Ho Bae, Yongwoo Kim, Liang Chen, Xiaotong Luo, Yanyun Qu, Geun-Woo Jeon, Jun-Ho Choi, Jun-Hyuk Kim, Jong-Seok Lee, Steven Marty, Éric Marty, Dongliang Xiong, Siang Chen, Lin Zha, Jiande Jiang, Xinbo Gao, Wen Lu, Haicheng Wang, Vineeth Bhaskara, Alex Levinshtein, Stavros Tsogkas, Allan D. Jepson, Xiangzhen Kong, Tongtong Zhao, Shanshan Zhao, Hrishikesh P. S, Densen Puthussery, C. Victor Jiji, Nan Nan, Shuai Liu, Jie Cai, Zibo Meng, Jiaming Ding, Chiu Man Ho, Xuehui Wang, Qiong Yan, Yuzhi Zhao, Long Chen, Long Sun, Wenhao Wang, Zhenbing Liu, Rushi Lan, Rao Muhammad Umer, Christian Micheloni
2020 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Lei Zhang, Wei Wei, Qinfeng Shi, Chunhua Shen, Anton van den Hengel, Yanning Zhang
2020 J jnl
Int. J. Comput. Vis.
Lei Zhang, Peng Wang, Chunhua Shen, Lingqiao Liu, Wei Wei, Yanning Zhang, Anton van den Hengel
2020 J jnl
IEEE Access
Wei Wei, Mengmeng Jiang, Xiangnan Zhang, Heng Liu, Chunna Tian
2020 J jnl
IEEE Trans. Computational Imaging
Wei Wei, Yuxuan Sun, Lei Zhang, Jiangtao Nie, Yanning Zhang
2020 J jnl
IEEE Trans. Computational Imaging
Wei Wei, Jiangtao Nie, Yong Li, Lei Zhang, Yanning Zhang
2020 C conf
IGARSS
Yu Li, Lei Zhang, Wei Wei, Yanning Zhang
2020 J jnl
IEEE Geosci. Remote. Sens. Lett.
Cong Wang, Lei Zhang, Wei Wei, Yanning Zhang
2020 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Wei Wei, Lei Zhang, Yu Li, Cong Wang, Yanning Zhang
2020 J jnl
CoRR
Lei Zhang, Fei Zhou, Wei Wei, Yanning Zhang
2020 conf
CVPR Workshops
Boaz Arad, Radu Timofte, Ohad Ben-Shahar, Yi-Tun Lin, Graham D. Finlayson, Shai Givati, Jiaojiao Li, Chaoxiong Wu, Rui Song, Yunsong Li, Fei Liu, Zhiqiang Lang, Wei Wei, Lei Zhang, Jiangtao Nie, Yuzhi Zhao, Lai-Man Po, Qiong Yan, Wei Liu, Tingyu Lin, Youngjung Kim, Changyeop Shin, Kyeongha Rho, Sungho Kim, Zhiyu Zhu, Junhui Hou, He Sun, Jinchang Ren, Zhenyu Fang, Yijun Yan, Hao Peng, Xiaomei Chen, Jie Zhao, Tarek Stiebel, Simon Koppers, Dorit Merhof, Honey Gupta, Kaushik Mitra, Biebele Joslyn Fubara, Mohamed H. Sedky, Dave Dyke, Atmadeep Banerjee, Akash Palrecha, Sabarinathan sabarinathan, K. Uma, D. Synthiya Vinothini, B. Sathya Bama, S. M. Md Mansoor Roomi
2020 J jnl
CoRR
Boaz Arad, Radu Timofte, Ohad Ben-Shahar, Yi-Tun Lin, Graham D. Finlayson, Shai Givati, Jiaojiao Li, Chaoxiong Wu, Rui Song, Yunsong Li, Fei Liu, Zhiqiang Lang, Wei Wei, Lei Zhang, Jiangtao Nie, Yuzhi Zhao, Lai-Man Po, Qiong Yan, Wei Liu, Tingyu Lin, Youngjung Kim, Changyeop Shin, Kyeongha Rho, Sungho Kim, Zhiyu Zhu, Junhui Hou, He Sun, Jinchang Ren, Zhenyu Fang, Yijun Yan, Hao Peng, Xiaomei Chen, Jie Zhao, Tarek Stiebel, Simon Koppers, Dorit Merhof, Honey Gupta, Kaushik Mitra, Biebele Joslyn Fubara, Mohamed H. Sedky, Dave Dyke, Atmadeep Banerjee, Akash Palrecha, Sabarinathan sabarinathan, K. Uma, D. Synthiya Vinothini, B. Sathya Bama, S. M. Md Mansoor Roomi
2020 A* conf
AAAI
Lei Zhang, Zhiqiang Lang, Peng Wang, Wei Wei, Shengcai Liao, Ling Shao, Yanning Zhang
2020 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Lei Zhang, Peng Wang, Lingqiao Liu, Chunhua Shen, Wei Wei, Yanning Zhang, Anton van den Hengel
2020 A* conf
CVPR
Lei Zhang, Jiangtao Nie, Wei Wei, Yanning Zhang, Shengcai Liao, Ling Shao
2020 J jnl
CoRR
Jiangtao Nie, Lei Zhang, Wei Wei, Zhiqiang Lang, Yanning Zhang
2020 A conf
ICME
Jiangtao Nie, Lei Zhang, Wei Wei, Chen Ding, Yanning Zhang
2019 J jnl
Remote. Sens.
Wei Wei, Mengting Ma, Cong Wang, Lei Zhang, Peng Zhang, Yanning Zhang
2019 J jnl
Appl. Soft Comput.
Lei Zhang, Yong Li, Peng Wang, Wei Wei, Songzheng Xu, Yanning Zhang
2019 conf
ICCV Workshops
Kai Zhang, Nan Nan, Chenghua Li, Xueyi Zou, Ning Kang, Zhan Wang, Hang Xu, Chaofeng Wang, Zheng Li, Linlin Wang, Jun Shi, Shuhang Gu, Wenyu Sun, Zhiqiang Lang, Jiangtao Nie, Wei Wei, Lei Zhang, Yazhe Niu, Peijin Zhuo, Xiangzhen Kong, Long Sun, Wenhao Wang, Radu Timofte, Zheng Hui, Xiumei Wang, Xinbo Gao, Dongliang Xiong, Shuai Liu, Ruipeng Gang
2019 J jnl
CoRR
Kai Zhang, Shuhang Gu, Radu Timofte, Zheng Hui, Xiumei Wang, Xinbo Gao, Dongliang Xiong, Shuai Liu, Ruipeng Gang, Nan Nan, Chenghua Li, Xueyi Zou, Ning Kang, Zhan Wang, Hang Xu, Chaofeng Wang, Zheng Li, Linlin Wang, Jun Shi, Wenyu Sun, Zhiqiang Lang, Jiangtao Nie, Wei Wei, Lei Zhang, Yazhe Niu, Peijin Zhuo, Xiangzhen Kong, Long Sun, Wenhao Wang
2019 J jnl
Inf. Sci.
Lei Zhang, Wei Wei, Qinfeng Shi, Chunhua Shen, Anton van den Hengel, Yanning Zhang
2019 C conf
IGARSS
Zhiqiang Lang, Lei Zhang, Wei Wei, Jiangtao Nie, Chunna Tian, Yanning Zhang
2019 J jnl
Neural Process. Lett.
Chen Ding, Ying Li, Lei Zhang, Jinyang Zhang, Lu Yang, Wei Wei, Yong Xia, Yanning Zhang
2019 C conf
IGARSS
Jinyang Zhang, Wei Wei, Lei Zhang, Yanning Zhang
2019 J jnl
IEEE Trans. Geosci. Remote. Sens.
Wei Wei, Lei Zhang, Yining Jiao, Chunna Tian, Cong Wang, Yanning Zhang
2019 conf
PRCV (3)
Yuxuan Ding, Wei Wang, Mengmeng Jiang, Heng Liu, Donghu Deng, Wei Wei, Chunna Tian
2019 J jnl
IEEE Trans. Geosci. Remote. Sens.
Lei Zhang, Jinyang Zhang, Wei Wei, Yanning Zhang
2019 J jnl
CoRR
Lei Zhang, Zhiqiang Lang, Peng Wang, Wei Wei, Shengcai Liao, Ling Shao, Yanning Zhang
2019 C conf
IGARSS
Jiangtao Nie, Lei Zhang, Cong Wang, Wei Wei, Yanning Zhang
2019 J jnl
IEEE Geosci. Remote. Sens. Lett.
Wei Wei, Wei Li, Lei Zhang, Cong Wang, Peng Zhang, Yanning Zhang
2019 conf
PRCV (2)
Ming Tian, Yuting Xue, Chunna Tian, Lei Wang, Donghu Deng, Wei Wei
2019 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Lei Zhang, Peng Wang, Wei Wei, Hao Lu, Chunhua Shen, Anton van den Hengel, Yanning Zhang
2019 C conf
IGARSS
Wei Li, Wei Wei, Lei Zhang, Cong Wang, Yanning Zhang
2019 A* conf
ICCV
Peng Wang, Bingliang Jiao, Lu Yang, Yifei Yang, Shizhou Zhang, Wei Wei, Yanning Zhang
2019 J jnl
CoRR
Peng Wang, Bingliang Jiao, Lu Yang, Yifei Yang, Shizhou Zhang, Wei Wei, Yanning Zhang
2018 conf
BigMM
Mengting Ma, Cong Wang, Lei Zhang, Yanning Zhang, Wei Wei
2018 conf
PRCV (2)
Yiqi Yan, Lei Zhang, Jun Li, Wei Wei, Yanning Zhang
2018 J jnl
CoRR
Yiqi Yan, Lei Zhang, Jun Li, Wei Wei, Yanning Zhang
2018 J jnl
CoRR
Lei Zhang, Peng Wang, Chunhua Shen, Lingqiao Liu, Wei Wei, Yanning Zhang, Anton van den Hengel
2018 J jnl
Int. J. Comput. Vis.
Lei Zhang, Wei Wei, Yanning Zhang, Chunhua Shen, Anton van den Hengel, Qinfeng Shi
2018 J jnl
Multim. Tools Appl.
Chunna Tian, Xiangnan Zhang, Wei Wei, Xinbo Gao
2018 J jnl
Remote. Sens.
Wei Wei, Jinyang Zhang, Lei Zhang, Chunna Tian, Yanning Zhang
2018 J jnl
IEEE Trans. Image Process.
Lei Zhang, Wei Wei, Chengcheng Bai, Yifan Gao, Yanning Zhang
2018 J jnl
Neurocomputing
Lei Zhang, Yanning Zhang, Hangqi Yan, Yifan Gao, Wei Wei
2018 conf
BigMM
Yong Li, Lei Zhang, Chen Ding, Wei Wei, Yanning Zhang
2018 J jnl
CoRR
Lei Zhang, Peng Wang, Lingqiao Liu, Chunhua Shen, Wei Wei, Yanning Zhang, Anton van den Hengel
2018 C conf
IGARSS
Yan Yu, Wei Wei, Jun Li, Yanning Zhang
2018 conf
BigMM
Jin Yuan, Chunna Tian, Xiangnan Zhang, Yuxuan Ding, Wei Wei
2018 J jnl
Remote. Sens.
Cong Wang, Lei Zhang, Wei Wei, Yanning Zhang
2017 J jnl
Sensors
Lingyan Ran, Yanning Zhang, Wei Wei, Qilin Zhang
2017 J jnl
CoRR
Lei Zhang, Wei Wei, Qinfeng Shi, Chunhua Shen, Anton van den Hengel, Yanning Zhang
2017 J jnl
Remote. Sens.
Chen Ding, Ying Li, Yong Xia, Wei Wei, Lei Zhang, Yanning Zhang
2017 A* conf
IJCAI
Zhen Zhang, Julian J. McAuley, Yong Li, Wei Wei, Yanning Zhang, Qinfeng Shi
2017 A conf
ICME
Yong Li, Lei Zhang, Chunna Tian, Chen Ding, Yanning Zhang, Wei Wei
2017 conf
ICNC-FSKD
Yifan Gao, Hangqi Yan, Lei Zhang, Runping Xi, Yanning Zhang, Wei Wei
2017 A* conf
AAAI
Zhen Zhang, Qinfeng Shi, Julian J. McAuley, Wei Wei, Yanning Zhang, Rui Yao, Anton van den Hengel
2017 J jnl
IEEE Trans. Geosci. Remote. Sens.
Wei Wei, Lei Zhang, Chunna Tian, Antonio Plaza, Yanning Zhang
2017 A* conf
ICCV
Hao Lu, Lei Zhang, Zhiguo Cao, Wei Wei, Ke Xian, Chunhua Shen, Anton van den Hengel
2017 J jnl
CoRR
Hao Lu, Lei Zhang, Zhiguo Cao, Wei Wei, Ke Xian, Chunhua Shen, Anton van den Hengel
2016 conf
ICIMCS
Cong Wang, Peng Zhang, Yanning Zhang, Lei Zhang, Wei Wei
2016 conf
ICIMCS
Lingyan Ran, Yanning Zhang, Wei Wei, Tao Yang
2016 conf
ECCV (5)
Lei Zhang, Wei Wei, Yanning Zhang, Chunhua Shen, Anton van den Hengel, Qinfeng Shi
2016 J jnl
IEEE Trans. Geosci. Remote. Sens.
Lei Zhang, Wei Wei, Yanning Zhang, Chunhua Shen, Anton van den Hengel, Qinfeng Shi
2016 J jnl
IEEE Trans. Image Process.
Lei Zhang, Wei Wei, Chunna Tian, Fei Li, Yanning Zhang
2016 J jnl
Pattern Recognit.
Wei Wei, Chunna Tian, Stephen John Maybank, Yanning Zhang
2016 C conf
IGARSS
Lei Zhang, Wei Wei, Yanning Zhang, Cong Wang
2016 J jnl
IEEE Trans. Computational Imaging
Lei Zhang, Wei Wei, Yanning Zhang, Hangqi Yan, Fei Li, Chunna Tian
2016 A* conf
CVPR
Zhen Zhang, Qinfeng Shi, Julian J. McAuley, Wei Wei, Yanning Zhang, Anton van den Hengel
2016 C conf
IGARSS
Hangqi Yan, Yanning Zhang, Wei Wei, Lei Zhang, Yong Li
2015 conf
PCM (2)
Ruijiao Zheng, Chunna Tian, Haiyang Li, Minglangjun Li, Wei Wei
2015 A* conf
ICCV
Lei Zhang, Wei Wei, Yanning Zhang, Fei Li, Chunhua Shen, Qinfeng Shi
2015 conf
WHISPERS
Lei Zhang, Wei Wei, Yanning Zhang, Fei Li, Hangqi Yan
2015 A* conf
CVPR
Lei Zhang, Wei Wei, Yanning Zhang, Chunna Tian, Fei Li
2015 J jnl
IEEE Trans. Image Process.
Chunna Tian, Xinbo Gao, Wei Wei, Hong Zheng
2014 C conf
IGARSS
Lei Zhang, Yanning Zhang, Wei Wei, Fei Li
2014 J jnl
Neurocomputing
Yanning Zhang, Wei Wei
2014 C conf
ICARCV
Yong Xia, Shen Lu, Wei Wei, David Dagan Feng, Yanning Zhang
2014 conf
SPAC
Chunna Tian, Xiangnan Zhang, Xinbo Gao, Wei Wei
2014 B conf
ICIP
Wei Wei, Chunna Tian, Yanning Zhang
2014 conf
WHISPERS
Lei Zhang, Wei Wei, Yanning Zhang, Fei Li, Hangqi Yan
2013 B conf
ICIP
Lei Zhang, Yanning Zhang, Wei Wei, Qingjie Meng
2013 conf
IScIDE
Qingjie Meng, Yanning Zhang, Wei Wei, Lei Zhang
2012 J jnl
Neurocomputing
Yanning Zhang, Wei Wei
2011 conf
IScIDE
Yanning Zhang, Wei Wei
2009 Misc conf
ICIG
Wei Wei, Yanning Zhang, Zenggang Lin
2009 conf
ACCV (2)
Wei Wei, Yanning Zhang
tests/unit/test_decompile_analysis.py
← Index tests/unit/test_decompile_analysis.py python
"""Unit tests (mocked Binary Ninja) for analysis modules:
- bninja/analysis/cfg.py — CFGAnalysis
- bninja/analysis/disassembly.py — DisassemblyAnalysis
- bninja/analysis/low_level.py — LowLevelAnalysis
"""
import sys
import pytest
from unittest.mock import MagicMock

from tests.unit.conftest_binja_stubs import (
    install_binja_stubs,
    BranchType,
    InstructionTextTokenType,
    MockBasicBlock,
    MockEdge,
    MockFunction,
    MockToken,
    MockDisassemblyLine,
    MockBinaryView,
    MockSymbol,
    SymbolType,
    LowLevelILOperation,
)

install_binja_stubs()

from redb.extractors.decompiler.bninja.analysis.cfg import CFGAnalysis
from redb.extractors.decompiler.bninja.analysis.disassembly import DisassemblyAnalysis
from redb.extractors.decompiler.bninja.arch.x86 import Arch_x86


# ============================================================================
# 9a. CFGAnalysis
# ============================================================================


class TestCFGCyclomaticComplexity:
    def test_cyclomatic_complexity_linear(self):
        """Single block, no edges: E - N + 2 = 0 - 1 + 2 = 1."""
        block = MockBasicBlock(start=0x1000, end=0x1010, outgoing_edges=[])
        func = MockFunction(start=0x1000, basic_blocks=[block])
        cfg = CFGAnalysis(func)
        result = cfg.extract_function_cfg()
        assert result["cyclomatic_complexity"] == 1

    def test_cyclomatic_complexity_branch(self):
        """Diamond: 4 blocks, 4 edges -> 4 - 4 + 2 = 2."""
        entry = MockBasicBlock(start=0x1000, end=0x1010)
        true_b = MockBasicBlock(start=0x1010, end=0x1020)
        false_b = MockBasicBlock(start=0x1020, end=0x1030)
        merge = MockBasicBlock(start=0x1030, end=0x1040)

        entry.outgoing_edges = [MockEdge(target=true_b), MockEdge(target=false_b)]
        true_b.outgoing_edges = [MockEdge(target=merge)]
        false_b.outgoing_edges = [MockEdge(target=merge)]
        merge.outgoing_edges = []

        func = MockFunction(start=0x1000, basic_blocks=[entry, true_b, false_b, merge])
        cfg = CFGAnalysis(func)
        result = cfg.extract_function_cfg()
        assert result["cyclomatic_complexity"] == 2

    def test_cyclomatic_complexity_loop(self):
        """Loop: 3 blocks, 3 edges -> 3 - 3 + 2 = 2."""
        header = MockBasicBlock(start=0x1000, end=0x1010)
        body = MockBasicBlock(start=0x1010, end=0x1020)
        exit_b = MockBasicBlock(start=0x1020, end=0x1030)

        header.outgoing_edges = [MockEdge(target=body), MockEdge(target=exit_b)]
        body.outgoing_edges = [MockEdge(target=header)]
        exit_b.outgoing_edges = []

        func = MockFunction(start=0x1000, basic_blocks=[header, body, exit_b])
        cfg = CFGAnalysis(func)
        result = cfg.extract_function_cfg()
        assert result["cyclomatic_complexity"] == 2


class TestCFGExtractFunctionCFG:
    def _make_simple_cfg(self):
        """Create a simple two-block CFG for testing structure."""
        entry = MockBasicBlock(start=0x1000, end=0x1010)
        exit_b = MockBasicBlock(start=0x1010, end=0x1020)

        entry.outgoing_edges = [MockEdge(source=entry, target=exit_b, edge_type=BranchType.UnconditionalBranch)]
        exit_b.incoming_edges = [MockEdge(source=entry, target=exit_b)]
        exit_b.outgoing_edges = []
        entry.incoming_edges = []

        func = MockFunction(start=0x1000, basic_blocks=[entry, exit_b])
        return func

    def test_extract_function_cfg_structure(self):
        func = self._make_simple_cfg()
        cfg = CFGAnalysis(func)
        result = cfg.extract_function_cfg()
        assert "function_address" not in result
        # New schema: no "blocks" or "measures" nesting
        assert "blocks" not in result
        assert "measures" not in result

    def test_function_cfg_new_keys(self):
        """Assert all expected keys are present in the new output dict."""
        func = self._make_simple_cfg()
        cfg = CFGAnalysis(func)
        result = cfg.extract_function_cfg()
        expected_keys = [
            "cfg_topology_hash",
            "block_count",
            "edge_count",
            "llil_total_operations",
            "call_count",
            "cyclomatic_complexity",
            "loop_count",
            "max_depth",
            "max_fan_out",
            "md_index_topdown",
            "md_index_bottomup",
            "prime_product_llil",
            "cfg_feature_tlsh",
            "wl_minhash",
            "bb_features",
            "cfg_adjacency",
        ]
        for key in expected_keys:
            assert key in result, f"Missing key: {key}"

    def test_returns_none_for_empty_blocks(self):
        func = MockFunction(start=0x1000, basic_blocks=[])
        cfg = CFGAnalysis(func)
        assert cfg.extract_function_cfg() is None


class TestCFGTopologyHash:
    def _make_two_block_cfg(self):
        entry = MockBasicBlock(start=0x1000, end=0x1010)
        exit_b = MockBasicBlock(start=0x1010, end=0x1020)
        entry.outgoing_edges = [MockEdge(target=exit_b)]
        exit_b.outgoing_edges = []
        return MockFunction(start=0x1000, basic_blocks=[entry, exit_b])

    def test_topology_hash_is_16_bytes(self):
        func = self._make_two_block_cfg()
        cfg = CFGAnalysis(func)
        result = cfg.extract_function_cfg()
        assert isinstance(result["cfg_topology_hash"], bytes)
        assert len(result["cfg_topology_hash"]) == 16

    def test_topology_hash_deterministic(self):
        func = self._make_two_block_cfg()
        r1 = CFGAnalysis(func).extract_function_cfg()
        r2 = CFGAnalysis(func).extract_function_cfg()
        assert r1["cfg_topology_hash"] == r2["cfg_topology_hash"]


class TestCFGLoopCount:
    def test_no_loops(self):
        entry = MockBasicBlock(start=0x1000, end=0x1010)
        exit_b = MockBasicBlock(start=0x1010, end=0x1020)
        entry.outgoing_edges = [MockEdge(target=exit_b)]
        exit_b.outgoing_edges = []
        func = MockFunction(start=0x1000, basic_blocks=[entry, exit_b])
        result = CFGAnalysis(func).extract_function_cfg()
        assert result["loop_count"] == 0

    def test_single_loop(self):
        header = MockBasicBlock(start=0x1000, end=0x1010)
        body = MockBasicBlock(start=0x1010, end=0x1020)
        exit_b = MockBasicBlock(start=0x1020, end=0x1030)
        header.outgoing_edges = [MockEdge(target=body), MockEdge(target=exit_b)]
        body.outgoing_edges = [MockEdge(target=header)]
        exit_b.outgoing_edges = []
        func = MockFunction(start=0x1000, basic_blocks=[header, body, exit_b])
        result = CFGAnalysis(func).extract_function_cfg()
        assert result["loop_count"] == 1


class TestCFGMaxDepth:
    def test_max_depth_linear(self):
        entry = MockBasicBlock(start=0x1000, end=0x1010)
        b1 = MockBasicBlock(start=0x1010, end=0x1020)
        b2 = MockBasicBlock(start=0x1020, end=0x1030)
        entry.outgoing_edges = [MockEdge(target=b1)]
        b1.outgoing_edges = [MockEdge(target=b2)]
        b2.outgoing_edges = []
        func = MockFunction(start=0x1000, basic_blocks=[entry, b1, b2])
        result = CFGAnalysis(func).extract_function_cfg()
        assert result["max_depth"] == 2

    def test_max_depth_single_block(self):
        block = MockBasicBlock(start=0x1000, end=0x1010, outgoing_edges=[])
        func = MockFunction(start=0x1000, basic_blocks=[block])
        result = CFGAnalysis(func).extract_function_cfg()
        assert result["max_depth"] == 0


class TestCFGCollectBlockLlilOps:
    """Test that _collect_block_llil_ops correctly maps LLIL data to native blocks."""

    def test_llil_fields_nonzero_with_mock_llil(self):
        """When LLIL is available, llil_total_operations and call_count should be non-zero."""
        # Two native blocks
        entry = MockBasicBlock(start=0x1000, end=0x1010)
        exit_b = MockBasicBlock(start=0x1010, end=0x1020)
        entry.outgoing_edges = [MockEdge(target=exit_b)]
        exit_b.outgoing_edges = []

        # LLIL instructions: SET_REG, CALL in first block; STORE, RET in second
        llil_instrs_1 = [
            MockLLILInstruction(LowLevelILOperation.LLIL_SET_REG),
            MockLLILInstruction(LowLevelILOperation.LLIL_CALL),
        ]
        llil_instrs_2 = [
            MockLLILInstruction(LowLevelILOperation.LLIL_STORE),
            MockLLILInstruction(LowLevelILOperation.LLIL_RET),
        ]

        # LLIL basic blocks map back to native blocks via source_block
        llil_bb1 = MockLLILBasicBlock(llil_instrs_1, source_block=entry)
        llil_bb2 = MockLLILBasicBlock(llil_instrs_2, source_block=exit_b)
        llil_func = MockLLILFunction([llil_bb1, llil_bb2])

        func = MockFunction(start=0x1000, basic_blocks=[entry, exit_b], llil=llil_func)
        result = CFGAnalysis(func, llil_function=llil_func).extract_function_cfg()

        assert result["llil_total_operations"] == 4
        assert result["call_count"] == 1
        assert result["prime_product_llil"] != 0

    def test_llil_none_gives_zero_fields(self):
        """Without LLIL, LLIL-dependent fields should be zero."""
        block = MockBasicBlock(start=0x1000, end=0x1010, outgoing_edges=[])
        func = MockFunction(start=0x1000, basic_blocks=[block])
        result = CFGAnalysis(func).extract_function_cfg()

        assert result["llil_total_operations"] == 0
        assert result["call_count"] == 0
        assert result["prime_product_llil"] == 0

    def test_bb_features_with_llil(self):
        """bb_features should reflect LLIL instruction categories when LLIL is available."""
        block = MockBasicBlock(start=0x1000, end=0x1010, outgoing_edges=[])

        llil_instrs = [
            MockLLILInstruction(LowLevelILOperation.LLIL_ADD),
            MockLLILInstruction(LowLevelILOperation.LLIL_LOAD),
            MockLLILInstruction(LowLevelILOperation.LLIL_CALL),
        ]
        llil_bb = MockLLILBasicBlock(llil_instrs, source_block=block)
        llil_func = MockLLILFunction([llil_bb])

        func = MockFunction(start=0x1000, basic_blocks=[block])
        result = CFGAnalysis(func, llil_function=llil_func).extract_function_cfg()

        feats = result["bb_features"]
        assert len(feats) == 1
        assert feats[0][0] == 3  # instruction count = 3
        # At least one non-zero category count (not all OTHER)
        category_counts = feats[0][1:7]
        assert sum(category_counts) > 0


# ============================================================================
# 9b. DisassemblyAnalysis
# ============================================================================


class TestDisassemblyAnalysisGetJson:
    def _make_analysis(self, instructions=None, basic_blocks=None):
        arch = Arch_x86()
        if instructions is None:
            instructions = [
                (
                    [
                        MockToken("push", InstructionTextTokenType.InstructionToken),
                        MockToken(" ", InstructionTextTokenType.TextToken),
                        MockToken("rbp", InstructionTextTokenType.RegisterToken),
                    ],
                    0x1000,
                ),
                (
                    [
                        MockToken("mov", InstructionTextTokenType.InstructionToken),
                        MockToken(" ", InstructionTextTokenType.TextToken),
                        MockToken("rsp", InstructionTextTokenType.RegisterToken),
                    ],
                    0x1003,
                ),
            ]
        if basic_blocks is None:
            basic_blocks = [MockBasicBlock(
                start=0x1000, end=0x1010,
                disassembly_text=[MockDisassemblyLine([MockToken("push rbp")])]
            )]

        func = MockFunction(
            name="test_func",
            start=0x1000,
            basic_blocks=basic_blocks,
            instructions=instructions,
            symbol=MockSymbol(symbol_type=SymbolType.FunctionSymbol, name="test_func"),
            stack_adjustment=MagicMock(value=-8),
            mlil=None,
        )
        bv = MockBinaryView()
        logger = MagicMock()
        return DisassemblyAnalysis(arch, func, bv, logger)

    def test_get_json_basic_structure(self):
        da = self._make_analysis()
        result, errors = da.get_json()
        expected_keys = [
            "disassembled_function_hash",
            "disassembled_function",
            "disassembled_function_no_addresses",
            "disassembled_function_name",
            "disassembled_function_address",
            "instructions_count",
            "function_type",
            "instructions_types",
            "control_flow_count",
            "memory_access_pattern",
            "register_usage",
            "data_references_count",
        ]
        for key in expected_keys:
            assert key in result, f"Missing key: {key}"

    def test_get_json_hash_deterministic(self):
        da = self._make_analysis()
        r1, _ = da.get_json()
        da2 = self._make_analysis()
        r2, _ = da2.get_json()
        assert r1["disassembled_function_hash"] == r2["disassembled_function_hash"]


class TestDisassemblyCollectInstructionTypes:
    def test_collect_instruction_types(self):
        arch = Arch_x86()
        instructions = [
            ([MockToken("MOV", InstructionTextTokenType.InstructionToken)], 0x1000),
            ([MockToken("ADD", InstructionTextTokenType.InstructionToken)], 0x1001),
            ([MockToken("MOV", InstructionTextTokenType.InstructionToken)], 0x1002),
        ]
        func = MockFunction(start=0x1000, instructions=instructions, symbol=MockSymbol())
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        types = da.collect_instruction_types()
        assert "DATA_MOVEMENT" in types
        assert "ARITHMETIC" in types

    def test_collect_instruction_types_empty(self):
        arch = Arch_x86()
        func = MockFunction(start=0x1000, instructions=[], symbol=MockSymbol())
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        types = da.collect_instruction_types()
        assert types == {}


class TestDisassemblyMemoryPatterns:
    def _make_memory_instruction(self, tokens):
        return ([t for t in tokens], 0x1000)

    def test_collect_memory_patterns_stack(self):
        arch = Arch_x86()
        tokens = [
            MockToken("[", InstructionTextTokenType.BeginMemoryOperandToken),
            MockToken("RSP", InstructionTextTokenType.RegisterToken),
            MockToken("+0x8", InstructionTextTokenType.TextToken),
            MockToken("]", InstructionTextTokenType.EndMemoryOperandToken),
        ]
        instructions = [self._make_memory_instruction(tokens)]
        func = MockFunction(start=0x1000, instructions=instructions, symbol=MockSymbol())
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        patterns = da.collect_memory_patterns()
        assert "MEM_STACK" in patterns

    def test_collect_memory_patterns_direct(self):
        arch = Arch_x86()
        tokens = [
            MockToken("[", InstructionTextTokenType.BeginMemoryOperandToken),
            MockToken("0x402000", InstructionTextTokenType.TextToken),
            MockToken("]", InstructionTextTokenType.EndMemoryOperandToken),
        ]
        instructions = [self._make_memory_instruction(tokens)]
        func = MockFunction(start=0x1000, instructions=instructions, symbol=MockSymbol())
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        patterns = da.collect_memory_patterns()
        assert "MEM_DIRECT" in patterns

    def test_collect_memory_patterns_scaled(self):
        arch = Arch_x86()
        tokens = [
            MockToken("[", InstructionTextTokenType.BeginMemoryOperandToken),
            MockToken("RAX+RCX*4", InstructionTextTokenType.TextToken),
            MockToken("]", InstructionTextTokenType.EndMemoryOperandToken),
        ]
        instructions = [self._make_memory_instruction(tokens)]
        func = MockFunction(start=0x1000, instructions=instructions, symbol=MockSymbol())
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        patterns = da.collect_memory_patterns()
        assert "MEM_SCALED_INDEX" in patterns

    def test_collect_memory_patterns_base_offset(self):
        arch = Arch_x86()
        tokens = [
            MockToken("[", InstructionTextTokenType.BeginMemoryOperandToken),
            MockToken("RAX+0x10", InstructionTextTokenType.TextToken),
            MockToken("]", InstructionTextTokenType.EndMemoryOperandToken),
        ]
        instructions = [self._make_memory_instruction(tokens)]
        func = MockFunction(start=0x1000, instructions=instructions, symbol=MockSymbol())
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        patterns = da.collect_memory_patterns()
        assert "MEM_BASE_OFFSET" in patterns


class TestDisassemblyRegisterUsage:
    def test_collect_register_usage_gpr(self):
        arch = Arch_x86()
        instructions = [
            ([MockToken("RAX", InstructionTextTokenType.RegisterToken)], 0x1000),
        ]
        func = MockFunction(start=0x1000, instructions=instructions, symbol=MockSymbol())
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        regs = da.collect_register_usage()
        assert "GPR" in regs

    def test_collect_register_usage_simd(self):
        arch = Arch_x86()
        instructions = [
            ([MockToken("XMM0", InstructionTextTokenType.RegisterToken)], 0x1000),
        ]
        func = MockFunction(start=0x1000, instructions=instructions, symbol=MockSymbol())
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        regs = da.collect_register_usage()
        assert "SIMD" in regs

    def test_collect_register_usage_fpu(self):
        arch = Arch_x86()
        instructions = [
            ([MockToken("ST0", InstructionTextTokenType.RegisterToken)], 0x1000),
        ]
        func = MockFunction(start=0x1000, instructions=instructions, symbol=MockSymbol())
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        regs = da.collect_register_usage()
        assert "FPU" in regs


class TestDisassemblyMisc:
    def test_count_data_references(self):
        arch = Arch_x86()
        func = MockFunction(start=0x1000, instructions=[], symbol=MockSymbol(), mlil=None)
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        assert da.count_data_references() == 0

    def test_compute_max_block_size(self):
        arch = Arch_x86()
        blocks = [
            MockBasicBlock(disassembly_text=[MockDisassemblyLine([]) for _ in range(3)]),
            MockBasicBlock(disassembly_text=[MockDisassemblyLine([]) for _ in range(5)]),
        ]
        func = MockFunction(start=0x1000, basic_blocks=blocks, instructions=[], symbol=MockSymbol())
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        assert da.compute_max_block_size() == 5

    def test_compute_num_calls(self):
        arch = Arch_x86()
        instructions = [
            ([MockToken("CALL", InstructionTextTokenType.InstructionToken)], 0x1000),
            ([MockToken("MOV", InstructionTextTokenType.InstructionToken)], 0x1005),
            ([MockToken("CALL", InstructionTextTokenType.InstructionToken)], 0x1010),
        ]
        func = MockFunction(start=0x1000, instructions=instructions, symbol=MockSymbol())
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        assert da.compute_num_calls() == 2

    def test_estimate_stack_size_value(self):
        arch = Arch_x86()
        stack = MagicMock()
        stack.value = -16
        func = MockFunction(start=0x1000, instructions=[], symbol=MockSymbol(), stack_adjustment=stack)
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        assert da.estimate_stack_size() == -16

    def test_estimate_stack_size_int(self):
        arch = Arch_x86()
        func = MockFunction(start=0x1000, instructions=[], symbol=MockSymbol(), stack_adjustment=-8)
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        assert da.estimate_stack_size() == -8

    def test_normalize_opcode(self):
        arch = Arch_x86()
        func = MockFunction(start=0x1000, instructions=[], symbol=MockSymbol())
        da = DisassemblyAnalysis(arch, func, MockBinaryView(), MagicMock())
        assert da.normalize_opcode("mov") == "MOV"
        assert da.normalize_opcode("PUSH") == "PUSH"


# ============================================================================
# 9c. LowLevelAnalysis (basic tests with mocked LLIL)
# ============================================================================


class MockLLILInstruction:
    """Mock LLIL instruction for low_level.py tests."""
    def __init__(self, operation, operands=None, address=0):
        self.operation = operation
        self.operands = operands or []
        self.address = address

    def __str__(self):
        return f"LLIL_{self.operation}"


class MockLLILBasicBlock:
    def __init__(self, instructions, source_block=None):
        self._instructions = instructions
        self.source_block = source_block

    def __iter__(self):
        return iter(self._instructions)


class MockLLILFunction:
    def __init__(self, basic_blocks):
        self.basic_blocks = basic_blocks
        self._instructions = []
        for bb in basic_blocks:
            self._instructions.extend(bb._instructions)

    @property
    def instructions(self):
        return iter(self._instructions)

    @property
    def source_function(self):
        mock = MagicMock()
        mock.start = 0x1000
        return mock


class TestLowLevelAnalysisCountControlFlow:
    def test_count_control_flow_instructions(self):
        from redb.extractors.decompiler.bninja.analysis.low_level import LowLevelAnalysis
        instrs = [
            MockLLILInstruction(LowLevelILOperation.LLIL_IF),
            MockLLILInstruction(LowLevelILOperation.LLIL_SET_REG),
            MockLLILInstruction(LowLevelILOperation.LLIL_CALL),
            MockLLILInstruction(LowLevelILOperation.LLIL_GOTO),
        ]
        bb = MockLLILBasicBlock(instrs)
        llil_func = MockLLILFunction([bb])

        func = MockFunction(start=0x1000, llil=llil_func, symbol=MockSymbol())
        func.low_level_il = None
        bv = MockBinaryView()
        bv.arch = MagicMock()
        bv.arch.stack_pointer = "sp"
        la = LowLevelAnalysis(func, bv, MagicMock())
        assert la.count_control_flow_instructions() == 3  # IF, CALL, GOTO


class TestLowLevelAnalysisNumCalls:
    def test_compute_num_calls_llil(self):
        from redb.extractors.decompiler.bninja.analysis.low_level import LowLevelAnalysis
        instrs = [
            MockLLILInstruction(LowLevelILOperation.LLIL_CALL),
            MockLLILInstruction(LowLevelILOperation.LLIL_TAILCALL),
            MockLLILInstruction(LowLevelILOperation.LLIL_SET_REG),
        ]
        bb = MockLLILBasicBlock(instrs)
        llil_func = MockLLILFunction([bb])

        func = MockFunction(start=0x1000, llil=llil_func, symbol=MockSymbol())
        func.low_level_il = None
        bv = MockBinaryView()
        la = LowLevelAnalysis(func, bv, MagicMock())
        assert la.compute_num_calls() == 2


class TestLowLevelAnalysisCollectNormalization:
    def test_collect_low_level(self):
        from redb.extractors.decompiler.bninja.analysis.low_level import LowLevelAnalysis
        instrs = [
            MockLLILInstruction(LowLevelILOperation.LLIL_SET_REG, address=0x1000),
            MockLLILInstruction(LowLevelILOperation.LLIL_STORE, address=0x1004),
        ]
        bb = MockLLILBasicBlock(instrs)
        llil_func = MockLLILFunction([bb])

        func = MockFunction(start=0x1000, llil=llil_func, symbol=MockSymbol())
        func.low_level_il = None
        bv = MockBinaryView()
        la = LowLevelAnalysis(func, bv, MagicMock())
        result, _ = la._collect_low_level_and_with_addr()
        assert len(result) == 2
        # Each item is a list of operation ints
        assert isinstance(result[0], list)

    def test_collect_low_level_with_addr_offset_clamping(self):
        from redb.extractors.decompiler.bninja.analysis.low_level import LowLevelAnalysis
        instrs = [
            MockLLILInstruction(LowLevelILOperation.LLIL_SET_REG, address=0x0FFF),  # Before function start
        ]
        bb = MockLLILBasicBlock(instrs)
        llil_func = MockLLILFunction([bb])

        func = MockFunction(start=0x1000, llil=llil_func, symbol=MockSymbol())
        func.low_level_il = None
        bv = MockBinaryView()
        la = LowLevelAnalysis(func, bv, MagicMock())
        _, result = la._collect_low_level_and_with_addr()
        assert len(result) == 1
        offset, _ = result[0]
        assert offset == 0  # Clamped to 0