Haibin Zhu

255 papers B 40C 29Misc 5Journal 125Unranked 54
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Trans. Comput. Soc. Syst.
Hua Ma, Qiong Huang, Xinyi Hu, Zhuoxuan Huang, Hong-yu Zhang, Tianyu Zhou, Haibin Zhu
2026 J jnl
IEEE Trans. Comput. Soc. Syst.
Yuanbai Li, Yuxiang Sun, Minghao Wang, Haibin Zhu, Xianzhong Zhou
2026 J jnl
IEEE Trans. Serv. Comput.
Peiyun Zhang, Jigang Ren, Jishi Yin, Qinglin Zhao, Haibin Zhu
2026 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Zhuoxuan Huang, Hongyu Zhang, Tianyu Zhou, Hua Ma, Haibin Zhu
2026 J jnl
Inf. Sci.
Feifei Lin, Zhenyu Meng, Haibin Zhu
2026 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Jiahui Yu, Libo Zhang, Haibin Zhu, Xianzhong Zhou
2026 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Hua Ma, Xiangru Fu, Wensheng Tang, Ming Chen, Haibin Zhu, Keqin Li
2026 J jnl
IEEE Trans. Comput. Soc. Syst.
Tianxing Wang, Jintong Zuo, Haibin Zhu, Bing Huang
2026 J jnl
IEEE Trans. Cybern.
Tianxing Wang, Haibin Zhu, Bing Huang
2025 C ed.
CSCWD
Weiming Shen, Marie-Hélène Abel, Nada Matta, Jean-Paul A. Barthès, Junzhou Luo, Jinghui Zhang, Haibin Zhu, Kunkun Peng
2025 J jnl
IEEE Trans. Cybern.
Laiqi Yu, Zhenyu Meng, Haibin Zhu
2025 J jnl
Knowl. Inf. Syst.
Tong Yi, Jinyan Wang, Wenqian Shang, Haibin Zhu, Xianxian Li
2025 J jnl
IEEE Trans. Serv. Comput.
Peiyun Zhang, Jiajun Fan, Yutong Chen, Wenjun Huang, Haibin Zhu, Qinglin Zhao
2025 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Junhao Chen, Haibin Zhu, Dongning Liu
2025 J jnl
IEEE Trans. Ind. Informatics
Peiyun Zhang, Fuya Xu, Tianlin Huang, Haibin Zhu, Qinglin Zhao
2025 conf
SysCon
Ke Gong, Haibin Zhu, Tianshuo Yang
2025 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Hua Ma, Chao Xiong, Xiangru Fu, Haibin Zhu, Yuqi Tang, Keqin Li
2025 J jnl
Expert Syst. Appl.
Rui Ding, Yuhan Zhu, Xianbin Feng, Chuanshan Zhang, Haibin Zhu
2025 J jnl
IEEE Robotics Autom. Lett.
Haixuan Wang, Fei Qiao, Shengxi Jiang, Haibin Zhu, Junkai Wang
2025 J jnl
IEEE Trans. Circuits Syst. I Regul. Pap.
Rui Guo, Jianwen Feng, Xiaoqun Wu, Jingyi Wang, Tingwen Huang, Haibin Zhu
2025 J jnl
Expert Syst. Appl.
Zhihang Yu, Bo Wang, Hao Hong, Libo Zhang, Haibin Zhu
2025 J jnl
IEEE Trans. Serv. Comput.
Wande Chen, Yong Tang, Haibin Zhu, Dongning Liu
2025 B conf
SMC
Haibin Zhu, Chengyu Peng, Kevin Zhe Yu, Jiajun Li
2025 J jnl
Comput. Mater. Continua
Jianxiang Cao, Jinyang Wu, Wenqian Shang, Chunhua Wang, Kang Song, Tong Yi, Jiajun Cai, Haibin Zhu
2025 J jnl
IEEE Trans. Comput. Soc. Syst.
Ruisi Yang, Shiyu Wu, Weiming Xiong, Haibin Zhu, Shenglin Li, Libo Zhang
2025 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Shiyu Wu, Shenglin Li, Haibin Zhu, Tianxing Wang, Libo Zhang
2025 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Qian Jiang, Dongning Liu, Haibin Zhu, Baoying Huang, Naiqi Wu, Yan Qiao
2025 J jnl
IEEE Trans. Cybern.
Shiyu Wu, Shenglin Li, Haibin Zhu, Rui Chen, Libo Zhang
2025 J jnl
Inf. Sci.
Xueyan Zhang, Tianxing Wang, Haibin Zhu, Bing Huang, Linyuan Liu
2025 J jnl
IEEE Trans. Comput. Soc. Syst.
Jie Yang, Haibin Zhu, Yi Liu
2025 J jnl
IEEE Trans. Comput. Soc. Syst.
Keyi Chen, Tianxing Wang, Haibin Zhu, Bing Huang
2025 J jnl
IEEE Trans. Comput. Soc. Syst.
Zhihang Yu, Cong Guo, Libo Zhang, Haibin Zhu, Bo Wang
2025 conf
SysCon
Evan Wells, Haibin Zhu
2025 J jnl
Knowl. Based Syst.
Yuting Cao, Ziyu Sheng, Haibin Zhu, Tingwen Huang, Shiping Wen
2025 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Zhihang Yu, Bo Wang, Libo Zhang, Zhi Wang, Haibin Zhu
2025 J jnl
IEEE Trans. Hum. Mach. Syst.
Xinlei Zhang, Zhaoquan Zhu, Yuanbai Li, Haibin Zhu, Yuxiang Sun, Xianzhong Zhou
2025 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Guanglei Wu, Yang Tang, Xiaotai Wu, Tingwen Huang, Haibin Zhu, Wenbing Zhang
2025 B conf
SMC
Zigeng Huang, Kangjin Wang, Haibin Zhu, Dongning Liu
2025 B conf
SMC
Kangjin Wang, Qilin Huang, Haibin Zhu, Dongning Liu
2025 J jnl
CCF Trans. High Perform. Comput.
Kaijia Luo, Haibin Zhu, Dongning Liu
2025 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Xinlei Zhang, Jiahui Yu, Danming Huang, Haibin Zhu, Yuxiang Sun, Xianzhong Zhou
2025 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Rongfeng Zhou, Chongle Ren, Zhenyu Meng, Haibin Zhu
2025 C conf
CSCWD
Haibin Zhu, Tianshuo Yang, Ke Gong, Chun Wang
2024 C ed.
CSCWD
Weiming Shen, Jean-Paul A. Barthès, Junzhou Luo, Tie Qiu, Xiaobo Zhou, Jinghui Zhang, Haibin Zhu, Kunkun Peng, Tianyi Xu, Ning Chen
2024 J jnl
IEEE Trans. Serv. Comput.
Peiyun Zhang, Jigang Ren, Wenjun Huang, Yutong Chen, Qinglin Zhao, Haibin Zhu
2024 J jnl
CoRR
Behzad Akbari, Mingfeng Yuan, Hao Wang, Haibin Zhu, Jinjun Shan
2024 J jnl
CAAI Trans. Intell. Technol.
Tong Yi, Minyong Shi, Wenqian Shang, Haibin Zhu
2024 J jnl
IEEE Trans. Comput. Soc. Syst.
Libo Zhang, Zhihang Yu, Shiyu Wu, Haibin Zhu, Yin Sheng
2024 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Zhihang Yu, Bo Wang, Haibin Zhu, Libo Zhang
2024 B conf
SMC
Tianshuo Yang, Haibin Zhu, Chun Wang, Phil Xing Yang
2024 J jnl
Inf. Fusion
Wenqian Shang, Jiazhao Chai, Jianxiang Cao, Xia Lei, Haibin Zhu, Yongkai Fan, Weiping Ding
2024 C conf
CSCWD
Hongze Guo, Haibin Zhu, Dongning Liu
2024 C conf
CSCWD
Xuewei Lin, Haibin Zhu, Dongning Liu
2024 J jnl
IEEE Trans. Comput. Soc. Syst.
Hua Ma, Jingze Li, Haibin Zhu, Wensheng Tang, Zhuoxuan Huang, Yuqi Tang
2024 J jnl
IEEE Trans. Comput. Soc. Syst.
Hongyu Zhang, Zhuoxuan Huang, Zixu Jiang, Hua Ma, Haibin Zhu
2024 B conf
SMC
Xuewei Lin, Xintong Ke, Haibin Zhu, Dongning Liu
2024 J jnl
IEEE Trans. Comput. Soc. Syst.
Peiyun Zhang, Xiaoqi Hua, Haibin Zhu
2024 Misc conf
SACI
Haibin Zhu
2024 C conf
CSCWD
Wenying Peng, Yanming Chen, Haibin Zhu, Yiwen Zhang
2024 J jnl
IEEE Trans. Comput. Soc. Syst.
Peiguang Zhang, Haibin Zhu, Dongning Liu
2024 B conf
SMC
Xiaoqi Hua, Jian Chen, Peiyun Zhang, Zhangjie Fu, Haibin Zhu, Kezhong Lu, Jigang Ren
2024 J jnl
IEEE Trans. Serv. Comput.
Peiyun Zhang, Yutong Chen, Wenjun Huang, Haibin Zhu, Qinglin Zhao
2024 J jnl
IEEE Trans. Comput. Soc. Syst.
Xintong Ke, Haibin Zhu, Dongning Liu
2024 B conf
SMC
Xintong Ke, Xuewei Lin, Haibin Zhu, Dongning Liu
2024 J jnl
IEEE Trans. Comput. Soc. Syst.
Qian Jiang, Dongning Liu, Haibin Zhu, Shijue Wu, Naiqi Wu, Xin Luo, Yan Qiao
2024 conf
CCECE
Jiehan Zhou, Kai Shao, Changrong Yu, Yixue Hao, Long Hu, Min Chen, Haibin Zhu
2024 J jnl
IEEE Trans. Comput. Soc. Syst.
Qian Jiang, Dongning Liu, Haibin Zhu, Baoying Huang, Naiqi Wu, Yan Qiao
2024 conf
ICHMS
Haibin Zhu, Mozhdeh Noroozi Rasoolabadi, Feng Hou, Tianshuo Yang, Chun Wang, Lisa Kaida
2024 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Behzad Akbari, Zikai Wang, Haibin Zhu, Lucas Wan, Ryan Adderson, Ya-Jun Pan
2024 B conf
SMC
Kaizhe Zeng, Weijian Liu, Haibin Zhu, Dongning Liu
2024 C conf
CSCWD
Xiaofeng Liu, Haibin Zhu, Dongning Liu
2024 C conf
CSCWD
Zhixiang Cheng, Haibin Zhu, Dongning Liu
2023 C ed.
CSCWD
Weiming Shen, Jean-Paul A. Barthès, Junzhou Luo, Adriana S. Vivacqua, Daniel Schneider, Cheng Xie, Jinghui Zhang, Haibin Zhu, Kunkun Peng, Cláudia Lage Rebello da Motta
2023 J jnl
CAAI Trans. Intell. Technol.
Haibin Zhu, Tong Yi, Songtao Shang, Minyong Shi, Zhucheng Li, Wenqian Shang
2023 J jnl
IEEE Trans. Comput. Soc. Syst.
Renata Wachowiak-Smolíkova, Haibin Zhu
2023 J jnl
IEEE Trans. Comput. Soc. Syst.
Qian Jiang, Dongning Liu, Haibin Zhu, Yan Qiao, Baoying Huang
2023 J jnl
IEEE Trans. Comput. Soc. Syst.
Qian Jiang, Haibin Zhu, Yan Qiao, Dongning Liu, Baoying Huang
2023 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Haibin Zhu
2023 conf
SSCI
Haibin Zhu, Behzad Akbari, Lucas Wan, Ya-Jun Pan
2023 C conf
CSCWD
Ziqi Xiong, Haibin Zhu, Dongning Liu, Jianhui Xian
2023 J jnl
J. Intell. Fuzzy Syst.
Hua Ma, Yuqi Tang, Xuxiang Zhang, Haibin Zhu, Peiji Huang, Hongyu Zhang
2023 C conf
CSCWD
Tianshuo Yang, Haibin Zhu
2023 J jnl
IEEE Access
Behzad Akbari, Haibin Zhu, Ya-Jun Pan, Ratnasingham Tharmarasa
2023 J jnl
CoRR
Behzad Akbari, Haibin Zhu, Ya-Jun Pan, Ratnasingham Tharmarasa
2023 B conf
SMC
Chengyu Peng, Haibin Zhu, Linyuan Liu, Ratvinder Singh Grewal
2023 C conf
CSCWD
Ziqing Ye, Haibin Zhu, Dongning Liu, Jianhui Xian
2023 J jnl
IEEE Trans. Comput. Soc. Syst.
Haibin Zhu
2023 J jnl
IEEE Trans. Learn. Technol.
Hua Ma, Zhuoxuan Huang, Wensheng Tang, Haibin Zhu, Hong-yu Zhang, Jingze Li
2023 J jnl
Soft Comput.
Hua Ma, Zhuoxuan Huang, Haibin Zhu, Wensheng Tang, Hongyu Zhang, Keqin Li
2023 J jnl
IEEE Trans. Comput. Soc. Syst.
Qian Jiang, Haibin Zhu, Yan Qiao, Dongning Liu, Baoying Huang
2023 J jnl
CoRR
Behzad Akbari, Zikai Wang, Haibin Zhu, Lucas Wan, Ryan Adderson, Ya-Jun Pan
2023 conf
ICNSC
Mozhdeh Noroozi Rasoolabadi, Haibin Zhu, Chun Wang
2023 J jnl
IEEE Trans. Comput. Soc. Syst.
Lu Liang, Jingdong Fu, Haibin Zhu, Dongning Liu
2023 B conf
SMC
Yuelin Cai, Haibin Zhu, Dongning Liu
2023 B conf
SMC
Behzad Akbari, Haibin Zhu, Yajun Pan
2022 C conf
CSCWD
Cong Guo, Shiyu Wu, Haibin Zhu, Yin Sheng, Libo Zhang
2022 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Qian Jiang, Haibin Zhu, Yan Qiao, Zhiwei He, Dongning Liu, Baoying Huang
2022 C conf
CSCWD
Shijue Wu, Haibin Zhu, Yanjiao Zeng, Dongning Liu
2022 C conf
CSCWD
Fuyan Wen, Haibin Zhu, Dongning Liu
2022 B conf
SMC
Behzad Akbari, Haibin Zhu
2022 J jnl
CAAI Trans. Intell. Technol.
Tong Yi, Minyong Shi, Haibin Zhu
2022 C conf
CSCWD
Yibo Li, Xuemei Sui, Senyue Zhang, Haibin Zhu
2022 B conf
SMC
Zhihang Yu, Ruisi Yang, Xiangjun Liu, Haibin Zhu, Libo Zhang
2022 conf
ICNSC
Chengyu Peng, Haibin Zhu, Linyuan Liu, Ratvinder Grewal
2022 J jnl
Future Gener. Comput. Syst.
Linyuan Liu, Haibin Zhu, Shenglei Chen, Zhiqiu Huang
2022 J jnl
IEEE Trans. Comput. Soc. Syst.
Qian Jiang, Dongning Liu, Haibin Zhu, Yan Qiao, Baoying Huang
2022 conf
ICCI*CC
Witold Kinsner, Okyay Kaynak, Haibin Zhu, Ming Hou, Julia Rayz, Marina L. Gavrilova, Guoyin Wang, George Baciu, Jun Peng, Christine W. Chan, Runhe Huang, Bowen Du
2022 J jnl
IEEE Trans. Comput. Soc. Syst.
Fan Wang, Haibin Zhu, Gautam Srivastava, Shancang Li, Mohammad Reza Khosravi, Lianyong Qi
2022 J jnl
IEEE Trans. Comput. Soc. Syst.
Haibin Zhu
2022 C conf
CSCWD
Yongzhi Zhang, Dongning Liu, Haibin Zhu, Wei Zhang, Ziqing Ye
2022 J jnl
IEEE Trans. Intell. Transp. Syst.
Behzad Akbari, Haibin Zhu
2022 B conf
SMC
Senyue Zhang, Weiliang Huang, Haibin Zhu
2021 B conf
SMC
Siqi Xiang, Dongning Liu, Shaohua Teng, Haibin Zhu, Wei Zhang
2021 C conf
CSCWD
Haibin Zhu
2021 conf
ICNSC
Libo Zhang, Zhihang Yu, Haibin Zhu, Yin Sheng
2021 conf
ICCI*CC
Witold Kinsner, Haibin Zhu, George Baciu, Guiming Luo, Fernando Rubio, Jie Sui, Runhe Huang, Hironori Hiraishi, Jun Peng, Liang Chen
2021 J jnl
Int. J. Wirel. Mob. Comput.
Wei Huang, Mengyu Liu, Wenqian Shang, Haibin Zhu, Weiguo Lin, Chunjie Zhang
2021 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Yiwen Zhang, Chunhui Yin, Qilin Wu, Qiang He, Haibin Zhu
2021 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Hua Ma, Wensheng Tang, Haibin Zhu, Hongyu Zhang
2021 C conf
CSCWD
Jinhao Qi, Haibin Zhu, Jiamin Xiang, Dongning Liu
2021 J jnl
IEEE Trans. Intell. Transp. Syst.
Xiaolong Xu, Qihe Huang, Haibin Zhu, Suraj Sharma, Xuyun Zhang, Lianyong Qi, Md. Zakirul Alam Bhuiyan
2021 J jnl
IEEE Trans. Comput. Soc. Syst.
Baoying Huang, Haibin Zhu, Dongning Liu, Naiqi Wu, Yan Qiao, Qian Jiang
2021 B conf
SMC
Haibin Zhu, Zhe Yu
2021 J jnl
IEEE Trans. Serv. Comput.
Hua Ma, Zhigang Hu, Keqin Li, Haibin Zhu
2021 J jnl
IEEE Trans. Comput. Soc. Syst.
Haibin Zhu
2020 J jnl
Knowl. Based Syst.
Tianxing Wang, Huaxiong Li, Xianzhong Zhou, Bing Huang, Haibin Zhu
2020 J jnl
IEEE Trans. Comput. Soc. Syst.
Haibin Zhu
2020 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Haibin Zhu
2020 J jnl
IEEE Trans. Comput. Soc. Syst.
Haibin Zhu
2020 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Xianjun Zhu, Haibin Zhu, Dongning Liu, Xianzhong Zhou
2020 J jnl
Int. J. Cooperative Inf. Syst.
Dongning Liu, Qian Jiang, Haibin Zhu, Baoying Huang
2020 B conf
SMC
Eric Brownlee, Haibin Zhu
2020 J jnl
IEEE CAA J. Autom. Sinica
Haibin Zhu
2020 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Haibin Zhu
2020 ed.
PECCS
Luis Gomes, Haibin Zhu, César Benavente-Peces
2020 conf
ICHMS
Haibin Zhu
2020 B conf
SMC
Haibin Zhu, Zhe Yu, Youssou Gningue
2020 J jnl
IEEE Trans Autom. Sci. Eng.
Dongning Liu, Baoying Huang, Haibin Zhu
2019 J jnl
IEEE Trans. Parallel Distributed Syst.
Hua Ma, Haibin Zhu, Keqin Li, Wensheng Tang
2019 conf
ICNSC
Haibin Zhu
2019 J jnl
Appl. Soft Comput.
Jie Yang, Haibin Zhu, Tieqiao Liu
2019 conf
ChineseCSCW
Qian Jiang, Haibin Zhu, Ming Liao, Baoying Huang, Xiaozhao Fang, Dongning Liu
2019 B conf
SMC
Haibin Zhu
2019 conf
ICNSC
Bo Lei, Haibin Zhu, Youssou Gningue
2018 C ed.
CSCWD
Weiming Shen, Junzhou Luo, Jean-Paul A. Barthès, Fang Dong, Jinghui Zhang, Haibin Zhu
2018 C conf
CSCWD
Shaohua Teng, Zhenhua Zhang, Luyao Teng, Wei Zhang, Haibin Zhu, Xiaozhao Fang, Lunke Fei
2018 conf
ICNSC
Haibin Zhu, Tyler Kennedy, Hua Ma, Hongyu Zhang, Bo Lei, Youssou Gningue
2018 C conf
CSCWD
Haibin Zhu, Hua Ma, Hongyu Zhang
2018 J jnl
IEEE Trans. Cybern.
Dongning Liu, Yunyi Yuan, Haibin Zhu, Shaohua Teng, Changqin Huang
2018 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Haibin Zhu, Yin Sheng, Xianzhong Zhou, Yu Zhu
2018 C conf
CSCWD
Hua Ma, Yuepeng Chen, Haibin Zhu, Hongyu Zhang, Wensheng Tang
2018 B conf
SMC
Haibin Zhu
2018 J jnl
IEEE CAA J. Autom. Sinica
Shaohua Teng, Naiqi Wu, Haibin Zhu, Luyao Teng, Wei Zhang
2018 conf
UEMCON
Yin Sheng, Haibin Zhu, Guan Wang
2018 C conf
CSCWD
Pei Luo, Haibin Zhu, Dongning Liu, Baoying Huang, Yan Hou
2017 conf
ICNSC
Haibin Zhu, Yu Zhu
2017 B conf
SMC
Haibin Zhu, Yu Davis Zhu
2017 B conf
SMC
Xianjun Zhu, Fangxiong Xiao, Haibin Zhu, Qilin Wu, Xianzhong Zhou, Wenting Hu
2017 J jnl
Future Gener. Comput. Syst.
Hua Ma, Haibin Zhu, Zhigang Hu, Wensheng Tang, Pingping Dong
2017 B conf
SMC
Jie Yang, Haibin Zhu, Xianjun Zhu, Yi Liu, Linyuan Liu, Tieqiao Liu
2017 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Haibin Zhu, Dongning Liu, Siqin Zhang, Shaohua Teng, Yu Zhu
2017 J jnl
Knowl. Based Syst.
Hua Ma, Haibin Zhu, Zhigang Hu, Keqin Li, Wensheng Tang
2016 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Mingsheng Tang, Haibin Zhu, Xinjun Mao
2016 B conf
SMC
Haibin Zhu, Shawn Mason
2016 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Haibin Zhu
2016 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Yin Sheng, Haibin Zhu, Xianzhong Zhou, Wenting Hu
2016 B conf
SMC
Xianjun Zhu, Xianzhong Zhou, Mo Zhang, Haibin Zhu, Xiumei He
2016 conf
ICAC
Antonio Bucchiarone, Giacomo Cabri, Nicola Capodieci, Haibin Zhu
2016 J jnl
Theor. Comput. Sci.
Haibin Zhu, Dongning Liu, Siqin Zhang, Yu Zhu, Luyao Teng, Shaohua Teng
2016 conf
ICCSA (5)
Haibin Zhu, Dongning Liu, Xianjun Zhu, Yu Zhu, Shaohua Teng, Xianzhong Zhou
2015 J jnl
Int. J. Cogn. Informatics Nat. Intell.
Wei Zhang, Yang Wang, Jingxin Zhu, Dongning Liu, Shaohua Teng, Haibin Zhu
2015 conf
CTS
Haibin Zhu
2015 J jnl
计算机科学
Shaohua Teng, Hong Zhang, Dongning Liu, Haibin Zhu, Wei Zhang, Lu Liang
2015 B conf
SMC
Xianjun Zhu, Youfa Wang, Wenting Hu, Xianzhong Zhou, Jie Yang, Haibin Zhu
2015 B conf
SMC
Haibin Zhu
2015 conf
ICCI*CC
Haibin Zhu, Yin Sheng, Xianzhong Zhou
2014 conf
ICDM Workshops
Luyao Teng, Shaohua Teng, Feiyi Tang, Haibin Zhu, Wei Zhang, Dongning Liu, Lu Liang
2014 J jnl
Int. J. Agent Technol. Syst.
Xinjun Mao, Menggao Dong, Haibin Zhu
2014 C conf
CSCWD
Shaohua Teng, Jihui Fan, Haibin Zhu, Wei Zhang, Dongning Liu, Xiao Chen, Xiufen Fu
2014 conf
ICNSC
Yin Sheng, Haibin Zhu, Xianzhong Zhou, Luming Feng
2014 B conf
SMC
Yin Sheng, Haibin Zhu, Xianzhong Zhou, Youfa Wang
2014 B conf
SMC
Dongning Liu, Shaohua Teng, Haibin Zhu, Yong Tang
2014 ch.
Cloud Computing and Digital Media
Jiehan Zhou, Haibin Zhu, Mika Ylianttila, Mika Rautiainen
2014 B conf
SMC
Mingsheng Tang, Xinjun Mao, Shuqiang Yang, Haibin Zhu
2014 conf
ICCI*CC
Wei Zhang, Jingxin Zhu, Dongning Liu, Shaohua Teng, Haibin Zhu
2013 J jnl
Int. J. Agent Technol. Syst.
Wei Zhang, Shaohua Teng, Haibin Zhu, Dongning Liu
2013 C conf
CSCWD
Wei Zhang, Shaohua Teng, Xiufen Fu, Jihui Fan, Yi Teng, Haibin Zhu
2013 B conf
SMC
Haibin Zhu, Luming Feng, Robert Pickering
2013 C conf
CSCWD
Haibin Zhu, Luming Feng
2013 conf
SummerSim
Haibin Zhu, Luming Feng, Ratvinder Singh Grewal
2013 C ed.
CSCWD
Weiming Shen, Weidong Li, Jean-Paul A. Barthès, Junzhou Luo, Haibin Zhu, Jianming Yong, Xiaoping Li
2012 J jnl
Int. J. Agent Technol. Syst.
Haibin Zhu, Ming Hou, MengChu Zhou
2012 conf
CTS
Haibin Zhu
2012 J jnl
IEEE Trans Autom. Sci. Eng.
Haibin Zhu, Ming Hou, Chun Wang, MengChu Zhou
2012 J jnl
Softw. Pract. Exp.
Luca Ferrari, Haibin Zhu
2012 J jnl
IEEE Trans. Syst. Man Cybern. Part A
Haibin Zhu, MengChu Zhou
2012 J jnl
IEEE Trans. Syst. Man Cybern. Part A
Haibin Zhu, MengChu Zhou, Rob Alkins
2012 conf
Canadian AI
Haibin Zhu
2011 J jnl
J. Softw.
Tao Dong, Wenqian Shang, Haibin Zhu
2011 J jnl
Expert Syst. Appl.
Linyuan Liu, Haibin Zhu, Zhiqiu Huang
2011 B conf
SMC
Haibin Zhu
2011 conf
CTS
Luca Ferrari, Haibin Zhu
2011 conf
CTS
Haibin Zhu
2011 J jnl
Comput. Stand. Interfaces
Linyuan Liu, Haibin Zhu, Zhiqiu Huang, Dongqing Xie
2011 J jnl
IEEE Trans. Syst. Man Cybern. Part C
Ming Hou, Haibin Zhu, MengChu Zhou, G. Robert Arrabito
2011 J jnl
Int. J. Cogn. Informatics Nat. Intell.
Haibin Zhu, Ming Hou
2010 J jnl
Int. J. Softw. Sci. Comput. Intell.
Shaohua Teng, Wei Zhang, Haibin Zhu, Xiufen Fu, Jiangyi Su, Baoliang Cui
2010 conf
CTS
Haibin Zhu, Ming Hou, MengChu Zhou
2010 conf
IEEE ICCI
Wei Zhang, Shaohua Teng, Haibin Zhu, Hongle Du, Xiaocong Li
2010 conf
IEEE ICCI
Haibin Zhu, Ming Hou, Wenqian Shang
2010 B conf
SMC
Haibin Zhu, MengChu Zhou
2010 J jnl
Int. J. Cogn. Informatics Nat. Intell.
Yingxu Wang, George Baciu, Yiyu Yao, Witold Kinsner, Keith C. C. Chan, Bo Zhang, Stuart R. Hameroff, Ning Zhong, Chu-Ren Huang, Ben Goertzel, Duoqian Miao, Kenji Sugawara, Guoyin Wang, Jane You, Du Zhang, Haibin Zhu
2010 J jnl
Int. J. Softw. Sci. Comput. Intell.
Haibin Zhu
2010 conf
CTS
Luca Ferrari, Haibin Zhu
2009 conf
IEEE ICCI
Haibin Zhu, Matthew Grenier
2009 J jnl
Int. J. Granul. Comput. Rough Sets Intell. Syst.
Haibin Zhu
2009 conf
CTS
Haibin Zhu, Rob Alkins
2009 B conf
SMC
Haibin Zhu, Rob Alkins
2009 conf
CSO (2)
Wenqian Shang, Hongbin Dong, Haibin Zhu
2009 J jnl
IEEE Trans. Syst. Man Cybern. Part A
Haibin Zhu, MengChu Zhou
2009 conf
CTS
Luca Ferrari, Haibin Zhu
2009 conf
IEEE ICCI
Yingxu Wang, George Baciu, Yiyu Yao, Bo Zhang, Witold Kinsner, Chu-Ren Huang, Keith C. C. Chan, Ben Goertzel, Duoqian Miao, Kenji Sugawara, Guoyin Wang, Jane You, Du Zhang, Ning Zhong, Haibin Zhu
2009 conf
CTS
Linyuan Liu, Zhiqiu Huang, Haibin Zhu
2008 conf
NLPKE
Wenqian Shang, Hongbin Dong, Haibin Zhu, Yongbin Wang
2008 B conf
SMC
Haibin Zhu, Matthew Grenier, Rob Alkins, Jeffery Lacarte, Jordon Hoskins
2008 conf
CTS
Haibin Zhu
2008 Misc conf
GrC
Haibin Zhu
2008 J jnl
IEEE Trans. Syst. Man Cybern. Part A
Haibin Zhu, MengChu Zhou
2008 J jnl
J. Softw.
Haibin Zhu, Rob Alkins, Matthew Grenier
2008 conf
IEEE ICCI
Haibin Zhu
2008 J jnl
IEEE Trans. Syst. Man Cybern. Part C
Haibin Zhu, MengChu Zhou
2008 B conf
SMC
Wei Zhang, Shaohua Teng, Xiufen Fu, Haibin Zhu
2007 J jnl
Expert Syst. Appl.
Wenqian Shang, Houkuan Huang, Haibin Zhu, Yongmin Lin, Youli Qu, Zhihai Wang
2007 B conf
SMC
Haibin Zhu, Rob Alkins
2007 conf
IEEE ICCI
Dongme Sun, Shaohua Teng, Wei Zhang, Haibin Zhu
2007 conf
IEEE ICCI
Wei Zhang, Shaohua Teng, Zhaohui Zhu, Xiufen Fu, Haibin Zhu
2007 conf
IEEE ICCI
Haibin Zhu
2007 conf
SETP
Haibin Zhu
2006 B conf
SMC
Haibin Zhu
2006 C conf
ISCC
Wenqian Shang, Youli Qu, Haibin Zhu, Houkuan Huang, Yongmin Lin, Hongbin Dong
2006 Misc conf
International Conference on Computational Science (3)
Wenqian Shang, Houkuan Huang, Haibin Zhu, Yongmin Lin, Youli Qu, Hongbin Dong
2006 conf
CCECE
Pierre Seguin, Haibin Zhu
2006 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Haibin Zhu, MengChu Zhou
2006 conf
IEEE ICCI
Haibin Zhu
2006 J jnl
IEEE Trans. Syst. Man Cybern. Part A
Haibin Zhu, MengChu Zhou, Pierre Seguin
2006 conf
IEEE ICCI
Jiming Ma, Haibin Zhu, Wenqian Shang
2005 conf
CIS (1)
Wenqian Shang, Houkuan Huang, Haibin Zhu, Yongmin Lin, Zhihai Wang, Youli Qu
2005 Misc conf
IRI
Haibin Zhu
2005 conf
IEEE SCC
Haibin Zhu
2005 B conf
SMC
Haibin Zhu
2004 conf
SMC (6)
Haibin Zhu
2004 conf
SMC (5)
Wenqian Shang, Haibin Zhu, Houkuan Huang
2003 Misc conf
IKE
Haibin Zhu
2003 B conf
SMC
Haibin Zhu
2003 conf
OOPSLA Companion
Haibin Zhu, MengChu Zhou
APK_CODE_ANALYSIS_PDD-Tech_Annex.md
← Index APK_CODE_ANALYSIS_PDD-Tech_Annex.md markdown
# APK Code Analysis — Technical Annex

