Xiaofeng Lu

168 papers A* 1A 2B 13C 3Misc 3Journal 96Unranked 50
YearRankTypeTitle / Venue / Authors
2026 J jnl
Syst. Control. Lett.
Xiaohua Li, Jia Xin, Haiyan Jin, Xiaofeng Lu, Wasiq Ali, Wei Liang
2026 J jnl
IEEE Internet Things J.
Zheng Du, Xiaofeng Lu, Chengnian Long, Lingfeng Bao
2026 J jnl
IEEE Internet Things J.
Pan Wang, Xiaofeng Lu, Chaoyi Bian, Pietro Lio
2026 J jnl
IEEE Access
Jinhui Yu, Yi Zeng, Yunkun Han, Chunpeng Cang, Hao Ren, Fuqi Si, Haoran Li, Xiaofeng Lu, Ge Yan, Ziyi Li, Shida Chen, Xuefan Tian
2026 J jnl
IEEE Trans. Multim.
Xiaogang Song, Haoyu Yuan, Xiaofeng Lu, Xinhong Hei, Rongrong Liu
2026 J jnl
IEEE Internet Things J.
Xiaoyu Zhang, Xiaofeng Lu, Yaru Zhao, Pietro Lio, Pan Hui
2026 J jnl
Signal Image Video Process.
Wei Huang, Xinrui Xu, Dan Zeng, Xiaofeng Lu
2026 J jnl
IEEE Trans. Parallel Distributed Syst.
Xiaofeng Lu, Luwen Zou, Yilu Mao, Pietro Lio, Pan Hui
2026 J jnl
IEEE Trans. Veh. Technol.
Boyu Jin, Xiaofeng Lu, Xueni Luo, Yuhang Wang, Halvin H. Yang, Kun Yang
2025 J jnl
IEEE J. Biomed. Health Informatics
Jiale Dun, Jun Wang, Juncheng Li, Qianhui Yang, Wenlong Hang, Xiaofeng Lu, Shihui Ying, Jun Shi
2025 J jnl
Comput. Vis. Image Underst.
Xiaogang Song, Junjie Tang, Kaixuan Yang, Weixuan Guo, Xiaofeng Lu, Xinhong Hei
2025 J jnl
Digit. Signal Process.
Xiaogang Song, Hailong Yang, Junjie Tang, Xiaochang Li, Xiaofeng Lu, Xinhong Hei
2025 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Leiku Yang, Xin Pei, Yidan Si, Xiuqing Hu, Yizhe Fan, Weiqian Ji, Ping Zhang, Ling Wang, Xiaofeng Lu, Xiaoqian Cheng
2025 J jnl
Displays
Xiaofeng Lu, Siyao Yue, Chaozhen Li, Xia Yang, Yulin Wang, Zhi Liu
2025 J jnl
IEEE Trans. Inf. Forensics Secur.
Caihong Yan, Xiaofeng Lu, Pietro Lio, Pan Hui
2025 J jnl
Displays
Yuanning Jia, Zhi Liu, Ying Lv, Xiaofeng Lu, Xuefeng Liu, Jie Chen
2025 J jnl
Signal Image Video Process.
Yiyun Wang, Xiaofeng Lu, Shize Zhang, Mengyao Cui, Wei Song
2025 J jnl
IEEE Access
Xiaofeng Lu, Zhiwei Guan, Dangfeng Pang, Rupeng Dou, Xiaolong Zheng
2025 J jnl
IEEE Internet Things J.
Pan Wang, Xiaofeng Lu, Pietro Lio
2025 J jnl
IEEE Internet Things J.
Caihong Yan, Xiaofeng Lu, Pietro Lio, Pan Hui, Daojing He
2025 J jnl
Appl. Soft Comput.
Xiaogang Song, Xinchao Pang, Lei Zhang, Xiaofeng Lu, Xinhong Hei
2025 J jnl
Neurocomputing
Xiaogang Song, Yuping Tan, Xinchao Pang, Lei Zhang, Xiaofeng Lu, Xinhong Hei
2025 C conf
ISCC
Xiaofeng Lu, Yinghui Li, Pietro Lio
2025 J jnl
IEEE Internet Things J.
Xingdong Ren, Hanzhou Wu, Yinggui Wang, Haojie Liu, Xiaofeng Lu, Guangling Sun
2024 conf
ISAIMS
Zhihao Wang, Zhenxuan Li, Yiming Fan, Xiaofeng Lu
2024 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Xiaogang Song, Pengfei Zhang, Xiaofeng Lu, Xinhong Hei, Rongrong Liu
2024 conf
ISAIMS
Yuxiao Qi, Yancheng Yang, Xiaofeng Lu
2024 J jnl
Multim. Tools Appl.
Sikai Fang, Xiaofeng Lu, Yifan Huang, Guangling Sun, Xuefeng Liu
2024 J jnl
Int. J. Digit. Earth
Leiku Yang, Weiqian Ji, Xin Pei, Yidan Si, Huan Liu, Shuang Chen, Chen Zhang, Xiaoqian Cheng, Xiaofeng Lu, Hongtao Wang
2024 J jnl
Knowl. Based Syst.
Jiawei Xie, Zhi Liu, Gongyang Li, Xiaofeng Lu, Tao Chen
2024 J jnl
CoRR
Jing Luo, Qi Mao, Weiwei Shi, Zhenghao Shi, Xiaofan Wang, Xiaofeng Lu, Xinhong Hei
2024 J jnl
EURASIP J. Image Video Process.
Xiaofeng Lu, Xuan Wang, Zhengyang Wang, Xinhong Hei
2024 J jnl
IEEE Robotics Autom. Lett.
Xiaogang Song, Zhenhua Zhou, Lei Zhang, Xiaofeng Lu, Xinhong Hei
2024 J jnl
IEEE Trans. Veh. Technol.
Xueni Luo, Xiaofeng Lu, Benquan Yin, Kun Yang
2024 conf
CyberC
Zixuan Yan, Xiaofeng Lu, Tiantian Pang, Jingbo Xu
2024 J jnl
Expert Syst. Appl.
Xiaofeng Lu, Jinglun Zhao, Senhao Zhu, Pietro Lio
2024 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Xiaogang Song, Fuqiang Guo, Lei Zhang, Xiaofeng Lu, Xinhong Hei
2024 J jnl
Pattern Recognit.
Xiaogang Song, Hongjuan Li, Li Liang, Weiwei Shi, Guo Xie, Xiaofeng Lu, Xinhong Hei
2024 J jnl
IEEE Trans. Multim.
Xiaogang Song, Haoyue Hu, Li Liang, Weiwei Shi, Guo Xie, Xiaofeng Lu, Xinhong Hei
2024 J jnl
IEEE Trans. Wirel. Commun.
Xueni Luo, Xiaofeng Lu, Boyu Jin, Benquan Yin, Kun Yang
2024 J jnl
Signal Image Video Process.
Xiaofeng Lu, Zichen Zhao, Weitao Ke, Qingsong Yan, Zhi Liu
2023 J jnl
IEEE/ACM Trans. Netw.
Xiaofeng Lu, Fan Yang, Luwen Zou, Pietro Liò, Pan Hui
2023 J jnl
Multim. Tools Appl.
Guangling Sun, Haoqi Hu, Yuying Su, Qi Liu, Xiaofeng Lu
2023 J jnl
Sci. China Inf. Sci.
Ji Zhou, Liangchuan Li, Jiale He, Xiaofeng Lu, Yu Bo, Guanyu Wang, Yuanda Huang, Gengchen Liu, Yanzhao Lu, Shecheng Gao, Yuanhua Feng, Shancheng Zhao, Weiping Liu, Changyuan Yu, Zhaohui Li
2023 conf
WWW (Companion Volume)
Xiaofeng Lu, Xiaoyu Zhang, Pietro Lió
2023 J jnl
Comput. Biol. Medicine
Ronglin Gong, Jing Shi, Jian Wang, Jun Wang, Jianwei Zhou, Xiaofeng Lu, Jun Du, Jun Shi
2023 J jnl
Comput. Graph.
Xiaogang Song, Wanbo Liu, Li Liang, Weiwei Shi, Guo Xie, Xiaofeng Lu, Xinhong Hei
2023 J jnl
Inf. Sci.
Xiaofeng Lu
2023 J jnl
IET Comput. Vis.
Xiaofeng Lu, Zhengyang Wang, Xuan Wang, Xinhong Hei
2023 J jnl
IEEE Trans. Parallel Distributed Syst.
Xiaofeng Lu, Chao Liu, Senhao Zhu, Yilu Mao, Pietro Lio, Pan Hui
2022 J jnl
JOCN
Ji Zhou, Jiale He, Xiaofeng Lu, Guanyu Wang, Yu Bo, Gengchen Liu, Yuanda Huang, Liangchuan Li, Chengkun Yang, Haide Wang, Wenxuan Mo, Weiping Liu, Changyuan Yu, Zhaohui Li
2022 J jnl
J. Intell. Fuzzy Syst.
Guangling Sun, Haoqi Hu, Xinpeng Zhang, Xiaofeng Lu
2022 J jnl
CoRR
Tianxing Zhang, Hanzhou Wu, Xiaofeng Lu, Guangling Sun
2022 J jnl
Remote. Sens.
Leiku Yang, Xinyao Tian, Chao Liu, Weiqian Ji, Yu Zheng, Huan Liu, Xiaofeng Lu, Huizheng Che
2022 conf
OFC
Ji Zhou, Jiale He, Xiaofeng Lu, Guanyu Wang, Yu Bo, Gengchen Liu, Yuanda Huang, Liangchuan Li, Haide Wang, Wenxuan Mo, Weiping Liu, Changyuan Yu, Zhaohui Li
2022 J jnl
IEEE Internet Things J.
Xiaofeng Lu, Yuying Liao, Chao Liu, Pietro Liò, Pan Hui
2022 conf
ACAI
Xiaofeng Lu, Jiaming Liu, Xiaofei Bai, Sixun Li
2022 J jnl
IEEE Geosci. Remote. Sens. Lett.
Xiaofeng Lu, Xiaofei Bai, Sixun Li, Xinhong Hei
2022 A* conf
CCS
Xiaofeng Lu, Renyu Pang, Pietro Liò
2022 J jnl
IEEE Access
Yachuan Bao, Baoguo Yu, Benquan Yin, Xueni Luo, Xiaofeng Lu
2022 A conf
MobiSys
Xiaofeng Lu, Jinglun Zhao, Pietro Lió
2022 J jnl
Digit. Commun. Networks
Jie Hu, Guangming Liang, Qin Yu, Kun Yang, Xiaofeng Lu
2022 conf
ICIAI
Xiaofeng Lu, Wentao Fan
2021 J jnl
Secur. Commun. Networks
Xiaofeng Lu, Songbing Fu, Cheng Jiang, Pietro Lió
2021 conf
VTC Fall
Yang Li, Xiaofeng Lu, Jie Hu, Kun Yang
2021 A conf
ACSAC
Xiaofeng Lu, Zhenhan Feng, Jupeng Xia
2021 J jnl
Symmetry
Yang Liu, Fuwei Gu, Mingxuan Li, Xiaofeng Lu, Xiaolei Zhu
2021 J jnl
J. Sensors
Pei Liu, Xiaoying Zhang, Chao Ma, Hebing Zhang, Ruimei Han, Xiaofeng Lu
2021 J jnl
IEEE Signal Process. Lett.
Haoqi Hu, Xiaofeng Lu, Xinpeng Zhang, Tianxing Zhang, Guangling Sun
2021 conf
DSN Workshops
Xiaofeng Lu, Pietro Liò
2021 conf
ChinaCom
Ruoxu Chen, Xiaofeng Lu, Kun Yang
2021 conf
ACCC
Xiaofeng Lu, Xuan Wang, Zhengyang Wang, Xinhong Hei
2020 J jnl
Comput. Secur.
Xiaofeng Lu, Shengfei Zhang, Pan Hui, Pietro Liò
2020 J jnl
Future Gener. Comput. Syst.
Xiaofeng Lu, Xiaoming Wang, Pietro Lio', Pan Hui
2020 J jnl
IEEE Access
Xiaofeng Lu, Xiao Zhou, Wenting Wang, Pietro Liò, Pan Hui
2020 J jnl
IEEE Access
Xiaofeng Lu, Yuying Liao, Pietro Liò, Pan Hui
2020 J jnl
J. Sensors
Pei Liu, Shoujun Jia, Ruimei Han, Yuanping Liu, Xiaofeng Lu, Hanwei Zhang
2020 J jnl
IEEE Access
Baoguo Yu, Yachuan Bao, Kexin Cheng, Ruoxu Chen, Xiaofeng Lu
2019 J jnl
Wirel. Pers. Commun.
Junyi Wei, Kun Yang, Guopeng Zhang, Xiaofeng Lu
2019 B conf
IWCMC
Yang Cai, Xiaofeng Lu, Yuansheng Luo, Kezhi Wang, Dongwei Chen, Kun Yang
2019 J jnl
Comput. Networks
Xiaofeng Lu, Fangshuo Jiang, Xiao Zhou, Shengwei Yi, Jing Sha, Pietro Liò
2019 Misc conf
ICASSP
Yuying Su, Guangling Sun, Weiqi Fan, Xiaofeng Lu, Zhi Liu
2019 J jnl
IEEE Access
Xiaohua Li, Chenxu Zhao, Xiaofeng Lu, Wei Wei
2019 conf
ICME Workshops
Weiqi Fan, Guangling Sun, Yuying Su, Zhi Liu, Xiaofeng Lu
2019 J jnl
IEEE Access
Xiaofeng Lu, Kun Yang, Jiayu Liu, Changlin Yang, Zibo Zhang, Hailin Zhang
2019 J jnl
Multim. Tools Appl.
Weiqi Fan, Guangling Sun, Yuying Su, Zhi Liu, Xiaofeng Lu
2019 J jnl
IEEE Trans. Veh. Technol.
Xiaofeng Lu, Kun Yang, Ning Fan, Hui Guo, Hailin Zhang
2019 B conf
ICCCN
Xiaofeng Lu, Fei Wang, Zifeng Shu
2019 J jnl
IEEE Trans. Commun.
Xiaofeng Lu, Qiang Ni, Danping Zhao, Wenchi Cheng, Hailin Zhang
2019 conf
ICC Workshops
Sihan Fan, Xiaofeng Lu, Bowen Liu, Huan Liu, Danping Zhao
2019 J jnl
IEEE Access
Xiaohua Li, Chenxu Zhao, Xiaofeng Lu, Wei Wei
2018 conf
ECOC
Xiaofeng Lu, Darko Zibar, Idelfonso Tafur Monroy
2018 conf
CSAE
Baoyan Zhong, Xiaofeng Lu, Qiaoyuan Wang, Siqi Zhao, Qianyun Liu
2018 J jnl
Neurocomputing
Qiaoyong Jiang, Lei Wang, Xinhong Hei, Jiatang Cheng, Xiaofeng Lu, Yanyan Lin, Guolin Yu
2018 conf
IIKI
Xiaofeng Lu, Shengfei Zhang, Shengwei Yi
2018 B conf
IWCMC
Yitian Zhang, Kun Yang, Xiaofeng Lu
2018 conf
OFC
Xiaofeng Lu, Darko Zibar, Idelfonso Tafur Monroy
2018 B conf
ICCCN
Xiaofeng Lu, Chen Liang, Shengfei Zhang, Pietro Liò, Jing Sha
2017 conf
ECOC
Xiaofeng Lu, Vladimir S. Lyubopytov, Lukasz Chorchos, Grzegorz Stepniak, Mikel Agustin, Jörg-R. Kropp, Nikolay N. Ledentsov, Vitaly A. Shchukin, Nikolay Ledentsov Jr., Jaroslaw P. Turkiewicz, Idelfonso Tafur Monroy
2017 conf
ECOC
Xiaofeng Lu, Vladimir S. Lyubopytov, Idelfonso Tafur Monroy
2017 conf
IIKI
Xiaofeng Lu, Xiao Zhou, Fangshuo Jiang, Shengwei Yi, Jing Sha
2017 J jnl
Appl. Soft Comput.
Qiaoyong Jiang, Lei Wang, Yanyan Lin, Xinhong Hei, Guolin Yu, Xiaofeng Lu
2017 B conf
IWCMC
Xuan Du, Kun Yang, Xiaofeng Lu, Xiaohui Wei
2017 B conf
WCNC
Mingjun Gao, Yongzhao Li, Tao Li, Xiaofeng Lu, Hailin Zhang
2017 B conf
WCNC
Xiaofeng Lu, Ruonan Zhang, Yuliang Zhou, Jiawei Liu, Xin Jin, Qi Guo, Chang Cao
2017 J jnl
IEEE Trans. Wirel. Commun.
Xiaofeng Lu, Qiang Ni, Wenna Li, Hailin Zhang
2017 J jnl
Mob. Networks Appl.
Guopeng Zhang, Kun Yang, Haifeng Jiang, Xiaofeng Lu, Ke Xu, Lianming Zhang
2017 J jnl
IEEE Trans. Veh. Technol.
Ruonan Zhang, Xiaofeng Lu, Jianping Zhao, Lin Cai, Jiao Wang
2017 J jnl
Knowl. Based Syst.
Qiaoyong Jiang, Lei Wang, Jiatang Cheng, Xiaoshu Zhu, Wei Li, Yanyan Lin, Guolin Yu, Xinhong Hei, Jinwei Zhao, Xiaofeng Lu
2016 B conf
CEC
Zijian Cao, Lei Wang, Xinhong Hei, Qiaoyong Jiang, Xiaofeng Lu, Xiaofan Wang
2016 conf
ICTC
Yunong Han, Kun Yang, Xiaofeng Lu, Dongdai Zhou
2016 J jnl
Sensors
Xiaofeng Lu, Pietro Liò, Pan Hui
2016 J jnl
Sci. China Inf. Sci.
Xiaofeng Lu, Kun Yang, Wenna Li, Shaojun Qiu, Hailin Zhang
2016 J jnl
Knowl. Based Syst.
Qiaoyong Jiang, Lei Wang, Xinhong Hei, Guolin Yu, Yanyan Lin, Xiaofeng Lu
2016 conf
BIH
Xiaofeng Lu, Mi Li, Shengfu Lu, Jiying Xu, Jia Xue
2016 J jnl
IEEE Trans. Wirel. Commun.
Ruonan Zhang, Shichao Wang, Xiaofeng Lu, Weiming Duan, Lin Cai
2016 conf
GRMSE (1)
Xiaofeng Lu, Jianlin Wang, Zibo Zhang, Haibin Bian, Erzhou Yang
2015 conf
IIKI
Xiaofeng Lu, Pan Hui
2015 J jnl
Secur. Commun. Networks
Jian Li, DanJie Song, Ruifan Li, Xiaofeng Lu
2015 J jnl
Wirel. Commun. Mob. Comput.
Xiaofeng Lu, Kun Yang, Yingting Liu, Dongdai Zhou, Shuhua Liu
2015 conf
VTC Spring
Stephan Hafner, Diego A. Dupleich, Robert Müller, Jian Luo, Egon Schulz, Christian Schneider, Reiner S. Thomä, Xiaofeng Lu, Tianxiang Wang
2015 B conf
PIMRC
Diego A. Dupleich, Stephan Hafner, Christian Schneider, Robert Müller, Reiner S. Thomä, Jian Luo, Naveed Iqbal, Egon Schulz, Xiaofeng Lu, Guangjian Wang
2015 B conf
WCNC
Ruonan Zhang, Xiaofeng Lu, Weiming Duan, Lin Cai, Jiao Wang
2015 Misc conf
ICNC
Ruonan Zhang, Lin Cai, Xiaofeng Lu, Pinlu Yang, Jian Zhou
2015 conf
CyberC
Xiaofeng Lu, Shaojun Qiu, Wenna Li, Ya Gao, Hailin Zhang
2015 conf
SiPS
Xiaofeng Lu, Junhao Zhang, Li Song, Rui Lei, Hengli Lu, Nam Ling
2015 conf
IIKI
Xiaofeng Lu, Pietro Liò
2015 J jnl
Int. J. Distributed Sens. Networks
Xiaofeng Lu, Zhaowei Qu, Qi Li, Pan Hui
2015 J jnl
IEEE Trans. Veh. Technol.
Meixia Hu, Yongzhao Li, Xiaofeng Lu, Hailin Zhang
2015 conf
VTC Spring
Robert Müller, Stephan Hafner, Diego A. Dupleich, Jian Luo, Egon Schulz, Ralf Herrmann, Christian Schneider, Reiner S. Thomä, Xiaofeng Lu, Tianxiang Wang
2014 C conf
CIT
Ya Gao, Hailin Zhang, Dong Yang, Xiaofeng Lu
2014 J jnl
Wirel. Pers. Commun.
Xiaofeng Lu, Kun Yang, Hailin Zhang
2014 J jnl
Pers. Ubiquitous Comput.
Xiaofeng Lu, Zhaowei Qu, Pietro Liò, Pan Hui, Qi Li, Peng Lu, Rongfang Bie
2014 conf
OFC
Henning Bülow, Xiaofeng Lu, Laurent Schmalen, Axel Klekamp, Fred Buchali
2014 B conf
FUZZ-IEEE
Xiaofeng Lu, Takashi Izumi, Tomoaki Takahashi, Lei Wang
2014 conf
IIKI
Xiaofeng Lu, Pietro Liò, Pan Hui, Zhaowei Qu
2014 conf
IIKI
Xiaofeng Lu, Qi Li, Zhaowei Qu, Pan Hui
2013 J jnl
Int. J. Distributed Sens. Networks
Xiaofeng Lu, Pietro Liò, Ben Hui, Haifei Jin
2013 J jnl
Sensors
Xiaofeng Lu, Li Song, Sumin Shen, Kang He, Songyu Yu, Nam Ling
2012 conf
IFTC
Xiaofeng Lu, Xiangwei Li, Sumin Shen, Kang He, Songyu Yu
2012 conf
VTC Spring
Ammar Ghazal, Cheng-Xiang Wang, Harald Haas, Mark A. Beach, Xiaofeng Lu, Dongfeng Yuan, Xiaohu Ge
2012 conf
CCIS
Jian Li, DanJie Song, Sicong Chen, Xiaofeng Lu
2012 J jnl
Sci. China Inf. Sci.
Xiaofeng Lu, Don Towsley, Pietro Liò, Zhang Xiong
2012 B conf
WCNC
Qi Yao, Yi Yuan, Ammar Ghazal, Cheng-Xiang Wang, Longyuan Luan, Xiaofeng Lu
2012 conf
CHINACOM
Yingting Liu, Chenxi Li, Xiaofeng Lu, Hailin Zhang, Yachuan Bao
2011 conf
WASA
Ruonan Zhang, Xiaofeng Lu, Zhimeng Zhong, Lin Cai
2011 conf
MSN
Xiaofeng Lu, Pan Hui, Pietro Liò
2010 conf
NAS
Xiaofeng Lu, Pan Hui
2010 J jnl
Comput. Networks
Xiaofeng Lu, Pan Hui, Don Towsley, Juahua Pu, Zhang Xiong
2010 J jnl
Wirel. Pers. Commun.
Xiaofeng Lu, Fletcher Wicker, Don Towsley, Zhang Xiong, Pietro Liò
2010 J jnl
IEICE Trans. Inf. Syst.
Xiaofeng Lu, Pan Hui, Don Towsley, Juhua Pu, Zhang Xiong
2009 B conf
WCNC
Zan Li, Jueping Cai, Xiaojun Chen, Xiaofeng Lu
2009 conf
ICC
Zan Li, Jueping Cai, Xiaofeng Lu, Jiangbo Si
2009 J jnl
Wirel. Commun. Mob. Comput.
Juhua Pu, Zhang Xiong, Xiaofeng Lu
2009 J jnl
EURASIP J. Wirel. Commun. Netw.
Xiaofeng Lu, Don Towsley, Pietro Liò, Fletcher Wicker, Zhang Xiong
2009 J jnl
Eur. Trans. Telecommun.
Xiaofeng Lu, Zan Li, Jueping Cai
2008 conf
ADHOC-NOW
Xiaofeng Lu, Yung-Chih Chen, Ian X. Y. Leung, Zhang Xiong, Pietro Liò
2008 conf
ICC
Xiaofeng Lu, Zan Li, Jueping Cai, Xiaojun Chen
2008 conf
EUC (2)
Xiaofeng Lu, Pan Hui, Pietro Liò, Zhang Xiong
2006 conf
VTC Fall
Renyong Wu, Guangxi Zhu, Xiaofeng Lu, Guoqin Ning
2006 conf
CCNC
Guangxi Zhu, Guoqin Ning, Renyong Wu, Xiaofeng Lu
2005 C conf
CIT
Xiaofeng Lu, Guangxi Zhu, Yingzhuang Liu, Xiao Xiao
2004 Misc conf
International Conference on Computational Science
Shoubin Dong, Xiaofeng Lu, Ling Zhang
2003 conf
GCC (1)
Shoubin Dong, Xiaofeng Lu, Ling Zhang, Kejing He
2003 conf
ICASSP (2)
Xiaofeng Lu, Songfeng Zheng, Nanning Zheng, Weixiang Liu
2003 conf
ICIP (3)
Xiaofeng Lu, Nanning Zheng, Songfeng Zheng
2003 conf
ICASSP (3)
Weixiang Liu, Nanning Zheng, Xiaofeng Lu
2003 conf
ICASSP (2)
Songfeng Zheng, Xiaofeng Lu, Nanning Zheng, Weipu Xu
redb/queries.py
← Index redb/queries.py python
"""
Database query functions for REDB.

Contains all functions that query ClickHouse for sample metadata,
deduplication checks, and catalog lookups.
"""
import os
import ast
import clickhouse_connect
from typing import List, Optional, Dict

