Jae Won Lee

66 papers A* 2B 3C 7Misc 1Journal 42Unranked 11
YearRankTypeTitle / Venue / Authors
2026 J jnl
Comput. Stat. Data Anal.
Lutz Edler, Erricos John Kontoghiorghes, Jae Won Lee, Martina Mittlböck, Joyce C. Niland, F. Javier Rubio
2026 A* conf
AAAI
Min Chan Kim, Yeonkyung Kim, Jae Won Lee, Ki Hwan Kim, Ji Woo Kwak, Jae Hong Park
2023 J jnl
BioData Min.
Jiyoon Park, Jae Won Lee, Mira Park
2023 J jnl
IEEE Trans. Veh. Technol.
Jae Won Lee, Chung Gu Kang
2021 J jnl
IEEE Access
Jae Won Lee, Minsig Han, Minjoong Rim, Chung Gu Kang
2021 J jnl
IEEE Access
Jae Won Lee, Minjoong Rim, Chung Gu Kang
2021 J jnl
Sensors
Minsig Han, Jae Won Lee, Minjoong Rim, Chung Gu Kang
2019 conf
CCNC
Jae Won Lee, Minsig Han, Chung Gu Kang, Minjoong Rim
2019 J jnl
Appl. Intell.
Yoojeong Song, Jae Won Lee, Jongwoo Lee
2019 J jnl
IEEE Trans. Wirel. Commun.
Yongin Choi, Jae Won Lee, Minjoong Rim, Chung Gu Kang
2019 conf
ICUFN
Jae Won Lee, Chung Gu Kang
2019 C conf
APCC
Jae Won Lee, Chung Gu Kang
2019 C conf
ICCE
Jae Min Kim, Jae Won Lee, Kyungsoo Lee, Junho Huh
2019 J jnl
Comput. Stat. Data Anal.
Ming-Yen Cheng, Michele Guindani, Jae Won Lee, Yi Li, Catherine Chunling Liu
2019 conf
CCNC
Minsig Han, Jae Won Lee, Chung Gu Kang, Minjoong Rim
2019 J jnl
Comput. Stat. Data Anal.
Byeongchan Choi, Jae Won Lee
2018 conf
DySPAN
Minsig Han, Jae Won Lee, Chung Gu Kang, Minjoong Rim
2018 J jnl
Axioms
Dae Ho Jin, Jae Won Lee
2018 conf
ICOIN
Jae Won Lee, Chung Gu Kang, Minjoong Rim
2017 J jnl
Int. J. Data Min. Bioinform.
Hyo Jung Lee, Jae Won Lee, Hee Jeong Yoo, Seohoon Jin, Mira Park
2017 J jnl
Comput. Stat. Data Anal.
Jae Won Lee, Nan Lin, Martina Mittlböck
2017 J jnl
Symmetry
Dae Won Yoon, Dong-Soo Kim, Young Ho Kim, Jae Won Lee
2017 J jnl
Symmetry
Dae Won Yoon, Dong-Soo Kim, Young Ho Kim, Jae Won Lee
2017 J jnl
Model. Assist. Stat. Appl.
Insuk Sohn, Sujong Kim, Jae Won Lee, Ja-Yong Koo, Junsu Ko
2016 conf
BIBM
Hyo Jung Lee, Jae Won Lee, Seohoon Jin, Hee Jeong Yoo, Mira Park
2016 J jnl
Symmetry
Dae Won Yoon, Jae Won Lee
2015 J jnl
J. Biomed. Informatics
Dae-Soon Son, Donghyuk Lee, Kyusang Lee, Sin-Ho Jung, TaeJin Ahn, EunJin Lee, Insuk Sohn, Jongsuk Chung, Woong-Yang Park, Nam Huh, Jae Won Lee
2013 J jnl
IEICE Electron. Express
KeeChan Park, Sang-Yun Kim, JaeHyeong Jang, SooHo Cho, Seung-O Kim, Jae Won Lee, Sangyeon Kim, HwanSool Oh, Jintae Kim
2012 J jnl
J. Appl. Math.
Dae Ho Jin, Jae Won Lee
2012 J jnl
J. Appl. Math.
DaeHo H. Jin, Jae Won Lee
2012 J jnl
Inf. Technol. Control.
Heemin Park, Jae Won Lee
2011 J jnl
Int. J. Math. Math. Sci.
Jae Won Lee
2011 J jnl
Int. J. Math. Math. Sci.
Jae Won Lee
2010 J jnl
Comput. Stat.
Byeong Yeob Choi, Ho Kim, Un Yeong Go, Jong-Hyeon Jeong, Jae Won Lee
2009 J jnl
Comput. Stat. Data Anal.
Lutz Edler, Jae Won Lee, Martina Mittlböck, Joyce C. Niland, Norbert Victor
2009 J jnl
Comput. Stat. Data Anal.
Insuk Sohn, JooYong Shim, Changha Hwang, Sujong Kim, Jae Won Lee
2009 J jnl
Comput. Stat. Data Anal.
JooYong Shim, Insuk Sohn, Sujong Kim, Jae Won Lee, Paul E. Green, Changha Hwang
2008 J jnl
OR Spectr.
Jae Won Lee, Myoungshic Jhun, Jong Young Kim, Jung Bok Lee
2008 J jnl
Comput. Stat. Data Anal.
Changyi Park, Ja-Yong Koo, Sujong Kim, Insuk Sohn, Jae Won Lee
2008 J jnl
Comput. Stat. Data Anal.
Insuk Sohn, Sujong Kim, Changha Hwang, Jae Won Lee
2008 J jnl
Bioinform.
Hyungjun Cho, Yang-jin Kim, Hee Jung Jung, Sang-Won Lee, Jae Won Lee
2008 J jnl
Comput. Stat. Data Anal.
Changyi Park, Ja-Yong Koo, Peter T. Kim, Jae Won Lee
2007 J jnl
IEEE Trans. Syst. Man Cybern. Part A
Jae Won Lee, Jonghun Park, Jangmin O, Jongwoo Lee, Euyseok Hong
2007 J jnl
Comput. Stat. Data Anal.
Mira Park, Jae Won Lee, Choongrak Kim
2006 conf
ISNN (2)
Byoung-Doo Kang, Jae Won Lee, Jong-Ho Kim, O-Hwa Kwon, Chi-Young Seong, Se-Myung Park, Sang-Kyoon Kim
2006 J jnl
Inf. Sci.
Jangmin O, Jongwoo Lee, Jae Won Lee, Byoung-Tak Zhang
2006 C conf
HPCC
Jongwoo Lee, Sung Dong Kim, Jae Won Lee, Jangmin O
2006 J jnl
BMC Bioinform.
Seo Young Kim, Jae Won Lee, Jong Sung Bae
2006 conf
ISNN (2)
Jong-Ho Kim, Jae Won Lee, Byoung-Doo Kang, O-Hwa Kwon, Chi-Young Seong, Sang-Kyoon Kim, Se-Myung Park
2006 conf
ISNN (2)
Jae Won Lee, Soo Beom Park, Sang-Kyoon Kim
2006 J jnl
Electron. Commer. Res. Appl.
Jae Won Lee, Jae Kyu Lee
2006 J jnl
Bioinform.
Ja-Yong Koo, Insuk Sohn, Sujong Kim, Jae Won Lee
2005 J jnl
Comput. Stat. Data Anal.
Jae Won Lee, Jung Bok Lee, Mira Park, Seuck Heun Song
2005 J jnl
IEICE Trans. Inf. Syst.
Jangmin O, Jongwoo Lee, Jae Won Lee, Byoung-Tak Zhang
2005 conf
WEC (2)
Seo Young Kim, Jae Won Lee, Jong Sung Bae
2005 Misc conf
IRI
Jae Won Lee, Sung Hwa Jung, Sung Chang Park, Young Joong Lee, Young Chul Jang
2004 J jnl
Pattern Recognit. Lett.
Soo Beom Park, Jae Won Lee, Sang-Kyoon Kim
2004 conf
ECML
Jangmin O, Jae Won Lee, Jongwoo Lee, Byoung-Tak Zhang
2004 C conf
IDEAL
Jangmin O, Jae Won Lee, Sung-Bae Park, Byoung-Tak Zhang
2003 C conf
ICEC
Jae Kyu Lee, Jae Won Lee
2002 C conf
DEXA
Jae Won Lee, Jangmin O
2002 C conf
DEXA
Sung Dong Kim, Jae Won Lee, Jongwoo Lee, Jinseok Chae
2002 B conf
PRICAI
Kyu Baek Hwang, Jae Won Lee, Seung-Woo Chung, Byoung-Tak Zhang
2002 B conf
PRICAI
Jae Won Lee, Sung Dong Kim
2002 A* conf
ICML
Jangmin O, Jae Won Lee, Byoung-Tak Zhang
2002 B conf
PRICAI
Jeong Ho Chang, Jae Won Lee, Yuseop Kim, Byoung-Tak Zhang
redb/extractors/decompiler/DecompileAPK.py
← Index redb/extractors/decompiler/DecompileAPK.py python
"""APK Code Analysis Extractor.

Decompiles and disassembles APK DEX bytecode at the method level,
producing per-method content and reference records analogous to
the Binary Ninja code_binja_* tables.

Uses androguard + JADX + apktool to replicate Binary Ninja analysis
depth for Android applications.
"""

