Skip to content

Commit

Permalink
Merge pull request #92 from kernelwernel/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
kernelwernel authored Jun 10, 2024
2 parents 15f3027 + 651fcfa commit 3b91815
Show file tree
Hide file tree
Showing 13 changed files with 999 additions and 694 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build_run_win_32.bat
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ cmake -DCMAKE_BUILD_TYPE=Debug -G "Visual Studio 17 2022" -A Win32 -S ..
"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\devenv.com" "VMAware.sln" /Build "Release|Win32" /Project "vmaware" /ProjectConfig "Release|Win32"
cd Release
vmaware.exe
vmaware.exe --discard-hyper-v
1 change: 1 addition & 0 deletions .github/workflows/build_run_win_64.bat
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ cmake -DCMAKE_BUILD_TYPE=Debug -G "Visual Studio 17 2022" -A x64 -S ..
"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\devenv.com" "VMAware.sln" /Build "Release|x64" /Project "vmaware" /ProjectConfig "Release|x64"
cd Release
vmaware.exe
vmaware.exe --discard-hyper-v
2 changes: 1 addition & 1 deletion .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ jobs:
working-directory: ${{ steps.strings.outputs.build-output-dir }}
# Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest --build-config --rerun-failed --output-on-failure ${{ matrix.build_type }}
run: ctest --build-config --rerun-failed --verbose --output-on-failure ${{ matrix.build_type }}
26 changes: 12 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,24 @@ project(
)


# set c++ standard
if(NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 20)
endif()


# compiler flags
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

if (MSVC)
set(CMAKE_CXX_FLAGS "/Wall /W4 /std:c++20 /EHsc")
set(CMAKE_CXX_FLAGS "/Wall /W4 /EHsc")
else()
set(CMAKE_CXX_FLAGS "-Wextra -Wall -Wextra -Wconversion -Wdouble-promotion -Wno-unused-parameter -Wno-unused-function -Wno-sign-conversion -fmax-errors=20")
set(CMAKE_CXX_FLAGS "-Wextra -Wall -Wextra -Wconversion -Wdouble-promotion -Wno-unused-parameter -Wno-unused-function -Wno-sign-conversion")
endif()

if(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -lstdc++ -lm")
else()
message("Unsupported compiler")
endif()


Expand Down Expand Up @@ -61,7 +64,7 @@ if (MSVC)
elseif(LINUX)
if(CMAKE_BUILD_TYPE MATCHES "Debug")
MESSAGE(STATUS "Build set to debug mode")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -DDEBUG -O0 -fsanitize=address")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fmax-errors=20 -DDEBUG -O0 -fsanitize=address")
elseif(CMAKE_BUILD_TYPE MATCHES "Release")
MESSAGE(STATUS "Build set to release mode")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g0 -O3")
Expand All @@ -77,7 +80,9 @@ endif()
# add executable
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${BUILD_DIR}")
add_executable(${TARGET} "src/cli.cpp")
set_property(TARGET ${TARGET} PROPERTY CXX_STANDARD 20)
if(NOT DEFINED CMAKE_CXX_STANDARD)
set_property(TARGET ${TARGET} PROPERTY CXX_STANDARD 20)
endif()
set_property(TARGET ${TARGET} PROPERTY CXX_STANDARD_REQUIRED ON)


Expand All @@ -91,13 +96,6 @@ else()
add_test(executable, "${BUILD_DIR}/${TARGET}")
endif()

#if(NOT MSVC)
#add_test(
# checks
# ${Python_EXECUTABLE} "${CMAKE_SOURCE_DIR}/cmake/ctest_checks.py"
#)
#endif()


