cmake_minimum_required(VERSION 3.14)

if(POLICY CMP0135)
  cmake_policy(SET CMP0135 NEW)
endif()

project(CycleszEngine VERSION 3.0.0 LANGUAGES CXX C)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(FetchContent)
include_directories(include)

# -------------------------------------------------------------------------
# 1. Capstone Engine (Disassembler / Decoder)
# -------------------------------------------------------------------------
find_library(CAPSTONE_LIB capstone HINTS /opt/homebrew/lib /usr/local/lib C:/vcpkg/installed/x64-windows/lib C:/vcpkg/installed/arm64-windows/lib)
find_path(CAPSTONE_INCLUDE capstone/capstone.h HINTS /opt/homebrew/include /usr/local/include C:/vcpkg/installed/x64-windows/include C:/vcpkg/installed/arm64-windows/include)

if(CAPSTONE_LIB AND CAPSTONE_INCLUDE)
    message(STATUS "[+] Capstone Library Found Locally: ${CAPSTONE_LIB}")
    include_directories(${CAPSTONE_INCLUDE})
    add_compile_definitions(CYCLESZ_USE_CAPSTONE)
    set(CAPSTONE_TARGET ${CAPSTONE_LIB})
else()
    message(STATUS "[+] Fetching Capstone 5.0.1 Zip archive via CMake FetchContent...")
    set(CAPSTONE_BUILD_STATIC ON CACHE BOOL "" FORCE)
    set(CAPSTONE_BUILD_SHARED OFF CACHE BOOL "" FORCE)
    set(CAPSTONE_BUILD_TESTS OFF CACHE BOOL "" FORCE)
    set(CAPSTONE_BUILD_CSTACK OFF CACHE BOOL "" FORCE)

    FetchContent_Declare(
        capstone
        URL https://github.com/capstone-engine/capstone/archive/refs/tags/5.0.1.zip
        DOWNLOAD_EXTRACT_TIMESTAMP TRUE
    )
    FetchContent_MakeAvailable(capstone)

    if(TARGET capstone OR TARGET capstone-static)
        message(STATUS "[+] Capstone 5.0.1 Successfully Fetched & Built!")
        add_compile_definitions(CYCLESZ_USE_CAPSTONE)
        if(TARGET capstone-static)
            set(CAPSTONE_TARGET capstone-static)
        else()
            set(CAPSTONE_TARGET capstone)
        endif()
    endif()
endif()