from redb import settings
from redb.s3_utils import generate_s3_key_from_hash


def get_supported_formats(magika_filter: Optional[str] = None) -> List[str]:
    """
    Get supported file formats from SUPPORTED_FORMATS env variable or magika_filter override.
    Expected format: SUPPORTED_FORMATS=['pebin', 'elf']

    Args:
        magika_filter: Optional single format to filter by (overrides env var)

    Returns:
        List of supported format strings, defaults to ['pebin'] if not set
    """
    # If magika_filter is provided, use it as the only format
    if magika_filter:
        return [magika_filter]

    formats_str = os.getenv('SUPPORTED_FORMATS', "['pebin']")
    try:
        formats = ast.literal_eval(formats_str)
        if isinstance(formats, list) and all(isinstance(f, str) for f in formats):
            return formats
        else:
            print(f"[WARNING] SUPPORTED_FORMATS must be a list of strings, got: {formats_str}")
            return ['pebin']
    except (ValueError, SyntaxError) as e:
        print(f"[WARNING] Failed to parse SUPPORTED_FORMATS '{formats_str}': {e}")
        return ['pebin']


def get_db_catalog_connection():
    """Create and return a ClickHouse client for catalog queries"""
    return clickhouse_connect.get_client(
        host=os.getenv("DB_HOST"),
        port=int(os.getenv("DB_PORT", "8123")),
        verify=os.getenv("DB_ENFORCE_SSL", "False").lower() == "true",
        username=os.getenv("DB_USER"),
        password=os.getenv("DB_PASSWORD"),
        database=os.getenv("DB_NAME")
    )