# release stuff
if (NOT MSVC)
Expand Down
8 changes: 4 additions & 4 deletions auxiliary/arg_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
#
# =============================================================
#
# This is just an internal script for CI/CD. The main goal is to
# check whether all of the techniques are actually updated since
# keeping track of the docs, the cli, and the table isn't easy,
# so I'm automating the checks in case I forget to update any.
# This is just an internal script for CI/CD. The main goal is to
# check whether all of the techniques are actually updated since
# keeping track of the docs, the cli, and the table isn't easy,
# so I'm automating the checks in case I forget to update any.
#
# ===============================================================
#
Expand Down
4 changes: 2 additions & 2 deletions auxiliary/cpuid_fuzzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
*
* ===============================================================
*
* This program serves as an internal tool for fuzzing cpuid values
* and comparing them between baremetal outputs and VM outputs.
* This program serves as an internal tool for fuzzing cpuid values
* and comparing them between baremetal outputs and VM outputs.
*
* ===============================================================
*
Expand Down
38 changes: 36 additions & 2 deletions auxiliary/test_standards.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,47 @@
#
# ===============================================================
#
# This script is designed to test different C++ standards to see
# if there are any edgecases before releasing it
# This script is designed to test different C++ standards to see
# if there are any edgecases before releasing it
#
# ===============================================================
#
# - Made by: @kernelwernel (https://github.com/kernelwernel)
# - Repository: https://github.com/kernelwernel/VMAware
# - License: GPL 3.0

clear

current_dir=$(pwd)
rm -rf build/
mkdir build/ 2>/dev/null
cd build/

standards=("11" "14" "17" "20" "23")

for version in "${standards[@]}"; do
echo "[LOG] Running cmake with $version standard"
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_STANDARD=$version ../..

echo "[LOG] make"
make
make_status=$?

if [ $make_status -ne 0 ]; then
exit
fi

cp ../../build/vmaware .

echo "[LOG] ./vmaware"
./vmaware 2>&1
vmaware_status=$?

if [ $vmaware_status -ne 0 ]; then
exit
fi
done

cd $(current_dir)

rm -rf build
8 changes: 4 additions & 4 deletions auxiliary/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
#
# ===============================================================
#
# This is an internal script to update the VMAware
# header file's banner automatically and much more reliably.
# For example, it'll update the line numbers for the sections
# header, and other basic information.
# This is an internal script to update the VMAware
# header file's banner automatically and much more reliably.
# For example, it'll update the line numbers for the sections
# header, and other basic information.
#
# ===============================================================
#
Expand Down
30 changes: 29 additions & 1 deletion auxiliary/vmtest.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,35 @@
/**
* ██╗ ██╗███╗ ███╗ █████╗ ██╗ ██╗ █████╗ ██████╗ ███████╗
* ██║ ██║████╗ ████║██╔══██╗██║ ██║██╔══██╗██╔══██╗██╔════╝
* ██║ ██║██╔████╔██║███████║██║ █╗ ██║███████║██████╔╝█████╗
* ╚██╗ ██╔╝██║╚██╔╝██║██╔══██║██║███╗██║██╔══██║██╔══██╗██╔══╝
* ╚████╔╝ ██║ ╚═╝ ██║██║ ██║╚███╔███╔╝██║ ██║██║ ██║███████╗
* ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝
*
* C++ VM detection library
*
* ===============================================================
*
* This program serves as a testing ground, it's not interesting tbh
* so I recommend you move on
*
* ===============================================================
*
* - Made by: @kernelwernel (https://github.com/kernelwernel)
* - Repository: https://github.com/kernelwernel/VMAware
* - License: GPL 3.0
*/

#include "../src/vmaware.hpp"
#include <iostream>

