Weiguo Sheng

127 papers A* 6A 1B 10C 1Misc 4Journal 92Unranked 13
YearRankTypeTitle / Venue / Authors
2026 J jnl
Sci. China Inf. Sci.
Tongxiang Li, Bo Chen, Weiguo Sheng, Wen-An Zhang
2026 J jnl
Neurocomputing
Minwei Huang, Luqiong Fan, Ze Chen, Weiguo Sheng
2026 J jnl
Neurocomputing
Jiafa Mao, Dingkai Yao, Yahong Hu, Sixian Chan, Weiguo Sheng, Hanlin Qin
2026 J jnl
Neurocomputing
Zuling Wang, Qingping Liu, Kao Xu, Yufeng Feng, Gang Xiao, Qi Li, Weiguo Sheng
2026 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Junyi Guan, Bingbing Jiang, Weiguo Sheng, Yangyang Zhao, Sheng Li, Xiongxiong He
2026 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Qi Li, Zidong Wang, Jun Hu, Weiguo Sheng
2026 conf
KDD (1)
Bingbing Jiang, Zhongli Wang, Jie Yang, Guangkui Xu, Wei Chen, Chenglong Zhang, Xinyan Liang, Peng Zhou, Weiguo Sheng, Weiping Ding
2025 B conf
CEC
Cong Li, Le Yan, Haoyu Zhang, Weiguo Sheng, Haibo Gao, Chang-Duo Liang
2025 J jnl
CoRR
Yujun Zheng, Xinya Chen, Xueqin Lu, Weiguo Sheng, Shengyong Chen
2025 A* conf
AAAI
Bingbing Jiang, Chenglong Zhang, Xinyan Liang, Peng Zhou, Jie Yang, Xingyu Wu, Junyi Guan, Weiping Ding, Weiguo Sheng
2025 J jnl
IEEE Trans. Ind. Informatics
Ruyu Liu, Yao Qin, Yihao Ying, Xiufeng Liu, Haoyu Zhang, Weiguo Sheng, Jianhua Zhang, Shengyong Chen
2025 A* conf
AAAI
Zhongli Wang, Jie Yang, Junyi Guan, Chenglong Zhang, Xinyan Liang, Bingbing Jiang, Weiguo Sheng
2025 J jnl
IEEE Trans. Fuzzy Syst.
Chuang Wang, Zidong Wang, Weiguo Sheng, Qingqiang Liu, Hongli Dong
2025 J jnl
Swarm Evol. Comput.
Zhihao Yu, Haoyu Zhang, Ruyu Liu, Sheng Dai, Xinan Chen, Weiguo Sheng, Yaochu Jin
2025 J jnl
IEEE Trans. Emerg. Top. Comput. Intell.
Yufeng Feng, Weiguo Sheng, Zidong Wang, Gang Xiao, Qi Li, Li Li, Zuling Wang
2025 J jnl
IEEE Access
Xiaoyu Xu, Dafang Zou, Jinding Zou, Shouhui Xia, Weiguo Sheng
2025 J jnl
Pattern Recognit.
Bingbing Jiang, Jun Liu, Zidong Wang, Chenglong Zhang, Jie Yang, Yadi Wang, Weiguo Sheng, Weiping Ding
2025 J jnl
IEEE Trans. Ind. Informatics
Yi Liu, Jiusun Zeng, Zidong Wang, Weiguo Sheng, Chuanhou Gao, Qi Xie, Lei Xie
2025 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Zhongyi Zhao, Zidong Wang, Lei Zou, Hongjian Liu, Weiguo Sheng
2024 J jnl
CoRR
Ting Yu, Xiaojun Lin, Shuhui Wang, Weiguo Sheng, Qingming Huang, Jun Yu
2024 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Ting Yu, Xiaojun Lin, Shuhui Wang, Weiguo Sheng, Qingming Huang, Jun Yu
2024 A* conf
ACM Multimedia
Ruyu Liu, Zhengzhe Liu, Haoyu Zhang, Guodao Zhang, Jianhua Zhang, Bo Sun, Weiguo Sheng, Xiufeng Liu, Yaochu Jin
2024 J jnl
Int. J. Syst. Sci.
Mengmeng Sheng, Weijie Ding, Weiguo Sheng
2024 J jnl
IEEE Trans. Emerg. Top. Comput. Intell.
Chenglong Zhang, Xinjie Zhu, Zidong Wang, Yan Zhong, Weiguo Sheng, Weiping Ding, Bingbing Jiang
2024 A* conf
IJCAI
Chenglong Zhang, Yang Fang, Xinyan Liang, Han Zhang, Peng Zhou, Xingyu Wu, Jie Yang, Bingbing Jiang, Weiguo Sheng
2024 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Wenling Li, Zidong Wang, Jun Hu, Junping Du, Weiguo Sheng
2024 B conf
IJCNN
Zihao Xu, Chenglong Zhang, Zhaolong Ling, Peng Zhou, Yan Zhong, Li Li, Han Zhang, Weiguo Sheng, Bingbing Jiang
2024 J jnl
Inf. Sci.
Xingyu Wu, Yan Zhong, Zhaolong Ling, Jie Yang, Li Li, Weiguo Sheng, Bingbing Jiang
2024 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Di Zhao, Zidong Wang, Yun Chen, Guoliang Wei, Weiguo Sheng
2024 A* conf
ACM Multimedia
Chenglong Zhang, Xinyan Liang, Peng Zhou, Zhaolong Ling, Yingwei Zhang, Xingyu Wu, Weiguo Sheng, Bingbing Jiang
2024 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Bingbing Jiang, Xingyu Wu, Xiren Zhou, Yi Liu, Anthony G. Cohn, Weiguo Sheng, Huanhuan Chen
2024 J jnl
Inf. Sci.
Yi Liu, Jiusun Zeng, Bingbing Jiang, Weiguo Sheng, Zidong Wang, Lei Xie, Li Li
2024 J jnl
IEEE Trans. Ind. Informatics
Chuang Wang, Zidong Wang, Lifeng Ma, Hongli Dong, Weiguo Sheng
2024 J jnl
IEEE Trans. Ind. Informatics
Chuang Wang, Zidong Wang, Qinyuan Liu, Hongli Dong, Weiguo Sheng
2024 J jnl
Inf. Fusion
Zhongyi Zhao, Zidong Wang, Lei Zou, Yun Chen, Weiguo Sheng
2023 J jnl
IEEE Access
Shenghao Zhou, Ze Chen, Qi Li, Mengjun Gu, Zhoucheng Bao, Wenda He, Weiguo Sheng
2023 J jnl
Knowl. Based Syst.
Chuang Wang, Zidong Wang, Lifeng Ma, Hongli Dong, Weiguo Sheng
2023 J jnl
Pattern Recognit.
Jiafa Mao, Lixin Wang, Ning Wang, Yahong Hu, Weiguo Sheng
2023 J jnl
Inf. Fusion
Bingbing Jiang, Chenglong Zhang, Yan Zhong, Yi Liu, Yingwei Zhang, Xingyu Wu, Weiguo Sheng
2023 J jnl
Inf. Sci.
Shenghao Zhou, Xiaomei Mo, Zidong Wang, Qi Li, Tianxiang Chen, Yujun Zheng, Weiguo Sheng
2023 A* conf
ICRA
Ruyu Liu, Zhengzhe Liu, Haoyu Zhang, Guodao Zhang, Zhigui Zuo, Weiguo Sheng
2023 B conf
CEC
Hao Yan, Lu Zhang, Xiaoyu Wang, Qingping Liu, Mengjun Gu, Weiguo Sheng
2023 J jnl
Inf. Sci.
Chenglong Zhang, Bingbing Jiang, Zidong Wang, Jie Yang, Yangfeng Lu, Xingyu Wu, Weiguo Sheng
2023 J jnl
Inf. Sci.
Qi Li, Yufu Zhi, Hailong Tan, Weiguo Sheng
2023 J jnl
Comput. Biol. Medicine
Ruyu Liu, Zhengzhe Liu, Jiaming Lu, Guodao Zhang, Zhigui Zuo, Bo Sun, Jianhua Zhang, Weiguo Sheng, Ran Guo, Lejun Zhang, Xiaozhen Hua
2023 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Yuqiang Luo, Zidong Wang, Weiguo Sheng, Dong Yue
2023 C conf
SAFEPROCESS
Zijie Luo, Weiguo Sheng, Bingbing Jiang, Yi Liu
2023 J jnl
Inf. Fusion
Zhongyi Zhao, Zidong Wang, Lei Zou, Yun Chen, Weiguo Sheng
2022 J jnl
IEEE Trans. Cybern.
Weiguo Sheng, Xi Wang, Zidong Wang, Qi Li, Yujun Zheng, Shengyong Chen
2022 B conf
CEC
Qingping Liu, Tingting Pang, Kaige Chen, Zuling Wang, Weiguo Sheng
2022 J jnl
Inf. Sci.
Zuling Wang, Ze Chen, Zidong Wang, Jing Wei, Xin Chen, Qi Li, Yujun Zheng, Weiguo Sheng
2022 J jnl
Soft Comput.
Le Yan, Xiaomei Mo, Qi Li, Mengjun Gu, Weiguo Sheng
2022 B conf
CEC
Tingting Pang, Jing Wei, Kaige Chen, Zuling Wang, Weiguo Sheng
2022 J jnl
IEEE Trans. Netw. Sci. Eng.
Zhongyi Zhao, Zidong Wang, Lei Zou, Yun Chen, Weiguo Sheng
2022 J jnl
Inf. Sci.
Qi Li, Zidong Wang, Hongli Dong, Weiguo Sheng
2022 J jnl
Inf. Sci.
Bingbing Jiang, Junhao Xiang, Xingyu Wu, Yadi Wang, Huanhuan Chen, Weiwei Cao, Weiguo Sheng
2022 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Qi Li, Zidong Wang, Jun Hu, Weiguo Sheng
2021 J jnl
IEEE Trans. Signal Inf. Process. over Networks
Qi Li, Zidong Wang, Bo Shen, Hongjian Liu, Weiguo Sheng
2021 J jnl
Inf. Sci.
Weiguo Sheng, Xi Wang, Zidong Wang, Qi Li, Yun Chen
2021 J jnl
Neurocomputing
Xi Wang, Zidong Wang, Mengmeng Sheng, Qi Li, Weiguo Sheng
2021 J jnl
IEEE Access
Le Yan, Jianjun Chen, Qi Li, Jiafa Mao, Weiguo Sheng
2021 J jnl
Inf. Sci.
Dafang Zou, Zidong Wang, Leimin Zhang, Jinting Zou, Qi Li, Yun Chen, Weiguo Sheng
2021 J jnl
Autom.
Qi Li, Zidong Wang, Jun Hu, Weiguo Sheng
2021 J jnl
IEEE Trans. Cybern.
Yun Chen, Zidong Wang, Licheng Wang, Weiguo Sheng
2021 J jnl
IEEE Trans. Cybern.
Li Li, Liang Chang, Tianlong Gu, Weiguo Sheng, Wanliang Wang
2021 A conf
CIKM
Bingbing Jiang, Junhao Xiang, Xingyu Wu, Wenda He, Libin Hong, Weiguo Sheng
2020 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Qi Li, Zidong Wang, Nan Li, Weiguo Sheng
2020 B conf
IJCNN
Jiafa Mao, Linlin Yu, Hui Yu, Yahong Hu, Weiguo Sheng
2020 J jnl
IEEE Trans. Cybern.
Min Wang, Zidong Wang, Yun Chen, Weiguo Sheng
2020 B conf
CEC
Yangyan Xu, Chenxin Wu, Bingbing Jiang, Weiguo Sheng
2020 J jnl
Inf. Sci.
Qi Li, Zidong Wang, Weiguo Sheng, Fawaz E. Alsaadi, Fuad E. Alsaadi
2020 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Min Wang, Zidong Wang, Yun Chen, Weiguo Sheng
2020 J jnl
IEEE Trans. Evol. Comput.
Yu-Jun Zheng, Yi-Chen Du, Hai-Feng Ling, Weiguo Sheng, Sheng-Yong Chen
2020 J jnl
Neural Comput. Appl.
Dafang Zou, Mengmeng Sheng, Hui Yu, Jiafa Mao, Shengyong Chen, Weiguo Sheng
2020 J jnl
CoRR
Dafang Zou, Leiming Zhang, Jiafa Mao, Weiguo Sheng
2020 J jnl
IEEE Access
Wenfan Chen, Mengmeng Sheng, Jiafa Mao, Weiguo Sheng
2020 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Yun Chen, Zidong Wang, Licheng Wang, Weiguo Sheng
2020 J jnl
IEEE Trans. Cybern.
Min Wang, Zidong Wang, Yun Chen, Weiguo Sheng
2020 J jnl
Autom.
Qi Li, Bo Shen, Zidong Wang, Weiguo Sheng
2020 J jnl
IET Image Process.
Jiafa Mao, Huang Wei, Weiguo Sheng
2019 B conf
IJCNN
Hui Yu, Haitao Sa, Dafang Zou, Jiafa Mao, Weiguo Sheng
2019 J jnl
Neurocomputing
Xi Wang, Mengmeng Sheng, Kangfei Ye, Jian Lin, Jiafa Mao, Shengyong Chen, Weiguo Sheng
2019 J jnl
INFORMS J. Appl. Anal.
Yu-Jun Zheng, Yi-Chen Du, Weiguo Sheng, Hai-Feng Ling
2019 J jnl
IEEE Trans. Ind. Informatics
Qin Song, Yu-Jun Zheng, Yu-Jiao Huang, Zhi-Ge Xu, Weiguo Sheng, Jun Yang
2019 J jnl
Neurocomputing
Xiaowu Zou, Zidong Wang, Qi Li, Weiguo Sheng
2019 J jnl
Neurocomputing
Fuchang Liu, Pengfei Fang, Zhengwei Yao, Ran Fan, Zhigeng Pan, Weiguo Sheng, Huansong Yang
2018 conf
Rep4NLP@ACL
Weiguo Sheng
2018 J jnl
Neural Networks
Yujun Zheng, Xiao-Han Zhou, Weiguo Sheng, Yu Xue, Sheng-Yong Chen
2018 J jnl
IET Image Process.
Jiafa Mao, Kaihui Wang, Yahong Hu, Weiguo Sheng, Qixin Feng
2018 J jnl
Neurocomputing
Jianwei Zheng, Hong Qiu, Weiguo Sheng, Xi Yang, Hongchuan Yu
2017 conf
BIC-TA
Kangfei Ye, Weiguo Sheng
2017 J jnl
Neurocomputing
Weiguo Sheng, Pengxiao Shan, Shengyong Chen, Yurong Liu, Fuad E. Alsaadi
2017 Misc conf
ICMLC
Ling Yang, Yuyang Guan, Weiguo Sheng
2017 J jnl
Int. J. Comput. Math.
Jiafa Mao, Gang Xiao, Weiguo Sheng, Tasawar Hayat, Xiaohui Liu
2017 conf
MDA
Ase Shen, Gang Xiao, Jiafa Mao, Hai-biao Hu, Weiguo Sheng, Li-Nan Zhu
2017 Misc conf
ICMLC
Xi Wang, Weiguo Sheng
2017 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Yu-Jun Zheng, Weiguo Sheng, Xing-Ming Sun, Sheng-Yong Chen
2017 J jnl
IEEE Access
Weiguo Sheng, Pengxiao Shan, Jiafa Mao, Yujun Zheng, Shengyong Chen, Zidong Wang
2017 J jnl
Neurocomputing
Qin Song, Yu-Jun Zheng, Yu Xue, Weiguo Sheng, Mei-rong Zhao
2017 conf
BIC-TA
Yuyang Guan, Ling Yang, Weiguo Sheng
2017 J jnl
Multim. Tools Appl.
Jiafa Mao, Weiguo Sheng, Yahong Hu, Gang Xiao, Zhiguo Qu, Xinxin Niu, Li-Nan Zhu
2016 J jnl
Neurocomputing
Jiafa Mao, Gang Xiao, Weiguo Sheng, Yahong Hu, Zhiguo Qu
2016 J jnl
Multim. Tools Appl.
Jiafa Mao, Xinxin Niu, Gang Xiao, Weiguo Sheng, Na-Na Zhang
2016 J jnl
IEEE Trans. Evol. Comput.
Weiguo Sheng, Shengyong Chen, Mengmeng Sheng, Gang Xiao, Jiafa Mao, Yujun Zheng
2016 J jnl
Neurocomputing
Jiafa Mao, Gang Xiao, Weiguo Sheng, Zhiguo Qu, Yurong Liu
2015 conf
EIT
Jiafa Mao, Gang Xiao, Weiguo Sheng, Xiaohui Liu
2015 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Weiguo Sheng, Shengyong Chen, Gang Xiao, Jiafa Mao, Yujun Zheng
2015 conf
UIC/ATC/ScalCom
Pengxiao Shan, Weiguo Sheng
2015 conf
CCBR
Mengya Lu, Zhiqiang Chen, Weiguo Sheng
2014 J jnl
IEEE Trans. Evol. Comput.
Weiguo Sheng, Shengyong Chen, Michael C. Fairhurst, Gang Xiao, Jiafa Mao
2012 J jnl
Inf. Manag. Comput. Secur.
Weiguo Sheng, Gareth Howells, Michael C. Fairhurst, Farzin Deravi, Shengyong Chen
2010 J jnl
Soft Comput.
Weiguo Sheng, Allan Tucker, Xiaohui Liu
2009 J jnl
Pattern Recognit.
Weiguo Sheng, Gareth Howells, Michael C. Fairhurst, Farzin Deravi, Karl Harmer
2008 J jnl
IEEE Trans. Knowl. Data Eng.
Weiguo Sheng, Xiaohui Liu, Michael C. Fairhurst
2008 B conf
IEEE Congress on Evolutionary Computation
Weiguo Sheng, Gareth Howells, Karl Harmer, Michael C. Fairhurst, Farzin Deravi
2008 conf
BLISS
Karl Harmer, Weiguo Sheng, W. Gareth J. Howells, Michael C. Fairhurst, Farzin Deravi
2008 J jnl
IEEE Trans. Inf. Forensics Secur.
Weiguo Sheng, Gareth Howells, Michael C. Fairhurst, Farzin Deravi
2007 conf
IPCV
Karl Harmer, Gareth Howells, Weiguo Sheng, Michael C. Fairhurst, Farzin Deravi
2007 J jnl
IEEE Trans. Inf. Forensics Secur.
Weiguo Sheng, Gareth Howells, Michael C. Fairhurst, Farzin Deravi
2007 conf
IPCV
Karl Harmer, Gareth Howells, Weiguo Sheng, Michael C. Fairhurst, Farzin Deravi
2007 conf
ICB
Weiguo Sheng, Gareth Howells, Karl Harmer, Michael C. Fairhurst, Farzin Deravi
2006 J jnl
J. Heuristics
Weiguo Sheng, Xiaohui Liu
2005 Misc conf
Visualization and Data Analysis
Leishi Zhang, Weiguo Sheng, Xiaohui Liu
2005 J jnl
IEEE Trans. Syst. Man Cybern. Part B
Weiguo Sheng, Stephen Swift, Leishi Zhang, Xiaohui Liu
2004 Misc conf
ICCVG
Leishi Zhang, Xiaohui Liu, Weiguo Sheng
2004 B conf
IEEE Congress on Evolutionary Computation
Weiguo Sheng, Xiaohui Liu
2004 conf
GECCO (2)
Weiguo Sheng, Allan Tucker, Xiaohui Liu
tests/unit/test_apk_strings_ioc.py
← Index tests/unit/test_apk_strings_ioc.py python
"""Tests for APK string extraction and IOC extraction integration.

Covers:
- APKCodeAnalyzer._extract_strings() — string extraction from DEX objects
- APKCodeAnalyzer._string_entropy() — Shannon entropy computation
- DecompileAPK strings export table schema
- IOCExtractorFromResults with APK-format analysis_results
- Worker IOC wiring for APK
"""
import os
import tempfile
from dataclasses import asdict
from unittest.mock import MagicMock, patch