def fetch_s3_objects_by_repository(repository: Optional[str], index_prefix: str, decompile: bool, notes: Optional[str] = None, magika_filter: Optional[str] = None, yara_scan: bool = False, force: bool = False) -> List[Dict]:
    """
    Query the ClickHouse repository_upload_sessions table to get samples.
    S3 bucket comes from env var, S3 key is derived from sha256.

    Args:
        repository: Repository name (e.g., "bazaar", "malshare"). If None or "all-repos", queries all repositories.
        index_prefix: Table prefix for checking existing samples
        decompile: Whether we're in decompile mode (affects which table to check for existing)
        notes: Optional filter for notes field
        magika_filter: Optional single filetype to filter by (overrides SUPPORTED_FORMATS)
        yara_scan: Whether we're in YARA-only mode (skips "already processed" check)

    Returns:
        List of dicts with sha256, s3_bucket, s3_key for each sample
    """
    try:
        client = get_db_catalog_connection()
        s3_bucket = os.getenv('S3_BUCKET')

        if not s3_bucket:
            print("[ERROR] S3_BUCKET environment variable is required")
            return []

        # Get supported formats from env or magika_filter override
        supported_formats = get_supported_formats(magika_filter)
        print(f"[INFO] Querying for supported formats: {supported_formats}")

        # Build query - repository filter is optional
        # Join with catalog_samples to get first_seen date
        if repository and repository != "all-repos":
            query = """
                SELECT DISTINCT rus.sha256, rus.filetype_magika, cs.first_seen
                FROM repository_upload_sessions rus
                LEFT JOIN catalog_samples cs ON rus.sha256 = cs.sha256
                WHERE rus.repository = %(repo)s
                  AND rus.filetype_magika IN %(formats)s
            """
            params = {"repo": repository, "formats": supported_formats}
        else:
            # Query all repositories
            query = """
                SELECT DISTINCT rus.sha256, rus.filetype_magika, cs.first_seen
                FROM repository_upload_sessions rus
                LEFT JOIN catalog_samples cs ON rus.sha256 = cs.sha256
                WHERE rus.filetype_magika IN %(formats)s
            """
            params = {"formats": supported_formats}

        if notes:
            query += " AND rus.notes LIKE %(notes)s"
            params["notes"] = f"%{notes}%"

        # Execute query and convert to list of dictionaries
        result = client.query(query, parameters=params)

        # Build rows with s3_bucket and s3_key derived from sha256
        rows = []
        for row in result.result_rows:
            sha256 = row[0]
            # Handle binary string if needed
            if isinstance(sha256, bytes):
                sha256 = sha256.decode('utf-8')

            rows.append({
                'sha256': sha256,
                's3_bucket': s3_bucket,
                's3_key': generate_s3_key_from_hash(sha256),
                'filetype_magika': row[1],
                'first_seen': row[2]  # From catalog_samples (None if not found)
            })

        print(f"[DEBUG] Found {len(rows)} objects in repository_upload_sessions for repository {repository}")

        # Extract SHA256 hashes from the results for bulk checking
        sha256_list = [row.get('sha256') for row in rows if row.get('sha256')]

        if sha256_list and not force:
            # Check which hashes are already in the database
            existing_hashes = is_in_db_bulk(sha256_list, index_prefix, decompile, yara_scan, magika_filter)
            print(f"[INFO] Found {len(existing_hashes)} objects already in database")

            # Filter out rows with existing hashes
            rows = [row for row in rows if row.get('sha256') not in existing_hashes]
            print(f"[INFO] After filtering, {len(rows)} objects remain to be processed")
        elif force:
            print(f"[INFO] Force mode: skipping deduplication check, processing all {len(sha256_list)} objects")

        # Randomize the order of rows before returning
        import random
        random.shuffle(rows)

        return rows
    except Exception as e:
        print(f"[ERROR] Failed to query repository_upload_sessions: {e}")
        return []
    finally:
        if 'client' in locals():
            client.close()


