Han-Jia Ye

184 papers A* 55A 3C 1Journal 116Unranked 8
YearRankTypeTitle / Venue / Authors
2026 A* conf
AAAI
Lan Li, Tao Hu, Da-Wei Zhou, Jia-Qi Yang, Han-Jia Ye, De-Chuan Zhan
2026 A* conf
AAAI
Yusheng Li, Xincen Duan, Beili Wang, Wei Guo, Han-Jia Ye
2026 J jnl
CoRR
Haoxuan Ma, Guannan Lai, Han-Jia Ye
2026 J jnl
CoRR
Zhen-Hao Xie, Jun-Tao Tang, Yu-Cheng Shi, Han-Jia Ye, De-Chuan Zhan, Da-Wei Zhou
2026 J jnl
CoRR
Guannan Lai, Da-Wei Zhou, Zhenguo Li, Han-Jia Ye
2026 J jnl
Frontiers Comput. Sci.
Xin-Yi Zhang, Han-Jia Ye, De-Chuan Zhan
2026 J jnl
CoRR
Yi-Kai Zhang, Zhiyuan Yao, Hongyan Hao, Yueqing Sun, Qi Gu, Hui Su, Xunliang Cai, De-Chuan Zhan, Han-Jia Ye
2026 J jnl
CoRR
Yi-Kai Zhang, Yueqing Sun, Hongyan Hao, Qi Gu, Xunliang Cai, De-Chuan Zhan, Han-Jia Ye
2026 J jnl
CoRR
Guannan Lai, Han-Jia Ye
2025 J jnl
CoRR
Han-Jia Ye, Si-Yang Liu, Wei-Lun Chao
2025 A* conf
IJCAI
Da-Wei Zhou, Han-Jia Ye
2025 J jnl
Medical Image Anal.
Zi-Yuan Wu, Wei Guo, Wei Zhou, Han-Jia Ye, Yuan Jiang, Houxuan Li, Zhi-Hua Zhou
2025 J jnl
Mach. Learn.
Zhi-Hong Qi, Da-Wei Zhou, Yiran Yao, Han-Jia Ye, De-Chuan Zhan
2025 A* conf
ICML
Lan Li, Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2025 J jnl
CoRR
Lan Li, Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2025 J jnl
CoRR
Lan Li, Tao Hu, Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2025 A* conf
AAAI
Yi-Kai Zhang, De-Chuan Zhan, Han-Jia Ye
2025 J jnl
CoRR
Yi-Kai Zhang, De-Chuan Zhan, Han-Jia Ye
2025 A* conf
ICML
Jun-Peng Jiang, Tao Zhou, De-Chuan Zhan, Han-Jia Ye
2025 A* conf
CVPR
Da-Wei Zhou, Zi-Wen Cai, Han-Jia Ye, Lijun Zhang, De-Chuan Zhan
2025 J jnl
CoRR
Xu-Xiang Zhong, Chao Yi, Han-Jia Ye
2025 J jnl
Pattern Recognit.
Xinyi Zhang, Xian-Kai Lu, Yi-Long Yin, Han-Jia Ye, De-Chuan Zhan
2025 J jnl
CoRR
Da-Wei Zhou, Kai-Wen Li, Jingyi Ning, Han-Jia Ye, Lijun Zhang, De-Chuan Zhan
2025 J jnl
CoRR
Hao-Run Cai, Han-Jia Ye
2025 J jnl
CoRR
Silin Chen, Kangjian Di, Yichu Xu, Han-Jia Ye, Wenhan Luo, Ningmu Zou
2025 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Yi Shi, Rui-Xiang Li, Le Gan, De-Chuan Zhan, Han-Jia Ye
2025 J jnl
CoRR
Zhi-Kai Chen, Jun-Peng Jiang, Han-Jia Ye, De-Chuan Zhan
2025 J jnl
CoRR
Zhen-Hao Wen, Yan Wang, Ji Feng, Han-Jia Ye, De-Chuan Zhan, Da-Wei Zhou
2025 A* conf
ICML
Ting-Ji Huang, Jia-Qi Yang, Chunxu Shen, Kai-Qi Liu, De-Chuan Zhan, Han-Jia Ye
2025 J jnl
CoRR
Yan Wang, Da-Wei Zhou, Han-Jia Ye
2025 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Da-Wei Zhou, Yuanhan Zhang, Yan Wang, Jingyi Ning, Han-Jia Ye, De-Chuan Zhan, Ziwei Liu
2025 A* conf
AAAI
Xu-Yang Chen, Lu Han, De-Chuan Zhan, Han-Jia Ye
2025 A* conf
AAAI
Hai-Long Sun, Da-Wei Zhou, Hanbin Zhao, Le Gan, De-Chuan Zhan, Han-Jia Ye
2025 J jnl
CoRR
Si-Yang Liu, Qile Zhou, Han-Jia Ye
2025 conf
ACL (1)
Hai-Long Sun, Zhun Sun, Houwen Peng, Han-Jia Ye
2025 J jnl
CoRR
Hai-Long Sun, Zhun Sun, Houwen Peng, Han-Jia Ye
2025 J jnl
CoRR
Yi-Kai Zhang, Jin Wang, Xu-Xiang Zhong, De-Chuan Zhan, Han-Jia Ye
2025 J jnl
CoRR
Jun-Peng Jiang, Yu Xia, Hai-Long Sun, Shiyin Lu, Qing-Guo Chen, Weihua Luo, Kaifu Zhang, De-Chuan Zhan, Han-Jia Ye
2025 J jnl
CoRR
Hao-Nan Shi, Ting-Ji Huang, Lu Han, De-Chuan Zhan, Han-Jia Ye
2025 J jnl
Sci. China Inf. Sci.
Hai-Long Sun, Da-Wei Zhou, De-Chuan Zhan, Han-Jia Ye
2025 A* conf
ICML
Hai-Long Sun, Da-Wei Zhou, Yang Li, Shiyin Lu, Chao Yi, Qing-Guo Chen, Zhao Xu, Weihua Luo, Kaifu Zhang, De-Chuan Zhan, Han-Jia Ye
2025 J jnl
CoRR
Jun-Peng Jiang, Si-Yang Liu, Hao-Run Cai, Qi-Le Zhou, Han-Jia Ye
2025 J jnl
Int. J. Comput. Vis.
Da-Wei Zhou, Zi-Wen Cai, Han-Jia Ye, De-Chuan Zhan, Ziwei Liu
2025 A* conf
ICLR
Han-Jia Ye, Huai-Hong Yin, De-Chuan Zhan, Wei-Lun Chao
2025 J jnl
Frontiers Comput. Sci.
Yi Shi, Han-Jia Ye, Dongliang Man, Xiaoxu Han, De-Chuan Zhan, Yuan Jiang
2025 J jnl
CoRR
Ting-Ji Huang, Xu-Yang Chen, Han-Jia Ye
2025 A* conf
ICML
Siyang Liu, Han-Jia Ye
2025 J jnl
CoRR
Si-Yang Liu, Han-Jia Ye
2025 J jnl
J. Mach. Learn. Res.
Si-Yang Liu, Hao-Run Cai, Qi-Le Zhou, Huai-Hong Yin, Tao Zhou, Jun-Peng Jiang, Han-Jia Ye
2025 A* conf
CVPR
Bowen Zheng, Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2025 J jnl
CoRR
Bowen Zheng, Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2025 J jnl
CoRR
Guannan Lai, Da-Wei Zhou, Xin Yang, Han-Jia Ye
2025 A* conf
ICML
Haorun Cai, Han-Jia Ye
2025 J jnl
CoRR
Hao-Run Cai, Han-Jia Ye
2025 J jnl
CoRR
Lu Han, Yu Liu, Qiwen Deng, Jian Jiang, Yinbo Sun, Zhe Yu, Binfeng Wang, Xingyu Lu, Lintao Ma, Han-Jia Ye, De-Chuan Zhan
2025 J jnl
CoRR
Hengzhuang Li, Xinsong Zhang, Qiming Peng, Bin Luo, Han Hu, Dengyang Jiang, Han-Jia Ye, Teng Zhang, Hai Jin
2025 A* conf
ICLR
Yi-Kai Zhang, Shiyin Lu, Qing-Guo Chen, De-Chuan Zhan, Han-Jia Ye
2024 J jnl
CoRR
Han-Jia Ye, Si-Yang Liu, Hao-Run Cai, Qi-Le Zhou, De-Chuan Zhan
2024 J jnl
CoRR
Zhi-Hong Qi, Da-Wei Zhou, Yiran Yao, Han-Jia Ye, De-Chuan Zhan
2024 A* conf
NeurIPS
Chao Yi, Yuhang He, De-Chuan Zhan, Han-Jia Ye
2024 J jnl
CoRR
Chao Yi, De-Chuan Zhan, Han-Jia Ye
2024 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Da-Wei Zhou, Qi-Wei Wang, Zhi-Hong Qi, Han-Jia Ye, De-Chuan Zhan, Ziwei Liu
2024 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Han-Jia Ye, Da-Wei Zhou, Lanqing Hong, Zhenguo Li, Xiu-Shen Wei, De-Chuan Zhan
2024 A* conf
IJCAI
Da-Wei Zhou, Hai-Long Sun, Jingyi Ning, Han-Jia Ye, De-Chuan Zhan
2024 J jnl
CoRR
Da-Wei Zhou, Hai-Long Sun, Jingyi Ning, Han-Jia Ye, De-Chuan Zhan
2024 J jnl
CoRR
Da-Wei Zhou, Zi-Wen Cai, Han-Jia Ye, Lijun Zhang, De-Chuan Zhan
2024 A* conf
ICML
Lan Li, Xin-Chun Li, Han-Jia Ye, De-Chuan Zhan
2024 A* conf
CVPR
Da-Wei Zhou, Hai-Long Sun, Han-Jia Ye, De-Chuan Zhan
2024 J jnl
CoRR
Da-Wei Zhou, Hai-Long Sun, Han-Jia Ye, De-Chuan Zhan
2024 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Han-Jia Ye, Lu Ming, De-Chuan Zhan, Wei-Lun Chao
2024 A* conf
WWW
Yucheng Wu, Leye Wang, Xiao Han, Han-Jia Ye
2024 J jnl
CoRR
Yucheng Wu, Leye Wang, Xiao Han, Han-Jia Ye
2024 J jnl
CoRR
Ting-Ji Huang, Jia-Qi Yang, Chunxu Shen, Kai-Qi Liu, De-Chuan Zhan, Han-Jia Ye
2024 A* conf
AAAI
Yu-Cheng He, Yao-Xiang Ding, Han-Jia Ye, Zhi-Hua Zhou
2024 A* conf
CVPR
Chao Yi, Lu Ren, De-Chuan Zhan, Han-Jia Ye
2024 J jnl
CoRR
Chao Yi, Lu Ren, De-Chuan Zhan, Han-Jia Ye
2024 J jnl
CoRR
Xu-Yang Chen, Lu Han, De-Chuan Zhan, Han-Jia Ye
2024 J jnl
CoRR
Hai-Long Sun, Da-Wei Zhou, Hanbin Zhao, Le Gan, De-Chuan Zhan, Han-Jia Ye
2024 J jnl
CoRR
Han-Jia Ye, Huai-Hong Yin, De-Chuan Zhan
2024 A* conf
ICML
Bowen Zheng, Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2024 J jnl
CoRR
Yi-Kai Zhang, Xu-Xiang Zhong, Shiyin Lu, Qing-Guo Chen, De-Chuan Zhan, Han-Jia Ye
2024 J jnl
CoRR
Shiyin Lu, Yang Li, Qing-Guo Chen, Zhao Xu, Weihua Luo, Kaifu Zhang, Han-Jia Ye
2024 J jnl
CoRR
Hai-Long Sun, Da-Wei Zhou, Yang Li, Shiyin Lu, Chao Yi, Qing-Guo Chen, Zhao Xu, Weihua Luo, Kaifu Zhang, De-Chuan Zhan, Han-Jia Ye
2024 A* conf
ICML
Lu Han, Han-Jia Ye, De-Chuan Zhan
2024 A* conf
NeurIPS
Han Lu, Xu-Yang Chen, Han-Jia Ye, De-Chuan Zhan
2024 J jnl
CoRR
Lu Han, Xu-Yang Chen, Han-Jia Ye, De-Chuan Zhan
2024 J jnl
CoRR
Si-Yang Liu, Hao-Run Cai, Qi-Le Zhou, Han-Jia Ye
2024 J jnl
CoRR
Da-Wei Zhou, Zhi-Hong Qi, Han-Jia Ye, De-Chuan Zhan
2024 J jnl
Frontiers Comput. Sci.
Da-Wei Zhou, Zhi-Hong Qi, Han-Jia Ye, De-Chuan Zhan
2024 A* conf
ICML
Jun-Peng Jiang, Han-Jia Ye, Leye Wang, Yang Yang, Yuan Jiang, De-Chuan Zhan
2024 J jnl
IEEE Trans. Knowl. Data Eng.
Lu Han, Han-Jia Ye, De-Chuan Zhan
2024 A* conf
AAAI
Lan Li, Bowen Tao, Lu Han, De-Chuan Zhan, Han-Jia Ye
2024 A* conf
NeurIPS
Yi-Kai Zhang, Shiyin Lu, Yang Li, Yanqing Ma, Qingguo Chen, Zhao Xu, Weihua Luo, Kaifu Zhang, De-Chuan Zhan, Han-Jia Ye
2024 J jnl
CoRR
Yi-Kai Zhang, Shiyin Lu, Yang Li, Yanqing Ma, Qing-Guo Chen, Zhao Xu, Weihua Luo, Kaifu Zhang, De-Chuan Zhan, Han-Jia Ye
2023 A* conf
ICLR
Da-Wei Zhou, Qi-Wei Wang, Han-Jia Ye, De-Chuan Zhan
2023 conf
MICCAI (6)
Yi Shi, Rui-Xiang Li, Wen-Qi Shao, Xincen Duan, Han-Jia Ye, De-Chuan Zhan, Bai-Shen Pan, Beili Wang, Wei Guo, Yuan Jiang
2023 A* conf
ICLR
Lu Han, Han-Jia Ye, De-Chuan Zhan
2023 A* conf
ICLR
Fu-Yun Wang, Da-Wei Zhou, Liu Liu, Han-Jia Ye, Yatao Bian, De-Chuan Zhan, Peilin Zhao
2023 conf
AALTD@ECML/PKDD
Ting-Ji Huang, Qi-Le Zhou, Han-Jia Ye, De-Chuan Zhan
2023 J jnl
CoRR
Da-Wei Zhou, Qi-Wei Wang, Zhi-Hong Qi, Han-Jia Ye, De-Chuan Zhan, Ziwei Liu
2023 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Da-Wei Zhou, Han-Jia Ye, Liang Ma, Di Xie, Shiliang Pu, De-Chuan Zhan
2023 A* conf
NeurIPS
Qi-Wei Wang, Da-Wei Zhou, Yi-Kai Zhang, De-Chuan Zhan, Han-Jia Ye
2023 J jnl
CoRR
Qi-Wei Wang, Da-Wei Zhou, Yi-Kai Zhang, De-Chuan Zhan, Han-Jia Ye
2023 J jnl
CoRR
Fu-Yun Wang, Wenshuo Chen, Guanglu Song, Han-Jia Ye, Yu Liu, Hongsheng Li
2023 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Han-Jia Ye, Su Lu, De-Chuan Zhan
2023 conf
ICME Workshops
Chao Yi, Ting-Ji Huang, Han-Jia Ye, De-Chuan Zhan
2023 A* conf
CVPR
Yi-Kai Zhang, Qi-Wei Wang, De-Chuan Zhan, Han-Jia Ye
2023 J jnl
CoRR
Lu Han, Xu-Yang Chen, Han-Jia Ye, De-Chuan Zhan
2023 J jnl
CoRR
Da-Wei Zhou, Yuanhan Zhang, Jingyi Ning, Han-Jia Ye, De-Chuan Zhan, Ziwei Liu
2023 A* conf
NeurIPS
Yi-Kai Zhang, Ting-Ji Huang, Yao-Xiang Ding, De-Chuan Zhan, Han-Jia Ye
2023 J jnl
CoRR
Yi-Kai Zhang, Ting-Ji Huang, Yao-Xiang Ding, De-Chuan Zhan, Han-Jia Ye
2023 J jnl
CoRR
Lu Han, Han-Jia Ye, De-Chuan Zhan
2023 conf
UniReps
Jun-Peng Jiang, Han-Jia Ye, Leye Wang, Yang Yang, Yuan Jiang, De-Chuan Zhan
2023 J jnl
CoRR
Hai-Long Sun, Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2023 A conf
ICME
Bowen Zheng, Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2023 J jnl
CoRR
Bowen Zheng, Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2023 J jnl
Sci. China Inf. Sci.
Da-Wei Zhou, Fu-Yun Wang, Han-Jia Ye, De-Chuan Zhan
2023 J jnl
CoRR
Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan, Ziwei Liu
2023 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Han-Jia Ye, Lu Han, De-Chuan Zhan
2023 J jnl
CoRR
Qi-Wei Wang, Hongyu Lu, Yu Chen, Da-Wei Zhou, De-Chuan Zhan, Ming Chen, Han-Jia Ye
2023 J jnl
CoRR
Lu Han, Han-Jia Ye, De-Chuan Zhan
2023 J jnl
CoRR
Han-Jia Ye, Qi-Le Zhou, De-Chuan Zhan
2023 conf
PKDD/ECML Workshops (5)
Chao Yi, Xu-Yang Chen, Lu Ren, Han-Jia Ye, De-Chuan Zhan
2023 J jnl
CoRR
Lan Li, Bowen Tao, Lu Han, De-Chuan Zhan, Han-Jia Ye
2023 J jnl
CoRR
Qi-Le Zhou, Han-Jia Ye, Leye Wang, De-Chuan Zhan
2023 J jnl
CoRR
Yi-Kai Zhang, Lu Ren, Chao Yi, Qi-Wei Wang, De-Chuan Zhan, Han-Jia Ye
2022 J jnl
CoRR
Da-Wei Zhou, Qi-Wei Wang, Han-Jia Ye, De-Chuan Zhan
2022 A conf
INTERSPEECH
Yi-Kai Zhang, Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2022 J jnl
CoRR
Lu Han, Han-Jia Ye, De-Chuan Zhan
2022 conf
ECCV (25)
Fu-Yun Wang, Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2022 J jnl
CoRR
Fu-Yun Wang, Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2022 J jnl
CoRR
Su Lu, Han-Jia Ye, De-Chuan Zhan
2022 J jnl
CoRR
Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2022 A* conf
CVPR
Da-Wei Zhou, Fu-Yun Wang, Han-Jia Ye, Liang Ma, Shiliang Pu, De-Chuan Zhan
2022 J jnl
CoRR
Da-Wei Zhou, Fu-Yun Wang, Han-Jia Ye, Liang Ma, Shiliang Pu, De-Chuan Zhan
2022 J jnl
CoRR
Han-Jia Ye, Su Lu, De-Chuan Zhan
2022 A* conf
ICLR
Han-Jia Ye, Wei-Lun Chao
2022 A* conf
CVPR
Han-Jia Ye, Yi Shi, De-Chuan Zhan
2022 J jnl
CoRR
Han-Jia Ye, Yi Shi, De-Chuan Zhan
2022 J jnl
Trans. Mach. Learn. Res.
Lu Han, Han-Jia Ye, De-Chuan Zhan
2021 A* conf
NeurIPS
Xiu-Shen Wei, Yang Shen, Xuhao Sun, Han-Jia Ye, Jian Yang
2021 A* conf
ACM Multimedia
Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2021 J jnl
CoRR
Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2021 J jnl
CoRR
Han-Jia Ye, Da-Wei Zhou, Lanqing Hong, Zhenguo Li, Xiu-Shen Wei, De-Chuan Zhan
2021 A* conf
AAAI
Haoyue Bai, Rui Sun, Lanqing Hong, Fengwei Zhou, Nanyang Ye, Han-Jia Ye, S.-H. Gary Chan, Zhenguo Li
2021 J jnl
CoRR
Su Lu, Han-Jia Ye, De-Chuan Zhan
2021 J jnl
CoRR
Han-Jia Ye, Lu Ming, De-Chuan Zhan, Wei-Lun Chao
2021 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Han-Jia Ye, De-Chuan Zhan, Yuan Jiang, Zhi-Hua Zhou
2021 J jnl
CoRR
Han-Jia Ye, Wei-Lun Chao
2021 J jnl
Int. J. Comput. Vis.
Han-Jia Ye, Hexiang Hu, De-Chuan Zhan
2021 A* conf
CVPR
Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2021 J jnl
CoRR
Da-Wei Zhou, Han-Jia Ye, De-Chuan Zhan
2021 A* conf
ACM Multimedia
Xiu-Shen Wei, Jufeng Yang, Han-Jia Ye, Jian Yang
2021 ed.
MULL @ ACM Multimedia
Xiu-Shen Wei, Han-Jia Ye, Jufeng Yang, Jian Yang
2021 J jnl
IEEE Trans. Knowl. Data Eng.
Xiu-Shen Wei, Han-Jia Ye, Xin Mu, Jianxin Wu, Chunhua Shen, Zhi-Hua Zhou
2021 A* conf
ICCV
Han-Jia Ye, De-Chuan Zhan, Wei-Lun Chao
2021 J jnl
CoRR
Han-Jia Ye, De-Chuan Zhan, Wei-Lun Chao
2021 J jnl
CoRR
Da-Wei Zhou, Fu-Yun Wang, Han-Jia Ye, De-Chuan Zhan
2021 J jnl
CoRR
Su Lu, Han-Jia Ye, De-Chuan Zhan
2021 A* conf
AAAI
Su Lu, Han-Jia Ye, De-Chuan Zhan
2021 A* conf
AAAI
Han-Jia Ye, Xin-Chun Li, De-Chuan Zhan
2021 A* conf
NeurIPS
Su Lu, Han-Jia Ye, Le Gan, De-Chuan Zhan
2020 J jnl
CoRR
Haoyue Bai, Rui Sun, Lanqing Hong, Fengwei Zhou, Nanyang Ye, Han-Jia Ye, S.-H. Gary Chan, Zhenguo Li
2020 A* conf
CVPR
Han-Jia Ye, Su Lu, De-Chuan Zhan
2020 A* conf
CVPR
Han-Jia Ye, Hexiang Hu, De-Chuan Zhan, Fei Sha
2020 J jnl
Mach. Learn.
Han-Jia Ye, Xiang-Rong Sheng, De-Chuan Zhan
2020 J jnl
CoRR
Han-Jia Ye, Hong-You Chen, De-Chuan Zhan, Wei-Lun Chao
2020 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Han-Jia Ye, De-Chuan Zhan, Nan Li, Yuan Jiang
2020 J jnl
CoRR
Chao Wang, Ruo-Ze Liu, Han-Jia Ye, Yang Yu
2020 J jnl
CoRR
Wei-Lun Chao, Han-Jia Ye, De-Chuan Zhan, Mark E. Campbell, Kilian Q. Weinberger
2020 J jnl
CoRR
Han-Jia Ye, Lu Han, De-Chuan Zhan
2019 J jnl
Mach. Learn.
Han-Jia Ye, De-Chuan Zhan, Yuan Jiang
2019 J jnl
CoRR
Han-Jia Ye, Hexiang Hu, De-Chuan Zhan, Fei Sha
2019 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Han-Jia Ye, De-Chuan Zhan, Yuan Jiang, Zhi-Hua Zhou
2018 A* conf
IJCAI
Han-Jia Ye, Xiang-Rong Sheng, De-Chuan Zhan, Peng He
2018 J jnl
CoRR
Han-Jia Ye, Hexiang Hu, De-Chuan Zhan, Fei Sha
2018 A* conf
ICML
Han-Jia Ye, De-Chuan Zhan, Yuan Jiang, Zhi-Hua Zhou
2017 A* conf
IJCAI
Han-Jia Ye, De-Chuan Zhan, Xue-Min Si, Yuan Jiang
2016 A* conf
ICDM
Han-Jia Ye, De-Chuan Zhan, Xiaolin Li, Zhen-Chuan Huang, Yuan Jiang
2016 A* conf
AAAI
Han-Jia Ye, De-Chuan Zhan, Yuan Jiang
2016 C conf
ACML
Han-Jia Ye, De-Chuan Zhan, Xue-Min Si, Yuan Jiang
2016 conf
NIPS
Han-Jia Ye, De-Chuan Zhan, Xue-Min Si, Yuan Jiang, Zhi-Hua Zhou
2015 A* conf
IJCAI
Yang Yang, Han-Jia Ye, De-Chuan Zhan, Yuan Jiang
2015 A conf
CIKM
Han-Jia Ye, De-Chuan Zhan, Yuan Miao, Yuan Jiang, Zhi-Hua Zhou
redb/extractors/hashes.py
← Index redb/extractors/hashes.py python
from dataclasses import asdict
from typing import Any
from datetime import datetime, timezone