import pytest

from redb.extractors.ioc_extractor.ioc_extractor import IOCExtractorFromResults
from redb.extractors.ioc_extractor.standalone_ioc_extractor import (
    IOCType,
    SourceType,
)

pytestmark = [pytest.mark.unit, pytest.mark.apk]


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def _make_analyzer(min_instructions=1):
    """Create an APKCodeAnalyzer with mocked dependencies."""
    with patch(
        "redb.extractors.decompiler.apk.analyzer.JADXDecompiler"
    ), patch(
        "redb.extractors.decompiler.apk.analyzer.ApktoolDisassembler"
    ):
        from redb.extractors.decompiler.apk.analyzer import APKCodeAnalyzer
        analyzer = APKCodeAnalyzer("/fake/path.apk")
        analyzer.min_instructions = min_instructions
        return analyzer


def _make_mock_dex(strings):
    """Create a mock DEX object that returns the given strings."""
    dex = MagicMock()
    dex.get_strings.return_value = strings
    return dex


def _create_fake_apk_file():
    """Create a temporary file to act as a fake APK."""
    fd, path = tempfile.mkstemp(suffix=".apk")
    os.write(fd, b"PK\x03\x04fake apk content for hashing")
    os.close(fd)
    return path


# ---------------------------------------------------------------------------
# Tests: _string_entropy
# ---------------------------------------------------------------------------

