### Installation Rules Source: https://github.com/kernelwernel/vmaware/blob/main/CMakeLists.txt Installs the target executable to the CMAKE_INSTALL_BINDIR and the header file to CMAKE_INSTALL_INCLUDEDIR. ```cmake include(GNUInstallDirs) install(TARGETS ${TARGET} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES "src/vmaware.hpp" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) ``` -------------------------------- ### Install Ruby Extension Source: https://github.com/kernelwernel/vmaware/blob/main/gem/extension/CMakeLists.txt Configures the installation of the built Ruby extension. This command ensures the extension is copied to the correct directory within the CMAKE_INSTALL_PREFIX when `make install` is invoked by RubyGems. ```cmake install(TARGETS ${CMAKE_PROJECT_NAME} LIBRARY DESTINATION . ) ``` -------------------------------- ### Example usage of vmaware struct Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Demonstrates how to instantiate and access members of the vmaware struct. Ensure 'vmaware.hpp' is included. ```cpp #include "vmaware.hpp" #include int main() { VM::vmaware vm; std::cout << "Is this a VM? = " << vm.is_vm << "\n"; std::cout << "How many techniques detected a VM? = " << vm.detected_count << "%\n"; std::cout << "What's the VM's type? = " << vm.type << "%\n"; std::cout << "What's the overview in a human-readable message?" << vm.conclusion << "\n"; } ``` -------------------------------- ### Get VM Type Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Retrieves the VM type or architecture as a string based on the detected brand. ```cpp #include "vmaware.hpp" #include int main() { // example output: VirtualBox is a Hypervisor (type 2) VM std::cout << VM::brand() " is a " << VM::type() << " VM\n"; } ``` -------------------------------- ### Find Ruby Installation Source: https://github.com/kernelwernel/vmaware/blob/main/gem/extension/CMakeLists.txt Locates the Ruby installation using find_package(Ruby) and sets up CMake targets like Ruby::Ruby for embedding Ruby into the project. ```cmake # ----------------------------------------------------------------------------- # Find Ruby Installation # ----------------------------------------------------------------------------- # find_package(Ruby) locates the Ruby installation and sets up: # - Ruby::Ruby - Target for embedding Ruby (links to libruby) find_package(Ruby) ``` -------------------------------- ### Build VMAware on Linux Source: https://github.com/kernelwernel/vmaware/blob/main/README.md These bash commands outline the process for building and installing the VMAware library on a Linux system using CMake. Ensure your package manager is updated before proceeding. ```bash sudo dnf/apt/yum update -y # change this to whatever your distro is mkdir build cd build cmake .. sudo make install ``` -------------------------------- ### Build VMAware on MacOS Source: https://github.com/kernelwernel/vmaware/blob/main/README.md These bash commands detail the steps to build and install the VMAware library on macOS using CMake. This process is similar to Linux, involving creating a build directory and running CMake. ```bash mkdir build cd build cmake .. sudo make install ``` -------------------------------- ### Get VM Brand Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Retrieves the detected VM brand as a string. Returns 'Unknown' if no brand is detected. Use VM::MULTIPLE to get a string of all detected conflicting brands. ```cpp #include "vmaware.hpp" #include int main() { const std::string result = VM::brand(); if (result == "KVM") { // do KVM specific stuff } else if (result == "VirtualBox") { // do vbox specific stuff } else { // you get the idea } } ``` ```cpp #include "vmaware.hpp" #include int main() { // format: "vmbrand1 or vmbrand2 [or vmbrandx...]" const std::string result = VM::brand(VM::MULTIPLE); // example output: "VMware or Bochs" std::cout << result << "\n"; // Keep in mind that there's no limit to how many conflicts there can be. // And if there's no conflict, it'll revert back to giving the brand string // normally as if the VM::MULTIPLE wasn't there } ``` -------------------------------- ### Get Detected VM Technique Count Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Fetches the number of detected techniques as a uint8_t. Returns 0 for baremetal, and typically between 4-15 for VMs. ```cpp #include "vmaware.hpp" #include int main() { const std::uint8_t count = VM::detected_count(); // output: 7 techniques were detected std::cout << count << " techniques were detected" << "\n"; // note that if it's baremetal, it should be 0. // if it's a VM, it should have at least 4 to // maybe around 15 max. The most I've seen was // around 18 but that only occurs very rarely. return 0; } ``` -------------------------------- ### Get Multiple VM Brands Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Retrieves a string listing potentially conflicting VM brands, separated by 'or'. Useful when multiple brands are detected. If no conflict, it returns the single detected brand. ```cpp #include "vmaware.hpp" #include int main() { // format: "vmbrand1 or vmbrand2 [or vmbrandx...]" const std::string result = VM::brand(VM::MULTIPLE); // example output: "VMware or Bochs" std::cout << result << "\n"; // Keep in mind that there's no limit to how many conflicts there can be. // And if there's no conflict, it'll revert back to giving the brand string // normally as if the VM::MULTIPLE wasn't there return 0; } ``` -------------------------------- ### Enable CMake Policy CMP0177 Source: https://github.com/kernelwernel/vmaware/blob/main/CMakeLists.txt Enables a new CMake policy for normalizing install destination paths, available from CMake 3.30 onwards. ```cmake if(POLICY CMP0177) cmake_policy(SET CMP0177 NEW) endif() ``` -------------------------------- ### Get Detected VM Techniques Count Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Fetches the number of VM detection techniques that have been successfully detected. ```cpp // This function returns a std::uint8_t representing the count. ``` -------------------------------- ### Get VM Conclusion Message Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Returns a conclusion message about the environment. With VM::DYNAMIC, it provides more detailed messages about the likelihood of being a VM. ```cpp // Default outputs: // Running on baremetal // Running inside a [brand] VM // With VM::DYNAMIC, more outputs are possible: // Very unlikely a [brand] VM // Unlikely a [brand] VM // Potentially a [brand] VM // Might be a [brand] VM // Likely a [brand] VM // Very likely a [brand] VM // Running inside a [brand] VM ``` -------------------------------- ### System Update for C++ Components on Linux Source: https://github.com/kernelwernel/vmaware/blob/main/README.md If you encounter linker errors in a new VM environment on Linux, update your system to install necessary C++ components. ```bash sudo apt update -y && sudo apt upgrade -y ``` ```bash sudo dnf update -y ``` ```bash sudo yum update -y ``` -------------------------------- ### Get VM Type Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Retrieves the VM type (e.g., Hypervisor type 2) as a std::string based on the detected brand. Used in conjunction with VM::brand() for a more descriptive output. ```cpp #include "vmaware.hpp" #include int main() { // example output: VirtualBox is a Hypervisor (type 2) VM std::cout << VM::brand() << " is a " << VM::type() << " VM\n"; return 0; } ``` -------------------------------- ### Get VM Brand Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Retrieves the VM brand as a std::string. Handles specific brands like KVM and VirtualBox, and provides aliases for VMware to prevent typos. Returns 'Unknown' if no brand is detected. ```cpp #include "vmaware.hpp" #include int main() { const std::string result = VM::brand(); if (result == "KVM") { // do KVM specific stuff } else if (result == "VirtualBox") { // you get the idea } else if (result == brands::VMWARE) { // having manual string comparisons like the two // previous ones can lead to typos which will // make the whole check completely redundant. // So the lib provides hardcoded string variables // as aliases to avoid these kinds of situations. // They are located in the aforementioned brand table } return 0; } ``` -------------------------------- ### VM Detection Certainty Percentage Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Use VM::percentage() to get a certainty score (0-100) of VM detection. Flags from VM::detect() can be applied. The result is memoized. ```cpp #include "vmaware.hpp" #include #include int main() { // uint8_t and unsigned char works too const std::uint8_t percent = VM::percentage(); if (percent == 100) { std::cout << "Definitely a VM!\n"; } else if (percent == 0) { std::cout << "Definitely NOT a VM\n"; } else { std::cout << "Unsure if it's a VM\n"; } // converted to std::uint32_t for console character encoding reasons std::cout << "percentage: " << static_cast(percent) << "%\n"; } ``` -------------------------------- ### Basic VM Detection with Default Checks Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Use VM::detect() without parameters to perform all recommended checks for VM detection. The result is memoized by default. ```cpp #include "vmaware.hpp" int main() { /** * The basic way to detect a VM where the default checks will * be performed. This is the recommended usage of the lib. */ bool is_vm = VM::detect(); /** * This does the exact same as above, but as an explicit alternative. */ bool is_vm2 = VM::detect(VM::DEFAULT); /** * All checks are performed including spoofable techniques * and a few other techniques that are disabled by default, * one of which is VM::CURSOR which waits 5 seconds for any * human mouse interaction to detect automated virtual environments. * If you're fine with having a 5 second delay, add VM::ALL */ bool is_vm3 = VM::detect(VM::ALL); /** * If you don't want the value to be memoized for whatever reason, * you can set the VM::NO_MEMO flag and the result will not be cached. * It's recommended to use this flag if you're only using one function * from the public interface a single time in total, so no unneccessary * caching will be operated when you're not going to re-use the previously * stored result at the end. */ bool is_vm4 = VM::detect(VM::NO_MEMO); /** * This will set the threshold bar to detect a VM higher than the default threshold. * Use this if you want to be extremely sure if it's a VM, but this can risk the result * to be a false negative. Use VM::percentage() for a more precise result if you want. */ bool is_vm5 = VM::detect(VM::HIGH_THRESHOLD); /** * Essentially means only the CPU brand, MAC, and hypervisor bit techniques * should be performed. Note that the less flags you provide, the more * likely the result will not be accurate. If you just want to check for * a single technique, use VM::check() instead. Also, read the flag table * at the end of this doc file for a full list of technique flags. */ bool is_vm6 = VM::detect(VM::CPU_BRAND, VM::MAC, VM::HYPERVISOR_BIT); /** * If you want to disable any technique for whatever reason, use VM::DISABLE(...). * This code snippet essentially means "perform all the default flags, but only * disable the VM::RDTSC technique". */ bool is_vm7 = VM::detect(VM::DISABLE(VM::RDTSC)); /** * Same as above, but you can disable multiple techniques at the same time. */ bool is_vm8 = VM::detect(VM::DISABLE(VM::VMID, VM::RDTSC, VM::HYPERVISOR_BIT)); /** * This is just an example to show that you can use a combination of * different flags and non-technique flags with the above examples. */ bool is_vm9 = VM::detect(VM::DEFAULT, VM::NO_MEMO, VM::HIGH_THRESHOLD, VM::DISABLE(VM::RDTSC, VM::VMID)); } ``` -------------------------------- ### Basic VM Detection and Information Retrieval Source: https://github.com/kernelwernel/vmaware/blob/main/README.md This C++ snippet demonstrates how to use the VMAware library to detect if the current environment is a virtual machine, and retrieve its brand, type, certainty, and hardening status. Include the 'vmaware.hpp' header and link the library. ```cpp #include "vmaware.hpp" #include int main() { if (VM::detect()) { std::cout << "Virtual machine detected!" << "\n"; } else { std::cout << "Running on baremetal" << "\n"; } std::cout << "VM name: " << VM::brand() << "\n"; std::cout << "VM type: " << VM::type() << "\n"; std::cout << "VM certainty: " << (int)VM::percentage() << "%" << "\n"; std::cout << "VM hardening: " << (VM::is_hardened() ? "likely" : "not found") << "\n"; } ``` -------------------------------- ### Iterate and Identify Detected VM Techniques Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Loops through all techniques in `VM::technique_vector`, checks if detected, and prints their string names. Useful for detailed analysis. ```cpp #include "vmaware.hpp" #include int main() { // this will loop through all the enums in the technique_vector variable, // and then checks each of them and outputs the enum that was detected for (const auto technique_enum : VM::technique_vector) { if (VM::check(technique_enum)) { const std::string name = VM::flag_to_string(technique_enum); std::cout << "VM::" << name << " was detected\n"; } } return 0; } ``` -------------------------------- ### C++ Wrapper for VM Detection Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Create a C++ wrapper around the vmaware.hpp header to avoid recompiling the entire library on every build. This improves build performance, especially in large projects. ```cpp // wrapper.hpp #include namespace wrapper { bool is_this_a_vm(); std::string vm_brand_name(); } ``` ```cpp // wrapper.cpp #include "vmaware.hpp" #include "wrapper.hpp" bool wrapper::is_this_a_vm() { return VM::detect(); } std::string wrapper::vm_brand_name() { return VM::brand(); } ``` ```cpp // something.cpp #include "wrapper.hpp" void something() { if (wrapper::is_this_a_vm()) { std::cout << wrapper::vm_brand_name() << "\n"; } } ``` -------------------------------- ### VM::conclusion() Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Returns a conclusion message about the system's environment, indicating whether it's running on bare metal or inside a VM. ```APIDOC ## `VM::conclusion()` ### Description Returns a string summarizing the system's environment, indicating if it's running on bare metal or inside a VM. With the `VM::DYNAMIC` flag, more detailed probabilistic outputs are available. ### Parameters - `VM::DYNAMIC` (flag, optional): If provided, enables more detailed and variadic conclusion messages. ### Returns - `std::string`: A conclusion message (e.g., 'Running on baremetal', 'Running inside a [brand] VM', or more detailed messages if `VM::DYNAMIC` is used). ### Example Usage ```cpp #include "vmaware.hpp" #include int main() { // Default usage std::cout << VM::conclusion() << "\n"; // With dynamic flag for more detailed output std::cout << VM::conclusion(VM::DYNAMIC) << "\n"; return 0; } ``` ``` -------------------------------- ### Get Vector of Detected VM Technique Enums Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Returns a vector of all detected technique flags as `VM::enum_flags`. Provides a programmatic overview of detected techniques. ```cpp #include "vmaware.hpp" #include int main() { std::vector flag_list = VM::detected_enums(); for (const auto flag : flag_list) { std::cout << "VM::" << VM::flag_to_string(flag) << " was detected" << "\n"; } return 0; } ``` -------------------------------- ### Fetch Rice Library using FetchContent Source: https://github.com/kernelwernel/vmaware/blob/main/gem/extension/CMakeLists.txt Integrates the Rice library, a header-only dependency, by automatically downloading it from GitHub using CMake's FetchContent module. This simplifies dependency management for users. ```cmake # ----------------------------------------------------------------------------- # Fetch Rice from GitHub # ----------------------------------------------------------------------------- # Rice is a header-only library, so we use FetchContent to download it # automatically. This eliminates the need for users to manually install Rice. # # FetchContent downloads the repository at configure time and makes it # available as if it were part of your project. # # Note: For production gems, you may want to pin to a specific release tag # instead of 'dev' for reproducible builds. include(FetchContent) FetchContent_Declare( rice GIT_REPOSITORY https://github.com/ruby-rice/rice.git GIT_TAG 4.11.4 ) FetchContent_MakeAvailable(rice) ``` -------------------------------- ### Project Definition Source: https://github.com/kernelwernel/vmaware/blob/main/CMakeLists.txt Defines the project name, description, and primary language. Sets up the basic project structure for CMake. ```cmake project( VMAware DESCRIPTION "VM detection library" LANGUAGES CXX ) ``` -------------------------------- ### Specify Source Files for Ruby Extension Source: https://github.com/kernelwernel/vmaware/blob/main/gem/extension/CMakeLists.txt Lists the source files required to build the Ruby extension. This includes the header declaring the Init function, the C++ implementation with Rice bindings, and other project-specific source files. ```cmake target_sources(${CMAKE_PROJECT_NAME} PRIVATE "${CMAKE_PROJECT_NAME}-rb.hpp" "${CMAKE_PROJECT_NAME}-rb.cpp" "../../src/vmaware.hpp" ) ``` -------------------------------- ### VM Detection Certainty Percentage Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Use VM::percentage() to get a certainty score (0-100) of VM detection. This function accepts the same flag system as VM::detect() for customized checks. ```cpp #include "vmaware.hpp" #include #include int main() { // uint8_t and unsigned char works too const std::uint8_t percent = VM::percentage(); if (percent == 100) { std::cout << "Definitely a VM!\n"; } else if (percent == 0) { std::cout << "Definitely NOT a VM\n"; } else { std::cout << "Unsure if it's a VM\n"; } // converted to int for console character encoding reasons std::cout << "percentage: " << static_cast(percent) << "%\n"; return 0; } ``` -------------------------------- ### Add Project and Rice Include Directories Source: https://github.com/kernelwernel/vmaware/blob/main/gem/extension/CMakeLists.txt Configures include directories for project headers and Rice headers. This allows the project to find its own header files and those provided by the Rice library. ```cmake target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE .) target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE "${rice_SOURCE_DIR}/include/") target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ../../src) ``` -------------------------------- ### Define Project and Set C++ Standard Source: https://github.com/kernelwernel/vmaware/blob/main/gem/extension/CMakeLists.txt Defines the project name as 'vmaware' and sets the C++ standard to 20 if not already defined, ensuring C++20 compliance. ```cmake project(vmaware LANGUAGES CXX) # set C++ standard if(NOT DEFINED CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 20) endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) ``` -------------------------------- ### VMAware Security Reporting Workflow Summary Source: https://github.com/kernelwernel/vmaware/blob/main/SECURITY.md A summary of the workflow for reporting security vulnerabilities, from reporter submission to maintainer response, investigation, patching, and disclosure. ```text Reporter -> jeanruyv@gmail.com (PGP optional) -> Maintainers ack in 48h -> Investigation in 5 days -> Patch in 30 days (if warranted) -> Public disclosure & credit (if warranted) ``` -------------------------------- ### CTest Configuration Source: https://github.com/kernelwernel/vmaware/blob/main/CMakeLists.txt Includes CTest support and sets up a test named 'executable' or 'TARGET' that runs the built target with '--all' arguments, conditional on BUILD_TESTING being enabled. ```cmake include(CTest) if(BUILD_TESTING) set(ARGUMENTS "--all") if(MSVC) add_test(NAME executable COMMAND $ ${ARGUMENTS}) else() add_test(NAME TARGET COMMAND $ ${ARGUMENTS}) endif() endif() ``` -------------------------------- ### Create Ruby Extension Library Source: https://github.com/kernelwernel/vmaware/blob/main/gem/extension/CMakeLists.txt Creates the VMAware library as a MODULE, which is essential for Ruby extensions as it produces a loadable plugin rather than a standard shared library. ```cmake # ----------------------------------------------------------------------------- # Create the Extension Library # ----------------------------------------------------------------------------- # IMPORTANT: Use MODULE instead of SHARED for Ruby extensions! # # - MODULE: Creates a loadable plugin that cannot be linked against. # This is correct for Ruby extensions loaded via require/dlopen. # - SHARED: Creates a shared library that can be linked against. # On macOS, this creates a .dylib which Ruby cannot load. add_library(${CMAKE_PROJECT_NAME} MODULE) ``` -------------------------------- ### Clone VMAware Repository Source: https://github.com/kernelwernel/vmaware/blob/main/README.md This bash snippet shows how to clone the VMAware repository from GitHub to your local machine. This is the first step for building the project from source or accessing its header files. ```bash git clone https://github.com/kernelwernel/VMAware cd VMAware ``` -------------------------------- ### Add Custom VM Detection Technique (Function Pointer) Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Allows adding a custom VM detection technique using a function pointer. Assigns a score (0-100) indicating the likelihood of a VM if the function returns true. ```cpp // Example 1 with function pointers bool new_technique() { // add your VM detection code here return true; } VM::add_custom(50, new_technique); ``` -------------------------------- ### VM::percentage() Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Returns a percentage indicating the certainty of VM detection based on all available techniques. This provides a more granular result than a simple boolean detection. ```APIDOC ## VM::percentage() ### Description Returns a `std::uint8_t` value between 0 and 100, representing the certainty of VM detection based on all available techniques. A value of 100 means definitely a VM, 0 means definitely not a VM, and values in between indicate uncertainty. ### Method ```cpp std::uint8_t VM::percentage(params...) ``` ### Parameters This function accepts the same flag system as `VM::detect()` to customize the detection process and influence the returned percentage. - **VM::DEFAULT**: Uses default checks for percentage calculation. - **VM::ALL**: Uses all available checks. - **VM::HIGH_THRESHOLD**: Uses a higher detection threshold. - **VM::DISABLE(technique1, technique2, ...)**: Excludes specified techniques from the calculation. ### Request Example ```cpp // Get the certainty percentage with default checks const std::uint8_t percent = VM::percentage(); // Get the certainty percentage using all techniques const std::uint8_t percent_all = VM::percentage(VM::ALL); // Get the certainty percentage with RDTSC technique disabled const std::uint8_t percent_no_rdtsc = VM::percentage(VM::DISABLE(VM::RDTSC)); ``` ### Response - **std::uint8_t**: A value from 0 to 100 indicating the certainty of VM detection. ``` -------------------------------- ### CMake: Download VMAware Header Source: https://github.com/kernelwernel/vmaware/blob/main/README.md This CMake script snippet shows how to download the 'vmaware.hpp' header file from the latest release if it doesn't already exist in the specified directory. It includes progress reporting for the download. ```cmake # edit this set(DIRECTORY "/path/to/your/directory/") set(DESTINATION "${DIRECTORY}vmaware.hpp") if (NOT EXISTS ${DESTINATION}) message(STATUS "Downloading VMAware") set(URL "https://github.com/kernelwernel/VMAware/releases/latest/download/vmaware.hpp") file(DOWNLOAD ${URL} ${DESTINATION} SHOW_PROGRESS) else() message(STATUS "VMAware already downloaded, skipping") endif() ``` -------------------------------- ### Build VMAware on Windows with Visual Studio Source: https://github.com/kernelwernel/vmaware/blob/main/README.md This command demonstrates how to configure the VMAware build on Windows using CMake, specifying the Visual Studio 2019 generator. You can append '-DCMAKE_BUILD_TYPE=Debug' for a debug build. ```bash cmake -S . -B build/ -G "Visual Studio 16 2019" ``` -------------------------------- ### VM::conclusion() Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Returns a conclusion message about the VM detection status, with extended options using the VM::DYNAMIC flag. ```APIDOC ## `VM::conclusion()` ### Description This function returns a conclusion message as a `std::string` indicating whether the system is running on bare metal or inside a VM. The `VM::DYNAMIC` flag allows for more nuanced output messages. ### Usage ```cpp #include "vmaware.hpp" std::cout << VM::conclusion(); // With dynamic flag: // std::cout << VM::conclusion(VM::DYNAMIC); ``` ### Returns - `std::string` - A message such as 'Running on baremetal' or 'Running inside a [brand] VM'. With `VM::DYNAMIC`, more specific likelihoods are returned. ``` -------------------------------- ### Detect VM Hardening Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Detects if the environment shows indications of VM hardening by analyzing technique combinations. This is a heuristic and not a guarantee. ```cpp #include "vmaware.hpp" #include int main() { if (VM::is_hardened()) { std::cout << "Potential hardening detected" << "\n"; } else { std::cout << "Unsure if hardened" << "\n"; } return 0; } ``` -------------------------------- ### Add Custom VM Detection Technique Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Allows adding custom VM detection techniques to the scoring system. Accepts a score (0-100) and a callable (lambda, function pointer, or std::function) that returns a boolean. ```cpp // Example 1 with function pointers bool new_technique() { // add your VM detection code here return true; } VM::add_custom(50, new_technique); ``` ```cpp // Example 2 with lambdas VM::add_custom(50, []() -> bool { // add your VM detection code here return true; }); auto new_technique = []() -> bool { // add your VM detection code here return true; } VM::add_custom(50, new_technique); ``` ```cpp // Example 3 with std::function std::function new_technique = []() -> bool { // add your VM detection code here return true; }; VM::add_custom(50, new_technique); ``` -------------------------------- ### VM::detected_count() Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Fetches the number of detected techniques as a `std::uint8_t`. Returns 0 for baremetal, and typically between 4 and 15 for VMs, with a rare maximum of around 18. ```APIDOC ## `VM::detected_count()` ### Description Fetches the number of techniques detected as a `std::uint8_t`. ### Return Value - `std::uint8_t`: The count of detected techniques. ``` -------------------------------- ### Configure Ruby Extension Output Properties Source: https://github.com/kernelwernel/vmaware/blob/main/gem/extension/CMakeLists.txt Sets properties for the Ruby extension output, including prefix, suffix, output name, visibility settings, and output directories. These settings ensure the extension is built with correct naming conventions and symbol visibility. ```cmake get_target_property(RUBY_EXT_SUFFIX Ruby::Ruby INTERFACE_RUBY_EXTENSION_SUFFIX) set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX "${RUBY_EXT_SUFFIX}" OUTPUT_NAME "vmaware_rb" CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON WINDOWS_EXPORT_ALL_SYMBOLS OFF LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../lib" ) ``` -------------------------------- ### Add Custom VM Detection Technique (Lambda) Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Allows adding a custom VM detection technique using a lambda expression. Assigns a score (0-100) indicating the likelihood of a VM if the lambda returns true. ```cpp // Example 2 with lambdas VM::add_custom(50, []() -> bool { // add your VM detection code here return true; }); auto new_technique = []() -> bool { // add your VM detection code here return true; } VM::add_custom(50, new_technique); ``` -------------------------------- ### Platform Detection Messages Source: https://github.com/kernelwernel/vmaware/blob/main/CMakeLists.txt Prints a status message indicating the detected platform (MSVC, Apple, or Linux). ```cmake if (MSVC) message(STATUS "MSVC generator detected") elseif(APPLE) message(STATUS "Apple platform detected") elseif(LINUX) message(STATUS "Linux platform detected") else() message(STATUS "Unknown platform") endif() ``` -------------------------------- ### VM::percentage() Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Returns the certainty of VM detection as a percentage (0-100). This function can also utilize the same flag system as VM::detect() to customize the detection process. ```APIDOC ## VM::percentage() ### Description Returns the certainty of VM detection as a percentage (0-100). This function can also utilize the same flag system as VM::detect() to customize the detection process. ### Method ```cpp std::uint8_t VM::percentage(flags...) ``` ### Parameters #### Flags Supports the same flags as `VM::detect()`, such as `VM::DEFAULT`, `VM::ALL`, `VM::NO_MEMO`, `VM::HIGH_THRESHOLD`, `VM::DISABLE(...)`, etc. ### Request Example ```cpp // Get the certainty percentage with default checks std::uint8_t certainty = VM::percentage(); // Get the certainty percentage with all checks enabled std::uint8_t certainty_all = VM::percentage(VM::ALL); // Get the certainty percentage with a disabled technique std::uint8_t certainty_disabled = VM::percentage(VM::DISABLE(VM::VMID)); ``` ### Response - **std::uint8_t**: A value between 0 and 100 representing the certainty of VM detection. ``` -------------------------------- ### Link DbgHelp Library on Windows Source: https://github.com/kernelwernel/vmaware/blob/main/CMakeLists.txt Links the DbgHelp library for Windows to enable stack trace functionality, particularly useful for debugging timeouts. ```cmake # DbgHelp for stack traces on timeout (Windows only) target_link_libraries(${TARGET} PRIVATE $<$:DbgHelp>) ``` -------------------------------- ### VM::add_custom() Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Allows users to add their own custom VM detection techniques to the library's scoring system. ```APIDOC ## `VM::add_custom()` ### Description This function enables the addition of custom VM detection techniques. It takes a score and a callable (lambda, function pointer, or `std::function`) that returns a boolean. ### Usage ```cpp #include "vmaware.hpp" #include // Using a function pointer bool my_technique() { return true; } VM::add_custom(50, my_technique); // Using a lambda VM::add_custom(75, []() -> bool { return true; }); // Using std::function std::function custom_func = []() -> bool { return true; }; VM::add_custom(25, custom_func); ``` ### Parameters - `score` (int) - Required - The percentage score (0-100) if the custom technique returns `true`. - `technique` (lambda, function pointer, or `std::function`) - Required - The custom VM detection logic. ``` -------------------------------- ### C++ Code Style and Best Practices Source: https://github.com/kernelwernel/vmaware/blob/main/CONTRIBUTING.md Demonstrates C++11 compatible coding standards including variable declaration, conditional statements, loop usage, and magic number avoidance. Follow these guidelines for readability and simplicity. ```cpp int main() { const u32 number = 10; // 1. use const whenever it should be used. // 2. use the rust integral type convention from 8 to 64 (i.e. i8, u16, u64, etc...) // 3. keep the names as simple and clear as possible, don't call it "n", call it "number". // Try to name the variables into something that can universally be discerned by anybody, // Make sure it's also context-aware and should make sense. Calling it "tmp" is also fine. // Consistency is also key in this aspect, don't do "u32 number = find_num()", do find_number(). if (number >= 54) { // 4. avoid magic numbers, put a comment or make a constexpr variable prior to using it, something(); // preferably the latter. } else if (number) { // 5. make the if, else if, and else statement lines the same without breaking lines, so don't do: something_else(); // if () } // { // something(); // } // else // { // something_else(); // } // // try to follow as shown in this actual demonstration. if ( ((number % 4) == 0) && // 6. use separate lines for each statement of a condition check. While this might look ok (number > 50) && // on a single line, in practice your conditions will most likely not be as short and (number < 100) // and simple as this. Try to avoid multiple condition checks in a single line for simplicity. ) { something() } for (u8 i = 0; i < number; i++) { // 6. Be as simple as possible without using fancy features like iterators if it's not necessary. something(); } // Other rules will be added in the future, this is just a rough guideline for the moment. } ``` -------------------------------- ### VM::brand() Source: https://github.com/kernelwernel/vmaware/blob/main/docs/documentation.md Returns the detected VM brand as a std::string. It can also return a combined string of multiple detected brands if the VM::MULTIPLE flag is used. ```APIDOC ## `VM::brand()` ### Description Returns the VM brand as a `std::string`. If multiple brands are detected, it can return a combined string of detected brands when the `VM::MULTIPLE` flag is used. ### Parameters - `VM::MULTIPLE` (flag, optional): If provided, returns a string listing all detected brands separated by ' or '. ### Returns - `std::string`: The detected VM brand, a combination of brands, or 'Unknown' if none are detected. ### Example Usage ```cpp #include "vmaware.hpp" #include int main() { const std::string result = VM::brand(); // ... const std::string multiple_results = VM::brand(VM::MULTIPLE); return 0; } ``` ``` -------------------------------- ### VM::detect() Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Detects if the current environment is a virtual machine. It can perform default checks or be customized with various flags to include or exclude specific detection techniques, control memoization, and adjust the detection threshold. ```APIDOC ## VM::detect() ### Description Detects if the current environment is a virtual machine. It can perform default checks or be customized with various flags to include or exclude specific detection techniques, control memoization, and adjust the detection threshold. ### Method ```cpp bool VM::detect(flags...) ``` ### Parameters #### Flags - **VM::DEFAULT**: Performs all recommended checks. - **VM::ALL**: Performs all checks, including spoofable and disabled-by-default techniques like VM::CURSOR (which introduces a 5-second delay). - **VM::NO_MEMO**: Disables result caching. - **VM::HIGH_THRESHOLD**: Increases the detection threshold, potentially leading to false negatives but higher certainty when a VM is detected. - **VM::CPU_BRAND, VM::MAC, VM::HYPERVISOR_BIT**: Specifies individual techniques to perform. - **VM::DISABLE(technique1, technique2, ...)**: Excludes specified techniques from the detection process. ### Request Example ```cpp // Basic detection bool is_vm = VM::detect(); // Detect with all checks bool is_vm_all = VM::detect(VM::ALL); // Detect without memoization bool is_vm_no_memo = VM::detect(VM::NO_MEMO); // Detect with specific techniques bool is_vm_specific = VM::detect(VM::CPU_BRAND, VM::MAC, VM::HYPERVISOR_BIT); // Detect with a disabled technique bool is_vm_disable = VM::detect(VM::DISABLE(VM::RDTSC)); // Combined flags bool is_vm_combined = VM::detect(VM::DEFAULT, VM::NO_MEMO, VM::HIGH_THRESHOLD, VM::DISABLE(VM::VMID, VM::RDTSC)); ``` ### Response - **bool**: Returns `true` if a VM is detected, `false` otherwise. ``` -------------------------------- ### VM::brand() Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Returns the detected VM brand as a std::string. It can also return 'Unknown' if no brand is detected or a combined string of detected brands if VM::MULTIPLE flag is used. ```APIDOC ## `VM::brand()` ### Description This function returns the detected VM brand as a `std::string`. If multiple brands are detected, it can return a combined string of brands when the `VM::MULTIPLE` flag is used. ### Usage ```cpp #include "vmaware.hpp" #include const std::string result = VM::brand(); // or with MULTIPLE flag: const std::string result_multiple = VM::brand(VM::MULTIPLE); ``` ### Parameters - `VM::MULTIPLE` (flag) - Optional - If provided, returns a string listing all detected VM brands separated by ' or '. ``` -------------------------------- ### VM::detected_count() Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Fetches the total number of VM detection techniques that have been successfully detected. ```APIDOC ## `VM::detected_count()` ### Description This function returns the count of VM detection techniques that have been successfully identified by the library. ### Usage ```cpp #include "vmaware.hpp" std::uint8_t count = VM::detected_count(); ``` ### Returns - `std::uint8_t` - The number of detected VM techniques. ``` -------------------------------- ### VM::type() Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Returns the VM type or architecture as a std::string based on the detected VM brand. ```APIDOC ## `VM::type()` ### Description This function returns the VM type or architecture as a `std::string`, determined by the VM brand that was found. ### Usage ```cpp #include "vmaware.hpp" #include std::cout << VM::brand() << " is a " << VM::type() << " VM\n"; ``` ### Returns - `std::string` - The type or architecture of the VM. ``` -------------------------------- ### Check VM Detection Technique Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Checks if a specific VM detection technique is effective. Returns a boolean value indicating the result of the technique. ```cpp #include "vmaware.hpp" #include int main() { if (VM::check(VM::VMID)) { std::cout << "VMID technique detected a VM!\n"; } if (VM::check(VM::HYPERVISOR_BIT)) { std::cout << "Hypervisor bit is set, most definitely a VM!\n"; } } ``` -------------------------------- ### VM::check() Source: https://github.com/kernelwernel/vmaware/wiki/Documentation Checks if a specific VM detection technique is effective, returning a boolean value. ```APIDOC ## `VM::check()` ### Description This function takes a single technique argument and returns a `bool` indicating whether the technique is effective. ### Usage ```cpp #include "vmaware.hpp" if (VM::check(VM::VMID)) { // VMID technique detected a VM } ``` ### Parameters - `technique` (enum/constant) - Required - The VM detection technique to check (e.g., `VM::VMID`, `VM::HYPERVISOR_BIT`). ``` -------------------------------- ### Configure Ruby Detection with Rice's FindRuby.cmake Source: https://github.com/kernelwernel/vmaware/blob/main/gem/extension/CMakeLists.txt Prepends the Rice module path to CMAKE_MODULE_PATH to ensure CMake uses Rice's enhanced FindRuby.cmake script. This provides proper CMake targets for Ruby, improving integration. ```cmake # ----------------------------------------------------------------------------- # Configure Ruby Detection # ----------------------------------------------------------------------------- # Rice provides an enhanced FindRuby.cmake that creates proper CMake targets # (Ruby::Ruby, Ruby::Module) instead of just setting variables. We prepend # Rice's module path so CMake finds this improved version. # # The upstream CMake FindRuby.cmake is being updated to support these targets, # but until that lands, we use Rice's version. list(PREPEND CMAKE_MODULE_PATH "${rice_SOURCE_DIR}") ```