Carman K. M. Lee

124 papers A 1B 1C 1Journal 100Unranked 21
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Trans. Ind. Informatics
Haishi Liu, Yung Po Tsang, Carman K. M. Lee, Chun-Ho Wu, Kai-Leung Yung
2025 J jnl
Appl. Soft Comput.
Zhonghao Zhao, Carman K. M. Lee, Xiaoyuan Yan
2025 J jnl
Ann. Oper. Res.
Yung Po Tsang, Haoran Ma, Kim Hua Tan, Carman K. M. Lee
2025 J jnl
Comput. Ind. Eng.
Zhonghao Zhao, Carman K. M. Lee, Xiaoyuan Yan
2025 conf
ISMSI
Yung Po Tsang, Daniel Y. Mo, Kwok Tung Chung, Carman K. M. Lee
2025 J jnl
J. Theor. Appl. Electron. Commer. Res.
Kin Lok Keung, Carman K. M. Lee, Kwok-To Luk
2025 J jnl
Comput. Ind. Eng.
Feng Liu, Carman K. M. Lee, Min Xu
2025 J jnl
IEEE Trans. Netw. Sci. Eng.
Kening Zhang, Carman K. M. Lee, Yung Po Tsang
2025 J jnl
Pattern Recognit. Lett.
Kening Zhang, Yung Po Tsang, Carman K. M. Lee, Chun-Ho Wu
2025 J jnl
IEEE Trans. Consumer Electron.
Mohammed Woyeso Geda, Yuk-Ming Tang, Carman K. M. Lee
2025 J jnl
Artif. Intell. Rev.
Kwok Tung Chung, Carman K. M. Lee, Yung Po Tsang
2025 J jnl
IEEE Trans. Instrum. Meas.
Xingchen Liu, Carman K. M. Lee, Jingyuan Huang, Qiuzhuang Sun
2025 J jnl
IEEE Internet Things J.
Kening Zhang, Carman K. M. Lee, Yung Po Tsang
2025 J jnl
IEEE Trans. Veh. Technol.
Kening Zhang, Carman K. M. Lee, Yung Po Tsang, Chun-Ho Wu
2024 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Jiage Huo, Carman K. M. Lee
2024 conf
GDN
Yanlin Li, Yung Po Tsang, Carman K. M. Lee, Yipu Yao
2024 conf
IEEM
Misbah Iqbal, Carman K. M. Lee, Kin Lok Keung
2024 J jnl
Enterp. Inf. Syst.
Yung Po Tsang, Youqing Fan, Carman K. M. Lee, Henry C. W. Lau
2024 J jnl
Ann. Oper. Res.
Yunzhang Huo, Carman K. M. Lee, Shuzhu Zhang
2024 conf
IEEM
Chengli Liu, Carman K. M. Lee, Zhonghao Zhao
2024 J jnl
Knowl. Based Syst.
Misbah Iqbal, Carman K. M. Lee, Kin Lok Keung
2024 J jnl
Adv. Eng. Informatics
Carman K. M. Lee, Jingying Liang, Kai-Leung Yung, Kin Lok Keung
2024 J jnl
Qual. Reliab. Eng. Int.
Yaqiong Lv, Xiaohu Zhang, Yiwei Cheng, Carman K. M. Lee
2024 C conf
IV
Haishi Liu, Yung Po Tsang, Carman K. M. Lee, Yutong Wang, Fei-Yue Wang
2024 J jnl
IEEE Trans. Ind. Informatics
Kening Zhang, Carman K. M. Lee, Yung Po Tsang
2024 J jnl
IEEE Trans. Ind. Informatics
Haishi Liu, Yung Po Tsang, Carman K. M. Lee, Chun-Ho Wu
2023 conf
IEEM
Zhonghao Zhao, Carman K. M. Lee, Xiaoyuan Yan, Haonan Wang
2023 J jnl
Robotics Comput. Integr. Manuf.
Kin Lok Keung, Carman K. M. Lee, Liqiao Xia, Chao Liu, Bufan Liu, P. Ji
2023 J jnl
Syst.
Sheron K. H. Sit, Carman K. M. Lee
2023 J jnl
Eng. Appl. Artif. Intell.
Yousaf Ayub, Yusha Hu, Jingzheng Ren, Weifeng Shen, Carman K. M. Lee
2023 J jnl
IEEE Trans. Intell. Transp. Syst.
Zhonghao Zhao, Carman K. M. Lee, Jingzheng Ren, Yung Po Tsang
2023 J jnl
Ann. Oper. Res.
Yunzhang Huo, Carman K. M. Lee, Shuzhu Zhang
2022 A conf
IROS
Junming Fan, Pai Zheng, Carman K. M. Lee
2022 conf
IEEM
Kin Lok Keung, Liqiao Xia, Carman K. M. Lee, C. Y. Leung
2022 J jnl
Appl. Intell.
Yiwei Cheng, Kui Hu, Jun Wu, Haiping Zhu, Carman K. M. Lee
2022 J jnl
Adv. Eng. Informatics
Xiangying Zhang, Junming Fan, Tao Peng, Pai Zheng, Carman K. M. Lee, Renzhong Tang
2022 J jnl
Robotics Comput. Integr. Manuf.
Chengxi Li, Pai Zheng, Shufei Li, Yat Ming Pang, Carman K. M. Lee
2022 J jnl
Adv. Eng. Informatics
Carman K. M. Lee, Kam K. H. Ng, Roger J. Jiao, Zhixin Yang
2022 J jnl
J. Grid Comput.
Yung Po Tsang, Chun-Ho Wu, W. H. Ip, Carman K. M. Lee
2022 J jnl
Comput. Chem. Eng.
Tao Shi, Yue Liu, Haoshui Yu, Ao Yang, Shirui Sun, Weifeng Shen, Carman K. M. Lee, Jingzheng Ren
2022 J jnl
Adv. Eng. Informatics
Kin Lok Keung, Carman K. M. Lee, P. Ji
2022 conf
IEEM
Misbah Iqbal, Carman K. M. Lee, Jingzheng Ren
2022 J jnl
Appl. Soft Comput.
Yiwei Cheng, Chao Wang, Jun Wu, Haiping Zhu, Carman K. M. Lee
2022 J jnl
Adv. Eng. Informatics
Xiangying Zhang, Pai Zheng, Tao Peng, Qiqi He, Carman K. M. Lee, Renzhong Tang
2021 conf
CASE
Junming Fan, Shufei Li, Pai Zheng, Carman K. M. Lee
2021 conf
IEEM
Kin Lok Keung, Carman K. M. Lee, Yuk Hin Yiu
2021 J jnl
Soft Comput.
Hanan Yakubu, C. K. Kwong, Carman K. M. Lee
2021 J jnl
Adv. Eng. Informatics
Kam K. H. Ng, Chun-Hsien Chen, Carman K. M. Lee, Roger Jianxin Jiao, Zhi-Xin Yang
2021 J jnl
Expert Syst. Appl.
Carman K. M. Lee, Kam K. H. Ng, Chun-Hsien Chen, Henry C. W. Lau, Sui Ying Chung, Tiffany Tsoi
2021 J jnl
IEEE Trans. Veh. Technol.
Zhonghao Zhao, Min Xu, Carman K. M. Lee
2021 J jnl
Adv. Eng. Informatics
Kin Lok Keung, Carman K. M. Lee, Ping Ji
2021 conf
IEEM
Jiage Huo, Kin Lok Keung, Carman K. M. Lee, Hiu Yin Ng
2021 J jnl
Adv. Eng. Informatics
Jiage Huo, Carman K. M. Lee
2021 J jnl
Comput. Ind. Eng.
Kam K. H. Ng, Chun-Hsien Chen, Carman K. M. Lee
2021 J jnl
Ind. Manag. Data Syst.
Henry C. W. Lau, Yung Po Tsang, Dilupa Nakandala, Carman K. M. Lee
2020 J jnl
Appl. Soft Comput.
K. K. H. Ng, Carman K. M. Lee, Felix T. S. Chan, Chun-Hsien Chen, Yichen Qin
2020 J jnl
Adv. Eng. Informatics
Eric Ka Ho Leung, Carman K. M. Lee, King Lun Choy
2020 J jnl
IEEE Access
Kin Lok Keung, Carman K. M. Lee, Ping Ji, Kam Hung Ng
2020 J jnl
IEEE Access
Carman K. M. Lee, Yunzhang Huo, Shuzhu Zhang, K. K. H. Ng
2020 conf
IEEM
Danping Lin, Carman K. M. Lee, Wenyan Guo
2020 J jnl
Adv. Eng. Informatics
Jiage Huo, Felix T. S. Chan, Carman K. M. Lee, Jan Ola Strandhagen, Ben Niu
2019 J jnl
Electron. Commer. Res.
Baozhuang Niu, Jingmai Wang, Carman K. M. Lee, Lei Chen
2019 J jnl
Int. J. Prod. Res.
Eric Ka Ho Leung, C. C. Luk, King Lun Choy, Hoi Yan Lam, Carman K. M. Lee
2019 J jnl
Expert Syst. Appl.
Eric Ka Ho Leung, King Lun Choy, George T. S. Ho, Carman K. M. Lee, Cathy H. Y. Lam, C. C. Luk
2019 J jnl
Asia Pac. J. Oper. Res.
Chengli Liu, Carman K. M. Lee, Eric Ka Ho Leung
2019 J jnl
Adv. Eng. Informatics
Carman K. M. Lee, Bingbing Lin, K. K. H. Ng, Yaqiong Lv, Wai Chun Tai
2019 J jnl
Int. J. Prod. Res.
Baozhuang Niu, Yaoqi Liu, Feng Liu, Carman K. M. Lee
2018 J jnl
Expert Syst. Appl.
Eric Ka Ho Leung, King Lun Choy, Paul K. Y. Siu, George T. S. Ho, Cathy H. Y. Lam, Carman K. M. Lee
2018 J jnl
Int. J. Knowl. Syst. Sci.
Kin Lok Keung, Carman K. M. Lee, K. K. H. Ng, Sing Sum Leung, King Lun Choy
2018 J jnl
Ind. Manag. Data Syst.
Henry C. W. Lau, Carman K. M. Lee, Dilupa Nakandala, Paul K. Shum
2018 J jnl
Int. J. Prod. Res.
Carman K. M. Lee, Yaqiong Lv, K. K. H. Ng, William Ho, King Lun Choy
2018 conf
CONF-IRM
Carman K. M. Lee
2018 conf
HCI (18)
Danni Chang, Carman K. M. Lee, Lo Kwok Leung
2018 conf
SOLI
Yaqiong Lv, Lei Tu, Carman K. M. Lee, Xin Tang
2018 J jnl
Ind. Manag. Data Syst.
Zhen Hong, Carman K. M. Lee, Linda Zhang
2018 J jnl
Appl. Soft Comput.
K. K. H. Ng, Carman K. M. Lee, Felix T. S. Chan, Yaqiong Lv
2018 conf
IEEM
Carman K. M. Lee, Kin Lok Keung, K. K. H. Ng, Daniel C. P. Lai
2018 J jnl
Ind. Manag. Data Syst.
Danping Lin, Carman K. M. Lee, Henry C. W. Lau, Yang Yang
2017 J jnl
Comput. Ind. Eng.
K. K. H. Ng, Carman K. M. Lee, Shuzhu Zhang, Kan Wu, William Ho
2017 conf
ICIC (1)
K. K. H. Ng, Carman K. M. Lee
2017 J jnl
Artif. Intell. Rev.
Shuzhu Zhang, Carman K. M. Lee, K. M. Yu, Henry C. W. Lau
2017 J jnl
Enterp. Inf. Syst.
Carman K. M. Lee, Catalin Mitrea, W. H. Ip, King Lun Choy, George T. S. Ho
2017 J jnl
Ind. Manag. Data Syst.
Carman K. M. Lee, Wing Bun Lee, Jay Lee
2016 J jnl
Expert Syst. Appl.
Linda L. Zhang, Carman K. M. Lee, Shuzhu Zhang
2016 J jnl
IEEE Trans Autom. Sci. Eng.
Kan Wu, Ning Zhao, Carman K. M. Lee
2016 J jnl
Ind. Manag. Data Syst.
Chengli Liu, Carman K. M. Lee, King Lun Choy
2015 B conf
SMC
Shuzhu Zhang, Carman K. M. Lee
2015 J jnl
Comput. Ind.
Carman K. M. Lee, Chloe Tan Ying Ru, Chui Ling Yeung, King Lun Choy, W. H. Ip
2015 conf
IEEM
K. K. H. Ng, M. Hau Man Tang, Carman K. M. Lee
2015 J jnl
Ind. Manag. Data Syst.
Carman K. M. Lee, C. Y. Chan, Sophie Ho, King Lun Choy, Andrew W. H. Ip
2015 J jnl
Expert Syst. J. Knowl. Eng.
George T. S. Ho, Henry C. W. Lau, King Lun Choy, Carman K. M. Lee, Cathy H. Y. Lam
2015 conf
IEEM
Carman K. M. Lee, Charlie L. Yeung, Mei Na Cheng
2015 J jnl
Eng. Appl. Artif. Intell.
Shuzhu Zhang, Carman K. M. Lee, Hing Kai Chan, King Lun Choy, Zhang Wu
2015 conf
IEEM
Danping Lin, Carman K. M. Lee, Jilin Yang
2014 J jnl
OR Spectr.
Zhen Hong, Carman K. M. Lee, Xiaofeng Nie
2014 J jnl
Ind. Manag. Data Syst.
Carman K. M. Lee, Danping Lin, Rohan Pasari
2013 J jnl
Decis. Support Syst.
Zhen Hong, Carman K. M. Lee
2013 J jnl
Expert Syst. Appl.
Cathy H. Y. Lam, King Lun Choy, George T. S. Ho, C. K. Kwong, Carman K. M. Lee
2013 J jnl
Eng. Appl. Artif. Intell.
Danping Lin, Carman K. M. Lee, William Ho
2012 J jnl
Expert Syst. Appl.
George T. S. Ho, W. H. Ip, Carman K. M. Lee, W. L. Mou
2011 conf
IEEM
Dwi Agustina, Carman K. M. Lee, Rajesh Piplani
2011 J jnl
Expert Syst. Appl.
Carman K. M. Lee, William Ho, George T. S. Ho, Henry C. W. Lau
2010 J jnl
Int. J. Serv. Technol. Manag.
Carman K. M. Lee, Henry C. W. Lau, S. K. Kwok, George T. S. Ho
2010 J jnl
OR Insight
William Ho, Carman K. M. Lee, George To Sum Ho
2010 J jnl
Comput. Ind.
Lianfeng (Linda) Zhang, Carman K. M. Lee, Qianli Xu
2009 J jnl
IEEE Trans. Syst. Man Cybern. Part A
Henry C. W. Lau, Cassandra X. H. Tang, B. P. K. Leung, Carman K. M. Lee, George T. S. Ho
2009 J jnl
Int. J. Manuf. Technol. Manag.
Henry C. W. Lau, Carman K. M. Lee, George T. S. Ho, Kit Fai Pun, King Lun Choy
2009 J jnl
Expert Syst. Appl.
Carman K. M. Lee, Henry C. W. Lau, George T. S. Ho, William Ho
2009 J jnl
Expert Syst. Appl.
Carman K. M. Lee, T. M. Chan
2009 J jnl
Expert Syst. Appl.
Henry C. W. Lau, George T. S. Ho, K. F. Chu, William Ho, Carman K. M. Lee
2008 J jnl
Expert Syst. Appl.
Henry C. W. Lau, E. N. M. Cheng, Carman K. M. Lee, George T. S. Ho
2008 J jnl
Ind. Manag. Data Syst.
George T. S. Ho, Henry C. W. Lau, Sai Ho Chung, Richard Y. K. Fung, Tak-Ming Chan, Carman K. M. Lee
2007 J jnl
Int. J. Comput. Appl. Technol.
George T. S. Ho, Henry C. W. Lau, Carman K. M. Lee, Andrew W. H. Ip
2007 J jnl
Int. J. Comput. Appl. Technol.
Carman K. M. Lee, George T. S. Ho, Henry C. W. Lau, Felix T. S. Chan
2007 J jnl
Int. J. Comput. Appl. Technol.
Henry C. W. Lau, George T. S. Ho, E. N. M. Cheng, Andrew Ning, Carman K. M. Lee
2007 conf
SoSE
Carman K. M. Lee
2007 J jnl
Int. J. Comput. Appl. Technol.
Henry C. W. Lau, Cassandra X. H. Tang, George T. S. Ho, Carman K. M. Lee
2006 J jnl
Expert Syst. Appl.
Carman K. M. Lee, George T. S. Ho, Henry C. W. Lau, K. M. Yu
2006 J jnl
Int. J. Comput. Integr. Manuf.
George T. S. Ho, Carman K. M. Lee, Henry C. W. Lau, Andrew W. H. Ip
2006 J jnl
Int. J. Inf. Technol. Manag.
George T. S. Ho, Henry C. W. Lau, Carman K. M. Lee, Andrew W. H. Ip, William Ho
2006 J jnl
IEEE Trans. Ind. Informatics
Henry C. W. Lau, W. T. Tsui, Carman K. M. Lee, George T. S. Ho, Andrew Ning
2006 J jnl
Int. J. Serv. Technol. Manag.
Henry C. W. Lau, George T. S. Ho, Andrew W. H. Ip, Carman K. M. Lee, Andrew Ning
2005 J jnl
Ind. Manag. Data Syst.
George T. S. Ho, Henry C. W. Lau, Carman K. M. Lee, Andrew W. H. Ip
2005 J jnl
Expert Syst. J. Knowl. Eng.
Henry C. W. Lau, Carman K. M. Lee, W. H. Ip, Felix T. S. Chan, Ricky W. K. Leung
redb/extractors/js_extractors/js_strings.py
← Index redb/extractors/js_extractors/js_strings.py python
import base64
import bisect
import inspect
import re
from datetime import datetime, timezone
from typing import Any