class TestStringEntropy:
    """Tests for Shannon entropy computation."""

    def test_empty_string(self):
        analyzer = _make_analyzer()
        assert analyzer._string_entropy("") == 0.0

    def test_single_char(self):
        analyzer = _make_analyzer()
        assert analyzer._string_entropy("a") == 0.0

    def test_repeated_char(self):
        analyzer = _make_analyzer()
        assert analyzer._string_entropy("aaaa") == 0.0

    def test_two_equal_chars(self):
        analyzer = _make_analyzer()
        # "ab" -> entropy = 1.0
        assert abs(analyzer._string_entropy("ab") - 1.0) < 0.01

    def test_higher_entropy(self):
        analyzer = _make_analyzer()
        # More variety = higher entropy
        low = analyzer._string_entropy("aabb")
        high = analyzer._string_entropy("abcd")
        assert high > low

    def test_url_string_entropy(self):
        analyzer = _make_analyzer()
        entropy = analyzer._string_entropy("https://evil.com/payload")
        assert entropy > 2.0  # URLs have moderate entropy


# ---------------------------------------------------------------------------
# Tests: _extract_strings
# ---------------------------------------------------------------------------

class TestExtractStrings:
    """Tests for DEX string extraction."""

    def test_basic_extraction(self):
        analyzer = _make_analyzer()
        dex = _make_mock_dex(["hello", "world"])
        result = analyzer._extract_strings([dex])

        assert len(result) == 2
        assert result[0]["string"] == "hello"
        assert result[1]["string"] == "world"

    def test_string_fields_present(self):
        analyzer = _make_analyzer()
        dex = _make_mock_dex(["test_string"])
        result = analyzer._extract_strings([dex])

        entry = result[0]
        assert "string" in entry
        assert "string_encoding" in entry
        assert "string_offset" in entry
        assert "string_length" in entry
        assert "string_entropy" in entry
        assert entry["string_encoding"] == "UTF8"
        assert entry["string_length"] == len("test_string")

    def test_deduplication_across_dex(self):
        """Same string in multiple DEX files is only extracted once."""
        analyzer = _make_analyzer()
        dex1 = _make_mock_dex(["shared", "unique1"])
        dex2 = _make_mock_dex(["shared", "unique2"])
        result = analyzer._extract_strings([dex1, dex2])

        string_values = [s["string"] for s in result]
        assert string_values.count("shared") == 1
        assert "unique1" in string_values
        assert "unique2" in string_values
        assert len(result) == 3

    def test_empty_strings_filtered(self):
        analyzer = _make_analyzer()
        dex = _make_mock_dex(["", "valid", None, "also_valid"])
        result = analyzer._extract_strings([dex])

        string_values = [s["string"] for s in result]
        assert "" not in string_values
        assert None not in string_values
        assert "valid" in string_values
        assert "also_valid" in string_values

    def test_no_dex_files(self):
        analyzer = _make_analyzer()
        result = analyzer._extract_strings([])
        assert result == []

    def test_dex_get_strings_returns_none(self):
        analyzer = _make_analyzer()
        dex = MagicMock()
        dex.get_strings.return_value = None
        result = analyzer._extract_strings([dex])
        assert result == []

    def test_dex_get_strings_exception(self):
        analyzer = _make_analyzer()
        dex = MagicMock()
        dex.get_strings.side_effect = RuntimeError("corrupt DEX")
        result = analyzer._extract_strings([dex])
        assert result == []

    def test_entropy_computed(self):
        analyzer = _make_analyzer()
        dex = _make_mock_dex(["abcdefgh"])
        result = analyzer._extract_strings([dex])
        assert result[0]["string_entropy"] > 0.0

    def test_incremental_offsets(self):
        """String offsets are incremented sequentially."""
        analyzer = _make_analyzer()
        dex = _make_mock_dex(["a", "b", "c"])
        result = analyzer._extract_strings([dex])

        offsets = [s["string_offset"] for s in result]
        assert offsets == [0, 1, 2]

    def test_url_strings_preserved(self):
        """URL strings are extracted without modification."""
        analyzer = _make_analyzer()
        dex = _make_mock_dex([
            "https://evil.com/payload",
            "http://c2.malware.org/gate",
        ])
        result = analyzer._extract_strings([dex])
        strings = [s["string"] for s in result]
        assert "https://evil.com/payload" in strings
        assert "http://c2.malware.org/gate" in strings