import hashlib
import inspect
from struct import pack

from magika import Magika
from signify.fingerprinter import AuthenticodeFingerprinter
import ppdeep
import tlsh

import pefile
from elftools.elf.elffile import ELFFile
from elftools.common.exceptions import ELFError

from redb.extractors.enum import Tag
from redb.models.dataclasses import Hashes
from redb.extractors.extractor import Extractor


class HashExtractor(Extractor):

    def __init__(
        self,
        filepath,
        log,
        exporters=None,
        index_prefix=None,
        elastic_index=None,
        known_benign=False,
        known_malicious=False,
        macho=None,
    ):
        super().__init__(
            filepath, log, exporters, index_prefix, elastic_index, known_benign, known_malicious
        )
        self.hashes = None
        self.elastic_index = self.index_prefix + "-hashes"
        self.filetype = Magika().identify_bytes(self.binary).output.label
        self.pe = None
        self.elf = None
        self.macho = macho
        if self.filetype == "pebin":  # else None
            try:
                self.pe = pefile.PE(self.filepath)
            except Exception as e:
                self.log.error(f"Failed to initialize PE file object: {e}")
                self.pe = None
        elif self.filetype == "elf":
            # ELF file will be created when needed in _extract_elf_hashes
            pass

    def _extract_hashes(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        
        # Initialize hash values with None
        md5 = None
        sha1 = None
        sha256 = None
        ssdeep_hash = None
        tlsh_hash = None
        
        # Calculate basic hashes with error handling
        try:
            md5 = hashlib.md5(self.binary).hexdigest()
        except Exception as e:
            self.log.error(f"Failed to calculate MD5 hash: {e}")
            
        try:
            sha1 = hashlib.sha1(self.binary).hexdigest()
        except Exception as e:
            self.log.error(f"Failed to calculate SHA1 hash: {e}")
            
        try:
            sha256 = hashlib.sha256(self.binary).hexdigest()
        except Exception as e:
            self.log.error(f"Failed to calculate SHA256 hash: {e}")
            
        try:
            ssdeep_hash = ppdeep.hash_from_file(self.filepath)
        except Exception as e:
            self.log.error(f"Failed to calculate ssdeep hash: {e}")
            
        try:
            tlsh_hash = tlsh.hash(self.binary)
        except Exception as e:
            self.log.error(f"Failed to calculate TLSH hash: {e}")
        
        # Create Hashes object with available values
        self.hashes = Hashes(
            md5 or "",
            sha1 or "",
            sha256 or "",
            ssdeep_hash or "",
            tlsh_hash or "",
        )

        if self.filetype == "pebin" and self.pe is not None:
            self.log.debug("Computing PEBIN related hash values")
            
            # Authentihash
            try:
                with open(self.filepath, 'rb') as f:
                    fingerprinter = AuthenticodeFingerprinter(f)
                    fingerprinter.add_authenticode_hashers(hashlib.sha256)
                    self.hashes.authentihash = fingerprinter.hash()['sha256'].hex()
            except Exception as e:
                self.log.error(f"Failed to calculate Authentihash: {e}")
                self.hashes.authentihash = None
                
            # Imphash
            try:
                self.hashes.imphash = self.pe.get_imphash()
            except Exception as e:
                self.log.error(f"Failed to calculate Imphash: {e}")
                self.hashes.imphash = None
                
            # Rich header hashes
            try:
                if self.pe.parse_rich_header():
                    self.log.debug("Computing RichHeader related hash values")
                    
                    richhash = self._compute_richhash()
                    if richhash:
                        self.hashes.richhash = richhash
                        
                    richpe_hash = self._compute_richpe_hash()
                    if richpe_hash:
                        self.hashes.richpe_hash = richpe_hash
                        
                    richpv_result = self._compute_richpv_hash()
                    if richpv_result:
                        self.hashes.richpv_hash, self.hashes.richpv_hash_sorted = richpv_result
            except Exception as e:
                self.log.error(f"Failed to calculate Rich header hashes: {e}")
        elif self.filetype == "pebin" and self.pe is None:
            self.log.warning("PE file type detected but PE object initialization failed - skipping PE-specific hashes")

        elif self.filetype == "elf":
            self.log.debug("Computing ELF related hash values")
            self._extract_elf_hashes()
        elif self.filetype == "macho":
            self.log.debug("Computing Mach-O related hash values")
            self._extract_macho_hashes()
        elif self.filetype == "apk":
            self.log.debug("Computing APK related hash values")
            self._extract_apk_hashes()
        else:
            pass
        self.log.debug(f"Hashes dump: {asdict(self.hashes)}")
        return self.hashes

    def _compute_richhash(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        try:
            rich_header = self.pe.parse_rich_header()
            if not rich_header:
                return ""
            data = rich_header["clear_data"]
            return hashlib.md5(data).hexdigest().lower()
        except:
            return ""

    def _compute_richpe_hash(self):
        """
        Computes the RichPE hash given a file path or PE object.

        RichPE hash is includes RichHeader CompID and count, as well as
        fields from IMAGE_FILE_HEADER and IMAGE_OPTIONAL_HEADER

        Parameters:
        input: it can be either a file path or a PE object

        Returns:
        richpe_hash: md5 hash of the RichPE value
        None: if no Rich Header present
        """
        try:
            # Attempt to parse Rich header
            self.log.debug(inspect.currentframe().f_code.co_name)
            rich_header = self.pe.parse_rich_header()
            if rich_header is None:
                return None

            # Get list of @Comp.IDs and counts from Rich header
            # Elements in rich_fields at even indices are @Comp.IDs
            # Elements in rich_fields at odd indices are counts
            rich_fields = rich_header.get("values", None)
            if not rich_fields or len(rich_fields) % 2 != 0:
                return None

            md5 = hashlib.md5()

            # Update hash using @Comp.IDs and masked counts from Rich header
            while len(rich_fields):
                compid = rich_fields.pop(0)
                count = rich_fields.pop(0)
                mask = 2 ** (count.bit_length() // 2 + 1) - 1
                count |= mask
                md5.update(pack("<L", compid))
                md5.update(pack("<L", count))

            # Update hash using metadata from the PE header
            md5.update(pack("<L", self.pe.FILE_HEADER.Machine))
            md5.update(pack("<L", self.pe.FILE_HEADER.Characteristics))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.Subsystem))
            md5.update(pack("<B", self.pe.OPTIONAL_HEADER.MajorLinkerVersion))
            md5.update(pack("<B", self.pe.OPTIONAL_HEADER.MinorLinkerVersion))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.MajorOperatingSystemVersion))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.MinorOperatingSystemVersion))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.MajorImageVersion))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.MinorImageVersion))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.MajorSubsystemVersion))
            md5.update(pack("<L", self.pe.OPTIONAL_HEADER.MinorSubsystemVersion))

            return md5.hexdigest()
        except Exception as e:
            self.log.error(f"Failed to compute RichPE hash: {e}")
            return None

    def _compute_richpv_hash(self):
        """
        Compute the RichPV hash values, sorted and unsorted.
        RichPV excludes the most volatile Rich Header field from the MD5 input data,
        the Product Count (pC) field.

        Returns:
        richpv_hash_unsorted: md5 hash of the RichPV value unsorted
        richpv_hash_sorted: md5 hash of the RichPV value sorted
        None: if no Rich Header present
        """
        try:
            self.log.debug(inspect.currentframe().f_code.co_name)
            # Attempt to parse Rich header
            rich_header = self.pe.parse_rich_header()
            if rich_header is None:
                return None

            # Get list of @Comp.IDs and counts from Rich header
            # Elements in rich_fields at even indices are @Comp.IDs
            # Elements in rich_fields at odd indices are counts
            rich_fields = rich_header.get("values", None)
            if not rich_fields or len(rich_fields) % 2 != 0:
                return None

            md5 = hashlib.md5()
            md5_sorted = hashlib.md5()
            sorted_vector = []

            # Update hash using @Comp.IDs only
            for i in range(0, len(rich_fields), 2):
                compid = rich_fields[i]
                md5.update(pack("<L", compid))
                sorted_vector.append(compid)

            sorted_vector.sort()
            for compid in sorted_vector:
                md5_sorted.update(pack("<L", compid))

            return md5.hexdigest(), md5_sorted.hexdigest()
        except Exception as e:
            self.log.error(f"Failed to compute RichPV hash: {e}")
            return None

    def _extract_elf_hashes(self):
        """Extract ELF specific similarity hashes."""
        self.log.debug(inspect.currentframe().f_code.co_name)

        try:
            with open(self.filepath, 'rb') as f:
                elf = ELFFile(f)
                if not elf:
                    return

                # Generate all similarity hashes
                import_hash = self._generate_elf_import_hash(elf)
                export_hash = self._generate_elf_export_hash(elf)
                section_hash = self._generate_elf_section_hash(elf)
                symbol_hash = self._generate_elf_symbol_hash(elf)
                dynamic_hash = self._generate_elf_dynamic_hash(elf)

                # Only set hashes if they have meaningful values
                if import_hash:
                    self.hashes.import_hash = import_hash
                if export_hash:
                    self.hashes.export_hash = export_hash
                if section_hash:
                    self.hashes.section_hash = section_hash
                if symbol_hash:
                    self.hashes.symhash = symbol_hash
                if dynamic_hash:
                    self.hashes.dynamic_hash = dynamic_hash

        except Exception as e:
            self.log.error(f"Failed to extract ELF hashes: {e}")

    def _generate_elf_import_hash(self, elf) -> str:
        """Generate MD5 hash of sorted, deduplicated imported symbol names."""
        try:
            imported_symbols = set()

            # Get dynamic symbol table
            dynsym_section = elf.get_section_by_name('.dynsym')
            if dynsym_section and hasattr(dynsym_section, 'iter_symbols'):
                for symbol in dynsym_section.iter_symbols():
                    # Look for undefined symbols (imports)
                    if (symbol.entry.get('st_shndx', 0) == 'SHN_UNDEF' and
                        symbol.name and
                        symbol.entry.get('st_info', {}).get('bind') in ['STB_GLOBAL', 'STB_WEAK']):
                        imported_symbols.add(symbol.name)

            # Also check relocations for additional imports
            for section in elf.iter_sections():
                if hasattr(section, 'iter_relocations'):
                    try:
                        for relocation in section.iter_relocations():
                            if hasattr(relocation, 'symbol') and relocation.symbol and relocation.symbol.name:
                                imported_symbols.add(relocation.symbol.name)
                    except:
                        pass

            # Sort and concatenate
            sorted_imports = sorted(list(imported_symbols))

            # Return None if no imports found
            if not sorted_imports:
                return None

            imports_string = '|'.join(sorted_imports)

            # Generate MD5 hash
            return hashlib.md5(imports_string.encode('utf-8')).hexdigest()

        except Exception as e:
            self.log.error(f"Error generating ELF import hash: {e}")
            return None

    def _generate_elf_export_hash(self, elf) -> str:
        """Generate MD5 hash of sorted, deduplicated exported symbol names."""
        try:
            exported_symbols = set()

            # Check both static and dynamic symbol tables
            symbol_sections = ['.symtab', '.dynsym']

            for section_name in symbol_sections:
                section = elf.get_section_by_name(section_name)
                if not section or not hasattr(section, 'iter_symbols'):
                    continue

                for symbol in section.iter_symbols():
                    # Check if symbol is exported (defined and globally visible)
                    if (symbol.name and
                        symbol.entry.get('st_shndx', 0) != 'SHN_UNDEF' and
                        symbol.entry.get('st_info', {}).get('bind') in ['STB_GLOBAL', 'STB_WEAK'] and
                        symbol.entry.get('st_info', {}).get('type') in ['STT_FUNC', 'STT_OBJECT']):
                        exported_symbols.add(symbol.name)

            # Sort and concatenate
            sorted_exports = sorted(list(exported_symbols))

            # Return None if no exports found
            if not sorted_exports:
                return None

            exports_string = '|'.join(sorted_exports)

            # Generate MD5 hash
            return hashlib.md5(exports_string.encode('utf-8')).hexdigest()

        except Exception as e:
            self.log.error(f"Error generating ELF export hash: {e}")
            return None

    def _generate_elf_section_hash(self, elf) -> str:
        """Generate MD5 hash of section layout (names, types, flags sequence)."""
        try:
            section_info = []

            for section in elf.iter_sections():
                header = section.header
                section_name = section.name or "<unnamed>"
                section_type = header.get('sh_type', 'SHT_NULL')
                section_flags = header.get('sh_flags', 0)

                # Create a consistent representation
                section_repr = f"{section_name}:{section_type}:{section_flags}"
                section_info.append(section_repr)

            # Return None if no meaningful sections found
            if not section_info:
                return None

            # Join all section info
            sections_string = '|'.join(section_info)

            # Generate MD5 hash
            return hashlib.md5(sections_string.encode('utf-8')).hexdigest()

        except Exception as e:
            self.log.error(f"Error generating ELF section hash: {e}")
            return None

    def _generate_elf_symbol_hash(self, elf) -> str:
        """Generate MD5 hash of sorted symbol names and types."""
        try:
            symbol_info = set()

            # Check both static and dynamic symbol tables
            symbol_sections = ['.symtab', '.dynsym']

            for section_name in symbol_sections:
                section = elf.get_section_by_name(section_name)
                if not section or not hasattr(section, 'iter_symbols'):
                    continue

                for symbol in section.iter_symbols():
                    if symbol.name:
                        symbol_type = symbol.entry.get('st_info', {}).get('type', 'STT_NOTYPE')
                        symbol_bind = symbol.entry.get('st_info', {}).get('bind', 'STB_LOCAL')

                        # Create a consistent representation
                        symbol_repr = f"{symbol.name}:{symbol_type}:{symbol_bind}"
                        symbol_info.add(symbol_repr)

            # Sort and concatenate
            sorted_symbols = sorted(list(symbol_info))

            # Return None if no symbols found
            if not sorted_symbols:
                return None

            symbols_string = '|'.join(sorted_symbols)

            # Generate MD5 hash
            return hashlib.md5(symbols_string.encode('utf-8')).hexdigest()

        except Exception as e:
            self.log.error(f"Error generating ELF symbol hash: {e}")
            return None

    def _generate_elf_dynamic_hash(self, elf) -> str:
        """Generate MD5 hash of dynamic section entries (DT_* tags)."""
        try:
            dynamic_info = []

            # Get the dynamic section
            dynamic_section = elf.get_section_by_name('.dynamic')
            if not dynamic_section:
                return None

            # Extract dynamic tags and their values
            for tag in dynamic_section.iter_tags():
                dt_tag = tag.entry.d_tag

                # Create a representation based on tag type
                if dt_tag == 'DT_NEEDED':
                    dynamic_info.append(f"DT_NEEDED:{tag.needed}")
                elif dt_tag == 'DT_SONAME':
                    dynamic_info.append(f"DT_SONAME:{tag.soname}")
                elif dt_tag == 'DT_RPATH':
                    dynamic_info.append(f"DT_RPATH:{tag.rpath}")
                elif dt_tag == 'DT_RUNPATH':
                    dynamic_info.append(f"DT_RUNPATH:{tag.runpath}")
                else:
                    # For other tags, use the tag name and value
                    dt_value = tag.entry.d_val if hasattr(tag.entry, 'd_val') else 0
                    dynamic_info.append(f"{dt_tag}:{dt_value}")

            # Sort to ensure consistent ordering
            dynamic_info.sort()
            dynamics_string = '|'.join(dynamic_info)

            # Generate MD5 hash
            return hashlib.md5(dynamics_string.encode('utf-8')).hexdigest()

        except Exception as e:
            self.log.error(f"Error generating ELF dynamic hash: {e}")
            return None

    def _extract_macho_hashes(self):
        """Extract Mach-O specific similarity hashes using machofile API.

        For FAT binaries, this extracts hashes for the current file being processed
        (either the FAT container or an individual slice). The machofile library
        handles the architecture-specific extraction when an arch parameter is provided.

        For slices: We parse the slice file directly since it's a standalone Mach-O.
        For FAT container: We use the provided macho object with combined/fat hashes.
        """
        self.log.debug(inspect.currentframe().f_code.co_name)

        try:
            # If we have a pre-parsed macho object (FAT container or single-arch with passed object)
            if self.macho:
                architectures = self.macho.get_architectures()
                is_fat = len(architectures) > 1

                if is_fat:
                    # For FAT container, get combined hashes (key may be 'fat' or 'combined')
                    all_hashes = self.macho.get_similarity_hashes()
                    if all_hashes:
                        # Try 'fat' first, then 'combined' for backwards compatibility
                        similarity_hashes = all_hashes.get('fat', all_hashes.get('combined', {}))
                    else:
                        similarity_hashes = {}
                else:
                    # Single-arch with pre-parsed object
                    similarity_hashes = self.macho.get_similarity_hashes(arch=architectures[0]) if architectures else {}
            else:
                # No pre-parsed object - parse the file (slice case)
                import machofile
                macho = machofile.UniversalMachO(self.filepath)
                macho.parse()

                architectures = macho.get_architectures()
                if architectures:
                    # For a slice, there's only one architecture
                    similarity_hashes = macho.get_similarity_hashes(arch=architectures[0]) or {}
                else:
                    similarity_hashes = {}

            # Set the hash values on the Hashes object
            if similarity_hashes:
                if similarity_hashes.get('dylib_hash'):
                    self.hashes.macho_dylib_hash = similarity_hashes['dylib_hash']
                if similarity_hashes.get('import_hash'):
                    self.hashes.macho_import_hash = similarity_hashes['import_hash']
                if similarity_hashes.get('export_hash'):
                    self.hashes.macho_export_hash = similarity_hashes['export_hash']
                if similarity_hashes.get('entitlement_hash'):
                    self.hashes.macho_entitlement_hash = similarity_hashes['entitlement_hash']
                if similarity_hashes.get('symhash'):
                    self.hashes.macho_symhash = similarity_hashes['symhash']

        except Exception as e:
            self.log.error(f"Failed to extract Mach-O hashes: {e}")

    def _extract_apk_hashes(self):
        """Extract APK specific similarity hashes (permhash)."""
        self.log.debug(inspect.currentframe().f_code.co_name)
        try:
            from permhash.functions import permhash_apk
            ph = permhash_apk(self.filepath)
            if ph:
                self.hashes.permhash = ph
        except Exception as e:
            self.log.error(f"Failed to extract APK hashes: {e}")

    def extract(self):
        try:
            self.log.debug(inspect.currentframe().f_code.co_name)
            self._extract_hashes()
            return self.hashes
        except Exception as e:
            self.log.error(f"Error extracting hashes: {e}")
            return None

    def prepare_export_data(self, exporter_type: str) -> Any:
        if exporter_type == "ElasticsearchExporter":
            return self.hashes
        elif exporter_type == "ClickHouseExporter":
            # Safely get hash values with fallbacks for None values
            sha256 = getattr(self.hashes, 'sha256', None) or ""
            md5 = getattr(self.hashes, 'md5', None) or ""
            sha1 = getattr(self.hashes, 'sha1', None) or ""
            ssdeep_hash = getattr(self.hashes, 'ssdeep_hash', None) or ""
            tlsh_hash = getattr(self.hashes, 'tlsh_hash', None) or ""
            authentihash = getattr(self.hashes, 'authentihash', None)
            imphash = getattr(self.hashes, 'imphash', None)
            impfuzzy = getattr(self.hashes, 'impfuzzy', None)
            typerefhash = getattr(self.hashes, 'typerefhash', None)
            richhash = getattr(self.hashes, 'richhash', None)
            richpe_hash = getattr(self.hashes, 'richpe_hash', None)
            richpv_hash = getattr(self.hashes, 'richpv_hash', None)
            richpv_hash_sorted = getattr(self.hashes, 'richpv_hash_sorted', None)
            # ELF hashes
            import_hash = getattr(self.hashes, 'import_hash', None)
            export_hash = getattr(self.hashes, 'export_hash', None)
            section_hash = getattr(self.hashes, 'section_hash', None)
            symbol_hash = getattr(self.hashes, 'symhash', None)
            dynamic_hash = getattr(self.hashes, 'dynamic_hash', None)
            # Mach-O hashes
            macho_dylib_hash = getattr(self.hashes, 'macho_dylib_hash', None)
            macho_import_hash = getattr(self.hashes, 'macho_import_hash', None)
            macho_export_hash = getattr(self.hashes, 'macho_export_hash', None)
            macho_entitlement_hash = getattr(self.hashes, 'macho_entitlement_hash', None)
            macho_symhash = getattr(self.hashes, 'macho_symhash', None)
            # APK hashes
            permhash = getattr(self.hashes, 'permhash', None)

            data = [[
                sha256,
                md5,
                sha1,
                ssdeep_hash,
                tlsh_hash,
                authentihash,
                imphash,
                impfuzzy,
                typerefhash,
                richhash,
                richpe_hash,
                richpv_hash,
                richpv_hash_sorted,
                import_hash,
                export_hash,
                section_hash,
                symbol_hash,
                dynamic_hash,
                macho_dylib_hash,
                macho_import_hash,
                macho_export_hash,
                macho_entitlement_hash,
                macho_symhash,
                permhash,
                datetime.now(timezone.utc)
            ]]

            column_names = [
                'sha256', 'md5', 'sha1', 'ssdeep_hash', 'tlsh_hash',
                'authentihash', 'imphash', 'impfuzzy', 'typerefhash',
                'richhash', 'richpe_hash', 'richpv_hash', 'richpv_hash_sorted',
                'import_hash', 'export_hash', 'section_hash', 'symbol_hash', 'dynamic_hash',
                'macho_dylib_hash', 'macho_import_hash', 'macho_export_hash',
                'macho_entitlement_hash', 'macho_symhash',
                'permhash',
                'analysis_date'
            ]

            column_type_names = [
                # sha256, md5, sha1
                'String', 'String', 'String',
                # ssdeep_hash, tlsh_hash
                'Nullable(String)', 'Nullable(String)',
                # authentihash, imphash, impfuzzy, typerefhash
                'Nullable(String)', 'Nullable(String)',
                'Nullable(String)', 'Nullable(String)',
                # richhash, richpe_hash, richpv_hash, richpv_hash_sorted
                'Nullable(String)', 'Nullable(String)',
                'Nullable(String)', 'Nullable(String)',
                # import_hash, export_hash, section_hash, symbol_hash, dynamic_hash
                'Nullable(FixedString(32))', 'Nullable(FixedString(32))',
                'Nullable(FixedString(32))', 'Nullable(FixedString(32))',
                'Nullable(FixedString(32))',
                # macho_dylib_hash, macho_import_hash, macho_export_hash, macho_entitlement_hash, macho_symhash
                'Nullable(FixedString(32))', 'Nullable(FixedString(32))',
                'Nullable(FixedString(32))', 'Nullable(FixedString(32))',
                'Nullable(FixedString(32))',
                # permhash (APK)
                'Nullable(FixedString(64))',
                # analysis_date
                'DateTime64(3, \'UTC\')'
            ]

            return (data, column_names, column_type_names)

    def get_clickhouse_table(self) -> str:
        return "redb_hashes"

    def tag(self):
        return Tag.HASH.value