def fetch_s3_objects_by_date_range(
    index_prefix: str,
    decompile: bool,
    start_date: str,
    end_date: str,
    repository: Optional[str] = None,
    notes: Optional[str] = None,
    magika_filter: Optional[str] = None,
    yara_scan: bool = False,
    force: bool = False,
    analyzed: bool = False
) -> List[Dict]:
    """
    Query samples from catalog_samples by first_seen date range, filtered to only include
    samples that exist in repository_upload_sessions (bulk/repo uploads only).

    Args:
        index_prefix: Table prefix for checking existing samples
        decompile: Whether we're in decompile mode
        start_date: Start date (inclusive) in YYYY-MM-DD format
        end_date: End date (exclusive) in YYYY-MM-DD format
        repository: Optional repository filter
        notes: Optional notes filter
        magika_filter: Optional single filetype to filter by (overrides SUPPORTED_FORMATS)
        yara_scan: Whether we're in YARA-only mode (skips "already processed" check)
        analyzed: Filter to only samples already in basic_properties (cross-database join)

    Returns:
        List of dicts with sha256, s3_bucket, s3_key for each sample
    """
    try:
        client = get_db_catalog_connection()
        s3_bucket = os.getenv('S3_BUCKET')

        if not s3_bucket:
            print("[ERROR] S3_BUCKET environment variable is required")
            return []

        # Get supported formats from env or magika_filter override
        supported_formats = get_supported_formats(magika_filter)
        print(f"[INFO] Querying for supported formats: {supported_formats}")

        # Join catalog_samples with repository_upload_sessions to:
        # 1. Filter by first_seen date from catalog_samples
        # 2. Only include samples that exist in repository_upload_sessions (not user uploads)
        # 3. Optionally filter to only already-analyzed samples (in basic_properties)
        analyzed_join = ""
        if analyzed:
            basic_table = f"{index_prefix}_basic_properties"
            analyzed_join = f"INNER JOIN {basic_table} bp ON cs.sha256 = bp.sha256"
            print(f"[INFO] Filtering to already-analyzed samples in {basic_table}")

        query = f"""
            SELECT DISTINCT cs.sha256, rus.filetype_magika, cs.first_seen
            FROM catalog_samples cs
            INNER JOIN repository_upload_sessions rus ON cs.sha256 = rus.sha256
            {analyzed_join}
            WHERE cs.first_seen >= %(start_date)s
              AND cs.first_seen < %(end_date)s
              AND rus.filetype_magika IN %(formats)s
        """
        params = {
            "start_date": start_date,
            "end_date": end_date,
            "formats": supported_formats
        }

        if repository:
            query += " AND rus.repository = %(repo)s"
            params["repo"] = repository

        if notes:
            query += " AND rus.notes LIKE %(notes)s"
            params["notes"] = f"%{notes}%"

        # Execute query
        result = client.query(query, parameters=params)

        # Build rows with s3_bucket and s3_key derived from sha256
        rows = []
        for row in result.result_rows:
            sha256 = row[0]
            # Handle binary string if needed
            if isinstance(sha256, bytes):
                sha256 = sha256.decode('utf-8')

            rows.append({
                'sha256': sha256,
                's3_bucket': s3_bucket,
                's3_key': generate_s3_key_from_hash(sha256),
                'filetype_magika': row[1],
                'first_seen': row[2]  # From catalog_samples
            })

        date_info = f"from {start_date} to {end_date}"
        repo_info = f" for repository {repository}" if repository else ""
        print(f"[DEBUG] Found {len(rows)} objects in catalog_samples {date_info}{repo_info}")

        # Extract SHA256 hashes from the results for bulk checking
        sha256_list = [row.get('sha256') for row in rows if row.get('sha256')]

        if sha256_list and not force:
            # Check which hashes are already in the database
            existing_hashes = is_in_db_bulk(sha256_list, index_prefix, decompile, yara_scan, magika_filter)
            print(f"[INFO] Found {len(existing_hashes)} objects already in database")

            # Filter out rows with existing hashes
            rows = [row for row in rows if row.get('sha256') not in existing_hashes]
            print(f"[INFO] After filtering, {len(rows)} objects remain to be processed")
        elif force:
            print(f"[INFO] Force mode: skipping deduplication check, processing all {len(sha256_list)} objects")

        # Randomize the order of rows before returning
        import random
        random.shuffle(rows)

        return rows
    except Exception as e:
        print(f"[ERROR] Failed to query catalog_samples by date range: {e}")
        return []
    finally:
        if 'client' in locals():
            client.close()