# ---------------------------------------------------------------------------
# Tests: strings in extract() integration
# ---------------------------------------------------------------------------

class TestExtractStringsIntegration:
    """Tests that strings are included in extract() results."""

    @patch("redb.extractors.decompiler.apk.analyzer.APKCodeAnalyzer._run_androguard")
    @patch("redb.extractors.decompiler.apk.analyzer.ApktoolDisassembler")
    @patch("redb.extractors.decompiler.apk.analyzer.JADXDecompiler")
    def test_extract_includes_strings(self, mock_jadx, mock_apktool, mock_androguard):
        from redb.extractors.decompiler.apk.analyzer import APKCodeAnalyzer

        mock_dex = _make_mock_dex(["hello", "world"])
        mock_analysis = MagicMock()
        mock_analysis.get_methods.return_value = []
        mock_androguard.return_value = (MagicMock(), [mock_dex], mock_analysis)

        analyzer = APKCodeAnalyzer("/fake/path.apk", log=MagicMock())
        results = analyzer.extract()

        assert "strings" in results
        assert len(results["strings"]) == 2
        assert results["strings"][0]["string"] == "hello"
        analyzer.cleanup()

    @patch("redb.extractors.decompiler.apk.analyzer.APKCodeAnalyzer._run_androguard")
    @patch("redb.extractors.decompiler.apk.analyzer.ApktoolDisassembler")
    @patch("redb.extractors.decompiler.apk.analyzer.JADXDecompiler")
    def test_extract_strings_error_is_non_fatal(self, mock_jadx, mock_apktool, mock_androguard):
        from redb.extractors.decompiler.apk.analyzer import APKCodeAnalyzer

        # Return a bad dex list that will cause _extract_strings to fail
        mock_analysis = MagicMock()
        mock_analysis.get_methods.return_value = []
        # dexs is not iterable — triggers the except block
        mock_androguard.return_value = (MagicMock(), 42, mock_analysis)

        analyzer = APKCodeAnalyzer("/fake/path.apk", log=MagicMock())
        results = analyzer.extract()

        # Should not crash, strings should be empty, error recorded
        assert results["strings"] == []
        assert any(
            e.get("error_location") == "strings"
            for e in results["analysis_errors"]
        )
        analyzer.cleanup()