**Companion to:** APK_CODE_ANALYSIS_PDD.md
**Audience:** Engineers implementing APK code analysis
**Date:** 2026-03-07

---

## Table of Contents

1. [File Structure](#1-file-structure)
2. [System Dependencies Setup](#2-system-dependencies-setup)
3. [Phase 1 — Core Infrastructure](#3-phase-1--core-infrastructure)
4. [Phase 2 — Extractor and Data Export](#4-phase-2--extractor-and-data-export)
5. [Phase 3 — Similarity and Obfuscation](#5-phase-3--similarity-and-obfuscation)
6. [Phase 4 — Integration Testing](#6-phase-4--integration-testing)
7. [ClickHouse Schema](#7-clickhouse-schema)
8. [Androguard API Quick Reference](#8-androguard-api-quick-reference)
9. [Smali Format Reference](#9-smali-format-reference)

---

## SDLC Requirements

**Each phase ends with a quality gate:**

1. All new code has unit tests (mocked externals — no JADX/apktool/Java required)
2. All existing tests pass (`pytest tests/unit/` — must remain at 579+ tests passing)
3. New tests are added to the appropriate test file and documented
4. `TEST_INDEX.md` is updated with new test counts and file descriptions
5. Code passes `flake8`, `pylint`, `black`, `isort` (existing dev tools in `requirements.txt`)
6. Commit only after all tests pass. Move to next phase only after commit.

---

## 1. File Structure

### New files to create:

```
redb/extractors/decompiler/
├── DecompileAPK.py                    # Main extractor (like DecompileBinja.py)
├── apk/
│   ├── __init__.py
│   ├── analyzer.py                    # APKCodeAnalyzer — orchestrates analysis
│   ├── jadx_wrapper.py               # JADXDecompiler — subprocess + output parsing
│   ├── apktool_wrapper.py            # ApktoolDisassembler — subprocess + smali parsing
│   ├── method_extractor.py           # Per-method content extraction and hashing
│   ├── library_filter.py             # Package-based library filtering
│   └── smali_parser.py               # Smali file parsing — method boundary detection

tests/unit/
├── test_apk_code_analyzer.py          # Analyzer, library filtering, method enumeration
├── test_apk_jadx_wrapper.py           # JADX subprocess, output parsing, timeouts
├── test_apk_apktool_wrapper.py        # Apktool subprocess, smali parsing, timeouts
├── test_apk_method_extractor.py       # Hashing, content extraction, similarity
├── test_apk_decompile_extractor.py    # DecompileAPK extractor, export, schema

docs/
└── apk-code-schema.md                 # ClickHouse table definitions (like new-code-binja-schema.md)
```

### Files to modify:

```
redb/extractors/enum.py               # Add APK_DECOMPILED tag
redb/models/dataclasses.py            # Add APK code analysis dataclasses
redb/workers.py                        # Wire up DecompileAPK in APK dispatch
tests/TEST_INDEX.md                    # Update test inventory
```

---

## 2. System Dependencies Setup

### JADX Installation

```bash
# Option 1: Download from GitHub releases
wget https://github.com/skylot/jadx/releases/download/v1.5.5/jadx-1.5.5.zip
unzip jadx-1.5.5.zip -d /opt/jadx
ln -s /opt/jadx/bin/jadx /usr/local/bin/jadx

# Option 2: Package manager (if available)
# apt install jadx  OR  brew install jadx

# Verify
jadx --version
```

### apktool Installation

```bash
# Download wrapper script + jar
wget https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool
wget https://github.com/iBotPeaches/Apktool/releases/download/v2.12.0/apktool_2.12.0.jar
mv apktool_2.12.0.jar /usr/local/bin/apktool.jar
mv apktool /usr/local/bin/apktool
chmod +x /usr/local/bin/apktool

# Verify
apktool --version
```

### Java Runtime

```bash
apt install openjdk-17-jre-headless
java -version
```

### Docker considerations

If running in Docker, add to Dockerfile:

```dockerfile
RUN apt-get update && apt-get install -y openjdk-17-jre-headless
# Then install jadx and apktool as above
```

---

## 3. Phase 1 — Core Infrastructure

### Task 1.1: Library Filter (`library_filter.py`)

**What to build:** A class that determines whether a method belongs to a known library/framework package and should be filtered out of content tables.

**Behavior:**
- Accept a list of package prefixes (default list in PDD §2.3)
- Configurable via `APK_LIBRARY_PREFIXES` environment variable (comma-separated)
- Method `is_library(class_name: str) -> bool` — returns True if class_name starts with any filter prefix
- Method `get_filter_stats() -> dict` — returns counts of filtered vs. retained classes (for logging)

**Reference pattern:** Similar to `is_lib_or_thunk()` in `redb/extractors/decompiler/bninja/decompiler.py` (module-level function that checks `symbol.type` against `SymbolType.LibraryFunctionSymbol`, etc.)

**Tests:** Unit tests with various class names, custom prefix lists, env var override.

---

### Task 1.2: Smali Parser (`smali_parser.py`)

**What to build:** Parser that reads apktool's smali output files and extracts individual method bodies.

**apktool output structure:**
```
<tmpdir>/smali/com/example/MyClass.smali
```

Each `.smali` file contains one class with all its methods. Method boundaries are delimited by:
```smali
.method public onCreate(Landroid/os/Bundle;)V
    .registers 4
    .param p1, "savedInstanceState"

    invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
    const/high16 v0, 0x7f090000
    invoke-virtual {p0, v0}, Lcom/example/MyClass;->setContentView(I)V
    return-void
.end method
```

**Methods to implement:**
- `parse_smali_file(filepath: str) -> List[SmaliMethod]` — Returns list of `(class_name, method_name, method_signature, method_body, instruction_count, register_count)`
- `parse_smali_directory(dirpath: str) -> Dict[str, SmaliMethod]` — Parses all `.smali` files, returns dict keyed by `class_name->method_name(signature)`
- `normalize_smali_body(body: str) -> str` — Strip comments, normalize whitespace, remove line numbers (`.line N` directives) for consistent hashing
- `count_instructions(body: str) -> int` — Count actual Dalvik instructions (skip directives like `.registers`, `.param`, `.line`, `.local`, `.annotation`)

**Key parsing rules:**
- Method starts with `.method` line, ends with `.end method`
- Access modifiers: `public`, `private`, `protected`, `static`, `final`, `abstract`, `native`
- Skip `abstract` and `native` methods (no body)
- Dalvik instructions start with a verb: `invoke-*`, `const*`, `move*`, `if-*`, `goto*`, `return*`, `new-*`, `iget*`, `iput*`, `sget*`, `sput*`, `aget*`, `aput*`, etc.
- Directives start with `.` — these are metadata, not instructions

**Tests:** Parse sample smali files, verify method boundaries, instruction counts, normalization.

---

### Task 1.3: JADX Wrapper (`jadx_wrapper.py`)

**What to build:** Subprocess wrapper for JADX decompilation, following the CAPA extractor pattern.

**Reference implementation:** `redb/extractors/capa.py` — uses `subprocess.Popen` with process group management and timeout escalation (SIGTERM → wait 3s → SIGKILL).

**Methods to implement:**
- `__init__(jadx_path, timeout, log)` — Configure from env vars `JADX_PATH` and `JADX_TIMEOUT`
- `decompile(apk_path: str, output_dir: str) -> bool` — Run JADX, return success/failure
- `parse_java_methods(output_dir: str) -> Dict[str, str]` — Parse JADX output into per-method Java source, keyed by `class_name.method_name(param_types)`
- `cleanup(output_dir: str)` — Remove temp directory

**JADX command:**
```bash
jadx --no-res --no-imports --threads-count 2 --output-dir <tmpdir>/jadx <apk_path>
```

**Output structure from JADX:**
```
<tmpdir>/jadx/sources/com/example/MyClass.java
```

Each `.java` file contains one class. Methods must be extracted by parsing Java source (find method signatures via regex or simple brace-counting parser).

**Java method extraction approach:**
- Use regex to find method declarations: `(public|private|protected|static|...)*\s+\w+\s+\w+\s*\([^)]*\)\s*\{`
- Track brace depth to find method end
- Key each method by `fully.qualified.ClassName.methodName(ParamType1, ParamType2)`
- Normalize: strip leading/trailing whitespace, normalize indentation

**Tests:** Mock subprocess, test output parsing with sample Java files, test timeout handling, test error recovery.

---

### Task 1.4: Apktool Wrapper (`apktool_wrapper.py`)

**What to build:** Subprocess wrapper for apktool disassembly, same pattern as JADX wrapper.

**Methods to implement:**
- `__init__(apktool_path, timeout, log)` — Configure from env vars `APKTOOL_PATH` and `APKTOOL_TIMEOUT`
- `disassemble(apk_path: str, output_dir: str) -> bool` — Run apktool, return success/failure
- `get_smali_directory(output_dir: str) -> str` — Return path to smali output (handles multi-dex: `smali/`, `smali_classes2/`, `smali_classes3/`, etc.)
- `cleanup(output_dir: str)` — Remove temp directory

**apktool command:**
```bash
apktool d --no-res --force --output <tmpdir>/apktool <apk_path>
```

**Multi-DEX handling:** apktool creates `smali/` for `classes.dex`, `smali_classes2/` for `classes2.dex`, etc. The wrapper must iterate all `smali*` directories.

**Tests:** Mock subprocess, test multi-dex directory detection, test timeout handling.

---

### Task 1.5: APK Code Analyzer (`analyzer.py`)

**What to build:** Orchestrator that combines androguard, JADX, and apktool into a single analysis engine. This is the APK equivalent of `BinaryNinjaDecompiler` in `redb/extractors/decompiler/bninja/decompiler.py`.

**Constructor:**
- `__init__(filepath, timeout, log, decompile_modules={"all"})` — Same module selection pattern as `BinaryNinjaDecompiler`

**Main method — `extract() -> dict`:**

1. Create temp directories for JADX and apktool output
2. Run JADX and apktool in parallel (use `concurrent.futures.ThreadPoolExecutor` with 2 workers)
3. While JADX/apktool run, start androguard analysis: `AnalyzeAPK(filepath)` → get `(apk, dexs, analysis)`
4. Wait for JADX and apktool to complete
5. Parse smali output → `Dict[method_key, SmaliMethod]`
6. Parse Java output → `Dict[method_key, str]`
7. Get method list from androguard `analysis.get_methods()`
8. For each method from androguard:
   a. Check if library → skip content if yes (but keep in xref arrays)
   b. Look up smali body from parsed smali output
   c. Look up Java source from parsed Java output
   d. Get xrefs: `method.get_xref_from()` (callers) and `method.get_xref_to()` (callees)
   e. Compute hashes (SHA-256 of normalized smali, SHA-256 of normalized Java)
   f. Apply minimum instruction filter (`APK_MIN_METHOD_INSTRUCTIONS`, default 5)
   g. Build content and reference records
9. Return results dict with keys: `decompiled_content`, `decompiled_refs`, `smali_content`, `smali_refs`, `similarity_metrics`, `analysis_errors`

**Method key matching:**
The critical challenge is matching methods across three tools that use different naming conventions:
- **Androguard:** `Lcom/example/MyClass;->onCreate(Landroid/os/Bundle;)V` (Dalvik descriptor format)
- **Smali (apktool):** Same Dalvik descriptor format (same as androguard)
- **Java (JADX):** `com.example.MyClass.onCreate(Bundle)` (Java format)

Build a `method_key_converter` utility that normalizes between these formats:
- `dalvik_to_java(descriptor: str) -> str` — Convert `Lcom/example/MyClass;->onCreate(Landroid/os/Bundle;)V` to `com.example.MyClass.onCreate(Bundle)`
- `java_to_dalvik(java_sig: str) -> str` — Reverse mapping (may not be needed)

**Reference pattern:** Study `BinaryNinjaDecompiler.analyze_binary()` in `redb/extractors/decompiler/bninja/decompiler.py` — it follows the same per-function loop with content extraction, hash computation, and cross-linking.

**Tests:** Mock all three tools, test method key matching, test library filtering integration, test parallel execution, test error handling when one tool fails.

---

### Phase 1 Quality Gate

After completing Tasks 1.11.5:

```bash
# Run all existing tests — must pass
pytest tests/unit/ -v

# Run new tests
pytest tests/unit/test_apk_code_analyzer.py tests/unit/test_apk_jadx_wrapper.py \
       tests/unit/test_apk_apktool_wrapper.py -v

# Linting
black redb/extractors/decompiler/apk/ tests/unit/test_apk_*.py
isort redb/extractors/decompiler/apk/ tests/unit/test_apk_*.py
flake8 redb/extractors/decompiler/apk/
```

Update `TEST_INDEX.md` with new test file entries. Commit.

---

## 4. Phase 2 — Extractor and Data Export

### Task 2.1: Tag Enum Update

**File:** `redb/extractors/enum.py`

Add after the existing APK tags:

```python
APK_DECOMPILED = "apk_decompiled"
```

---

### Task 2.2: Dataclasses

**File:** `redb/models/dataclasses.py`

Add the 6 dataclasses defined in PDD §4.1:
- `APKDecompiledMethodContent`
- `APKDecompiledMethodReference`
- `APKSmaliMethodContent`
- `APKSmaliMethodReference`
- `APKMethodSimilarityMetrics`
- `APKCodeAnalysisError`

Follow the exact style of existing dataclasses in the file. Use `Optional` for nullable fields, `field(default_factory=list)` for list defaults.

---

### Task 2.3: DecompileAPK Extractor (`DecompileAPK.py`)

**What to build:** The main extractor class, following `DecompileBinja.py` exactly.

**File:** `redb/extractors/decompiler/DecompileAPK.py`

**Pattern to follow (from `DecompileBinja.py`):**
- Extends `Extractor` directly
- Constructor: filepath, log, exporters, index_prefix, filetype
- Timeouts from env vars: `APK_DECOMPILE_TIMEOUT` (default 1800s)
- `extract()`: Run `APKCodeAnalyzer` in a daemon thread with timeout (same pattern as DecompileBinja)
- `tag()`: Return `Tag.APK_DECOMPILED.value`
- `prepare_export_data()`: Build `multi_table` dict for ClickHouse export
- `cleanup_run()`: Remove temp directories, force GC
- `get_clickhouse_table()`: Return `None` (multi-table export, no single table)

**Multi-table export structure** (from `prepare_export_data` — follow the exact pattern in `DecompileBinja.prepare_export_data()`):

```python
export_data = {"multi_table": True}

# Table 1: Decompiled method content
if self.analysis_results.get("decompiled_content"):
    export_data["code_apk_decompiled_methods_content"] = {
        "data": [...],
        "column_names": [...],
        "column_type_names": [...]
    }

# Table 2: Decompiled method references
# Table 3: Smali method content
# Table 4: Smali method references
# Table 5: Similarity metrics
# Table 6: Analysis errors
```

**Column names and types** must match the ClickHouse schema in §7. Study `DecompileBinja.prepare_export_data()` for the exact tuple format.

---

### Task 2.4: ClickHouse Schema Functions

**File:** `docs/apk-code-schema.md`

Create table creation functions following `docs/new-code-binja-schema.md` pattern. Full schema in §7 below.

---

### Task 2.5: Workers Integration

**File:** `redb/workers.py`

In the APK processing section (search for `apk` filetype handling), add `DecompileAPK` after the existing APK extractors.

Follow the same conditional pattern used for `DecompileBinja`:
- Check if module is selected
- Instantiate with filepath, logger, exporters
- Call `export_data()`

Also update `get_module_by_name()` to register `"DecompileAPK"` in the modules map.

---

### Phase 2 Quality Gate

```bash
pytest tests/unit/ -v                          # All existing + new tests pass
pytest tests/unit/test_apk_decompile_extractor.py -v   # New extractor tests
pytest tests/unit/test_apk_dataclasses.py -v           # Updated dataclass tests
```

Update `TEST_INDEX.md`. Commit.

---

## 5. Phase 3 — Similarity and Obfuscation

### Task 3.1: Method-Level Similarity Hashes

**File:** Extend `method_extractor.py`

Compute for each user method's smali body:
- **ssdeep** — Use `ppdeep` (already in requirements): `ppdeep.hash(smali_body.encode())`
- **TLSH** — Use `tlsh` (already in requirements): `tlsh.hash(smali_body.encode())`
- **MinHash** — Use existing `MinHashCustom` from `redb/extractors/decompiler/bninja/similarity.py`. Generate n-grams from smali instructions, compute MinHash signature.

**Reference:** Study `BinaryNinjaDecompiler.analyze_binary()` where it computes `ssdeep_disassembly`, `tlsh_disassembly`, and calls `MinHasher`.

**Minimum size for fuzzy hashes:** ssdeep and TLSH both require minimum input sizes. Skip if smali body is too short (ssdeep < 4096 bytes returns empty, TLSH < 50 bytes returns empty).

---

### Task 3.2: Obfuscation Indicators (per method)

**File:** Extend `method_extractor.py`

For each method's smali body, compute:
- `short_method_name`: method name length <= 2
- `short_class_name`: class simple name (after last `/`) length <= 2
- `has_string_encryption`: presence of `const-string` followed within 3 instructions by `invoke-*` to known decryptor patterns
- `has_reflection_calls`: presence of `invoke-*` targeting `Ljava/lang/reflect/*` or `Ljava/lang/Class;->forName`
- `excessive_goto_count`: count of `goto` / `goto/16` / `goto/32` instructions exceeds `max(5, instruction_count * 0.15)`

---

### Task 3.3: Populate Similarity Metrics Table

Extend `APKCodeAnalyzer.extract()` to populate the `similarity_metrics` results key with `APKMethodSimilarityMetrics` records.

---

### Phase 3 Quality Gate

```bash
pytest tests/unit/ -v
pytest tests/unit/test_apk_method_extractor.py -v   # Hashing + obfuscation tests
```

Update `TEST_INDEX.md`. Commit.

---

## 6. Phase 4 — Integration Testing

### Task 4.1: Integration Test Suite

**File:** `tests/integration/test_apk_code_analysis.py`

**Requirements:** JADX, apktool, and Java must be installed.

**Test cases:**
1. **Simple APK** — Known benign APK with 5-10 user classes. Verify: methods extracted, smali and Java content populated, xrefs present, hashes computed.
2. **Multi-DEX APK** — APK with `classes.dex` + `classes2.dex`. Verify: methods from both DEX files analyzed, cross-DEX xrefs work.
3. **Obfuscated APK** — ProGuard/R8 obfuscated APK. Verify: short name indicators detected, library filter still works on renamed packages.
4. **Empty DEX** — APK with only framework calls, no user code after filtering. Verify: extractor returns gracefully with zero methods.
5. **Packed APK** — APK with encrypted DEX (e.g., Qihoo 360). Verify: error logged, no crash, analysis_errors table populated.
6. **JADX failure** — Simulate JADX timeout/crash. Verify: smali analysis still completes, decompiled content tables empty, error logged.
7. **apktool failure** — Same for apktool. Verify: Java analysis still completes.
8. **Large APK** — APK with 1000+ user methods. Verify: completes within timeout, memory stays bounded.

**Markers:**
```python
@pytest.mark.integration
@pytest.mark.apk
@pytest.mark.decompile
```

---

### Task 4.2: Performance Profiling

Run the integration tests with timing:
```bash
pytest tests/integration/test_apk_code_analysis.py -v --durations=0
```

Verify:
- apktool + JADX subprocess total < 60s for a typical APK
- Androguard analysis < 30s for a typical APK
- Per-method processing < 5ms
- Total pipeline < `APK_DECOMPILE_TIMEOUT` (1800s) for even the largest APKs

---

### Task 4.3: Final TEST_INDEX.md Update

Add all new test files, update counts, add integration test descriptions.

Final commit.

---

## 7. ClickHouse Schema

All tables follow the `ReplacingMergeTree(analysis_date)` pattern from `docs/new-code-binja-schema.md`,
except `code_apk_analysis_errors` which uses `MergeTree()`.

Full DDL is also available in `docs/apk-code-schema.md`.

### Table overview

| # | Table | Analog (Binja) | Engine | Key |
|---|-------|----------------|--------|-----|
| 1 | `code_apk_decompiled_methods_content` | `code_binja_decompiled_functions_content` | ReplacingMergeTree | `decompiled_method_hash` |
| 2 | `code_apk_decompiled_methods_references` | `code_binja_decompiled_functions_references` | ReplacingMergeTree | `(sha256, decompiled_method_hash)` |
| 3 | `code_apk_smali_methods_content` | `code_binja_disassembled_functions_content` | ReplacingMergeTree | `smali_method_hash` |
| 4 | `code_apk_smali_methods_references` | `code_binja_disassembled_functions_references` | ReplacingMergeTree | `(sha256, smali_method_hash)` |
| 5 | `code_apk_method_similarity_metrics` | `code_binja_function_similarity_metrics` | ReplacingMergeTree | `smali_method_hash` |
| 6 | `code_apk_cfg_methods` | `code_binja_cfg_functions` | ReplacingMergeTree | `smali_method_hash` |
| 7 | `code_binja_strings_raw` *(shared)* | — | Null (→ MV) | — |
| 8 | `code_apk_analysis_errors` | `function_analysis_errors_binja` | MergeTree | `(sha256, error_location, error_hash)` |

### Table 1: `code_apk_decompiled_methods_content`

**Analog:** `code_binja_decompiled_functions_content`

```sql
CREATE TABLE IF NOT EXISTS code_apk_decompiled_methods_content (
    decompiled_method_hash FixedString(64),          -- SHA-256 of normalized Java source
    decompiled_method String CODEC(ZSTD(3)),          -- Full Java method source
    decompiled_method_lower String MATERIALIZED lower(decompiled_method) CODEC(ZSTD(3)),
    method_type Enum8('USER'=1, 'LIBRARY'=2, 'UNKNOWN'=5) DEFAULT 'UNKNOWN',
    has_string_encryption UInt8 DEFAULT 0,
    has_reflection_calls UInt8 DEFAULT 0,
    excessive_goto_count UInt8 DEFAULT 0,
    analysis_date DateTime64(3, 'UTC'),

    INDEX idx_method_content_token lower(decompiled_method) TYPE tokenbf_v1(32768, 3, 0) GRANULARITY 1,
    INDEX idx_method_hash decompiled_method_hash TYPE bloom_filter GRANULARITY 1
) ENGINE = ReplacingMergeTree(analysis_date)
PRIMARY KEY decompiled_method_hash
ORDER BY decompiled_method_hash;
```

### Table 2: `code_apk_decompiled_methods_references`

**Analog:** `code_binja_decompiled_functions_references`

```sql
CREATE TABLE IF NOT EXISTS code_apk_decompiled_methods_references (
    sha256 FixedString(64),
    sha1 FixedString(40),
    md5 FixedString(32),
    decompiled_method_hash FixedString(64),
    smali_method_hash Nullable(FixedString(64)),
    class_name LowCardinality(String),
    method_name LowCardinality(String),
    method_signature String,                          -- Dalvik descriptor: (Landroid/os/Bundle;)V
    method_prototype String,                          -- Java-style: void onCreate(Bundle)
    functions_caller Array(String),
    functions_call Array(String),
    analysis_date DateTime64(3, 'UTC'),

    INDEX idx_sha256 sha256 TYPE bloom_filter GRANULARITY 1,
    INDEX idx_method_hash decompiled_method_hash TYPE bloom_filter GRANULARITY 1,
    INDEX idx_class_name class_name TYPE tokenbf_v1(32768, 3, 0) GRANULARITY 1,
    INDEX idx_method_name method_name TYPE tokenbf_v1(32768, 3, 0) GRANULARITY 1
) ENGINE = ReplacingMergeTree(analysis_date)
ORDER BY (sha256, decompiled_method_hash);
```

### Table 3: `code_apk_smali_methods_content`

**Analog:** `code_binja_disassembled_functions_content`

```sql
CREATE TABLE IF NOT EXISTS code_apk_smali_methods_content (
    smali_method_hash FixedString(64),                -- SHA-256 of normalized smali body
    smali_method String CODEC(ZSTD(3)),               -- Full smali method body
    method_type Enum8('USER'=1, 'LIBRARY'=2, 'UNKNOWN'=5) DEFAULT 'UNKNOWN',
    instructions_count UInt32,
    register_count UInt16,
    has_string_encryption UInt8 DEFAULT 0,
    has_reflection_calls UInt8 DEFAULT 0,
    excessive_goto_count UInt8 DEFAULT 0,
    analysis_date DateTime64(3, 'UTC'),

    INDEX idx_smali_ngram smali_method TYPE ngrambf_v1(3, 32768, 3, 0) GRANULARITY 1,
    INDEX idx_method_type method_type TYPE set(10) GRANULARITY 1,
    INDEX idx_instr_count instructions_count TYPE minmax GRANULARITY 4
) ENGINE = ReplacingMergeTree(analysis_date)
ORDER BY smali_method_hash;
```

### Table 4: `code_apk_smali_methods_references`

**Analog:** `code_binja_disassembled_functions_references`

```sql
CREATE TABLE IF NOT EXISTS code_apk_smali_methods_references (
    sha256 FixedString(64),
    sha1 FixedString(40),
    md5 FixedString(32),
    smali_method_hash FixedString(64),
    decompiled_method_hash Nullable(FixedString(64)),
    class_name LowCardinality(String),
    method_name LowCardinality(String),
    method_signature String,
    ssdeep_smali Nullable(String),
    tlsh_smali Nullable(FixedString(72)),
    analysis_date DateTime64(3, 'UTC'),

    INDEX idx_sha256 sha256 TYPE bloom_filter GRANULARITY 1,
    INDEX idx_smali_hash smali_method_hash TYPE bloom_filter GRANULARITY 1,
    INDEX idx_tlsh_smali tlsh_smali TYPE bloom_filter GRANULARITY 1,
    INDEX idx_ssdeep_smali ssdeep_smali TYPE bloom_filter GRANULARITY 1
) ENGINE = ReplacingMergeTree(analysis_date)
ORDER BY (sha256, smali_method_hash);
```

### Table 5: `code_apk_method_similarity_metrics`

**Analog:** `code_binja_function_similarity_metrics`

Content-based fuzzy matching table. Structural/CFG scalars (block_count, edge_count, etc.)
are in `code_apk_cfg_methods` (Table 6) — this table holds only fuzzy hashes and MinHash.

```sql
CREATE TABLE IF NOT EXISTS code_apk_method_similarity_metrics (
    smali_method_hash FixedString(64),
    cyclomatic_complexity Nullable(UInt16),
    ssdeep_smali Nullable(String),
    tlsh_smali Nullable(FixedString(72)),
    minhash Array(UInt8),
    analysis_date DateTime64(3, 'UTC'),

    INDEX idx_complexity cyclomatic_complexity TYPE minmax GRANULARITY 4,
    INDEX idx_ssdeep ssdeep_smali TYPE bloom_filter GRANULARITY 1,
    INDEX idx_tlsh tlsh_smali TYPE bloom_filter GRANULARITY 1
) ENGINE = ReplacingMergeTree(analysis_date)
ORDER BY smali_method_hash;
```

### Table 6: `code_apk_cfg_methods`

**Analog:** `code_binja_cfg_functions` (see `db_migration/cfg_functions_ddl.sql`)

Structural and topological features computed from smali CFG. All fields mirror
the Binja table with APK-appropriate naming (`smali_method_hash` instead of
`disassembled_function_hash`, `instructions_count` instead of `llil_total_operations`,
`prime_product_smali` instead of `prime_product_llil`).

```sql
CREATE TABLE IF NOT EXISTS code_apk_cfg_methods (
    -- Identity
    smali_method_hash FixedString(64),

    -- Tier 0: Exact structural match
    cfg_topology_hash FixedString(16),

    -- Tier 1: Structural pre-filtering
    block_count UInt16,
    edge_count UInt16,
    instructions_count UInt32,               -- Dalvik instruction count (analog: llil_total_operations)
    call_count UInt16,
    cyclomatic_complexity UInt16,
    loop_count UInt8,
    max_depth UInt16,
    max_fan_out UInt8,
    md_index_topdown UInt64,
    md_index_bottomup UInt64,
    prime_product_smali UInt64,              -- Dalvik semantic primes (analog: prime_product_llil)

    -- Tier 2: Fuzzy matching
    cfg_feature_tlsh Nullable(FixedString(72)),
    wl_minhash Array(UInt8),

    -- Embedding-ready storage
    bb_features Array(Array(UInt16)),        -- ACFG block feature vectors
    cfg_adjacency Array(UInt32),             -- Packed (src << 16 | tgt)

    analysis_date DateTime64(3, 'UTC'),

    -- Indexes
    INDEX idx_topology cfg_topology_hash TYPE bloom_filter GRANULARITY 1,
    INDEX idx_complexity cyclomatic_complexity TYPE minmax GRANULARITY 4,
    INDEX idx_block_count block_count TYPE minmax GRANULARITY 4,
    INDEX idx_edge_count edge_count TYPE minmax GRANULARITY 4,
    INDEX idx_call_count call_count TYPE minmax GRANULARITY 4,
    INDEX idx_instr_count instructions_count TYPE minmax GRANULARITY 4,
    INDEX idx_md_topdown md_index_topdown TYPE bloom_filter GRANULARITY 1,
    INDEX idx_md_bottomup md_index_bottomup TYPE bloom_filter GRANULARITY 1,
    INDEX idx_prime prime_product_smali TYPE bloom_filter GRANULARITY 1,
    INDEX idx_cfg_tlsh cfg_feature_tlsh TYPE bloom_filter GRANULARITY 1
) ENGINE = ReplacingMergeTree(analysis_date)
ORDER BY smali_method_hash
SETTINGS index_granularity = 8192;
```

**Column mapping (APK → Binja):**

| APK column | Binja column | Notes |
|------------|-------------|-------|
| `smali_method_hash` | `disassembled_function_hash` | Both SHA-256 of normalized code |
| `instructions_count` | `llil_total_operations` | Dalvik instructions vs LLIL operations |
| `prime_product_smali` | `prime_product_llil` | Same prime algorithm, Dalvik semantic categories |
| All others | Same name | Identical algorithms from shared `cfg_features.py` |

### Table 7: `code_binja_strings_raw` (shared)

APK strings are inserted into the existing `code_binja_strings_raw` Null-engine table,
which feeds materialized views (`code_binja_strings_by_binary`, `mv_string_popularity_public`).
This enables cross-format string correlation between PE/ELF/Mach-O/APK samples.

No new table creation needed — see `docs/new-code-binja-schema.md` for the existing DDL.

### Table 8: `code_apk_analysis_errors`

**Analog:** `function_analysis_errors_binja`

```sql
CREATE TABLE IF NOT EXISTS code_apk_analysis_errors (
    sha256 FixedString(64),
    class_name Nullable(String) CODEC(ZSTD(3)),
    method_name Nullable(String) CODEC(ZSTD(3)),
    error_location LowCardinality(String) CODEC(ZSTD(3)),   -- 'jadx', 'apktool', 'androguard', 'analysis'
    error_message Nullable(String) CODEC(ZSTD(3)),
    error_type Nullable(String) CODEC(ZSTD(3)),
    error_hash FixedString(32),                               -- MD5 for dedup
    status Enum8('new' = 1, 'investigating' = 2, 'fixed' = 3, 'wontfix' = 4) DEFAULT 'new',
    analysis_date DateTime64(3, 'UTC'),
    PRIMARY KEY (sha256, error_location, error_hash)
) ENGINE = MergeTree()
ORDER BY (sha256, error_location, error_hash);
```

---

## 8. Androguard API Quick Reference

Key API calls used by `APKCodeAnalyzer`:

```python
from androguard.misc import AnalyzeAPK

# Parse APK — returns (APK object, list of DEX objects, Analysis object)
apk, dexs, analysis = AnalyzeAPK("sample.apk")

# Enumerate all methods
for method in analysis.get_methods():
    # method is a MethodAnalysis object

    # Check if it's an external method (no code body)
    if method.is_external():
        continue

    # Get the underlying EncodedMethod
    encoded = method.get_method()
    class_name = encoded.get_class_name()    # "Lcom/example/MyClass;"
    method_name = encoded.get_name()          # "onCreate"
    descriptor = encoded.get_descriptor()     # "(Landroid/os/Bundle;)V"

    # Cross-references: who calls this method
    for ref_class, ref_method, offset in method.get_xref_from():
        caller = f"{ref_method.get_class_name()}->{ref_method.get_name()}"

    # Cross-references: what this method calls
    for ref_class, ref_method, offset in method.get_xref_to():
        callee = f"{ref_method.get_class_name()}->{ref_method.get_name()}"

# Call graph (networkx MultiDiGraph)
call_graph = analysis.get_call_graph()
# Nodes are MethodAnalysis objects
# Edges represent caller → callee relationships
```

**Important notes:**
- `AnalyzeAPK()` loads ALL DEX files (handles multi-DEX automatically)
- `is_external()` returns True for methods declared but not defined (framework methods)
- `get_xref_from()` and `get_xref_to()` return tuples of `(ClassAnalysis, MethodAnalysis, int_offset)`
- The Analysis object is the single source of truth for method enumeration and xrefs

---

## 9. Smali Format Reference

### Method declaration syntax

```smali
.method <access_flags> <name>(<param_descriptors>)<return_type>
    .registers <N>              # Total register count
    .param p1, "paramName"      # Parameter name (debug info, may be missing)
    .line <N>                   # Source line number (debug info)

    # Instructions (Dalvik opcodes)
    invoke-virtual {p0, v0}, Lcom/example/Foo;->bar(I)V
    const-string v1, "hello"
    if-eqz v0, :cond_0
    goto :goto_0

    :cond_0                     # Label
    return-void
.end method
```

### Type descriptors

| Descriptor | Java Type |
|-----------|-----------|
| `V` | void |
| `Z` | boolean |
| `B` | byte |
| `I` | int |
| `J` | long |
| `F` | float |
| `D` | double |
| `Lcom/example/Foo;` | com.example.Foo |
| `[I` | int[] |
| `[Ljava/lang/String;` | String[] |

### Instructions to count (not directives)

All lines that are NOT labels (`:label_N`) and NOT directives (`.something`) are instructions. Common instruction prefixes:
`invoke-*`, `const*`, `move*`, `return*`, `if-*`, `goto*`, `new-*`, `iget*`, `iput*`, `sget*`, `sput*`, `aget*`, `aput*`, `check-cast`, `instance-of`, `throw`, `monitor-*`, `fill-*`, `packed-switch`, `sparse-switch`, `cmp*`, `add-*`, `sub-*`, `mul-*`, `div-*`, `rem-*`, `and-*`, `or-*`, `xor-*`, `shl-*`, `shr-*`, `ushr-*`, `neg-*`, `not-*`, `int-to-*`, `long-to-*`, `float-to-*`, `double-to-*`, `array-length`, `nop`

---

## Appendix A — Phase 5: CFG Feature Parity with Binary Ninja Pipeline

**Date:** 2026-03-13
**Depends on:** Phases 13 complete
**Reference:** APK_CODE_ANALYSIS_PDD.md, Appendix A

This appendix provides the implementation details for adding a dedicated `code_apk_cfg_methods` table and refactoring `code_apk_method_similarity_metrics` to match the Binja pipeline's separation of concerns.

---

### A.1 Rationale

The existing `smali_cfg.py` already builds full adjacency lists and computes per-block ACFG feature vectors, but this data is either reduced to scalars (block_count, edge_count, etc.) or silently dropped (bb_features). Meanwhile, `cfg_features.py` contains generic graph algorithms (topology hash, MD-index, WL-MinHash, etc.) that operate on adjacency lists — they have no Binary Ninja dependency. Connecting these two modules requires minimal glue code.

---

### A.2 File Changes

#### Modified files:

```
redb/extractors/decompiler/apk/smali_cfg.py       # Add predecessors, wire cfg_features
redb/extractors/decompiler/apk/method_extractor.py # Add call_count, prime_product_smali
redb/extractors/decompiler/apk/analyzer.py         # Populate new CFG fields in results
redb/extractors/decompiler/DecompileAPK.py         # New table export, slim similarity table
docs/apk-code-schema.md                            # Add code_apk_cfg_methods schema
tests/unit/test_apk_method_extractor.py            # Tests for new fields
```

#### No new files needed.

---

### A.3 Task A.1: Extend `smali_cfg.py`

**A.1.1 — Build predecessors from successors**

Add to `compute_cfg_metrics()`, after the adjacency list is built:

```python
predecessors = [[] for _ in range(n)]
for src, targets in enumerate(successors):
    for tgt in targets:
        predecessors[tgt].append(src)
```

**A.1.2 — Compute advanced CFG features**

Import and call `cfg_features.py` functions after building the graph:

```python
from redb.extractors.decompiler.bninja.analysis import cfg_features

bfs = cfg_features.bfs_order(successors, n)
topology_hash = cfg_features.compute_topology_hash(successors, bfs, n)
md_topdown = cfg_features.compute_md_index_topdown(successors, predecessors, bfs)
md_bottomup = cfg_features.compute_md_index_bottomup(successors, predecessors, n)
cfg_tlsh = cfg_features.compute_cfg_feature_tlsh(block_features, bfs)
wl_minhash = cfg_features.compute_wl_minhash(successors, predecessors, block_features, n)
adjacency = cfg_features.pack_adjacency(successors)
```

**A.1.3 — Extend `SmaliCFGMetrics` dataclass**

Add fields to the existing dataclass:

```python
@dataclass
class SmaliCFGMetrics:
    # Existing fields (unchanged)
    block_count: int = 0
    edge_count: int = 0
    cyclomatic_complexity: int = 1
    loop_count: int = 0
    max_depth: int = 0
    max_fan_out: int = 0
    block_features: List[List[int]] = field(default_factory=list)

    # New fields
    cfg_topology_hash: bytes = field(default_factory=lambda: b'\x00' * 16)
    md_index_topdown: int = 0
    md_index_bottomup: int = 0
    cfg_feature_tlsh: Optional[str] = None
    wl_minhash: List[int] = field(default_factory=lambda: [255] * 128)
    cfg_adjacency: List[int] = field(default_factory=list)
```

---

### A.4 Task A.2: Smali Prime Product (`method_extractor.py`)

Define a Dalvik-to-prime mapping using the semantic categories already in `smali_normalization.py`. Each category maps to the same prime its LLIL equivalent uses in `cfg_features.py`:

```python
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."""
    product = 1
    for line in smali_body.splitlines():
        stripped = line.strip()
        if not stripped or stripped.startswith(('.', ':', '#')):
            continue
        category = classify_instruction(stripped)  # existing function
        prime = SMALI_OP_PRIMES.get(category, 1)
        product = (product * prime) % (2**64)
    return product
```

**`call_count`** — count lines where `classify_instruction()` returns `"CALL"`.

---

### A.5 Task A.3: Populate CFG Results (`analyzer.py`)

In `_process_method()`, after `compute_cfg_metrics()`, add the new fields to the results dict:

```python
cfg_metrics = compute_cfg_metrics(smali_body)

# Build cfg entry (separate from similarity_metrics)
cfg_entry = {
    "smali_method_hash": sha256_smali,
    "cfg_topology_hash": cfg_metrics.cfg_topology_hash,
    "block_count": cfg_metrics.block_count,
    "edge_count": cfg_metrics.edge_count,
    "instructions_count": instruction_count,
    "call_count": call_count,
    "cyclomatic_complexity": cfg_metrics.cyclomatic_complexity,
    "loop_count": cfg_metrics.loop_count,
    "max_depth": cfg_metrics.max_depth,
    "max_fan_out": cfg_metrics.max_fan_out,
    "md_index_topdown": cfg_metrics.md_index_topdown,
    "md_index_bottomup": cfg_metrics.md_index_bottomup,
    "prime_product_smali": prime_product,
    "cfg_feature_tlsh": cfg_metrics.cfg_feature_tlsh,
    "wl_minhash": cfg_metrics.wl_minhash,
    "bb_features": cfg_metrics.block_features,
    "cfg_adjacency": cfg_metrics.cfg_adjacency,
}
```

Add `"cfg"` as a new top-level key in the results dict returned by `extract()`.

---

### A.6 Task A.4: Export Tables (`DecompileAPK.py`)

**New table — `code_apk_cfg_methods`:**

```python
if self.analysis_results.get("cfg"):
    export["cfg_methods"] = {
        "table": "code_apk_cfg_methods",
        "data": [
            [
                cfg["smali_method_hash"],
                cfg["cfg_topology_hash"],
                cfg["block_count"],
                cfg["edge_count"],
                cfg.get("instructions_count", 0),
                cfg.get("call_count", 0),
                cfg["cyclomatic_complexity"],
                cfg.get("loop_count", 0),
                cfg.get("max_depth", 0),
                cfg.get("max_fan_out", 0),
                cfg.get("md_index_topdown", 0),
                cfg.get("md_index_bottomup", 0),
                cfg.get("prime_product_smali", 0),
                cfg.get("cfg_feature_tlsh"),
                cfg.get("wl_minhash", []),
                cfg.get("bb_features", []),
                cfg.get("cfg_adjacency", []),
                now,
            ]
            for cfg in self.analysis_results["cfg"]
            if cfg is not None
        ],
        "column_names": [
            "smali_method_hash", "cfg_topology_hash",
            "block_count", "edge_count", "instructions_count",
            "call_count", "cyclomatic_complexity", "loop_count",
            "max_depth", "max_fan_out",
            "md_index_topdown", "md_index_bottomup",
            "prime_product_smali", "cfg_feature_tlsh",
            "wl_minhash", "bb_features", "cfg_adjacency",
            "analysis_date",
        ],
        "column_type_names": [
            "FixedString(64)", "FixedString(16)",
            "UInt16", "UInt16", "UInt32",
            "UInt16", "UInt16", "UInt8",
            "UInt16", "UInt8",
            "UInt64", "UInt64",
            "UInt64", "Nullable(FixedString(72))",
            "Array(UInt8)", "Array(Array(UInt16))", "Array(UInt32)",
            "DateTime64(3, 'UTC')",
        ],
    }
```

**Slim down `code_apk_method_similarity_metrics`** — remove `block_count`, `edge_count`, `loop_count`, `max_depth`, `max_fan_out` from its column lists and data arrays.

---

### A.7 Task A.5: ClickHouse Schema

```sql
CREATE TABLE IF NOT EXISTS code_apk_cfg_methods (
    smali_method_hash FixedString(64),
    cfg_topology_hash FixedString(16),
    block_count UInt16,
    edge_count UInt16,
    instructions_count UInt32,
    call_count UInt16,
    cyclomatic_complexity UInt16,
    loop_count UInt8,
    max_depth UInt16,
    max_fan_out UInt8,
    md_index_topdown UInt64,
    md_index_bottomup UInt64,
    prime_product_smali UInt64,
    cfg_feature_tlsh Nullable(FixedString(72)),
    wl_minhash Array(UInt8),
    bb_features Array(Array(UInt16)),
    cfg_adjacency Array(UInt32),
    analysis_date DateTime64(3, 'UTC'),

    INDEX idx_topology cfg_topology_hash TYPE bloom_filter GRANULARITY 1,
    INDEX idx_complexity cyclomatic_complexity TYPE minmax GRANULARITY 4,
    INDEX idx_block_count block_count TYPE minmax GRANULARITY 4,
    INDEX idx_md_topdown md_index_topdown TYPE bloom_filter GRANULARITY 1,
    INDEX idx_md_bottomup md_index_bottomup TYPE bloom_filter GRANULARITY 1,
    INDEX idx_prime prime_product_smali TYPE bloom_filter GRANULARITY 1,
    INDEX idx_cfg_tlsh cfg_feature_tlsh TYPE bloom_filter GRANULARITY 1
) ENGINE = ReplacingMergeTree(analysis_date)
ORDER BY smali_method_hash;
```

---

### A.8 Task A.6: Tests

Add to `tests/unit/test_apk_method_extractor.py`:

- **`test_predecessors_from_successors`** — verify reverse mapping is correct
- **`test_cfg_topology_hash_identical_graphs`** — two methods with same control flow produce same hash
- **`test_cfg_topology_hash_different_graphs`** — different structure produces different hash
- **`test_md_index_topdown_bottomup`** — verify non-zero values for multi-block methods
- **`test_prime_product_smali`** — known input produces expected product
- **`test_prime_product_smali_position_independent`** — reordering blocks doesn't change result
- **`test_call_count`** — count invoke-* instructions
- **`test_wl_minhash_length`** — verify 128-element signature
- **`test_cfg_feature_tlsh_small_method`** — returns None when < 50 bytes
- **`test_bb_features_exported`** — verify block features appear in results
- **`test_cfg_adjacency_packed`** — verify (src << 16) | tgt encoding
- **`test_similarity_table_slimmed`** — verify block_count etc. removed from similarity export

---

### A.9 Phase 5 Quality Gate

```bash
# All existing tests pass
pytest tests/unit/ -v

# New CFG tests
pytest tests/unit/test_apk_method_extractor.py -k "cfg or prime_product or call_count or wl_minhash" -v

# Linting
black redb/extractors/decompiler/apk/ tests/unit/test_apk_method_extractor.py
isort redb/extractors/decompiler/apk/ tests/unit/test_apk_method_extractor.py
flake8 redb/extractors/decompiler/apk/
```

Update `TEST_INDEX.md`. Commit.