def fetch_analyzed_samples(
    index_prefix: str,
    decompile: bool,
    magika_filter: Optional[str] = None,
    yara_scan: bool = False,
    force: bool = False,
    rerun: bool = False
) -> List[Dict]:
    """
    Query samples from basic_properties that have already been analyzed.
    Useful for reprocessing with decompilation or specific modules.

    Args:
        index_prefix: Table prefix for ClickHouse
        decompile: Whether we're in decompile mode (affects filtering)
        magika_filter: Optional single filetype to filter by (overrides SUPPORTED_FORMATS)
        yara_scan: Whether we're in YARA-only mode (skips decompile filtering)
        force: Skip all deduplication checks when True
        rerun: Query disassembled table directly (only already-disassembled samples)

    Returns:
        List of dicts with sha256, s3_bucket, s3_key for each analyzed sample
    """
    try:
        client = settings.create_clickhouse_client()
        s3_bucket = os.getenv('S3_BUCKET')

        if not s3_bucket:
            print("[ERROR] S3_BUCKET environment variable is required")
            return []

        # Rerun mode: query directly from disassembled_functions_references
        # instead of basic_properties. This targets only samples that already
        # went through binja successfully.
        if rerun:
            disassembled_table = _get_code_dedup_table(magika_filter)
            basic_table = f"{index_prefix}_basic_properties"

            # Join with basic_properties to get filetype_magika and apply format filters
            conditions = []
            params = {}

            if magika_filter:
                conditions.append("bp.filetype_magika = %(magika)s")
                params["magika"] = magika_filter
            else:
                supported_formats = get_supported_formats()
                conditions.append("bp.filetype_magika IN %(formats)s")
                params["formats"] = supported_formats

            query = (
                f"SELECT DISTINCT d.sha256, bp.filetype_magika "
                f"FROM {disassembled_table} d FINAL "
                f"INNER JOIN {basic_table} bp FINAL ON d.sha256 = bp.sha256"
            )
            if conditions:
                query += " WHERE " + " AND ".join(conditions)

            result = client.query(query, parameters=params)

            rows = []
            for row in result.result_rows:
                sha256 = row[0]
                if isinstance(sha256, bytes):
                    sha256 = sha256.decode('utf-8')
                rows.append({
                    'sha256': sha256,
                    's3_bucket': s3_bucket,
                    's3_key': generate_s3_key_from_hash(sha256),
                    'filetype_magika': row[1]
                })

            print(f"[INFO] Rerun mode: found {len(rows)} already-disassembled samples in {disassembled_table}")

            import random
            random.shuffle(rows)
            return rows

        basic_table = f"{index_prefix}_basic_properties"

        # Build query
        conditions = []
        params = {}

        if magika_filter:
            conditions.append("filetype_magika = %(magika)s")
            params["magika"] = magika_filter
        else:
            supported_formats = get_supported_formats()
            conditions.append("filetype_magika IN %(formats)s")
            params["formats"] = supported_formats

        query = f"SELECT DISTINCT sha256, filetype_magika FROM {basic_table} FINAL"
        if conditions:
            query += " WHERE " + " AND ".join(conditions)

        result = client.query(query, parameters=params)

        rows = []
        for row in result.result_rows:
            sha256 = row[0]
            if isinstance(sha256, bytes):
                sha256 = sha256.decode('utf-8')
            rows.append({
                'sha256': sha256,
                's3_bucket': s3_bucket,
                's3_key': generate_s3_key_from_hash(sha256),
                'filetype_magika': row[1]
            })

        print(f"[DEBUG] Found {len(rows)} analyzed samples in {basic_table}")

        # In YARA-only mode, filter out already-scanned samples (unless force)
        if yara_scan and not force:
            sha256_list = [r['sha256'] for r in rows]
            if sha256_list:
                already_scanned = _check_yara_matches_bulk(sha256_list)
                print(f"[INFO] Found {len(already_scanned)} already YARA-scanned samples")
                rows = [r for r in rows if r['sha256'].lower() not in already_scanned]
                print(f"[INFO] After filtering, {len(rows)} samples remain for YARA scanning")
        # In decompile mode, filter out already-disassembled samples (unless force)
        # We check disassembly (not decompilation) because disassembly is the ground truth:
        # disassembly always succeeds, decompilation may not, so a missing decompile
        # entry doesn't mean the sample wasn't analyzed.
        elif decompile and not force:
            sha256_list = [r['sha256'] for r in rows]
            if sha256_list:
                disassembled_table = _get_code_dedup_table(magika_filter)
                batch_size = 3900

                already_disassembled = set()
                for i in range(0, len(sha256_list), batch_size):
                    batch = sha256_list[i:i+batch_size]
                    placeholders = "','".join(batch)
                    check_query = f"SELECT DISTINCT sha256 FROM {disassembled_table} FINAL WHERE sha256 IN ('{placeholders}')"
                    check_result = client.query(check_query)
                    for check_row in check_result.result_rows:
                        hash_value = check_row[0]
                        if isinstance(hash_value, bytes):
                            hash_value = hash_value.decode('utf-8')
                        already_disassembled.add(hash_value)

                print(f"[INFO] Found {len(already_disassembled)} already-disassembled samples")
                rows = [r for r in rows if r['sha256'] not in already_disassembled]
                print(f"[INFO] After filtering, {len(rows)} samples remain for decompilation")
        elif force:
            print(f"[INFO] Force mode: returning all {len(rows)} analyzed samples")

        # Randomize the order of rows before returning
        import random
        random.shuffle(rows)

        return rows
    except Exception as e:
        print(f"[ERROR] Failed to query analyzed samples: {e}")
        return []
    finally:
        if 'client' in locals():
            client.close()