# ---------------------------------------------------------------------------
# Tests: DecompileAPK strings export table
# ---------------------------------------------------------------------------

class TestDecompileAPKStringsExport:
    """Tests for strings table in DecompileAPK.prepare_export_data()."""

    def _make_extractor_with_strings(self, strings_data):
        from redb.extractors.decompiler.DecompileAPK import DecompileAPK
        apk_path = _create_fake_apk_file()
        ext = DecompileAPK(apk_path, MagicMock())
        ext.analysis_results = {
            "sha256": "a" * 64,
            "sha1": "b" * 40,
            "md5": "c" * 32,
            "decompiled_content": [],
            "decompiled_refs": [],
            "smali_content": [],
            "smali_refs": [],
            "similarity_metrics": [],
            "strings": strings_data,
            "analysis_errors": [],
        }
        return ext, apk_path

    def test_strings_table_present(self):
        ext, path = self._make_extractor_with_strings([
            {"string": "hello", "string_encoding": "UTF8",
             "string_offset": 0, "string_length": 5, "string_entropy": 2.32}
        ])
        try:
            export = ext.prepare_export_data("ClickHouseExporter")
            assert "strings_raw" in export
        finally:
            os.unlink(path)

    def test_strings_table_schema(self):
        ext, path = self._make_extractor_with_strings([
            {"string": "hello", "string_encoding": "UTF8",
             "string_offset": 0, "string_length": 5, "string_entropy": 2.32}
        ])
        try:
            export = ext.prepare_export_data("ClickHouseExporter")
            sr = export["strings_raw"]
            assert sr["table"] == "code_binja_strings_raw"
            assert len(sr["column_names"]) == 8
            assert len(sr["column_type_names"]) == 8
            assert "sha256" in sr["column_names"]
            assert "string" in sr["column_names"]
            assert "string_raw" in sr["column_names"]
            assert "string_encoding" in sr["column_names"]
            assert "string_offset" in sr["column_names"]
            assert "string_length" in sr["column_names"]
            assert "string_raw_length" in sr["column_names"]
            assert "string_entropy" in sr["column_names"]
            assert len(sr["data"]) == 1
            assert len(sr["data"][0]) == 8
        finally:
            os.unlink(path)

    def test_strings_sha256_propagated(self):
        ext, path = self._make_extractor_with_strings([
            {"string": "test", "string_encoding": "UTF8",
             "string_offset": 0, "string_length": 4, "string_entropy": 2.0}
        ])
        try:
            export = ext.prepare_export_data("ClickHouseExporter")
            row = export["strings_raw"]["data"][0]
            assert row[0] == "a" * 64  # sha256 is first column
        finally:
            os.unlink(path)

    def test_empty_strings_not_exported(self):
        ext, path = self._make_extractor_with_strings([])
        try:
            export = ext.prepare_export_data("ClickHouseExporter")
            assert "strings_raw" not in export
        finally:
            os.unlink(path)