int main(void) {
std::cout << VM::detect() << "\n";
const bool test1 = VM::detect();
const bool test2 = VM::detect(VM::ALL);
const bool test3 = VM::detect(VM::DEFAULT);
const bool test4 = VM::detect(VM::DEFAULT, VM::ALL);
const bool test5 = VM::detect(VM::DEFAULT, VM::DISABLE(VM::RDTSC));
const bool test6 = VM::detect(VM::DEFAULT, VM::DISABLE(VM::RDTSC), VM::EXTREME);
const bool test7 = VM::detect(VM::NO_MEMO, VM::EXTREME, VM::MULTIPLE, VM::DISCARD_HYPERV_DEFAULT);
return 0;
}
19 changes: 12 additions & 7 deletions docs/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ int main() {
* 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_vm2 = VM::detect(VM::BRAND, VM::MAC, VM::HYPERV_BIT);
bool is_vm2 = VM::detect(VM::BRAND, VM::MAC, VM::HYPERVISOR_BIT);


/**
Expand Down Expand Up @@ -66,10 +66,18 @@ int main() {


/**
* If you want to disable any techniques for whatever reason, use VM::DISABLE().
* This will essentially mean "perform all the default flags, but only disable
* the VM::RDTSC technique".
*/
bool is_vm6 = VM::detect(VM::DEFAULT & ~(VM::RDTSC));
bool is_vm6 = VM::detect(VM::DISABLE(VM::RDTSC));


/**
* Same as above, but you can disable multiple techniques at the same time.
*/
bool is_vm6 = VM::detect(VM::DISABLE(VM::VMID, VM::RDTSC));

}
```

Expand Down Expand Up @@ -158,7 +166,7 @@ int main() {
## `VM::check()`
This takes a single flag argument and returns a `bool`. It's essentially the same as `VM::detect()` but it doesn't have a scoring system. It only returns the technique's effective output. The reason why this exists is because it allows end-users to have fine-grained control over what is being executed and what isn't.

`VM::detect()` is meant for a range of techniques to be evaluated in the bigger picture with weights and biases in its scoring system, while `VM::check()` is meant for a single technique to be evaluated without any points or anything extra. It just gives you what the technique has found on its own. For example:
`VM::detect()` is meant for a range of techniques to be evaluated in the bigger picture with weights and biases in its scoring system, while `VM::check()` is meant for a single technique to be evaluated without any points or anything extra. It very simply just gives you what the technique has found on its own. For example:

```cpp
#include "vmaware.hpp"
Expand All @@ -172,9 +180,6 @@ int main() {
if (VM::check(VM::HYPERVISOR_BIT)) {
std::cout << "Hypervisor bit is set, most definitely a VM!\n";
}

// invalid, will throw an std::invalid_argument exception
bool result = VM::check(VM::VMID | VM::HYPERVISOR_BIT);
}
```

Expand Down Expand Up @@ -353,5 +358,5 @@ VMAware provides a convenient way to not only check for VMs, but also have the f
| `VM::NO_MEMO` | This will disable memoization, meaning the result will not be fetched through a previous computation of the `VM::detect()` function. Use this if you're only using a single function from the `VM` struct for a performance boost. |
| `VM::EXTREME` | This will disregard the weights/biases and its scoring system. It will essentially treat any technique that found a hit as a VM detection no matter how low that technique's certainty is, so if a single technique is positive then it will return true. |
| `VM::DEFAULT` | This represents a range of flags which are enabled if no default argument is provided. The reason why this exists is to easily disable any bits manually (shown in the is_vm6 example in the `VM::detect()` section)
| `VM::WIN_HYPERV_DEFAULT` | Windows 11 (and sometimes 10) may have Hyper-V as a default virtualisation software for any program even if the OS is running as host, which is one of the main hurdles of the library to overcome between host virtualisation and actual virtualisation. The library will discard any Hyper-V brand suspicions as not running in a VM. This flag will basically mean "I'm aware this program might be running in a default virtualised environment even if the user is only using the host environment, but I'll still count this as running in a VM anyway whether it's default virtualisation or manual virtualisation" |
| `VM::DISCARD_HYPERV_DEFAULT` | Windows 11 (and sometimes 10) may have Hyper-V as a default virtualisation software for any program even if the OS is running as host, which is one of the main hurdles of the library to overcome between host virtualisation and actual virtualisation. The library will discard any Hyper-V brand suspicions as not running in a VM. This flag will basically mean "I'm aware this program might be running in a default virtualised environment even if the user is only using the host environment, but I'll still count this as running in a VM anyway whether it's default virtualisation or manually intended virtualisation" |
| `VM::MULTIPLE` | This is specific to `VM::brand()`. This will basically return a `std::string` message of what brands could be involved. For example, it could return "`VMware or VirtualBox`" instead of having a single brand string output. |
Loading

0 comments on commit 3b91815

Please sign in to comment.