def is_in_db(sha256, index_prefix, client=None):
    """
    Check if a sample with given SHA256 already exists in the database

    Args:
        sha256: File's SHA256 hash
        index_prefix: Table prefix for ClickHouse
        client: Optional ClickHouse client instance

    Returns:
        bool: True if file exists, False otherwise
    """
    table = f"{index_prefix}_basic_properties"
    close_client = False

    try:
        if client is None:
            client = settings.create_clickhouse_client()
            close_client = True

        # No need for FINAL when checking existence with LIMIT 1
        # Any version of the row proves the sample exists
        query = f"SELECT 1 FROM {table} WHERE sha256 = %(sha256)s LIMIT 1"
        result = client.query(query, parameters={"sha256": sha256})

        return len(result.result_rows) > 0
    except Exception as e:
        print(f"[ERROR] Failed to check if file is in DB: {e}")
        return False
    finally:
        if close_client and client:
            client.close()


def _get_code_dedup_table(magika_filter: Optional[str] = None) -> str:
    """
    Return the code-analysis table used for deduplication based on filetype.

    APK samples are disassembled into code_apk_smali_methods_references;
    everything else uses {CLICKHOUSE_CODE_PREFIX}_disassembled_functions_references.
    """
    if magika_filter == "apk":
        return "code_apk_smali_methods_references"
    code_prefix = os.getenv("CLICKHOUSE_CODE_PREFIX", "code_binja")
    return f"{code_prefix}_disassembled_functions_references"