# ---------------------------------------------------------------------------
# Tests: IOCExtractorFromResults with APK format
# ---------------------------------------------------------------------------

class TestIOCExtractorAPKFormat:
    """Tests that IOCExtractorFromResults handles APK analysis_results."""

    def setup_method(self):
        self.log = MagicMock()

    def test_extract_iocs_from_apk_strings(self):
        """IOCs extracted from APK strings (same format as Binja)."""
        results = {
            "strings": [
                {"string": "https://evil.com/payload", "string_offset": 0},
                {"string": "Contact [email protected]", "string_offset": 1},
            ],
            "decompiled": [],
            "decompiled_content": [],
        }
        extractor = IOCExtractorFromResults(results, sha256="a" * 64, log=self.log)
        iocs = extractor.extract()

        url_iocs = [i for i in iocs if i.ioc_type == IOCType.URL]
        assert len(url_iocs) >= 1
        assert any("evil.com" in i.ioc_value for i in url_iocs)

    def test_extract_iocs_from_apk_decompiled_content(self):
        """IOCs extracted from APK's decompiled_content key."""
        results = {
            "strings": [],
            "decompiled": [],  # Binja format — empty
            "decompiled_content": [  # APK format
                {
                    "decompiled_method": "connect('https://c2.malware.org/gate');",
                    "decompiled_method_hash": "hash123",
                    "method_type": "USER",
                }
            ],
        }
        extractor = IOCExtractorFromResults(results, sha256="a" * 64, log=self.log)
        iocs = extractor.extract()

        url_iocs = [i for i in iocs if i.ioc_type == IOCType.URL]
        assert len(url_iocs) >= 1

    def test_apk_library_methods_skipped(self):
        """LIBRARY methods in decompiled_content are skipped."""
        results = {
            "strings": [],
            "decompiled": [],
            "decompiled_content": [
                {
                    "decompiled_method": "https://should-skip.com",
                    "decompiled_method_hash": "lib_hash",
                    "method_type": "LIBRARY",
                }
            ],
        }
        extractor = IOCExtractorFromResults(results, sha256="a" * 64, log=self.log)
        iocs = extractor.extract()
        assert len(iocs) == 0

    def test_combined_binja_and_apk_sources(self):
        """Both Binja and APK format decompiled entries are processed."""
        results = {
            "strings": [],
            "decompiled": [
                {
                    "decompiled_function": "call('https://binja.example.com');",
                    "decompiled_function_hash": "binja_hash",
                    "function_type": "USER",
                }
            ],
            "decompiled_content": [
                {
                    "decompiled_method": "send('https://apk.example.com');",
                    "decompiled_method_hash": "apk_hash",
                    "method_type": "USER",
                }
            ],
        }
        extractor = IOCExtractorFromResults(results, sha256="a" * 64, log=self.log)
        iocs = extractor.extract()

        url_iocs = [i for i in iocs if i.ioc_type == IOCType.URL]
        urls = [i.ioc_value for i in url_iocs]
        assert any("binja.example.com" in u for u in urls)
        assert any("apk.example.com" in u for u in urls)

    def test_apk_results_only(self):
        """Works when only APK keys are present (no 'decompiled' key)."""
        results = {
            "strings": [
                {"string": "https://evil.com", "string_offset": 0},
            ],
            "decompiled_content": [
                {
                    "decompiled_method": "x = 1",
                    "decompiled_method_hash": "h",
                    "method_type": "USER",
                }
            ],
        }
        extractor = IOCExtractorFromResults(results, sha256="a" * 64, log=self.log)
        iocs = extractor.extract()
        # Should not crash, and should find URL from strings
        url_iocs = [i for i in iocs if i.ioc_type == IOCType.URL]
        assert len(url_iocs) >= 1

    def test_source_type_is_string_for_strings(self):
        results = {
            "strings": [
                {"string": "https://evil.com/test", "string_offset": 42},
            ],
            "decompiled_content": [],
        }
        extractor = IOCExtractorFromResults(results, sha256="a" * 64, log=self.log)
        iocs = extractor.extract()
        url_iocs = [i for i in iocs if i.ioc_type == IOCType.URL]
        assert url_iocs[0].source_type == SourceType.STRING
        assert url_iocs[0].source_identifier == "42"

    def test_source_type_is_decompiled_for_methods(self):
        results = {
            "strings": [],
            "decompiled_content": [
                {
                    "decompiled_method": "https://evil.com/method",
                    "decompiled_method_hash": "myhash",
                    "method_type": "USER",
                }
            ],
        }
        extractor = IOCExtractorFromResults(results, sha256="a" * 64, log=self.log)
        iocs = extractor.extract()
        url_iocs = [i for i in iocs if i.ioc_type == IOCType.URL]
        assert url_iocs[0].source_type == SourceType.DECOMPILED_FUNCTION
        assert url_iocs[0].source_identifier == "myhash"


# ---------------------------------------------------------------------------
# Tests: Worker IOC wiring for APK
# ---------------------------------------------------------------------------

class TestWorkerAPKIOCWiring:
    """Tests that workers.py wires IOC extraction for APK."""

    def test_worker_source_contains_ioc_for_apk(self):
        """Verify workers.py source has IOC extraction in APK branch."""
        import inspect
        from redb import workers
        source = inspect.getsource(workers)
        # APK branch should import IOCExtractorFromResults
        assert "IOCExtractorFromResults" in source
        # Should be in the APK section (near DecompileAPK)
        apk_section = source[source.index("DecompileAPK("):]
        ioc_pos = apk_section.find("IOCExtractorFromResults")
        assert ioc_pos != -1, "IOCExtractorFromResults not found after DecompileAPK"