### Install WiX Toolset and Extensions Source: https://github.com/ap3x/panoptes/blob/main/README.md Install the WiX Toolset v5 CLI tool and required WiX extensions using the dotnet CLI. These are necessary for building the MSI installer. ```bash # Install WiX v5 CLI tool dotnet tool install --global wix --version 5.0.0 # Install required WiX extensions wix extension add -g WixToolset.UI.wixext/5.0.0 wix extension add -g WixToolset.Util.wixext/5.0.0 ``` -------------------------------- ### Example Extensibility Module Exports (PanoptesYara) Source: https://context7.com/ap3x/panoptes/llms.txt Provides example implementations for PanoBind, PanoEntry, and PanoUnbind functions, demonstrating how an extensibility module integrates with the Panoptes container system. PanoEntry handles scan requests and sends results. ```cpp // Example extensibility module exports (e.g., PanoptesYara DLL) extern "C" { // Called by container to register with main service PANO_API int PanoBind(int containerPort) { PanoptesServiceClient client; return client.Hello(EXTENSIBILITY_TYPE_YARA, containerPort) ? 1 : 0; } // Called for each scan request PANO_API bool PanoEntry(PeScan* peScan, MemScan* memScan) { if (peScan != nullptr) { YaraScanner scanner("C:\\Program Files\\Panoptes\\rules.pkg"); auto results = scanner.YaraScanFile(peScan->PePath); PanoptesServiceClient client; client.SendResults_Yara(peScan->PePath, peScan->FileHash, results); return true; } return false; } // Called on shutdown PANO_API bool PanoUnbind() { // Cleanup resources return true; } } ``` -------------------------------- ### Install Library Artifacts Source: https://github.com/ap3x/panoptes/blob/main/src/libraries/Configuration/CMakeLists.txt Defines installation rules for the built library. It specifies the destination directories for the static archive, shared library, and runtime binaries based on standard CMake installation variables. ```cmake # Installation install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) ``` -------------------------------- ### Basic CMake Project Setup Source: https://github.com/ap3x/panoptes/blob/main/src/container/CMakeLists.txt Sets the minimum CMake version, project name, and C++ standard to C++17. Ensure Protobuf and gRPC are available. ```cmake cmake_minimum_required(VERSION 3.15) project(PanoptesContainer) # Set C++17 as required set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Find required packages find_package(Protobuf CONFIG REQUIRED) find_package(gRPC CONFIG REQUIRED) ``` -------------------------------- ### Configure WiX v5 Installer with CMake Source: https://github.com/ap3x/panoptes/blob/main/installer/Wix/CMakeLists.txt Locates the WiX toolset, defines source files, and sets up custom build commands for generating an MSI installer. ```cmake cmake_minimum_required(VERSION 3.15) project(PanoptesInstaller) find_program(WIX_COMMAND wix.exe PATHS "$ENV{USERPROFILE}/.dotnet/tools" DOC "Path to WiX v5 command-line tool") if(NOT WIX_COMMAND) message(FATAL_ERROR "WiX v5 Toolset not found. Please install using: dotnet tool install --global wix --version 5.0.0") endif() # Set output directories set(OUTPUT_DIR "${CMAKE_SOURCE_DIR}/bin/installer") file(MAKE_DIRECTORY ${OUTPUT_DIR}) # Define WiX source files set(WIX_SOURCES AppComponents.wxs Execute.wxs Folders.wxs Package.en-us.wxl Package.wxs ) # Create custom command for WiX v5 build add_custom_command( OUTPUT ${OUTPUT_DIR}/PanoptesInstaller.msi COMMAND ${WIX_COMMAND} build -arch x64 -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext -bindpath "${CMAKE_SOURCE_DIR}/assets/yara" -bindpath "${CMAKE_SOURCE_DIR}/assets" -bindpath "${CMAKE_SOURCE_DIR}/bin/$" -bindpath "${CMAKE_SOURCE_DIR}/bin/driver/$" -bindpath "${CMAKE_SOURCE_DIR}/bin/driver" -bindpath "${CMAKE_SOURCE_DIR}/assets/icons" -bindpath "${CMAKE_CURRENT_SOURCE_DIR}/assets" ${WIX_SOURCES} -o ${OUTPUT_DIR}/PanoptesInstaller.msi DEPENDS ${WIX_SOURCES} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) # Create a custom target for the installer add_custom_target(installer ALL DEPENDS ${OUTPUT_DIR}/PanoptesInstaller.msi ) # Configure CPack with WiX v5 include(CPack) set(CPACK_GENERATOR "WIX") set(CPACK_WIX_VERSION "5") set(CPACK_WIX_ARCHITECTURE "x64") set(CPACK_WIX_UI_REF "WixUI_InstallDir") set(CPACK_WIX_EXTENSIONS "WixToolset.UI.wixext;WixToolset.Util.wixext") ``` -------------------------------- ### Install Public Headers Source: https://github.com/ap3x/panoptes/blob/main/src/libraries/Configuration/CMakeLists.txt Installs the public header files into the installation directory. The headers are copied from the current source directory and placed in a subdirectory named after the project. ```cmake # Install public headers file(GLOB PUBLIC_HEADERS "*.h") install(FILES ${PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} ) ``` -------------------------------- ### Build Panoptes MSI Installer with CMake Source: https://github.com/ap3x/panoptes/blob/main/README.md Configure and build the MSI installer for Panoptes by enabling the BUILD_WIX_INSTALLER and BUILD_DRIVER CMake options. The final MSI package will be located in the bin/installer directory. ```powershell cmake --preset default -DBUILD_WIX_INSTALLER=ON -DBUILD_DRIVER=ON cmake --build build/default --config Release cmake --build build/default --config Release --target installer ``` -------------------------------- ### Manage Panoptes Configuration Source: https://context7.com/ap3x/panoptes/llms.txt Provides the C++ class structure for parsing JSON configuration files and an example of the expected configuration format. ```cpp // Configuration.hpp - Configuration management class Configuration { public: enum ContainerType : int { CONTAINER_TYPE_NONE = 0, CONTAINER_TYPE_AMSI = 10, CONTAINER_TYPE_PE = 20, CONTAINER_TYPE_YARA = 30 }; std::vector m_exclusions; std::vector m_extensibility; std::vector m_extensibilityListName; std::vector> m_eventProviders; bool m_ignoreDriver = false; bool m_quartine = false; Configuration(std::string configurationPath); void Parse(); void IsValidJson(); std::vector GetJsonKeys(); }; ``` ```json { "ExtensibilitySelected": [ "PE", "YARA", "AMSI" ], "Exclusions": [ "C:\\Windows", "C:\\Program Files\\Microsoft Visual Studio\\", "C:\\Program Files (x86)\\Microsoft\\" ], "IgnoreDriver": false, "QuarantineMaliciousFiles": true, "EventProviders": [ "Microsoft-Windows-Kernel-Process,0,0" ] } ``` ```cpp // Usage in main service int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { std::string configPath = "C:\\ProgramData\\Panoptes\\Panoptes.config"; Configuration* configuration = new Configuration(configPath); try { configuration->Parse(); // configuration->m_extensibility contains enabled modules // configuration->m_exclusions contains paths to skip } catch (const int& err) { // Handle configuration error return err; } // Start containers based on configuration ERRORCODE errCode = StartContainers(configuration->m_extensibility); } ``` -------------------------------- ### CMake Build Configuration for TrayNotificationsCore Source: https://github.com/ap3x/panoptes/blob/main/src/libraries/TrayNotificationsCore/CMakeLists.txt Defines the project, source files, include directories, and installation targets for the static library. ```cmake cmake_minimum_required(VERSION 3.15) project(TrayNotificationsCore CXX) set(SOURCES src/TrayNotifications.cpp src/TrayNotifications.rc assets/panoptes-head.ico ) set(HEADERS include/TrayNotifications.h include/resource.h ) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${PANOPTES_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ) if(MSVC) set_target_properties(${PROJECT_NAME} PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" WINDOWS_EXPORT_ALL_SYMBOLS TRUE ) endif() install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) file(GLOB PUBLIC_HEADERS "*.h") install(FILES ${PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} ) ``` -------------------------------- ### CMakeLists.txt Configuration for Panoptes Source: https://github.com/ap3x/panoptes/blob/main/src/libraries/ResourceCore/CMakeLists.txt This is the main CMakeLists.txt file for the Panoptes project. It defines the project name, source and header files, and builds a shared library. It also includes Windows-specific configurations for symbol exports and sets up installation rules. ```cmake cmake_minimum_required(VERSION 3.15) project(Resources CXX) # Source files set(SOURCES src/ResourceCore.cpp ) set(HEADERS include/ResourceCore.h include/Resource.rc ) # Create shared library (DLL) add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS}) # Define RESOURCES_EXPORTS for DLL exports target_compile_definitions(${PROJECT_NAME} PRIVATE RESOURCES_EXPORTS) # Include directories target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ) # Set Windows specific properties if(MSVC) # Set properties for MSVC set_target_properties(${PROJECT_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE ) endif() # Installation install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/ResourceCore.h ${CMAKE_CURRENT_SOURCE_DIR}/include/resource.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} ) # Set output directories set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/${PRESET_NAME}" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/${PRESET_NAME}" ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/${PRESET_NAME}" ) ``` -------------------------------- ### Set VCPKG_ROOT Environment Variable Source: https://github.com/ap3x/panoptes/blob/main/README.md Set the VCPKG_ROOT environment variable to your vcpkg installation directory. This can be done temporarily for the current session or permanently for the user. ```powershell # If installed with Visual Studio $env:VCPKG_ROOT = "C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\vcpkg" # Or set it permanently [System.Environment]::SetEnvironmentVariable("VCPKG_ROOT", "C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\vcpkg", "User") ``` -------------------------------- ### Initialize Kernel Callbacks Source: https://context7.com/ap3x/panoptes/llms.txt Initializes the process creation and image load notification routines. Ensure to unregister these routines if initialization fails. ```cpp NTSTATUS InitializeKernelCallbacks() { NTSTATUS status; InitializeListHead(&g_ProcessList); status = PsSetCreateProcessNotifyRoutineEx(ProcessCreateCallback, FALSE); if (!NT_SUCCESS(status)) return status; status = PsSetLoadImageNotifyRoutine(LoadImageNotifyRoutine); if (!NT_SUCCESS(status)) { PsSetCreateProcessNotifyRoutineEx(ProcessCreateCallback, TRUE); return status; } return STATUS_SUCCESS; } ``` -------------------------------- ### Dynamically Loading Extensibility Modules Source: https://context7.com/ap3x/panoptes/llms.txt Demonstrates the process of dynamically loading an extensibility module (DLL) and retrieving pointers to its PanoBind, PanoEntry, and PanoUnbind functions using Windows API calls. ```cpp // Container loads extensibility module dynamically bool LoadExtensibility(std::string dllFile) { HMODULE extensibility = LoadLibraryA(dllFile.c_str()); PanoBind = (ExtensibilityCore::PanoBindPtr) GetProcAddress(extensibility, "PanoBind"); PanoEntry = (ExtensibilityCore::PanoEntryPtr) GetProcAddress(extensibility, "PanoEntry"); PanoUnbind = (ExtensibilityCore::PanoUnbindPtr) GetProcAddress(extensibility, "PanoUnbind"); return (PanoBind && PanoEntry && PanoUnbind); } ``` -------------------------------- ### Define Source and Header Files Source: https://github.com/ap3x/panoptes/blob/main/src/container/CMakeLists.txt Lists the source and header files for the project. The proto file is included as a source. ```cmake set(PROTO_FILE "${CMAKE_SOURCE_DIR}/proto/src/panoptes.proto") # Source files set(SOURCES src/container.cpp src/ext_server.cpp ${PROTO_FILE} ) # Header files set(HEADERS include/container.h include/container_ipc.hpp ) ``` -------------------------------- ### Define Source and Header Files Source: https://github.com/ap3x/panoptes/blob/main/src/dll/CMakeLists.txt Lists the source and header files for the project. Ensure these paths are correct relative to the project root. ```cmake # Source files set(SOURCES src/dllmain.cpp src/hook.cpp ) set(HEADERS include/def.h include/framework.h include/hook.hpp ) ``` -------------------------------- ### Create Executable Source: https://github.com/ap3x/panoptes/blob/main/src/container/CMakeLists.txt Creates the main executable for the project, including Windows-specific settings. ```cmake # Create executable add_executable(${PROJECT_NAME} WIN32 ${SOURCES} ${HEADERS}) ``` -------------------------------- ### AmsiScanner Class - Windows AMSI Integration Source: https://context7.com/ap3x/panoptes/llms.txt The AmsiScanner class provides an interface to scan files using the Windows Antimalware Scan Interface (AMSI). It leverages installed antivirus solutions without acting as an AMSI provider itself. ```APIDOC ## AmsiScanner Class - Windows AMSI Integration The `AmsiScanner` class integrates with Windows Antimalware Scan Interface (AMSI) to leverage installed antivirus solutions for file scanning without being an AMSI provider itself. ### Method `static HRESULT AmsiScanFile(std::string PathToFile, std::string CopyPath, int* AmsiResult)` ### Description Scans a specified file using AMSI. This method initializes AMSI, opens a session, reads the file content, and then scans the buffer. It returns the AMSI scan result. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```cpp int scanResult; HRESULT hr = AmsiScanner::AmsiScanFile("C:\\suspect\\file.exe", "", &scanResult); if (SUCCEEDED(hr)) { if (scanResult == AmsiScanner::AMSI_RESULT_PANO_DETECTED) { std::cout << "Malware detected by AMSI!" << std::endl; } else if (scanResult == AmsiScanner::AMSI_RESULT_PANO_CLEAN) { std::cout << "File is clean" << std::endl; } } ``` ### Response #### Success Response (200) - **amsi_result** (int) - The result of the AMSI scan. Possible values are defined in `AMSI_RESULT_PANO` enum: - `AMSI_RESULT_PANO_CLEAN = 0`: The file is clean. - `AMSI_RESULT_PANO_NOT_DETECTED = 1`: No threat was detected. - `AMSI_RESULT_PANO_BLOCKED_BY_ADMIN_START` to `AMSI_RESULT_PANO_BLOCKED_BY_ADMIN_END`: The scan was blocked by administrative policy. - `AMSI_RESULT_PANO_DETECTED = 32768`: Malware or a threat was detected. #### Response Example (The `AmsiScanFile` method returns an `HRESULT` indicating success or failure of the operation itself. The actual scan result is passed via the `amsi_result` output parameter.) ### Error Handling - Returns `HRESULT` indicating success or failure of the AMSI operation. - `FAILED(hr)` checks if the AMSI initialization or session opening failed. - `GetLastError()` can be used to retrieve more specific Windows error codes on failure. ``` -------------------------------- ### CMake Project Configuration Source: https://github.com/ap3x/panoptes/blob/main/src/dll/CMakeLists.txt Sets up the basic project properties, C++ standard, and runtime library for MSVC. Ensure CMAKE_CXX_STANDARD is set to 17 or higher. ```cmake cmake_minimum_required(VERSION 3.15) project(PanoptesDLL VERSION 1.0 DESCRIPTION "Panoptes DLL Project" LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Enable static linking for both architectures set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") ``` -------------------------------- ### Link Libraries and Set Target Properties Source: https://github.com/ap3x/panoptes/blob/main/src/scanner/PanoptesScan/CMakeLists.txt Configures include directories, links required gRPC and Windows libraries, and sets output directories. ```cmake # Include directories target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/../../../proto/build ) # Link libraries target_link_libraries(${PROJECT_NAME} PRIVATE gRPC::gpr gRPC::grpc gRPC::grpc++ gRPC::grpc++_alts Crypt32 ) # Set output directories to match the vcxproj configuration set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/${PRESET_NAME}" ) ``` -------------------------------- ### Run Panoptes Tests Source: https://github.com/ap3x/panoptes/blob/main/README.md Navigate to the test executable directory and run the Panoptes test executables to verify project functionality. ```bash cd bin/tests/Debug ./PanoptesAMSITest.exe ./PanoptesPETest.exe ./PanoptesYaraTest.exe ./PanoptesLinterTest.exe ``` -------------------------------- ### Configure CMake with vcpkg Source: https://context7.com/ap3x/panoptes/llms.txt These PowerShell commands demonstrate how to set up the vcpkg environment variable and configure CMake builds using presets. This is essential for managing dependencies and building Panoptes components. ```powershell # Set vcpkg environment variable $env:VCPKG_ROOT = "C:\\Program Files\\Microsoft Visual Studio\\2022\\Professional\\VC\\vcpkg" # Configure CMake with default preset cmake --preset default # Build Debug configuration cmake --build build/default --config Debug # Build Release configuration cmake --build build/default --config Release # Build with kernel driver (requires WDK) cmake --preset default -DBUILD_DRIVER=ON cmake --build build/default --config Debug --target PanoptesDriver # Build MSI installer (requires WiX Toolset v5) dotnet tool install --global wix --version 5.0.0 wix extension add -g WixToolset.UI.wixext/5.0.0 wix extension add -g WixToolset.Util.wixext/5.0.0 cmake --preset default -DBUILD_WIX_INSTALLER=ON -DBUILD_DRIVER=ON cmake --build build/default --config Release cmake --build build/default --config Release --target installer # Enable test signing for driver development bcdedit /set TESTSIGNING ON # Restart system after enabling test signing # Run unit tests cd bin/tests/Debug ./PanoptesAMSITest.exe ./PanoptesPETest.exe ./PanoptesYaraTest.exe ./PanoptesLinterTest.exe # Compile custom YARA rules yr.exe compile -o rules.pkg ``` -------------------------------- ### Configure Windows-Specific Build Settings Source: https://github.com/ap3x/panoptes/blob/main/src/scanner/PanoptesScan/CMakeLists.txt Handles Windows-specific resource files, compiler definitions, and MSVC runtime configurations. ```cmake # Add icon resource set(APP_ICON "${CMAKE_CURRENT_SOURCE_DIR}/../../../assets/icons/panoptes-head.ico") if(EXISTS ${APP_ICON}) target_sources(${PROJECT_NAME} PRIVATE ${APP_ICON}) endif() # Windows-specific configurations if(WIN32) # Add PANOPTESAMSI_EXPORTS define for DLL exports target_compile_definitions(${PROJECT_NAME} PRIVATE PANOPTESAMSI_EXPORTS _WINDOWS _USRDLL ) # Set static runtime library for all configurations if(MSVC) set_property(TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") # Set Windows subsystem set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS") endif() endif() target_compile_definitions(${PROJECT_NAME} PRIVATE $<$:_DEBUG> $<$:NDEBUG> $<$:NDEBUG> ) # Disable generating debug info for Release and Test configurations if(MSVC) set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELEASE "/DEBUG:NONE" LINK_FLAGS_TEST "/DEBUG:NONE" ) endif() ``` -------------------------------- ### Configure Panoptes CMake Project Source: https://github.com/ap3x/panoptes/blob/main/src/scanner/PanoptesScan/CMakeLists.txt Initializes the project, sets the C++ standard, and defines source and header file lists. ```cmake cmake_minimum_required(VERSION 3.15) project(PanoptesScan VERSION 1.0.0 LANGUAGES CXX) # Set C++ standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(gRPC CONFIG REQUIRED) set(PROTO_FILE "${CMAKE_SOURCE_DIR}/proto/src/panoptes.proto") # Source files set(SOURCES src/scan.cpp src/scanner_ipc.cpp ${PROTO_FILE} ) # Header files set(HEADERS include/scanner_ipc.hpp include/resource.h ${CMAKE_CURRENT_SOURCE_DIR}/include/PanoptesScan.rc ) # Create executable add_executable(${PROJECT_NAME} WIN32 ${SOURCES} ${HEADERS} ) ``` -------------------------------- ### Configure CMake Project and Dependencies Source: https://github.com/ap3x/panoptes/blob/main/src/linter/test/CMakeLists.txt Initializes the project, sets C++ standards, and configures static runtime libraries for MSVC compilers. ```cmake cmake_minimum_required(VERSION 3.15) project(Test_Linter) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Force static runtime libraries set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") include(FetchContent) FetchContent_Declare( googletest URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip ) # For Windows: Prevent overriding the parent project's compiler/linker settings set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) FetchContent_MakeAvailable(googletest) # Static runtime for MSVC enable_testing() add_executable( Test_Linter Test_Linter.cpp ) target_link_libraries( Test_Linter GTest::gtest_main ) if(MSVC) # Set static runtime library for all configurations set_property(TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") # Additional MSVC-specific flags for static linking target_compile_options(${PROJECT_NAME} PRIVATE $<$:/MT> $<$:/MTd> ) endif() include(GoogleTest) gtest_discover_tests(Test_Linter) ``` -------------------------------- ### Configure PanoptesScanCLI CMake Project Source: https://github.com/ap3x/panoptes/blob/main/src/scanner/PanoptesScanCLI/CMakeLists.txt Initializes the project, sets the C++17 standard, and finds required dependencies including gRPC, Abseil, and nlohmann_json. ```cmake cmake_minimum_required(VERSION 3.15) project(PanoptesScanCLI VERSION 1.0.0 LANGUAGES CXX) # Set C++ standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(gRPC CONFIG REQUIRED) find_package(absl CONFIG REQUIRED) find_package(nlohmann_json REQUIRED) set(PROTO_FILE "${CMAKE_SOURCE_DIR}/proto/src/panoptes.proto") # Source files set(SOURCES src/scan_cli.cpp src/scanner_ipc.cpp ${PROTO_FILE} ) # Header files set(HEADERS include/scanner_ipc.hpp ) # Create executable add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS}) ``` -------------------------------- ### Configure Panoptes CMake Build Source: https://github.com/ap3x/panoptes/blob/main/installer/Setup/CMakeLists.txt Sets up the C++17 standard, links Abseil and Windows-specific libraries, and configures output directories. ```cmake cmake_minimum_required(VERSION 3.20) # Project name and language project(PanoptesSetup VERSION 1.0 LANGUAGES CXX) # Set C++ standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(absl CONFIG REQUIRED) # Add executable add_executable(PanoptesSetup WIN32 src/PanoptesSetup.cpp) target_link_libraries(${PROJECT_NAME} PRIVATE absl::flags absl::flags_parse Crypt32 ) # Configure for Windows if(WIN32) # Use Unicode character set target_compile_definitions(PanoptesSetup PRIVATE UNICODE _UNICODE) # Link required Windows libraries target_link_libraries(PanoptesSetup PRIVATE setupapi) # Set static runtime library set_property(TARGET PanoptesSetup PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") endif() target_include_directories(PanoptesSetup PRIVATE ${CATCH_INCLUDE_DIR}) set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/${PRESET_NAME}" ) # Configure specific settings for different configurations foreach(CONFIG ${CMAKE_CONFIGURATION_TYPES}) string(TOUPPER ${CONFIG} CONFIG_UPPER) if(${CONFIG} STREQUAL "Test") # Test configuration inherits from Release with debug info set(CMAKE_C_FLAGS_${CONFIG_UPPER} ${CMAKE_C_FLAGS_RELEASE}) set(CMAKE_CXX_FLAGS_${CONFIG_UPPER} ${CMAKE_CXX_FLAGS_RELEASE}) set_target_properties(PanoptesSetup PROPERTIES COMPILE_DEFINITIONS_${CONFIG_UPPER} "NDEBUG" ) endif() endforeach() ``` -------------------------------- ### Configure Windows-Specific Build Settings Source: https://github.com/ap3x/panoptes/blob/main/src/scanner/PanoptesScanCLI/CMakeLists.txt Handles Windows-specific configurations including icon resources, DLL exports, MSVC runtime settings, and subsystem definitions. ```cmake # Add icon resource set(APP_ICON "${CMAKE_CURRENT_SOURCE_DIR}/../../../assets/icons/panoptes-head.ico") if(EXISTS ${APP_ICON}) target_sources(${PROJECT_NAME} PRIVATE ${APP_ICON}) endif() # Windows-specific configurations if(WIN32) # Add PANOPTESAMSI_EXPORTS define for DLL exports target_compile_definitions(${PROJECT_NAME} PRIVATE PANOPTESAMSI_EXPORTS _WINDOWS _USRDLL ) # Set static runtime library for all configurations if(MSVC) set_property(TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") # Set console subsystem for all configurations set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/SUBSYSTEM:CONSOLE" LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE" LINK_FLAGS_RELEASE "/SUBSYSTEM:CONSOLE" LINK_FLAGS_TEST "/SUBSYSTEM:CONSOLE") endif() endif() target_compile_definitions(${PROJECT_NAME} PRIVATE $<$:_DEBUG> $<$:NDEBUG> $<$:NDEBUG> ) # Disable generating debug info for Release and Test configurations if(MSVC) set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELEASE "/DEBUG:NONE" LINK_FLAGS_TEST "/DEBUG:NONE" ) endif() ``` -------------------------------- ### Set Output Directories Source: https://github.com/ap3x/panoptes/blob/main/src/container/CMakeLists.txt Configures the output directory for the runtime files, aligning with Visual Studio project structure. ```cmake # Set output directories to match Visual Studio structure set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/${PRESET_NAME}" ) ``` -------------------------------- ### Build Panoptes with Multiple CMake Options Source: https://github.com/ap3x/panoptes/blob/main/README.md Configure and build the Panoptes project with multiple CMake options enabled, such as building the driver and documentation simultaneously. ```powershell cmake --preset default -DBUILD_DRIVER=ON -DBUILD_DOC=ON cmake --build build/default --config Release ``` -------------------------------- ### Scan a File with PanoptesScanCLI Source: https://context7.com/ap3x/panoptes/llms.txt This C++ code implements the PanoptesScanCLI tool. It parses command-line arguments to specify a file for scanning, queues the file for a PE scan using PanoptesServiceClient, and pretty-prints the JSON results. Ensure the PanoptesServiceClient is correctly implemented and accessible. ```cpp // scan_cli.cpp - CLI implementation #include "scanner_ipc.hpp" #include "absl/flags/flag.h" #include "absl/flags/parse.h" ABSL_FLAG(std::string, file, "", "File for Panoptes To Scan"); int main() { absl::ParseCommandLine(__argc, __argv); if (absl::GetFlag(FLAGS_file).empty()) { printf("ERROR: No file specified\n"); printf("Usage: PanoptesScanCLI.exe -file \n"); return 1; } std::string fileToScan = absl::GetFlag(FLAGS_file); PanoptesServiceClient client; std::string results; if (!client.QueuePeScan(fileToScan, "", results)) { std::cout << "An Error Occured:" << "\n" << results << std::endl; return 1; } // Wait for scan if file hasn't been scanned before if (results.empty()) { Sleep(2000); client.QueuePeScan(fileToScan, "", results); } // Pretty print JSON results nlohmann::json j = nlohmann::json::parse(results); std::cout << "Scan Results:" << "\n" << j.dump(4) << std::endl; return 0; } // scanner_ipc.hpp - Service client for CLI class PanoptesServiceClient { public: PanoptesServiceClient(); bool QueuePeScan(std::string PePath, std::string FileHash, std::string& message); }; // Command line usage examples: // PanoptesScanCLI.exe -file "C:\\Downloads\\suspicious.exe" // PanoptesScanCLI.exe -file "C:\\malware_samples\\sample001.dll" // Example output: /* Scan Results: { "portable_executable_path": "C:\\Downloads\\suspicious.exe", "file_hash": "a1b2c3d4e5f6...", "yara_scan": { "detected_rules": ["malware::trojan_generic", "packer::upx"] }, "amsi_result": 32768, "Time": "2024-01-15T10:30:45Z" } */ ``` -------------------------------- ### Create Static Library Target Source: https://github.com/ap3x/panoptes/blob/main/src/libraries/Configuration/CMakeLists.txt Defines a static library target named 'Configuration' using the specified source and header files. Static libraries are linked directly into the executable. ```cmake # Create shared library add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) ``` -------------------------------- ### Configure gRPC and Protobuf Generation Source: https://github.com/ap3x/panoptes/blob/main/src/scanner/PanoptesScan/CMakeLists.txt Conditional block to handle gRPC dependency discovery and protobuf source generation. ```cmake if(BUILD_GRPC) find_package(gRPC CONFIG REQUIRED) # Set proto file path set(PROTO_FILE_DIR "${CMAKE_SOURCE_DIR}/proto/src/") set(PROTO_BUILD_DIR "${CMAKE_SOURCE_DIR}/proto/build") # Create build directory if it doesn't exist file(MAKE_DIRECTORY ${PROTO_BUILD_DIR}) message(" --> PROTOBUF LIB: ${PROTOBUF_LIBRARIES}") message(" --> PROTOBUF INCLUDE: ${Protobuf_INCLUDE_DIRS}") message(" --> PROTOBUF VERSION: ${Protobuf_VERSION}") message(" --> PROTOBUF Found: ${Protobuf_FOUND}") message(" --> PROTOBUF SRC: ${PROTO_SRC}") message(" --> PROTOBUF HEADER: ${PROTO_HEADER}") message(" --> PROTOBUF Folder: ${CMAKE_BINARY_DIR}/proto") #target_link_libraries(${PROJECT_NAME} PUBLIC protobuf::libprotobuf gRPC::grpc++) set(PROTO_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated") target_include_directories(${PROJECT_NAME} PUBLIC "$") protobuf_generate( TARGET ${PROJECT_NAME} IMPORT_DIRS ${PROTO_FILE_DIR} PROTOC_EXE "${Protobuf_PROTOC_EXECUTABLE}" PROTOC_OUT_DIR "${PROTO_BINARY_DIR}") protobuf_generate( TARGET ${PROJECT_NAME} LANGUAGE grpc GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PROTOC_EXE "${Protobuf_PROTOC_EXECUTABLE}" PLUGIN "protoc-gen-grpc=\$" IMPORT_DIRS ${PROTO_FILE_DIR} PROTOC_OUT_DIR "${PROTO_BINARY_DIR}") endif() ``` -------------------------------- ### Configure Panoptes Project with CMake Source: https://github.com/ap3x/panoptes/blob/main/README.md Configure the Panoptes project using CMake with the default preset. This prepares the build environment for subsequent build commands. ```powershell cmake --preset default ``` -------------------------------- ### Link Libraries and Set Target Properties Source: https://github.com/ap3x/panoptes/blob/main/src/scanner/PanoptesScanCLI/CMakeLists.txt Defines include directories, links external libraries, and sets output directories for the project. ```cmake # Include directories target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ) # Link libraries target_link_libraries(${PROJECT_NAME} PRIVATE nlohmann_json::nlohmann_json gRPC::gpr gRPC::grpc gRPC::grpc++ gRPC::grpc++_alts absl::flags absl::flags_parse Crypt32 ) # Set output directories to match the vcxproj configuration set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/${PRESET_NAME}" ) ``` -------------------------------- ### Configure Include Directories Source: https://github.com/ap3x/panoptes/blob/main/src/libraries/Configuration/CMakeLists.txt Sets the public and private include directories for the 'Configuration' target. Public headers are accessible to consumers of the library, while private headers are internal. ```cmake # Include directories target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${PANOPTES_INCLUDE_DIR} ${EXTERNAL_INCLUDE_DIR} ${RESOURCES_INCLUDE_DIR} ${INTERFACE_INCLUDE_DIRECTORIES} ) ``` -------------------------------- ### Copy DLL and PDB Post-Build Source: https://github.com/ap3x/panoptes/blob/main/src/extensibility/PanoptesPE/CMakeLists.txt Executes a post-build command to copy the target DLL and PDB files to a designated external directory for Debug builds. ```cmake add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_SOURCE_DIR}/bin/Debug/ext" COMMAND ${CMAKE_COMMAND} -E copy_if_different "$" "${CMAKE_SOURCE_DIR}/bin/Debug/ext/$" COMMAND ${CMAKE_COMMAND} -E copy_if_different "$" "${CMAKE_SOURCE_DIR}/bin/Debug/ext/$" COMMENT "Copying ${PROJECT_NAME} DLL and PDB to ext directory" ) ``` -------------------------------- ### Build Panoptes Project with CMake Source: https://github.com/ap3x/panoptes/blob/main/README.md Build the Panoptes project using CMake. Choose between a Debug build with symbols or an optimized Release build. ```powershell # Debug build (with debug symbols for your code) cmake --build build/default --config Debug # Release build (optimized) cmake --build build/default --config Release ``` -------------------------------- ### Link Libraries Configuration Source: https://github.com/ap3x/panoptes/blob/main/src/container/CMakeLists.txt Links the necessary gRPC libraries to the project. Includes specific gRPC components and Windows Crypt32 library if on Windows. ```cmake # Link libraries target_link_libraries(${PROJECT_NAME} PRIVATE gRPC::gpr gRPC::grpc gRPC::grpc++ gRPC::grpc++_alts ) if(WIN32) target_link_libraries(${PROJECT_NAME} PRIVATE Crypt32) endif() ``` -------------------------------- ### Create x64 and x86 Targets Source: https://github.com/ap3x/panoptes/blob/main/src/dll/CMakeLists.txt Calls the `configure_target` function to create both x64 and x86 DLL targets for the Panoptes project. This ensures the project can be built for both architectures. ```cmake # Create x64 and x86 targets configure_target(${PROJECT_NAME}x64 "x64") configure_target(${PROJECT_NAME}x86 "x86") ``` -------------------------------- ### gRPC Code Generation Configuration Source: https://github.com/ap3x/panoptes/blob/main/src/container/CMakeLists.txt Configures gRPC code generation if BUILD_GRPC is enabled. This involves setting up directories, finding Protobuf and gRPC components, and using protobuf_generate to create C++ headers and sources. ```cmake if(BUILD_GRPC) find_package(gRPC CONFIG REQUIRED) # Set proto file path set(PROTO_FILE_DIR "${CMAKE_SOURCE_DIR}/proto/src/") set(PROTO_BUILD_DIR "${CMAKE_SOURCE_DIR}/proto/build") # Create build directory if it doesn't exist file(MAKE_DIRECTORY ${PROTO_BUILD_DIR}) message(" --> PROTOBUF LIB: ${PROTOBUF_LIBRARIES}") message(" --> PROTOBUF INCLUDE: ${Protobuf_INCLUDE_DIRS}") message(" --> PROTOBUF VERSION: ${Protobuf_VERSION}") message(" --> PROTOBUF Found: ${Protobuf_FOUND}") message(" --> PROTOBUF SRC: ${PROTO_SRC}") message(" --> PROTOBUF HEADER: ${PROTO_HEADER}") message(" --> PROTOBUF Folder: ${CMAKE_BINARY_DIR}/proto") #target_link_libraries(${PROJECT_NAME} PUBLIC protobuf::libprotobuf gRPC::grpc++) set(PROTO_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated") target_include_directories(${PROJECT_NAME} PUBLIC "$") protobuf_generate( TARGET ${PROJECT_NAME} IMPORT_DIRS ${PROTO_FILE_DIR} PROTOC_EXE "${Protobuf_PROTOC_EXECUTABLE}" PROTOC_OUT_DIR "${PROTO_BINARY_DIR}" ) protobuf_generate( TARGET ${PROJECT_NAME} LANGUAGE grpc PROTOC_EXE "${Protobuf_PROTOC_EXECUTABLE}" GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=$" IMPORT_DIRS ${PROTO_FILE_DIR} PROTOC_OUT_DIR "${PROTO_BINARY_DIR}" ) endif() ``` -------------------------------- ### Implement NTDLL Function Hooks Source: https://context7.com/ap3x/panoptes/llms.txt Provides the implementation for hooked NTDLL functions, including logging or analysis logic before calling the original function. Requires global pointers to store original function addresses. ```cpp // hook.cpp - Implementation using Microsoft Detours pNtWriteVirtualMemory pOriginal_NtWriteVirtualMemory = NULL; pNtModifyBootEntry pOriginal_NtModifyBootEntry = NULL; pNtMapViewOfSectionEx pOriginal_NtMapViewOfSectionEx = NULL; NTSTATUS NTAPI Hooked_NtWriteVirtualMemory( HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, SIZE_T NumberOfBytesToWrite, PSIZE_T NumberOfBytesWritten) { // Log or analyze the write operation here // Then call original function return pOriginal_NtWriteVirtualMemory(ProcessHandle, BaseAddress, Buffer, NumberOfBytesToWrite, NumberOfBytesWritten); } ``` -------------------------------- ### Include Directories Configuration Source: https://github.com/ap3x/panoptes/blob/main/src/container/CMakeLists.txt Specifies private include directories for the project, including custom headers and shared extensibility directories. ```cmake # Include directories target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src/extensibility/shared ${CMAKE_SOURCE_DIR}/src/container/include ) ``` -------------------------------- ### Add Post-Build Copy Command Source: https://github.com/ap3x/panoptes/blob/main/src/service/CMakeLists.txt Adds a custom command to copy the panoptes.config file to the target's output directory after the build is complete. This ensures the configuration file is available with the executable. ```cmake add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/assets/panoptes.config $/panoptes.config ) ``` -------------------------------- ### Implement YARA scanning with YaraScanner Source: https://context7.com/ap3x/panoptes/llms.txt The YaraScanner class loads pre-compiled YARA rules and scans files for malware signatures. Requires rules to be pre-compiled using the yr.exe CLI tool. ```cpp // PanoptesYara.h - YARA scanning interface class YaraScanner { private: YRX_RULES* g_yaraRules = nullptr; public: struct ScanData { int detections; std::vector detectedRules; }; YaraScanner(const char* Rules); ~YaraScanner(); std::vector YaraScanFile(std::string PathToFile); }; // yara-scan.cpp - Implementation YaraScanner::YaraScanner(const char* rulesPath) { YRX_RESULT result = YRX_NOT_SUPPORTED; auto readBuffer = readFileToBuffer(rulesPath); if (readBuffer.empty()) { throw std::runtime_error("Failed to read rules file"); } result = yrx_rules_deserialize(readBuffer.data(), readBuffer.size(), &g_yaraRules); if (result != YRX_SUCCESS) { throw std::runtime_error("Failed to deserialize YARA rules"); } } std::vector YaraScanner::YaraScanFile(std::string file_path) { std::vector detectedRules; YRX_SCANNER* scanner = nullptr; yrx_scanner_create(g_yaraRules, &scanner); yrx_scanner_on_matching_rule(scanner, matchingRule, &detectedRules); std::vector scanBuffer = readFileToBuffer(file_path); yrx_scanner_scan(scanner, scanBuffer.data(), scanBuffer.size()); yrx_scanner_destroy(scanner); return detectedRules; } // Compile YARA rules using yr.exe CLI tool: // yr.exe compile -o rules.pkg // Example usage in extensibility module YaraScanner* scanner = new YaraScanner("C:\\Program Files\\Panoptes\\rules.pkg"); std::vector detections = scanner->YaraScanFile("C:\\suspect\\malware.exe"); for (const auto& rule : detections) { std::cout << "Detected rule: " << rule << std::endl; // Output: "malware_namespace::trojan_generic" } ``` -------------------------------- ### Configure gRPC and Protobuf Generation Source: https://github.com/ap3x/panoptes/blob/main/src/scanner/PanoptesScanCLI/CMakeLists.txt Conditionally configures Protobuf and gRPC code generation if the BUILD_GRPC flag is enabled. ```cmake if(BUILD_GRPC) find_package(gRPC CONFIG REQUIRED) # Set proto file path set(PROTO_FILE_DIR "${CMAKE_SOURCE_DIR}/proto/src/") set(PROTO_BUILD_DIR "${CMAKE_SOURCE_DIR}/proto/build") # Create build directory if it doesn't exist file(MAKE_DIRECTORY ${PROTO_BUILD_DIR}) message(" --> PROTOBUF LIB: ${PROTOBUF_LIBRARIES}") message(" --> PROTOBUF INCLUDE: ${Protobuf_INCLUDE_DIRS}") message(" --> PROTOBUF VERSION: ${Protobuf_VERSION}") message(" --> PROTOBUF Found: ${Protobuf_FOUND}") message(" --> PROTOBUF SRC: ${PROTO_SRC}") message(" --> PROTOBUF HEADER: ${PROTO_HEADER}") message(" --> PROTOBUF Folder: ${CMAKE_BINARY_DIR}/proto") #target_link_libraries(${PROJECT_NAME} PUBLIC protobuf::libprotobuf gRPC::grpc++) set(PROTO_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated") target_include_directories(${PROJECT_NAME} PUBLIC "$") protobuf_generate( TARGET ${PROJECT_NAME} IMPORT_DIRS ${PROTO_FILE_DIR} PROTOC_EXE "${Protobuf_PROTOC_EXECUTABLE}" PROTOC_OUT_DIR "${PROTO_BINARY_DIR}" ) protobuf_generate( TARGET ${PROJECT_NAME} LANGUAGE grpc PROTOC_EXE "${Protobuf_PROTOC_EXECUTABLE}" GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=\$" IMPORT_DIRS ${PROTO_FILE_DIR} PROTOC_OUT_DIR "${PROTO_BINARY_DIR}" ) endif() ```