def is_in_code_db(sha256, client=None, filetype=None):
    """
    Check if a sample with given SHA256 has already been disassembled.

    Args:
        sha256: File's SHA256 hash
        client: Optional ClickHouse client instance
        filetype: Magika filetype label (e.g. 'apk') to pick the right code table

    Returns:
        bool: True if file has been disassembled, False otherwise
    """
    table = _get_code_dedup_table(filetype)
    close_client = False

    try:
        if client is None:
            client = settings.create_clickhouse_client()
            close_client = True

        query = f"SELECT 1 FROM {table} WHERE sha256 = %(sha256)s LIMIT 1"
        result = client.query(query, parameters={"sha256": sha256})

        return len(result.result_rows) > 0
    except Exception as e:
        print(f"[ERROR] Failed to check if file is in code DB: {e}")
        return False
    finally:
        if close_client and client:
            client.close()


def _check_yara_matches_bulk(sha256_list):
    """
    Check which samples have already been YARA-scanned by querying yara_matches.

    The yara_matches table uses FixedString(32) binary sha256, so we convert
    hex strings with unhex().

    Args:
        sha256_list: List of hex SHA256 strings to check

    Returns:
        set: Set of hex SHA256 hashes that already have YARA matches
    """
    # unhex('64hexchars') adds 9 chars overhead per entry vs plain '64hexchars'.
    # 3900 works for plain strings (~67 chars each = 261K) but overflows
    # max_query_size (262144) with unhex() wrapping (~73 chars each = 285K).
    # 3500 × 73 = 255K stays safely under the limit.
    batch_size = 3500
    already_scanned = set()

    try:
        client = settings.create_clickhouse_client()

        total_batches = (len(sha256_list) + batch_size - 1) // batch_size
        for batch_num, i in enumerate(range(0, len(sha256_list), batch_size), 1):
            batch = sha256_list[i:i+batch_size]
            unhex_list = ",".join(f"unhex('{h}')" for h in batch)
            query = f"SELECT DISTINCT hex(sha256) FROM yara_matches FINAL WHERE sha256 IN ({unhex_list})"
            result = client.query(query)
            for row in result.result_rows:
                hash_value = row[0]
                if isinstance(hash_value, bytes):
                    hash_value = hash_value.decode('utf-8')
                already_scanned.add(hash_value.lower())

            if batch_num % 100 == 0 or batch_num == total_batches:
                print(f"[INFO] YARA dedup progress: batch {batch_num}/{total_batches}, found {len(already_scanned)} so far")

        print(f"[INFO] YARA dedup: found {len(already_scanned)} already-scanned samples")
        return already_scanned

    except Exception as e:
        raise RuntimeError(f"YARA dedup query failed — aborting to prevent reprocessing all samples: {e}")
    finally:
        if 'client' in locals():
            client.close()