from redb.extractors.enum import Tag
from redb.extractors.js_extractor import JSExtractor
from redb.extractors.js_extractors.js_patterns import STRING_PATTERNS, line_offsets

# Local aliases for the compiled patterns this extractor uses. Defined and
# compiled exactly once in js_patterns.STRING_PATTERNS.
_HEX_STRING_RE = STRING_PATTERNS["hex_escape_seq"]
_UNICODE_STRING_RE = STRING_PATTERNS["unicode_escape_seq"]
_CHARCODE_RE = STRING_PATTERNS["charcode_call"]
_BASE64_STRING_RE = STRING_PATTERNS["base64_quoted"]
_CONCAT_STRING_RE = STRING_PATTERNS["concat_chain"]

# Tokeniser used inside _reconstruct_concat to pull each quoted part out of a
# matched concat chain. Compiled once at module load (was recompiled on every
# concat match before).
_CONCAT_TOKEN_RE = re.compile(r'["\']([^"\']*)["\']')


class JSStringsExtractor(JSExtractor):

    def __init__(
        self, filepath, log, exporters=None, index_prefix=None,
        known_benign=False, known_malicious=False, source=None, context=None,
    ):
        super().__init__(
            filepath, log, exporters, index_prefix,
            known_benign, known_malicious, source, context=context,
        )
        self.string_findings = None
        self.log.debug(inspect.currentframe().f_code.co_name)

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

    def _decode_hex_string(self, hex_str):
        """Decode \\x41\\x42 style hex strings."""
        try:
            # Remove \\x prefix and decode
            clean = hex_str.replace('\\x', '')
            return bytes.fromhex(clean).decode('utf-8', errors='replace')
        except Exception:
            return None

    def _decode_unicode_string(self, uni_str):
        """Decode \\u0041\\u0042 style unicode strings."""
        try:
            return uni_str.encode('utf-8').decode('unicode_escape')
        except Exception:
            return None

    def _decode_charcode(self, charcode_str):
        """Decode String.fromCharCode(72, 101, 108, ...) sequences."""
        try:
            codes = [int(c.strip()) for c in charcode_str.split(',') if c.strip().isdigit()]
            return ''.join(chr(c) for c in codes if 0 <= c <= 0x10FFFF)
        except Exception:
            return None

    def _decode_base64(self, b64_str):
        """Attempt to decode base64 string."""
        try:
            decoded = base64.b64decode(b64_str)
            # Check if result is printable text
            text = decoded.decode('utf-8', errors='strict')
            # Only return if it looks like text (>80% printable)
            printable = sum(1 for c in text if c.isprintable() or c in '\n\r\t')
            if printable / len(text) > 0.8:
                return text
        except Exception:
            pass
        return None

    def _reconstruct_concat(self, concat_match):
        """Reconstruct concatenated string parts."""
        try:
            parts = _CONCAT_TOKEN_RE.findall(concat_match)
            return ''.join(parts)
        except Exception:
            return None

    def _find_line_number(self, match_start):
        """1-indexed line number for `match_start`, looked up in O(log L) via
        bisect over `self._line_offsets` (built once per extract() call).

        Replaces the historical `self.js_source[:match_start].count('\\n') + 1`
        which was O(N) per call and quadratic across all matches in a sample.
        """
        return bisect.bisect_right(self._line_offsets, match_start)

    def _scan_text(self, text):
        """Run every encoded-string pattern over `text` and return a list of
        finding dicts. Stateless apart from the per-call `_line_offsets` cache,
        which `_find_line_number` reads — callers must reset it before invoking
        this so line numbers reference the text being scanned, not the previous
        one.
        """
        findings = []

        # Hex-encoded strings
        for m in _HEX_STRING_RE.finditer(text):
            raw = m.group()
            decoded = self._decode_hex_string(raw)
            if decoded and len(decoded) >= 4:
                findings.append({
                    'string': decoded[:4000],
                    'string_raw': raw[:4000],
                    'string_encoding': 'hex',
                    'string_offset': self._find_line_number(m.start()),
                    'string_length': len(decoded),
                    'string_raw_length': len(raw),
                    'string_entropy': self._calculate_text_entropy(decoded),
                })

        # Unicode-encoded strings
        for m in _UNICODE_STRING_RE.finditer(text):
            raw = m.group()
            decoded = self._decode_unicode_string(raw)
            if decoded and len(decoded) >= 3:
                findings.append({
                    'string': decoded[:4000],
                    'string_raw': raw[:4000],
                    'string_encoding': 'unicode',
                    'string_offset': self._find_line_number(m.start()),
                    'string_length': len(decoded),
                    'string_raw_length': len(raw),
                    'string_entropy': self._calculate_text_entropy(decoded),
                })

        # String.fromCharCode sequences
        for m in _CHARCODE_RE.finditer(text):
            raw = m.group()
            decoded = self._decode_charcode(m.group(1))
            if decoded and len(decoded) >= 4:
                findings.append({
                    'string': decoded[:4000],
                    'string_raw': raw[:4000],
                    'string_encoding': 'charcode',
                    'string_offset': self._find_line_number(m.start()),
                    'string_length': len(decoded),
                    'string_raw_length': len(raw),
                    'string_entropy': self._calculate_text_entropy(decoded),
                })

        # Base64-encoded strings
        for m in _BASE64_STRING_RE.finditer(text):
            raw = m.group(0)
            b64_val = m.group(1)
            decoded = self._decode_base64(b64_val)
            if decoded and len(decoded) >= 10:
                findings.append({
                    'string': decoded[:4000],
                    'string_raw': raw[:4000],
                    'string_encoding': 'base64',
                    'string_offset': self._find_line_number(m.start()),
                    'string_length': len(decoded),
                    'string_raw_length': len(raw),
                    'string_entropy': self._calculate_text_entropy(decoded),
                })

        # Concatenated strings (reassembled)
        for m in _CONCAT_STRING_RE.finditer(text):
            raw = m.group()
            reconstructed = self._reconstruct_concat(raw)
            if reconstructed and len(reconstructed) >= 20:
                findings.append({
                    'string': reconstructed[:4000],
                    'string_raw': raw[:4000],
                    'string_encoding': 'concat',
                    'string_offset': self._find_line_number(m.start()),
                    'string_length': len(reconstructed),
                    'string_raw_length': len(raw),
                    'string_entropy': self._calculate_text_entropy(reconstructed),
                })

        return findings

    def extract(self):
        src = self.js_source
        if not src:
            return None

        # Pass 1: raw source. _line_offsets is keyed off whichever text is
        # currently being scanned so _find_line_number resolves to that text.
        self._line_offsets = line_offsets(src)
        findings = self._scan_text(src)

        # Pass 2: deobfuscated text, when the deobfuscator produced something
        # meaningfully different. Same patterns, but a different surface — for
        # samples where the encoded payload is hidden behind an outer wrapper
        # (e.g. array.join() + eval in Vjw0rm/WSH-RAT) only this pass yields
        # any rows at all.
        deobf_text, _ = self._context.deobfuscated
        if deobf_text and deobf_text != src:
            self._line_offsets = line_offsets(deobf_text)
            findings.extend(self._scan_text(deobf_text))

        if not findings:
            return None

        # Deduplicate by decoded string value (raw pass wins on collision: it
        # comes first in `findings`). A string that surfaces only in the
        # deobfuscated text still gets persisted, which is the whole point of
        # the second pass.
        seen_values = set()
        deduped = []
        for f in findings:
            val_key = f['string'][:100]
            if val_key not in seen_values:
                seen_values.add(val_key)
                deduped.append(f)

        self.string_findings = deduped[:500]  # Limit per file
        # Publish to the shared context so post-loop consumers (notably the IOC
        # plumbing in workers.py) can scrape the decoded strings without
        # holding a reference to this extractor instance.
        self._context.decoded_strings = self.string_findings
        return self.string_findings

    def prepare_export_data(self, exporter_type: str) -> Any:
        if exporter_type == "ClickHouseExporter":
            if not self.string_findings:
                return None

            data = []
            for f in self.string_findings:
                data.append([
                    self.sha256,
                    f['string'],
                    f['string_raw'],
                    f['string_encoding'],
                    f['string_offset'],
                    f['string_length'],
                    f['string_raw_length'],
                    f['string_entropy'],
                ])

            column_names = [
                "sha256",
                "string",
                "string_raw",
                "string_encoding",
                "string_offset",
                "string_length",
                "string_raw_length",
                "string_entropy",
            ]

            column_type_names = [
                "FixedString(64)",
                "String",
                "String",
                "LowCardinality(String)",
                "UInt64",
                "UInt32",
                "UInt32",
                "Float32",
            ]

            return (data, column_names, column_type_names)

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