import gc
import hashlib
import inspect
import logging
import os
import threading
import time
from datetime import datetime, timezone
from typing import Any, Dict, Optional

from redb.extractors.decompiler.apk.analyzer import APKCodeAnalyzer
from redb.extractors.enum import Tag
from redb.extractors.extractor import Extractor


class DecompileAPK(Extractor):
    """APK code analysis extractor — produces multi-table ClickHouse export.

    Follows the same pattern as DecompileBinja for consistency.
    """

    def __init__(
        self,
        filepath,
        log,
        exporters=None,
        index_prefix=None,
        known_benign=False,
        known_malicious=False,
        filetype=None,
        decompile_modules=None,
    ):
        super().__init__(
            filepath,
            log,
            exporters,
            index_prefix,
            known_benign=known_benign,
            known_malicious=known_malicious,
        )
        self.log.debug(inspect.currentframe().f_code.co_name)
        self.analysis_results = None
        self.analyzer = None
        self.filetype = filetype or "apk"
        self.decompile_modules = decompile_modules or {"all"}

        try:
            self.APK_DECOMPILE_TIMEOUT = int(
                os.getenv("APK_DECOMPILE_TIMEOUT", "600")
            )
        except ValueError:
            self.log.warning(
                "Invalid APK_DECOMPILE_TIMEOUT value, using default of 600 seconds"
            )
            self.APK_DECOMPILE_TIMEOUT = 600

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.cleanup_run()

    def calculate_md5(self, input_str):
        """Calculate MD5 hash of a string."""
        return hashlib.md5(input_str.encode("utf-8")).hexdigest()

    def cleanup_run(self):
        """Clean up after analysis."""
        try:
            if self.analyzer:
                self.analyzer.cleanup()
                self.analyzer = None
            gc.collect()
        except Exception as e:
            self.log.error(f"Error in cleanup: {e}")

    def analyze_apk(self) -> Optional[Dict[str, Any]]:
        """Run APK code analysis and return results."""
        self.log.debug("Starting APK code analysis")
        try:
            self.analyzer = APKCodeAnalyzer(
                filepath=self.filepath,
                timeout=self.APK_DECOMPILE_TIMEOUT,
                log=self.log,
                decompile_modules=self.decompile_modules,
            )
            results = self.analyzer.extract()
            return results
        except Exception as e:
            self.log.error(f"Error in APK code analysis: {e}")
            import traceback
            self.log.error(f"Traceback: {traceback.format_exc()}")
            return None
        finally:
            self.cleanup_run()

    def extract(self):
        """Extract and process all analysis results.

        Uses daemon thread with timeout, same pattern as DecompileBinja.
        """
        self.log.debug(inspect.currentframe().f_code.co_name)

        extraction_completed = False
        extraction_result = False
        extraction_error = None

        def do_extraction():
            nonlocal extraction_completed, extraction_result, extraction_error
            try:
                results = self.analyze_apk()
                if not results:
                    extraction_result = False
                else:
                    self.analysis_results = results
                    self.analysis_results["sha256"] = self.sha256
                    self.analysis_results["sha1"] = self.sha1
                    self.analysis_results["md5"] = self.md5
                    extraction_result = True
            except Exception as e:
                extraction_error = e
                extraction_result = False
            finally:
                extraction_completed = True

        extraction_thread = threading.Thread(target=do_extraction)
        extraction_thread.daemon = True
        extraction_thread.start()

        start_time = time.time()
        while (
            not extraction_completed
            and (time.time() - start_time) < self.APK_DECOMPILE_TIMEOUT
        ):
            time.sleep(1)

        if not extraction_completed:
            self.log.error(
                f"APK extraction timed out after {self.APK_DECOMPILE_TIMEOUT} seconds"
            )
            self.cleanup_run()
            return None

        if extraction_error:
            self.log.error(f"Error in APK extraction: {extraction_error}")
            return None

        return self.analysis_results if extraction_result else None

    def prepare_export_data(self, exporter_type: str) -> Any:
        """Prepare data for database export."""
        self.log.debug(inspect.currentframe().f_code.co_name)
        if not self.analysis_results:
            return None

        if exporter_type == "ClickHouseExporter":
            now = datetime.now(timezone.utc)
            export = {"multi_table": True}

            # Table 1: Decompiled method content
            if self.analysis_results.get("decompiled_content"):
                export["decompiled_content"] = {
                    "table": "code_apk_decompiled_methods_content",
                    "data": [
                        [
                            f["decompiled_method_hash"],
                            f["decompiled_method"],
                            f.get("decompiled_method_type", "UNKNOWN"),
                            1 if f.get("decompiled_has_string_encryption") else 0,
                            1 if f.get("decompiled_has_reflection_calls") else 0,
                            1 if f.get("decompiled_excessive_goto_count") else 0,
                            now,
                        ]
                        for f in self.analysis_results["decompiled_content"]
                    ],
                    "column_names": [
                        "decompiled_method_hash",
                        "decompiled_method",
                        "decompiled_method_type",
                        "decompiled_has_string_encryption",
                        "decompiled_has_reflection_calls",
                        "decompiled_excessive_goto_count",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "String",
                        "Enum8('USER'=1, 'LIBRARY'=2, 'UNKNOWN'=5)",
                        "UInt8",
                        "UInt8",
                        "UInt8",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Table 2: Decompiled method references
            if self.analysis_results.get("decompiled_refs"):
                export["decompiled_refs"] = {
                    "table": "code_apk_decompiled_methods_references",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            f["decompiled_method_hash"],
                            f.get("smali_method_hash"),
                            f.get("decompiled_class_name", ""),
                            f.get("decompiled_method_name", ""),
                            f.get("decompiled_method_signature", ""),
                            f.get("decompiled_method_prototype", ""),
                            f.get("functions_caller", []),
                            f.get("functions_call", []),
                            now,
                        ]
                        for f in self.analysis_results["decompiled_refs"]
                    ],
                    "column_names": [
                        "sha256",
                        "decompiled_method_hash",
                        "smali_method_hash",
                        "decompiled_class_name",
                        "decompiled_method_name",
                        "decompiled_method_signature",
                        "decompiled_method_prototype",
                        "functions_caller",
                        "functions_call",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "FixedString(64)",
                        "Nullable(FixedString(64))",
                        "LowCardinality(String)",
                        "LowCardinality(String)",
                        "String",
                        "String",
                        "Array(String)",
                        "Array(String)",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Table 3: Smali method content
            if self.analysis_results.get("smali_content"):
                export["smali_content"] = {
                    "table": "code_apk_smali_methods_content",
                    "data": [
                        [
                            f["smali_method_hash"],
                            f["smali_method"],
                            f.get("smali_method_type", "UNKNOWN"),
                            f.get("smali_instructions_count", 0),
                            f.get("smali_register_count", 0),
                            1 if f.get("smali_has_string_encryption") else 0,
                            1 if f.get("smali_has_reflection_calls") else 0,
                            1 if f.get("smali_excessive_goto_count") else 0,
                            f.get("smali_flattened_score", 0.0),
                            f.get("smali_mba_score", 0.0),
                            now,
                        ]
                        for f in self.analysis_results["smali_content"]
                    ],
                    "column_names": [
                        "smali_method_hash",
                        "smali_method",
                        "smali_method_type",
                        "smali_instructions_count",
                        "smali_register_count",
                        "smali_has_string_encryption",
                        "smali_has_reflection_calls",
                        "smali_excessive_goto_count",
                        "smali_flattened_score",
                        "smali_mba_score",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "String",
                        "Enum8('USER'=1, 'LIBRARY'=2, 'UNKNOWN'=5)",
                        "UInt32",
                        "UInt16",
                        "UInt8",
                        "UInt8",
                        "UInt8",
                        "Float64",
                        "Float64",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Table 4: Smali method references
            if self.analysis_results.get("smali_refs"):
                export["smali_refs"] = {
                    "table": "code_apk_smali_methods_references",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            f["smali_method_hash"],
                            f.get("decompiled_method_hash"),
                            f.get("smali_class_name", ""),
                            f.get("smali_method_name", ""),
                            f.get("smali_method_signature", ""),
                            now,
                        ]
                        for f in self.analysis_results["smali_refs"]
                    ],
                    "column_names": [
                        "sha256",
                        "smali_method_hash",
                        "decompiled_method_hash",
                        "smali_class_name",
                        "smali_method_name",
                        "smali_method_signature",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "FixedString(64)",
                        "Nullable(FixedString(64))",
                        "LowCardinality(String)",
                        "LowCardinality(String)",
                        "String",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Table 5: Method similarity metrics (content-based fuzzy matching)
            if self.analysis_results.get("similarity_metrics"):
                export["method_similarity_metrics"] = {
                    "table": "code_apk_method_similarity_metrics",
                    "data": [
                        [
                            f["smali_method_hash"],
                            f.get("ssdeep_smali"),
                            f.get("tlsh_smali"),
                            f.get("ssdeep_smali_normalized"),
                            f.get("tlsh_smali_normalized"),
                            f.get("minhash", []),
                            now,
                        ]
                        for f in self.analysis_results["similarity_metrics"]
                    ],
                    "column_names": [
                        "smali_method_hash",
                        "ssdeep_smali",
                        "tlsh_smali",
                        "ssdeep_smali_normalized",
                        "tlsh_smali_normalized",
                        "minhash",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "Nullable(String)",
                        "Nullable(FixedString(72))",
                        "Nullable(String)",
                        "Nullable(FixedString(72))",
                        "Array(UInt8)",
                        "DateTime64(3, 'UTC')",
                    ],
                }

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

            # Table 6: Strings — reuse code_binja_strings_raw for cross-format correlation
            # DEX strings are MUTF-8; string_raw = string since no encoding difference
            if self.analysis_results.get("strings"):
                export["strings_raw"] = {
                    "table": "code_binja_strings_raw",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            s["string"],
                            s["string"],  # string_raw = string (MUTF-8 decoded to UTF-8)
                            s.get("string_encoding", "UTF8"),
                            s.get("string_offset", 0),
                            s.get("string_length", len(s["string"])),
                            s.get("string_length", len(s["string"])),  # string_raw_length = string_length
                            s.get("string_entropy", 0.0),
                        ]
                        for s in self.analysis_results["strings"]
                    ],
                    "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",
                    ],
                }

            # Table 7: Analysis errors
            if self.analysis_results.get("analysis_errors"):
                export["analysis_errors"] = {
                    "table": "code_apk_analysis_errors",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            f.get("class_name"),
                            f.get("method_name"),
                            f.get("error_location", "unknown"),
                            f.get("error_message", ""),
                            f.get("error_type", "unknown"),
                            self.calculate_md5(
                                f"{f.get('error_message', '')}"
                                f"{f.get('class_name', '')}"
                                f"{f.get('method_name', '')}"
                                f"{f.get('error_location', 'unknown')}"
                            ),
                            "new",
                            now,
                        ]
                        for f in self.analysis_results["analysis_errors"]
                    ],
                    "column_names": [
                        "sha256",
                        "class_name",
                        "method_name",
                        "error_location",
                        "error_message",
                        "error_type",
                        "error_hash",
                        "status",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "Nullable(String)",
                        "Nullable(String)",
                        "LowCardinality(String)",
                        "Nullable(String)",
                        "Nullable(String)",
                        "FixedString(32)",
                        "Enum8('new'=1, 'investigating'=2, 'fixed'=3, 'wontfix'=4)",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            return export

        return None

    def tag(self) -> str:
        """Return the tag for this extractor."""
        return Tag.APK_DECOMPILED.value

    def get_clickhouse_table(self) -> str:
        """Not used directly as we're handling multiple tables."""
        pass