def is_in_db_bulk(sha256_list, index_prefix, decompile, yara_scan=False, magika_filter=None):
    """
    Check which samples from a list of SHA256 hashes should be skipped.

    Args:
        sha256_list: List of SHA256 hashes to check
        index_prefix: Table prefix for ClickHouse
        decompile: Whether we're in decompile mode
        yara_scan: Whether we're in YARA-only mode (checks yara_matches table)
        magika_filter: Magika filetype label (e.g. 'apk') to pick the right code table

    Returns:
        set: Set of SHA256 hashes that should be skipped
    """
    if not sha256_list:
        return set()

    # YARA-only mode: check yara_matches table for already-scanned samples
    if yara_scan:
        return _check_yara_matches_bulk(sha256_list)

    basic_table = f"{index_prefix}_basic_properties"
    batch_size = 3900

    try:
        client = settings.create_clickhouse_client()

        # Step 1: Check basic_properties (required for both modes)
        in_basic_properties = set()
        for i in range(0, len(sha256_list), batch_size):
            batch = sha256_list[i:i+batch_size]
            placeholders = "','".join(batch)
            query = f"SELECT DISTINCT sha256 FROM {basic_table} FINAL WHERE sha256 IN ('{placeholders}')"
            result = client.query(query)
            for row in result.result_rows:
                hash_value = row[0]
                if isinstance(hash_value, bytes):
                    hash_value = hash_value.decode('utf-8')
                in_basic_properties.add(hash_value)

        if not decompile:
            # Analysis mode: skip samples already in basic_properties
            return in_basic_properties

        # Decompile mode: skip samples NOT in basic_properties + already decompiled
        not_in_basic = set(sha256_list) - in_basic_properties

        if not in_basic_properties:
            return set(sha256_list)  # None ready for decompilation

        # Step 2: Check disassembled table for samples that ARE in basic_properties
        # Disassembly is the ground truth for code analysis (it always succeeds,
        # unlike decompilation which may fail).
        disassembled_table = _get_code_dedup_table(magika_filter)

        already_disassembled = set()
        samples_to_check = list(in_basic_properties)
        for i in range(0, len(samples_to_check), batch_size):
            batch = samples_to_check[i:i+batch_size]
            placeholders = "','".join(batch)
            query = f"SELECT DISTINCT sha256 FROM {disassembled_table} FINAL WHERE sha256 IN ('{placeholders}')"
            result = client.query(query)
            for row in result.result_rows:
                hash_value = row[0]
                if isinstance(hash_value, bytes):
                    hash_value = hash_value.decode('utf-8')
                already_disassembled.add(hash_value)

        return not_in_basic | already_disassembled

    except Exception as e:
        print(f"[ERROR] Failed to check hashes in DB: {e}")
        return set()
    finally:
        if 'client' in locals():
            client.close()