# -------------------------------------------------------------------------
# 2. AsmJit (JIT Code Emitter)
# -------------------------------------------------------------------------
message(STATUS "[+] Auto-Fetching AsmJit JIT Emitter Library...")
set(ASMJIT_STATIC ON CACHE BOOL "" FORCE)
FetchContent_Declare(
    asmjit
    URL https://github.com/asmjit/asmjit/archive/refs/heads/master.zip
    DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
FetchContent_MakeAvailable(asmjit)

if(TARGET asmjit)
    message(STATUS "[+] AsmJit Library Successfully Fetched & Built!")
    add_compile_definitions(CYCLESZ_USE_ASMJIT)
    set(ASMJIT_TARGET asmjit)
endif()

# -------------------------------------------------------------------------
# 3. PolyHook v2 Detour Engine
# -------------------------------------------------------------------------
add_compile_definitions(CYCLESZ_USE_POLYHOOK)

# -------------------------------------------------------------------------
# 4. mimalloc (High-Performance & Safe Dual-Mapping W^X Allocator)
# -------------------------------------------------------------------------
message(STATUS "[+] Auto-Fetching mimalloc Memory Allocator...")
set(MI_BUILD_STATIC ON CACHE BOOL "" FORCE)
set(MI_BUILD_SHARED OFF CACHE BOOL "" FORCE)
set(MI_BUILD_TESTS OFF CACHE BOOL "" FORCE)
FetchContent_Declare(
    mimalloc
    URL https://github.com/microsoft/mimalloc/archive/refs/tags/v2.1.2.zip
    DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
FetchContent_MakeAvailable(mimalloc)

if(TARGET mimalloc-static OR TARGET mimalloc)
    message(STATUS "[+] mimalloc Library Successfully Fetched & Built!")
    add_compile_definitions(CYCLESZ_USE_MIMALLOC)
    if(TARGET mimalloc-static)
        set(MIMALLOC_TARGET mimalloc-static)
    else()
        set(MIMALLOC_TARGET mimalloc)
    endif()
endif()

# -------------------------------------------------------------------------
# 5. Build Targets & Executables
# -------------------------------------------------------------------------
add_executable(real_world_demo examples/real_world_demo.cpp)
add_executable(live_process_injection_demo examples/live_process_injection_demo.cpp)
add_executable(dype_full_stack_demo examples/dype_full_stack_demo.cpp)
add_executable(dye_flow_demo examples/dye_flow_demo.cpp)
add_executable(dye_vmprotect_demo examples/dye_vmprotect_demo.cpp)
add_executable(dye_visor_stress_test examples/dye_visor_stress_test.cpp)
add_executable(dye_oep_finder_app examples/dye_oep_finder_app.cpp)
add_executable(scan_system examples/scan_system.cpp)

if(WIN32)
    add_executable(target_msgbox_app examples/target_msgbox_app.cpp)
    add_executable(target_large_trace_app examples/target_large_trace_app.cpp)
    add_executable(target_heavy_deadlock_app examples/target_heavy_deadlock_app.cpp)
    add_executable(target_rop_simulation_app examples/target_rop_simulation_app.cpp)
    add_executable(target_cpuid_demo_app examples/target_cpuid_demo_app.cpp)
    add_executable(target_anomaly_30s_demo examples/target_anomaly_30s_demo.cpp)
    add_library(dye_ext SHARED 
        extensions/dye_ext/dye_ext.cpp 
        extensions/dye_ext/dye_ext_cmd_addr.cpp 
        extensions/dye_ext/dye_ext_cmd_audit.cpp 
        extensions/dye_ext/dye_ext_cmd_rwx.cpp
        extensions/dye_ext/dye_ext_cmd_scan.cpp
        extensions/dye_ext/dye_ext.def
    )
endif()

add_executable(test_cyclesz tests/test_cyclesz.cpp)
add_executable(test_tcm_dye tests/test_tcm_dye.cpp)
add_executable(test_didecode tests/test_didecode.cpp)
add_executable(test_production_stack tests/test_production_stack.cpp)
add_executable(test_cyclesz_all tests/test_cyclesz_all.cpp)
add_executable(test_cfg_builder tests/test_cfg_builder.cpp)
add_executable(test_wsw_atom_detector tests/test_wsw_atom_detector.cpp)
add_executable(test_stk_stack_isolation tests/test_stk_stack_isolation.cpp)
add_executable(test_dype_enclave_engine tests/test_dype_enclave_engine.cpp)
add_executable(test_mov_ss_fault_handler tests/test_mov_ss_fault_handler.cpp)
add_executable(test_oep_finder tests/test_oep_finder.cpp)
add_executable(test_pdata_kcfg tests/test_pdata_kcfg.cpp)
add_executable(test_vad_tree_scanner tests/test_vad_tree_scanner.cpp)
add_executable(test_dr7_teb_storage tests/test_dr7_teb_storage.cpp)
add_executable(test_advanced_engine_suite tests/test_advanced_engine_suite.cpp)
add_executable(test_execution_anomaly tests/test_execution_anomaly.cpp)

set(ALL_PROD_LIBS "")
if(CAPSTONE_TARGET)
    list(APPEND ALL_PROD_LIBS ${CAPSTONE_TARGET})
endif()
if(ASMJIT_TARGET)
    list(APPEND ALL_PROD_LIBS ${ASMJIT_TARGET})
endif()
if(MIMALLOC_TARGET)
    list(APPEND ALL_PROD_LIBS ${MIMALLOC_TARGET})
endif()

if(ALL_PROD_LIBS)
    target_link_libraries(real_world_demo PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(live_process_injection_demo PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(dype_full_stack_demo PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(dye_flow_demo PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(dye_vmprotect_demo PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(dye_visor_stress_test PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(dye_oep_finder_app PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(scan_system PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(dye_ext PRIVATE ${ALL_PROD_LIBS} dbgeng.lib)
    target_link_libraries(test_didecode PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_production_stack PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_cyclesz_all PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_cfg_builder PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_wsw_atom_detector PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_stk_stack_isolation PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_dype_enclave_engine PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_mov_ss_fault_handler PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_oep_finder PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_pdata_kcfg PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_vad_tree_scanner PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_dr7_teb_storage PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_advanced_engine_suite PRIVATE ${ALL_PROD_LIBS})
    target_link_libraries(test_execution_anomaly PRIVATE ${ALL_PROD_LIBS})
    if(WIN32)
        target_link_libraries(target_rop_simulation_app PRIVATE ${ALL_PROD_LIBS})
    endif()
endif()

# -------------------------------------------------------------------------
# 6. CTest Test Runner
# -------------------------------------------------------------------------
enable_testing()
add_test(NAME test_cyclesz COMMAND test_cyclesz)
add_test(NAME test_tcm_dye COMMAND test_tcm_dye)
add_test(NAME test_didecode COMMAND test_didecode)
add_test(NAME test_production_stack COMMAND test_production_stack)
add_test(NAME test_cyclesz_all COMMAND test_cyclesz_all)
add_test(NAME test_cfg_builder COMMAND test_cfg_builder)
add_test(NAME test_wsw_atom_detector COMMAND test_wsw_atom_detector)
add_test(NAME test_stk_stack_isolation COMMAND test_stk_stack_isolation)
add_test(NAME test_dype_enclave_engine COMMAND test_dype_enclave_engine)
add_test(NAME test_mov_ss_fault_handler COMMAND test_mov_ss_fault_handler)
add_test(NAME test_oep_finder COMMAND test_oep_finder)
add_test(NAME test_pdata_kcfg COMMAND test_pdata_kcfg)
add_test(NAME test_vad_tree_scanner COMMAND test_vad_tree_scanner)
add_test(NAME test_dr7_teb_storage COMMAND test_dr7_teb_storage)
add_test(NAME test_advanced_engine_suite COMMAND test_advanced_engine_suite)
add_test(NAME test_execution_anomaly COMMAND test_execution_anomaly)
