diff --git a/VMAware/CMakeLists.txt b/VMAware/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7973b842fdad01183607625785bff83d976096dc
--- /dev/null
+++ b/VMAware/CMakeLists.txt
@@ -0,0 +1,111 @@
+# basic info
+cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
+project(
+    VMAware
+    DESCRIPTION "VM detection library"
+    LANGUAGES CXX
+)
+
+
+# set c++ standard
+if(NOT DEFINED CMAKE_CXX_STANDARD)
+    set(CMAKE_CXX_STANDARD 20)
+endif()
+
+
+# compiler flags
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+
+if (MSVC)
+    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")
+endif()
+
+if(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU")
+    set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -lstdc++ -lm")
+endif()
+
+
+# fetch and set build type
+set(available_build_types Debug Release)
+if(NOT CMAKE_BUILD_TYPE)
+set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build (Debug or Release)" FORCE)
+endif()
+if(NOT CMAKE_BUILD_TYPE IN_LIST available_build_types)
+MESSAGE(FATAL_ERROR "Invalid build type: ${CMAKE_BUILD_TYPE}. Allowed values: ${available_build_types}")
+endif()
+
+
+# Define preprocessor macros based on the build type
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+add_compile_definitions(__VMAWARE_DEBUG__)
+elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
+add_compile_definitions(__VMAWARE_RELEASE__)
+endif()
+
+
+# general variables
+set(PROJECT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+set(BUILD_DIR "${PROJECT_DIR}/build")
+set(TARGET "vmaware")
+
+
+# debug/release CXX flag options
+if (MSVC)
+    if(CMAKE_BUILD_TYPE MATCHES "Debug")
+        MESSAGE(STATUS "Build set to debug mode")
+        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Od")
+    elseif(CMAKE_BUILD_TYPE MATCHES "Release")
+        MESSAGE(STATUS "Build set to release mode")
+        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2")
+    endif()
+elseif(LINUX)
+    if(CMAKE_BUILD_TYPE MATCHES "Debug")
+        MESSAGE(STATUS "Build set to debug mode")
+        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fmax-errors=5 -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 -O2")
+        if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64")
+            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mtune=native")
+        elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
+            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=native")
+        endif()
+    endif()
+endif()
+
+
+# add executable
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${BUILD_DIR}")
+add_executable(${TARGET} "src/cli.cpp")
+if(NOT DEFINED CMAKE_CXX_STANDARD)
+    set_property(TARGET ${TARGET} PROPERTY CXX_STANDARD 20)
+endif()
+set_property(TARGET ${TARGET} PROPERTY CXX_STANDARD_REQUIRED ON)
+
+
+# CTest stuff
+include(CTest)
+enable_testing()
+set(ARGUMENTS "--all")
+if(MSVC)
+add_test(executable, "${BUILD_DIR}/Release/${TARGET}")
+else()
+add_test(NAME TARGET COMMAND "${BUILD_DIR}/${TARGET}" ${ARGUMENTS})
+endif()
+
+
+# release stuff
+if (NOT MSVC)
+    if(CMAKE_BUILD_TYPE MATCHES "Release")
+        install(TARGETS ${TARGET} DESTINATION /usr/local/bin)
+        install(FILES "src/vmaware.hpp" DESTINATION /usr/include)
+    else()
+        install(TARGETS ${TARGET} DESTINATION ${CMAKE_SOURCE_DIR})
+    endif()
+elseif(MSVC)
+    set(CMAKE_INSTALL_PREFIX "C:\\Program Files\\YourApplication")
+    install(TARGETS ${TARGET} DESTINATION .)
+endif()
\ No newline at end of file
diff --git a/VMAware/COPYING b/VMAware/COPYING
new file mode 100644
index 0000000000000000000000000000000000000000..3877ae0a7ff6f94ac222fd704e112723db776114
--- /dev/null
+++ b/VMAware/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/VMAware/LICENSE b/VMAware/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..89665167932369ea5d77fb157d205b27b2f9770d
--- /dev/null
+++ b/VMAware/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 kernelwernel
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/VMAware/README.md b/VMAware/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..b010d8f3e797758fb1c87ae7853754fff5dc085a
--- /dev/null
+++ b/VMAware/README.md
@@ -0,0 +1,239 @@
+<h1 align="center">VMAware</h1>
+<br>
+<p align="center">
+<img src="assets/banner.jpg" align="center" width="500" title="VMAware">
+<br>
+<img align="center" src="https://img.shields.io/github/actions/workflow/status/kernelwernel/VMAware/cmake-multi-platform.yml">
+<img align="center" src="https://img.shields.io/github/downloads/kernelwernel/VMAware/total">
+<img align="center" src="https://img.shields.io/github/license/a0rtega/pafish">
+<img align="center" src="https://img.shields.io/github/license/kernelwernel/Tourneys-bot">
+</p>
+
+**VMAware** (VM + Aware) is a cross-platform C++ library for virtual machine detection.
+
+The library is:
+- Very easy to use
+- Cross-platform (Windows + MacOS + Linux)
+- Compatible with x86 and ARM, with backwards compatibility for 32-bit systems
+- Features up to 100+ unique VM detection techniques [[list](https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#flag-table)]
+- Able to detect 50+ VM brands including VMware, VirtualBox, QEMU, Hyper-V, and much more [[list](https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmbrand)]
+- Very flexible, with total fine-grained control over which techniques get executed
+- Able to detect various semi-VM technologies like hypervisors, emulators, containers, and so on
+- Available with C++11 and above
+- Header-only
+- Memoized, meaning past results are cached and retrieved if ran again for performance benefits 
+- Contains separate MIT and GPL-3.0 compliant library header files
+
+
+<br>
+
+
+## Example 🧪
+```cpp
+#include "vmaware.hpp"
+#include <iostream>
+
+int main() {
+    if (VM::detect()) {
+        std::cout << "Virtual machine detected!" << "\n";
+        std::cout << "VM name: " << VM::brand() << "\n";
+    } else {
+        std::cout << "Running in baremetal" << "\n";
+    }
+    
+    std::cout << "VM certainty: " << (int)VM::percentage() << "%" << "\n";
+}
+```
+
+<br>
+
+## Structure ⚙️
+
+<p align="center">
+<img src="assets/vmaware.drawio.png" align="center" title="VMAware">
+<br>
+</p>
+
+<br>
+
+## CLI tool 🔧
+This project also provides a tiny, but handy CLI tool utilising the full potential of what the library can do. It'll give you all sorts of details about the environment it's running under.
+
+<img src="assets/demo.jpg" width="500" title="cli">
+
+<br>
+
+## Installation 📥
+To install the library, download the `vmaware.hpp` file in the latest [release section](https://github.com/kernelwernel/VMAware/releases/latest) to your project. No CMake or shared object linkages are necessary, it's literally that simple.
+
+However, if you want the full project (globally accessible headers with <vmaware.hpp> and the CLI tool), follow these commands:
+```bash
+git clone https://github.com/kernelwernel/VMAware 
+cd VMAware
+```
+
+### FOR LINUX:
+```bash
+sudo dnf/apt/yum update -y # change this to whatever your distro is
+mkdir build
+cd build
+cmake ..
+sudo make install
+```
+
+### FOR WINDOWS:
+```bash
+cmake -S . -B build/ -G "Visual Studio 16 2019"
+```
+
+### CMake installation
+```cmake
+set(DESTINATION "/path/to/destination/vmaware.hpp") # set this manually
+
+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()
+```
+
+<br>
+
+If you just want the binaries, head over to the latest [release section](https://github.com/kernelwernel/VMAware/releases/latest)
+
+<br>
+
+## Documentation 📒
+You can view the full docs [here](docs/documentation.md). All the details such as functions, techniques, settings and examples are provided. Trust me, it's not too intimidating ;)
+
+<br>
+
+## Q&A ❓
+
+<details>
+<summary>How does it work?</summary>
+<br>
+
+> It utilises a comprehensive list of low-level and high-level anti-VM techniques that gets accounted in a scoring system. The scores (0-100) for each technique are arbitrarily given, and every technique that has detected a VM will have their score added to a single accumulative point, where a threshold point number will decide whether it's actually running in a VM.
+
+</details>
+
+<details>
+<summary>Who is this library for and what are the use cases?</summary>
+<br>
+
+> It's designed for security researchers, VM engineers, gamer developers, and pretty much anybody who needs a practical and rock-solid VM detection mechanism in their project. For example, the library is suitable if you're making a VM and you're testing the effectiveness of concealing itself. If you're a game developer/proprietary software developer, the library is useful to thwart against reverse engineers. If you're a malware analyst and you want to check the concealment capability of your VM, this would be the perfect tool to benchmark how well-concealed your VM is against malware. Additionally, software could optimize performance or resource usage based on the detected environment, and some applications might want to restrict usage in VMs to prevent unauthorized distribution or testing.
+
+</details>
+
+<details>
+<summary>Why another VM detection project?</summary>
+<br>
+
+> There's already loads of projects that have the same goal such as 
+<a href="https://github.com/CheckPointSW/InviZzzible">InviZzzible</a>, <a href="https://github.com/a0rtega/pafish">pafish</a> and <a href="https://github.com/LordNoteworthy/al-khaser">Al-Khaser</a>. But the difference between the aforementioned projects is that they don't provide a programmable interface to interact with the detection mechanisms, on top of having little to no support for non-Windows systems. I wanted the core detection techniques to be accessible programmatically in a cross-platform way for everybody to get something useful out of it rather than providing just a CLI tool. It also contains a larger quantity of techniques, so it's basically just a VM detection library and tool on steroids with maximum flexibility.
+
+</details>
+
+
+<details>
+<summary>How does it compare to paid VM detection libraries? Wouldn't it make it inferior for having it open source?</summary>
+<br>
+
+> There are a few paid software to protect the licensing of other software against against reverse engineers or software cracking, such as <a href="https://docs.sentinel.thalesgroup.com/home.htm">Thales' Sentinel RMS</a> and <a href="https://vmpsoft.com/">VMProtect</a>. Although these are not meant to ONLY be VM detection libraries, they are limited in their capabilities in different ways. Sentinel RMS' VM detection does not have as many VM brands (not to mention the pricing is only meant for corporations, not individuals), and VMProtect has a <a href="https://cyber.wtf/2023/02/09/defeating-vmprotects-latest-tricks/">very limited number of detection techniques</a>, where some of them don't require a lot of effort to bypass with only a few configurations to the VM (the detection mechanism has also been <a href="https://github.com/jmpoep/vmprotect-3.5.1/blob/d8fcb7c0ffd4fb45a8cfbd770c8b117d7dbe52b5/runtime/loader.cc#L2464">leaked</a>, so there's no benefit of having it closed source now). Speaking of which, the only downside to VMAware is that it's fully open source, which makes the job of bypassers easier compared to having it closed source. However, I'd argue that's a worthy tradeoff by having as many VM detection techniques in an open and interactive way, including having valuable community feedback to make the library more effective and accurate.
+
+</details>
+
+
+<details>
+<summary>How can the library distinguish between Hyper-V artifacts and an actual Hyper-V VM in the system?</summary>
+<br>
+
+> Hyper-V has an obscure feature where if it's enabled in the host system, the CPU hardware values makes it look like the whole system is running inside Hyper-V, which isn't true. This makes it a challenge to determine whether the hardware values the library is collecting is either a real Hyper-V VM, or just the artifacts of what Hyper-V has left as a consequence of having it enabled in the host system. The reason why this is a problem is because the library might falsely conclude that your the host system is running in Hyper-V, which is a false positive. This is where the **Hyper-X** mechanism comes into play to distinguish between these two. This was designed by <a href="https://github.com/NotRequiem">Requiem</a>
+
+<p align="center">
+<img src="assets/hyper-x/v4/Hyper-X_version_4.drawio.png" align="center" title="Hyper-X">
+<br>
+</details>
+
+
+<details>
+<summary>Is it possible to spoof the result?</summary>
+<br>
+
+> Yes. There are some techniques that are trivially spoofable, and there's nothing the library can do about it whether it's a deliberate false positive or even a false negative. This is a problem that every VM detection project is facing whether closed or open source, which is why the library is trying to test every technique possible to get the best result based on the environment it's running under. Remember, EVERYTHING is technically spoofable.
+
+</details>
+
+<details>
+<summary>What about using this for malware?</summary>
+<br>
+
+> This project is not soliciting the development of malware for obvious reasons. Even if you intend to use it for concealment purposes, it'll most likely be flagged by antiviruses anyway and nothing is obfuscated to begin with. Good fucking luck obfuscating 10k+ lines of C++ code lmao.
+
+</details>
+
+<details>
+<summary>Why GPL-3.0 and MIT?</summary>
+<br>
+
+> I would've made it strictly MIT so proprietary software can make use of the library, but some of the techniques employed are from GPL 3.0 projects, and I have no choice but to use the same license for legal reasons. This gave me an idea to make an MIT version without all of the GPL code so it can also be used without forcing your code to be open-source. It should be noted that the MIT version removes <b>12</b> techniques out of 116 (as of 1.9 version), and the lesser the number of techniques, the less accurate the overall result might be.
+
+</details>
+
+<details>
+<summary>I have linker errors when compiling</summary>
+<br>
+
+> If you're compiling with gcc or clang, add the <code>-lm</code> and <code>-lstdc++</code> flags, or use g++/clang++ compilers instead. If you're receiving linker errors from a brand new VM environment on Linux, update your system with `sudo apt/dnf/yum update -y` to install the necessary C++ components.
+
+</details>
+
+
+<br>
+
+## Issues and pull requests 📬
+If you have any suggestions, ideas, or any sort of contribution, feel free to ask! I'll be more than happy to discuss in the [issue](https://github.com/kernelwernel/VMAware/issues) section. If you want to personally ask something in private, my discord is `kr.nl`
+
+And if you found this project useful, a star would be appreciated :)
+
+<br>
+
+## Credits and contributors ✒️
+- [Check Point Research](https://research.checkpoint.com/)
+- [Unprotect Project](https://unprotect.it/)
+- [Al-Khaser](https://github.com/LordNoteworthy/al-khaser)
+- [pafish](https://github.com/a0rtega/pafish)
+- [Matteo Malvica](https://www.matteomalvica.com)
+- N. Rin, EP_X0FF
+- [Peter Ferrie, Symantec](https://github.com/peterferrie)
+- [Graham Sutherland, LRQA Nettitude](https://www.nettitude.com/uk/)
+- [Requiem](https://github.com/NotRequiem)
+- [Alex](https://github.com/greenozon)
+- [Marek Knápek](https://github.com/MarekKnapek)
+- [Vladyslav Miachkov](https://github.com/fameowner99)
+- [(Offensive Security) Danny Quist](chamuco@gmail.com)
+- [(Offensive Security) Val Smith](mvalsmith@metasploit.com)
+- Tom Liston + Ed Skoudis
+- [Tobias Klein](https://www.trapkit.de/index.html)
+- [(S21sec) Alfredo Omella](https://www.s21sec.com/)
+- [hfiref0x](https://github.com/hfiref0x)
+- [Waleedassar](http://waleedassar.blogspot.com)
+- [一半人生](https://github.com/TimelifeCzy)
+- [Thomas Roccia (fr0gger)](https://github.com/fr0gger)
+- [systemd project](https://github.com/systemd/systemd)
+- mrjaxser
+- [iMonket](https://github.com/PrimeMonket)
+- Eric Parker's discord community 
+- [ShellCode33](https://github.com/ShellCode33)
+- [Georgii Gennadev (D00Movenok)](https://github.com/D00Movenok)
+- [utoshu](https://github.com/utoshu)
+
+<br>
+
+## Legal 📜
+I am not responsible nor liable for any damage you cause through any malicious usage of this project. 
+
+License: GPL-3.0/MIT
\ No newline at end of file
diff --git a/VMAware/TODO.md b/VMAware/TODO.md
new file mode 100644
index 0000000000000000000000000000000000000000..016bb8342c344baefbfae3487da4ca68e308b77b
--- /dev/null
+++ b/VMAware/TODO.md
@@ -0,0 +1,71 @@
+- [ ] analyse the UUID check technique's efficiency
+- [X] fix c++11 debug function param error
+- [X] completely remove std::system() grep commands
+- [ ] add github metrics for license (looks cool af)
+- [X] add CTest before alpha release
+- [ ] test for processor type and stuff like that for cpuid EAX=1
+- [ ] grep everywhere for QEMU shit
+- [X] implement VM::EXTREME flag
+- [X] update the cli tool image in the readme
+- [X] focus on hyperv detection (https://labs.nettitude.com/blog/vm-detection-tricks-part-3-hyper-v-raw-network-protocol/)
+- [X] add percentage overload functionality for VM::detect()
+- [X] maybe document the project in codeproject.com when a 1.0 is ready
+- [X] add a cpuid fuzzer (baremetal and VM)
+- [ ] organise the registry existence function better and group them together as a single utility function
+- [X] add <source_location> for error handling
+- [X] make an MIT version for 1.0
+- [X] add function to add custom techniques for end-user
+- [X] fix memoization
+- [X] add a python script to automatically set the lines of the seperate sections in the header
+- [ ] add C++20 concepts for the VM::add_custom() function
+- [X] check for valid monitor technique
+- [X] fix the is_admin code for windows
+- [X] test it on compiler explorer with windows 32-bit settings
+- [ ] upload the lib to dnf 
+- [ ] upload the lib to apt 
+- [X] add ARM support
+- [X] look into what `fv-az663-325` is
+- [X] implement techniques from [here](https://labs.nettitude.com/blog/vm-detection-tricks-part-3-hyper-v-raw-network-protocol/)
+- [X] add multiple choice for VM::brand()
+- [ ] add c++20 module support 
+- [X] design a way to disable some techniques way easier
+- [ ] make a man file in markdown for the cli tool
+- [X] implement smbios version technique [here](https://github.com/Print3M/Anti-VM/blob/eb524ed89e783b36c149acc450b2350d4198b06b/detectors.cpp#L88)
+- [ ] implement a display size technique for linux with EDID 
+- [X] implement a technique that matches the CPU product name and match it with a database of core counts for that specific CPU product
+- [X] add usage example in the .hpp file directly below the banner
+- [X] use the [[assume()]] attribute in C++23 for certain areas (not sure where exactly) 
+- [X] maybe add [[deprecated]]?
+- [ ] implement techniques from here https://stackoverflow.com/questions/43026032/detect-running-on-virtual-machine
+- [ ] add a .clang_format thingy
+- [ ] maybe add internal is_cached functionalities in the cache fetchers
+- [ ] make the whole cache table into a mutex so i can claim it's thread-safe
+- [ ] make a medium post about it
+- [ ] test the VM::modify_score() function
+- [ ] check if bios date in /sys/class/dmi/id/ could be useful under QEMU
+- [X] make the cli demo in the readme for the 1.9 version
+- [X] fix the percentage thing for the disabled techniques
+- [X] adopt the firmware technique from the vmprotect source code leak
+- [ ] add a .so, .dll, and .dylib shared object files in the release 
+- [X] make a struct version as an alternative
+- [X] add the license style like in ffmpeg https://github.com/FFmpeg/FFmpeg/tree/master?tab=License-1-ov-file
+- [ ] fix the issue of VM::QEMU_USB being ultra slow
+- [X] make a MIT transformer python script from GPL to MIT
+- [ ] /sys/class/dmi/id/product_name check this in qemu
+- [ ] update sourceforge
+- [X] fix the VM::vmaware struct
+- [X] do the ACPI technique and add it to hyper-x
+- [X] "running inside AN unknown VM" instead of "a unknown" for conclusion message
+- [X] fix the DMESG error thing
+- [ ] do the IDT thing
+- [ ] filesystem idea from requiemn
+- [ ] update the graph with the scanner and wmi 
+- [ ] add linux support for the hdd_serial_number technique
+- [ ] update the hyper-x graph to v5 with the acpi thingy
+
+# Distant plans
+- add the library to conan.io when released
+- add a python version of the library (or any other lang for that matter)
+- add a GUI version of the lib
+- add a rust version of the lib
+- submit the project to oss-fuzz 
diff --git a/VMAware/assets/Screenshot from 2024-05-11 16-30-04.png b/VMAware/assets/Screenshot from 2024-05-11 16-30-04.png
new file mode 100644
index 0000000000000000000000000000000000000000..a8b530a7716fe638a34aaca0b362f13c1c4cdf72
Binary files /dev/null and b/VMAware/assets/Screenshot from 2024-05-11 16-30-04.png differ
diff --git a/VMAware/assets/banner.jpg b/VMAware/assets/banner.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..c1f37e5d0043e702e1a42c3ac451ea5dc70173d3
Binary files /dev/null and b/VMAware/assets/banner.jpg differ
diff --git a/VMAware/assets/demo.jpg b/VMAware/assets/demo.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f7e1ec9451dc012cb70ea96f3403bb13d1d8cd64
Binary files /dev/null and b/VMAware/assets/demo.jpg differ
diff --git a/VMAware/assets/hyper-x/v1/Hyper-X.drawio b/VMAware/assets/hyper-x/v1/Hyper-X.drawio
new file mode 100644
index 0000000000000000000000000000000000000000..8c48231eaa1bcbcb971e319dd6526fbb9fa4ec5b
--- /dev/null
+++ b/VMAware/assets/hyper-x/v1/Hyper-X.drawio
@@ -0,0 +1,201 @@
+<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0" version="24.7.6">
+  <diagram name="Page-1" id="zGf0Ftu6_07F7baFzf_Y">
+    <mxGraphModel dx="1206" dy="795" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <mxCell id="x2cThCooTCoZfJnJUzE6-1" value="" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="120" y="150" width="880" height="520" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-2" value="START" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
+          <mxGeometry x="200" y="200" width="120" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-3" value="&lt;div&gt;Run the VM::HYPERVISOR_STR&lt;/div&gt;&lt;div&gt;technique, fetch eax&lt;br&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="180" y="290" width="160" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-4" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-2" target="x2cThCooTCoZfJnJUzE6-3" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="400" y="440" as="sourcePoint" />
+            <mxPoint x="450" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-5" value="is eax 12?" style="rhombus;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="205" y="380" width="110" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-6" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-3" target="x2cThCooTCoZfJnJUzE6-5" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="270" y="270" as="sourcePoint" />
+            <mxPoint x="270" y="310" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-7" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-5" target="x2cThCooTCoZfJnJUzE6-9" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="400" y="440" as="sourcePoint" />
+            <mxPoint x="450" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-8" value="Hyper-X mechanism" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=34;fontStyle=1" parent="1" vertex="1">
+          <mxGeometry x="360" y="170" width="400" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-9" value="is eax 11?" style="rhombus;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="205" y="470" width="110" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-10" value="Not Hyper-V, continue as normal" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1">
+          <mxGeometry x="220" y="560" width="80" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-11" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-9" target="x2cThCooTCoZfJnJUzE6-10" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="400" y="440" as="sourcePoint" />
+            <mxPoint x="450" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-12" value="No" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="250" y="530" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-13" value="No" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="250" y="440" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-14" value="Hyper-V VM, continue as normal" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1">
+          <mxGeometry x="360" y="460" width="80" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-15" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-9" target="x2cThCooTCoZfJnJUzE6-14" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="400" y="440" as="sourcePoint" />
+            <mxPoint x="450" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-16" value="Yes" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="300" y="470" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-17" value="At this point, it&#39;s fair to assume it&#39;s Hyper-V, but not sure whether host artifacts or VM" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="360" y="380" width="170" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-18" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-5" target="x2cThCooTCoZfJnJUzE6-17" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="400" y="440" as="sourcePoint" />
+            <mxPoint x="450" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-19" value="Yes" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="300" y="381" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-20" value="Run all the Hyper-V techniques that may only appear in the VM, and not the host (most of these are firmware and OS-based)" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="360" y="250" width="170" height="90" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-21" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-17" target="x2cThCooTCoZfJnJUzE6-20" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="400" y="440" as="sourcePoint" />
+            <mxPoint x="450" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-22" value="AcpiData" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="580" y="230" width="120" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-23" value="SMBIOS&lt;br&gt;(VM::MSSMBIOS)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="580" y="310" width="120" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-24" value="Motherboard string&lt;br&gt;(VM::VPC_BOARD)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="580" y="390" width="120" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-25" value="Hyper-V event logs&lt;br&gt;(VM::EVENT_LOGS)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="580" y="470" width="120" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-26" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-20" target="x2cThCooTCoZfJnJUzE6-22" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="690" y="440" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="560" y="295" />
+              <mxPoint x="560" y="260" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-27" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" target="x2cThCooTCoZfJnJUzE6-23" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="560" y="290" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="560" y="340" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-28" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" target="x2cThCooTCoZfJnJUzE6-24" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="560" y="340" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="560" y="420" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-29" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" target="x2cThCooTCoZfJnJUzE6-25" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="560" y="410" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="560" y="500" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-30" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-22" target="x2cThCooTCoZfJnJUzE6-31" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="690" y="440" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="720" y="260" />
+              <mxPoint x="720" y="371" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-31" value="Do any of these have any&lt;br&gt;signs of Hyper-V?" style="rhombus;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="750" y="330" width="200" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-32" value="Hyper-V VM, continue as normal" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1">
+          <mxGeometry x="800" y="440" width="100" height="100" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-33" value="Hyper-V host artifacts detected, this is NOT a VM" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
+          <mxGeometry x="800" y="200" width="100" height="100" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-34" value="" style="endArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endFill=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-23" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="690" y="440" as="sourcePoint" />
+            <mxPoint x="720" y="340" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-35" value="" style="endArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endFill=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-24" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="710" y="350" as="sourcePoint" />
+            <mxPoint x="720" y="420" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-36" value="" style="endArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endFill=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-25" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="690" y="440" as="sourcePoint" />
+            <mxPoint x="720" y="370" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="720" y="500" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-38" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-31" target="x2cThCooTCoZfJnJUzE6-32" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="690" y="440" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-39" value="Yes" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="840" y="410" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-40" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-31" target="x2cThCooTCoZfJnJUzE6-33" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="690" y="440" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-41" value="No" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="840" y="305" width="60" height="30" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+</mxfile>
diff --git a/VMAware/assets/hyper-x/v1/Hyper-X.png b/VMAware/assets/hyper-x/v1/Hyper-X.png
new file mode 100644
index 0000000000000000000000000000000000000000..eaebf291caeaf4f6a78c0fdfe74877363930cab7
Binary files /dev/null and b/VMAware/assets/hyper-x/v1/Hyper-X.png differ
diff --git a/VMAware/assets/hyper-x/v2/Hyper-X_version_2.drawio b/VMAware/assets/hyper-x/v2/Hyper-X_version_2.drawio
new file mode 100644
index 0000000000000000000000000000000000000000..dc53209e50fab8aecc97c47d2c0bee6da58bb6c4
--- /dev/null
+++ b/VMAware/assets/hyper-x/v2/Hyper-X_version_2.drawio
@@ -0,0 +1,242 @@
+<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0" version="24.7.17">
+  <diagram name="Page-1" id="zGf0Ftu6_07F7baFzf_Y">
+    <mxGraphModel dx="1920" dy="788" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <mxCell id="x2cThCooTCoZfJnJUzE6-1" value="" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="-10" y="150" width="1010" height="590" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-2" value="START" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
+          <mxGeometry x="110" y="180" width="120" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-3" value="&lt;div&gt;Run the VM::HYPERVISOR_STR&lt;/div&gt;&lt;div&gt;technique, fetch eax. Does eax have the value of 11 or 12?&lt;br&gt;&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="10" y="345" width="140" height="85" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-8" value="Hyper-X mechanism" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=34;fontStyle=1" parent="1" vertex="1">
+          <mxGeometry x="360" y="170" width="400" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-10" value="Not Hyper-V, continue as normal" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1">
+          <mxGeometry x="400" y="630" width="90" height="90" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-17" value="At this point, it&#39;s fair to assume it&#39;s Hyper-V, but not sure whether host artifacts or VM" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="360" y="390" width="170" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-20" value="Run all the Hyper-V techniques that may only appear in the VM, and not the host (most of these are firmware and OS-based)" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="360" y="250" width="170" height="90" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-21" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-17" target="x2cThCooTCoZfJnJUzE6-20" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="400" y="440" as="sourcePoint" />
+            <mxPoint x="450" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-22" value="AcpiData" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="580" y="230" width="120" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-23" value="SMBIOS&lt;br&gt;(VM::MSSMBIOS)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="580" y="310" width="120" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-24" value="Motherboard string&lt;br&gt;(VM::VPC_BOARD)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="580" y="390" width="120" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-25" value="Hyper-V event logs&lt;br&gt;(VM::EVENT_LOGS)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="580" y="470" width="120" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-26" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-20" target="x2cThCooTCoZfJnJUzE6-22" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="690" y="440" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="560" y="295" />
+              <mxPoint x="560" y="260" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-27" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" target="x2cThCooTCoZfJnJUzE6-23" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="560" y="290" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="560" y="340" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-28" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" target="x2cThCooTCoZfJnJUzE6-24" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="560" y="340" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="560" y="420" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-29" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" target="x2cThCooTCoZfJnJUzE6-25" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="560" y="410" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="560" y="500" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-30" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-22" target="x2cThCooTCoZfJnJUzE6-31" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="690" y="440" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="720" y="260" />
+              <mxPoint x="720" y="375" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-31" value="Do any of these have any&lt;br&gt;signs of Hyper-V?" style="rhombus;whiteSpace=wrap;html=1;spacingTop=6;" parent="1" vertex="1">
+          <mxGeometry x="745" y="330" width="210" height="90" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-32" value="&lt;font style=&quot;font-size: 11px;&quot;&gt;Hyper-V detected, this is in fact a VM&lt;/font&gt;" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
+          <mxGeometry x="800" y="455" width="100" height="100" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-33" value="Hyper-V host artifacts detected, this is NOT a VM" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1">
+          <mxGeometry x="800" y="200" width="100" height="100" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-34" value="" style="endArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endFill=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-23" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="690" y="440" as="sourcePoint" />
+            <mxPoint x="720" y="340" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-35" value="" style="endArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endFill=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-24" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="710" y="350" as="sourcePoint" />
+            <mxPoint x="720" y="420" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-36" value="" style="endArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endFill=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-25" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="690" y="440" as="sourcePoint" />
+            <mxPoint x="720" y="370" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="720" y="500" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-38" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-31" target="x2cThCooTCoZfJnJUzE6-32" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="690" y="440" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-39" value="Yes" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="840" y="420" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-40" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-31" target="x2cThCooTCoZfJnJUzE6-33" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="690" y="440" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-41" value="No" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="840" y="305" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-1" value="&lt;font style=&quot;font-size: 11px;&quot;&gt;Are at least 2 of these true?&lt;/font&gt;" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
+          <mxGeometry x="362.5" y="505" width="165" height="90" as="geometry" />
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-2" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4PM8ViUepl_GfYZcxHRn-1" target="x2cThCooTCoZfJnJUzE6-10">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="400" y="500" as="sourcePoint" />
+            <mxPoint x="450" y="450" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-3" value="&lt;div&gt;No&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="440" y="600" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-5" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="4PM8ViUepl_GfYZcxHRn-1" target="x2cThCooTCoZfJnJUzE6-17">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="400" y="500" as="sourcePoint" />
+            <mxPoint x="450" y="450" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-6" value="Yes" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="440" y="465" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-9" value="Does the CPU manufacturer have the &quot;Microsoft Hv&quot; string with the hypervisor cpuid leaf?" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
+          <mxGeometry x="190" y="345" width="140" height="85" as="geometry" />
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-10" value="Does the CPU match with the VMProtect technique for Hyper-V root partition detection?" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
+          <mxGeometry x="95" y="440" width="150" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-14" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" edge="1" parent="1" source="x2cThCooTCoZfJnJUzE6-3" target="4PM8ViUepl_GfYZcxHRn-18">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="200" y="500" as="sourcePoint" />
+            <mxPoint x="250" y="450" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="80" y="570" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-15" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4PM8ViUepl_GfYZcxHRn-10" target="4PM8ViUepl_GfYZcxHRn-18">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="200" y="500" as="sourcePoint" />
+            <mxPoint x="170" y="550" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="170" y="550" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-16" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" source="4PM8ViUepl_GfYZcxHRn-9" target="4PM8ViUepl_GfYZcxHRn-18">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="200" y="500" as="sourcePoint" />
+            <mxPoint x="265" y="550" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="260" y="530" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-18" value="" style="triangle;whiteSpace=wrap;html=1;" vertex="1" parent="1">
+          <mxGeometry x="300" y="510" width="30" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-19" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4PM8ViUepl_GfYZcxHRn-18" target="4PM8ViUepl_GfYZcxHRn-1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="230" y="500" as="sourcePoint" />
+            <mxPoint x="280" y="450" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-20" value="" style="triangle;whiteSpace=wrap;html=1;direction=north;" vertex="1" parent="1">
+          <mxGeometry x="130" y="265" width="80" height="35" as="geometry" />
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-22" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="x2cThCooTCoZfJnJUzE6-2" target="4PM8ViUepl_GfYZcxHRn-20">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="380" y="500" as="sourcePoint" />
+            <mxPoint x="170" y="260" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-23" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.75;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4PM8ViUepl_GfYZcxHRn-20" target="4PM8ViUepl_GfYZcxHRn-9">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="200" y="500" as="sourcePoint" />
+            <mxPoint x="250" y="450" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="190" y="320" />
+              <mxPoint x="260" y="320" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-24" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4PM8ViUepl_GfYZcxHRn-20" target="4PM8ViUepl_GfYZcxHRn-10">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="200" y="500" as="sourcePoint" />
+            <mxPoint x="250" y="450" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-25" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4PM8ViUepl_GfYZcxHRn-20" target="x2cThCooTCoZfJnJUzE6-3">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="200" y="500" as="sourcePoint" />
+            <mxPoint x="250" y="450" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="150" y="320" />
+              <mxPoint x="80" y="320" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+</mxfile>
diff --git a/VMAware/assets/hyper-x/v2/Hyper-X_version_2.png b/VMAware/assets/hyper-x/v2/Hyper-X_version_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..afaefad4dc12ecc4adccf5be2217f44faf8df14c
Binary files /dev/null and b/VMAware/assets/hyper-x/v2/Hyper-X_version_2.png differ
diff --git a/VMAware/assets/hyper-x/v3/Hyper-X_version_3.drawio b/VMAware/assets/hyper-x/v3/Hyper-X_version_3.drawio
new file mode 100644
index 0000000000000000000000000000000000000000..a8733610e5953d282d7de64aaafb777202370c99
--- /dev/null
+++ b/VMAware/assets/hyper-x/v3/Hyper-X_version_3.drawio
@@ -0,0 +1,153 @@
+<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0" version="24.7.17">
+  <diagram name="Page-1" id="zGf0Ftu6_07F7baFzf_Y">
+    <mxGraphModel dx="1167" dy="860" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <mxCell id="x2cThCooTCoZfJnJUzE6-1" value="" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="50" y="80" width="710" height="600" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-2" value="START" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
+          <mxGeometry x="110" y="180" width="120" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-3" value="&lt;div&gt;Run the VM::HYPERVISOR_STR&lt;/div&gt;&lt;div&gt;technique, fetch eax.&lt;br&gt;&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="100" y="277.5" width="140" height="85" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-8" value="Hyper-X mechanism (v3)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=34;fontStyle=1" parent="1" vertex="1">
+          <mxGeometry x="205" y="120" width="400" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-10" value="Not Hyper-V, continue as normal" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1">
+          <mxGeometry x="125" y="540" width="90" height="90" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-23" value="Does the SMBIOS show any strings related to Hyper-V?&lt;br&gt;(VM::MSSMBIOS)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="330" y="460" width="150" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-24" value="Does the motherboard match with Hyper-V&lt;br&gt;or VirtualPC?&lt;br&gt;(VM::VPC_BOARD)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="330" y="362.5" width="150" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-32" value="&lt;font style=&quot;font-size: 11px;&quot;&gt;Hyper-V detected, this is in fact a VM&lt;/font&gt;" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
+          <mxGeometry x="585" y="535" width="100" height="100" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-33" value="Hyper-V host artifacts detected, this is NOT a VM" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1">
+          <mxGeometry x="585" y="260" width="100" height="100" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-38" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="mEdIK6QNIQfA6IXG1Q04-20" target="x2cThCooTCoZfJnJUzE6-32" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="1245" y="440" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-40" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="1" source="mEdIK6QNIQfA6IXG1Q04-20" target="x2cThCooTCoZfJnJUzE6-33" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="1245" y="350" as="sourcePoint" />
+            <mxPoint x="740" y="390" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-10" value="Does the CPU match with the VMProtect technique for Hyper-V root partition detection?" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="330" y="260" width="150" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-22" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-2" target="x2cThCooTCoZfJnJUzE6-3" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="380" y="500" as="sourcePoint" />
+            <mxPoint x="170" y="265" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="mEdIK6QNIQfA6IXG1Q04-6" value="Does eax have the &lt;br&gt;value of 11 or 12?" style="rhombus;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="85" y="400" width="170" height="100" as="geometry" />
+        </mxCell>
+        <mxCell id="mEdIK6QNIQfA6IXG1Q04-7" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="x2cThCooTCoZfJnJUzE6-3" target="mEdIK6QNIQfA6IXG1Q04-6" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="380" y="500" as="sourcePoint" />
+            <mxPoint x="430" y="450" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="mEdIK6QNIQfA6IXG1Q04-16" value="Do the Windows event logs show any indication of Hyper-V?&lt;br&gt;(VM::EVENT_LOGS)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="330" y="560" width="150" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="mEdIK6QNIQfA6IXG1Q04-20" value="Are at least one &lt;br&gt;of these true?" style="rhombus;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="550" y="400" width="170" height="100" as="geometry" />
+        </mxCell>
+        <mxCell id="mEdIK6QNIQfA6IXG1Q04-29" value="No" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="165" y="502" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="mEdIK6QNIQfA6IXG1Q04-30" value="No" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="625" y="370.5" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="mEdIK6QNIQfA6IXG1Q04-32" value="Yes" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="625" y="502" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="mEdIK6QNIQfA6IXG1Q04-33" value="Yes" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+          <mxGeometry x="240" y="420" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="mEdIK6QNIQfA6IXG1Q04-37" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="mEdIK6QNIQfA6IXG1Q04-6" target="x2cThCooTCoZfJnJUzE6-10" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="410" y="490" as="sourcePoint" />
+            <mxPoint x="460" y="440" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3IsLGjAELvZnN1pZ9IzM-2" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="mEdIK6QNIQfA6IXG1Q04-6" target="4PM8ViUepl_GfYZcxHRn-10">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="500" y="410" as="sourcePoint" />
+            <mxPoint x="550" y="360" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="290" y="450" />
+              <mxPoint x="290" y="300" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3IsLGjAELvZnN1pZ9IzM-3" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" target="x2cThCooTCoZfJnJUzE6-24">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="290" y="403" as="sourcePoint" />
+            <mxPoint x="550" y="360" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3IsLGjAELvZnN1pZ9IzM-5" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" target="mEdIK6QNIQfA6IXG1Q04-16">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="290" y="450" as="sourcePoint" />
+            <mxPoint x="550" y="360" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="290" y="600" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3IsLGjAELvZnN1pZ9IzM-6" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" target="x2cThCooTCoZfJnJUzE6-23">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="290" y="500" as="sourcePoint" />
+            <mxPoint x="550" y="360" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3IsLGjAELvZnN1pZ9IzM-7" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4PM8ViUepl_GfYZcxHRn-10" target="mEdIK6QNIQfA6IXG1Q04-20">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="500" y="410" as="sourcePoint" />
+            <mxPoint x="550" y="360" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="510" y="300" />
+              <mxPoint x="510" y="450" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3IsLGjAELvZnN1pZ9IzM-8" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" target="x2cThCooTCoZfJnJUzE6-24">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="510" y="403" as="sourcePoint" />
+            <mxPoint x="550" y="360" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3IsLGjAELvZnN1pZ9IzM-10" value="" style="endArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="mEdIK6QNIQfA6IXG1Q04-16">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="370" y="410" as="sourcePoint" />
+            <mxPoint x="510" y="450" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="510" y="600" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="3IsLGjAELvZnN1pZ9IzM-12" value="" style="endArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="x2cThCooTCoZfJnJUzE6-23">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="700" y="410" as="sourcePoint" />
+            <mxPoint x="510" y="500" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+</mxfile>
diff --git a/VMAware/assets/hyper-x/v3/Hyper-X_version_3.png b/VMAware/assets/hyper-x/v3/Hyper-X_version_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..01cc5b0e369ec1ba021bb947887bdaf454b12cfd
Binary files /dev/null and b/VMAware/assets/hyper-x/v3/Hyper-X_version_3.png differ
diff --git a/VMAware/assets/hyper-x/v4/Hyper-X_version_4.drawio b/VMAware/assets/hyper-x/v4/Hyper-X_version_4.drawio
new file mode 100644
index 0000000000000000000000000000000000000000..5c0fd9a93839be992be3eb17b792da22708e373f
--- /dev/null
+++ b/VMAware/assets/hyper-x/v4/Hyper-X_version_4.drawio
@@ -0,0 +1,192 @@
+<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0" version="24.7.17">
+  <diagram name="Page-1" id="zGf0Ftu6_07F7baFzf_Y">
+    <mxGraphModel dx="1875" dy="788" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <mxCell id="x2cThCooTCoZfJnJUzE6-1" value="" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="-30" y="130" width="990" height="540" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-2" value="START" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
+          <mxGeometry x="790" y="360" width="120" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-3" value="&lt;div&gt;Run the VM::HYPERVISOR_STR&lt;/div&gt;&lt;div&gt;technique, fetch eax.&lt;br&gt;&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="780" y="220" width="140" height="85" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-8" value="Hyper-X mechanism (v4)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=34;fontStyle=1" parent="1" vertex="1">
+          <mxGeometry x="265" y="160" width="400" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-10" value="Not Hyper-V, continue as normal" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1">
+          <mxGeometry y="207" width="110" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-23" value="Does the SMBIOS show any strings related to Hyper-V?&lt;br&gt;(VM::MSSMBIOS)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="240" y="390" width="150" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-24" value="Does the motherboard match with Hyper-V&lt;br&gt;or VirtualPC?&lt;br&gt;(VM::VPC_BOARD)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="70" y="390" width="150" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-32" value="&lt;div&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;Hyper-V detected,&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font style=&quot;font-size: 11px;&quot;&gt;this is in fact a VM&lt;/font&gt;&lt;/div&gt;" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
+          <mxGeometry x="610" y="520" width="110" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="x2cThCooTCoZfJnJUzE6-33" value="Hyper-V host artifacts detected, this is NOT a VM" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1">
+          <mxGeometry x="130" y="520" width="110" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="4PM8ViUepl_GfYZcxHRn-10" value="Does the CPU match with the VMProtect technique for Hyper-V root partition detection?" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="180" y="222" width="150" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="mEdIK6QNIQfA6IXG1Q04-6" value="Does eax have the &lt;br&gt;&lt;div&gt;value of 11?&lt;/div&gt;" style="rhombus;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="580" y="212.5" width="170" height="100" as="geometry" />
+        </mxCell>
+        <mxCell id="mEdIK6QNIQfA6IXG1Q04-16" value="Do the Windows event logs show any indication of Hyper-V?&lt;br&gt;(VM::EVENT_LOGS)" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="410" y="390" width="150" height="80" as="geometry" />
+        </mxCell>
+        <mxCell id="mEdIK6QNIQfA6IXG1Q04-20" value="Are at least one &lt;br&gt;of these true?" style="rhombus;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="340" y="525" width="170" height="100" as="geometry" />
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-1" value="Does eax have the &lt;br&gt;&lt;div&gt;value of 12?&lt;/div&gt;" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
+          <mxGeometry x="370" y="212" width="170" height="100" as="geometry" />
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-2" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="mEdIK6QNIQfA6IXG1Q04-6" target="x2cThCooTCoZfJnJUzE6-32">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="310" y="550" as="sourcePoint" />
+            <mxPoint x="360" y="500" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-3" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="x2cThCooTCoZfJnJUzE6-2" target="x2cThCooTCoZfJnJUzE6-3">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="340" y="550" as="sourcePoint" />
+            <mxPoint x="390" y="500" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-4" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="x2cThCooTCoZfJnJUzE6-3" target="mEdIK6QNIQfA6IXG1Q04-6">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="340" y="550" as="sourcePoint" />
+            <mxPoint x="390" y="500" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-5" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="mEdIK6QNIQfA6IXG1Q04-6" target="6Mm_VMVsP4fTWzJjbTtz-1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="340" y="550" as="sourcePoint" />
+            <mxPoint x="390" y="500" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-6" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="6Mm_VMVsP4fTWzJjbTtz-1" target="4PM8ViUepl_GfYZcxHRn-10">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="340" y="550" as="sourcePoint" />
+            <mxPoint x="390" y="500" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-7" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="4PM8ViUepl_GfYZcxHRn-10" target="x2cThCooTCoZfJnJUzE6-10">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="300" y="310" as="sourcePoint" />
+            <mxPoint x="350" y="260" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-8" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" target="x2cThCooTCoZfJnJUzE6-24">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="260" y="360" as="sourcePoint" />
+            <mxPoint x="420" y="260" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="145" y="360" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-11" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" target="mEdIK6QNIQfA6IXG1Q04-16">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="260" y="360" as="sourcePoint" />
+            <mxPoint x="420" y="260" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="485" y="360" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-12" value="" style="endArrow=none;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=0;" edge="1" parent="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="250" y="302" as="sourcePoint" />
+            <mxPoint x="315" y="360" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="250" y="330" />
+              <mxPoint x="315" y="330" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-13" value="" style="endArrow=none;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;endFill=0;" edge="1" parent="1" source="6Mm_VMVsP4fTWzJjbTtz-1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="450" y="320" as="sourcePoint" />
+            <mxPoint x="310" y="330" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="455" y="330" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-15" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" target="x2cThCooTCoZfJnJUzE6-23">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="315" y="360" as="sourcePoint" />
+            <mxPoint x="380" y="420" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-16" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="x2cThCooTCoZfJnJUzE6-24" target="mEdIK6QNIQfA6IXG1Q04-20">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="330" y="420" as="sourcePoint" />
+            <mxPoint x="380" y="370" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="145" y="500" />
+              <mxPoint x="425" y="500" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-17" value="" style="endArrow=none;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" target="x2cThCooTCoZfJnJUzE6-23">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="315" y="500" as="sourcePoint" />
+            <mxPoint x="430" y="370" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-18" value="" style="endArrow=none;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" target="mEdIK6QNIQfA6IXG1Q04-16">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="420" y="500" as="sourcePoint" />
+            <mxPoint x="430" y="370" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="485" y="500" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-19" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="mEdIK6QNIQfA6IXG1Q04-20" target="x2cThCooTCoZfJnJUzE6-32">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="380" y="420" as="sourcePoint" />
+            <mxPoint x="430" y="370" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-20" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="mEdIK6QNIQfA6IXG1Q04-20" target="x2cThCooTCoZfJnJUzE6-33">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="380" y="420" as="sourcePoint" />
+            <mxPoint x="430" y="370" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-21" value="No" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="280" y="545" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-22" value="Yes" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="510" y="545" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-23" value="No" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="120" y="230" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-24" value="No" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="323" y="231" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-25" value="Yes" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="395" y="302" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-26" value="Yes" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="250" y="302" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-27" value="No" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="530" y="231" width="60" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="6Mm_VMVsP4fTWzJjbTtz-30" value="Yes" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
+          <mxGeometry x="605" y="312" width="60" height="30" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+</mxfile>
diff --git a/VMAware/assets/hyper-x/v4/Hyper-X_version_4.drawio.png b/VMAware/assets/hyper-x/v4/Hyper-X_version_4.drawio.png
new file mode 100644
index 0000000000000000000000000000000000000000..a61d612bc97ae9ac07e50ff72ee89e3c759a27bd
Binary files /dev/null and b/VMAware/assets/hyper-x/v4/Hyper-X_version_4.drawio.png differ
diff --git a/VMAware/assets/vmaware.drawio b/VMAware/assets/vmaware.drawio
new file mode 100644
index 0000000000000000000000000000000000000000..476600e6c6fdb6adc237a8efc18996dc753ce3e2
--- /dev/null
+++ b/VMAware/assets/vmaware.drawio
@@ -0,0 +1,174 @@
+<mxfile host="Electron" modified="2024-02-29T00:38:27.863Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/23.1.5 Chrome/120.0.6099.109 Electron/28.1.0 Safari/537.36" etag="gHwHJGod5kbf3SDjCA3a" version="23.1.5" type="device">
+  <diagram name="Page-1" id="tMRFHP5p-LFzW88CfEth">
+    <mxGraphModel dx="642" dy="510" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-1" value="&lt;h1 style=&quot;line-height: 205%;&quot;&gt;&lt;font color=&quot;#000000&quot; style=&quot;font-size: 32px;&quot;&gt;&lt;u&gt;VMAware library structure&lt;/u&gt;&lt;/font&gt;&lt;/h1&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#bac8d3;strokeColor=#23445d;verticalAlign=top;" parent="1" vertex="1">
+          <mxGeometry x="70" y="40" width="880" height="450" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-5" value="&lt;h3 style=&quot;line-height: 30%;&quot;&gt;&lt;font style=&quot;font-size: 15px;&quot; color=&quot;#000000&quot;&gt;PRIVATE COMPONENTS&lt;/font&gt;&lt;/h3&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;horizontal=1;verticalAlign=top;fillColor=#9EBAD3;strokeColor=#23445d;strokeWidth=1;" parent="1" vertex="1">
+          <mxGeometry x="100" y="120" width="390" height="340" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-2" value="&lt;font color=&quot;#000000&quot;&gt;&lt;b&gt;utility&lt;/b&gt;&lt;br&gt;(for general operations)&lt;br&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fad9d5;strokeColor=#ae4132;" parent="1" vertex="1">
+          <mxGeometry x="140" y="310" width="140" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-4" value="&lt;font color=&quot;#000000&quot;&gt;&lt;b&gt;cpu&lt;/b&gt;&lt;br&gt;(for CPU operations)&lt;br&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#b0e3e6;strokeColor=#0e8088;" parent="1" vertex="1">
+          <mxGeometry x="140" y="240" width="140" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-3" value="&lt;font color=&quot;#000000&quot;&gt;&lt;b&gt;memoization&lt;/b&gt;&lt;br&gt;(for caching operations)&lt;br&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#b1ddf0;strokeColor=#10739e;" parent="1" vertex="1">
+          <mxGeometry x="140" y="168" width="140" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-6" value="&lt;font color=&quot;#000000&quot;&gt;&lt;b&gt;&lt;u&gt;technique table&lt;br&gt;&lt;/u&gt;&lt;/b&gt;&lt;br&gt;(stores all the VM detection techniques)&lt;br&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fad7ac;strokeColor=#b46504;enumerate=0;" parent="1" vertex="1">
+          <mxGeometry x="320" y="165" width="140" height="130" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-13" value="&lt;font color=&quot;#000000&quot;&gt;&lt;b&gt;&lt;u&gt;brand table&lt;br&gt;&lt;/u&gt;&lt;/b&gt;&lt;/font&gt;&lt;div&gt;&lt;br&gt;&lt;font color=&quot;#000000&quot;&gt;(stores a scoreboard table of every VM brand)&lt;/font&gt;&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d0cee2;strokeColor=#56517e;verticalAlign=middle;" parent="1" vertex="1">
+          <mxGeometry x="320" y="330" width="140" height="110" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-16" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#000000;" parent="1" source="_5j-xkA9-BKe6-_lW6Nw-6" target="_5j-xkA9-BKe6-_lW6Nw-13" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="470" y="230" as="sourcePoint" />
+            <mxPoint x="520" y="180" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-19" value="&lt;h3 style=&quot;line-height: 20%;&quot;&gt;&lt;font color=&quot;#000000&quot;&gt;PUBLIC COMPONENTS&lt;/font&gt;&lt;/h3&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;horizontal=1;verticalAlign=top;fillColor=#9CA9D3;strokeColor=#23445d;strokeWidth=1;" parent="1" vertex="1">
+          <mxGeometry x="640" y="120" width="280" height="350" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-17" value="&lt;b&gt;VM::brand()&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;" parent="1" vertex="1">
+          <mxGeometry x="660" y="400" width="119.5" height="50" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-23" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeColor=#000000;" parent="1" source="_5j-xkA9-BKe6-_lW6Nw-13" target="_5j-xkA9-BKe6-_lW6Nw-17" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="550" y="230" as="sourcePoint" />
+            <mxPoint x="600" y="180" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="510" y="385" />
+              <mxPoint x="510" y="438" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-26" value="&lt;b&gt;VM::detect()&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;" parent="1" vertex="1">
+          <mxGeometry x="660" y="340" width="119.5" height="50" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-30" value="&lt;b&gt;VM::percentage()&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;" parent="1" vertex="1">
+          <mxGeometry x="660" y="280" width="119.5" height="50" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-32" value="Returns the most likely VM brand" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;" parent="1" vertex="1">
+          <mxGeometry x="779.5" y="400" width="119.5" height="50" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-34" value="Returns a boolean &lt;br&gt;true or false value whether it&#39;s a VM" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;" parent="1" vertex="1">
+          <mxGeometry x="779.5" y="340" width="119.5" height="50" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-36" value="&lt;b&gt;VM::check()&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;" parent="1" vertex="1">
+          <mxGeometry x="660" y="220" width="119.5" height="50" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-38" value="Run every VM detection technique in the table" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+          <mxGeometry x="520" y="256" width="80" height="128" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-45" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;strokeColor=#000000;startArrow=classic;startFill=1;" parent="1" source="_5j-xkA9-BKe6-_lW6Nw-38" target="_5j-xkA9-BKe6-_lW6Nw-6" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="630" y="240" as="sourcePoint" />
+            <mxPoint x="680" y="190" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="500" y="320" />
+              <mxPoint x="500" y="263" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-47" value="Returns a 0 to 100 percentage of how likely it&#39;s a VM" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;" parent="1" vertex="1">
+          <mxGeometry x="779.5" y="280" width="119.5" height="50" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-48" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#000000;startArrow=classic;startFill=1;" parent="1" source="_5j-xkA9-BKe6-_lW6Nw-36" target="_5j-xkA9-BKe6-_lW6Nw-6" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="820" y="260" as="sourcePoint" />
+            <mxPoint x="870" y="210" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="620" y="245" />
+              <mxPoint x="620" y="230" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-49" value="Returns the result of a single specific technique" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;" parent="1" vertex="1">
+          <mxGeometry x="779.5" y="220" width="119.5" height="50" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-57" value="&lt;font color=&quot;#000000&quot;&gt;&lt;b&gt;core&lt;/b&gt;&lt;br&gt;(for key operations)&lt;br&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#bac8d3;strokeColor=#23445d;" parent="1" vertex="1">
+          <mxGeometry x="140" y="380" width="140" height="60" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-81" value="&lt;b&gt;VM::add_custom()&lt;/b&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;" parent="1" vertex="1">
+          <mxGeometry x="660" y="160" width="119.5" height="50" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-83" value="Adds a custom VM detection technique&amp;nbsp;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;" parent="1" vertex="1">
+          <mxGeometry x="779.5" y="160" width="119.5" height="50" as="geometry" />
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-84" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;strokeColor=#000000;" parent="1" source="_5j-xkA9-BKe6-_lW6Nw-81" target="_5j-xkA9-BKe6-_lW6Nw-6" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="660" y="310" as="sourcePoint" />
+            <mxPoint x="710" y="260" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="620" y="185" />
+              <mxPoint x="620" y="198" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-91" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;sourcePerimeterSpacing=0;strokeColor=#000000;endFill=0;startArrow=classic;startFill=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" target="_5j-xkA9-BKe6-_lW6Nw-57" edge="1" source="_5j-xkA9-BKe6-_lW6Nw-6">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="300" y="250" as="sourcePoint" />
+            <mxPoint x="440" y="260" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="300" y="230" />
+              <mxPoint x="300" y="410" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="_5j-xkA9-BKe6-_lW6Nw-92" value="" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#000000;" parent="1" target="_5j-xkA9-BKe6-_lW6Nw-4" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="300" y="270" as="sourcePoint" />
+            <mxPoint x="350" y="260" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="cPlAHG-HkCh-T9TprcrS-1" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;strokeColor=#000000;" parent="1" source="_5j-xkA9-BKe6-_lW6Nw-17" target="_5j-xkA9-BKe6-_lW6Nw-38" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="570" y="290" as="sourcePoint" />
+            <mxPoint x="620" y="240" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="620" y="413" />
+              <mxPoint x="620" y="352" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="cPlAHG-HkCh-T9TprcrS-2" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.25;exitDx=0;exitDy=0;strokeColor=#000000;" parent="1" source="_5j-xkA9-BKe6-_lW6Nw-38" target="_5j-xkA9-BKe6-_lW6Nw-30" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="570" y="290" as="sourcePoint" />
+            <mxPoint x="620" y="240" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="630" y="288" />
+              <mxPoint x="630" y="305" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="cPlAHG-HkCh-T9TprcrS-3" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#000000;" parent="1" source="_5j-xkA9-BKe6-_lW6Nw-38" target="_5j-xkA9-BKe6-_lW6Nw-26" edge="1">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="570" y="290" as="sourcePoint" />
+            <mxPoint x="620" y="240" as="targetPoint" />
+            <Array as="points">
+              <mxPoint x="630" y="320" />
+              <mxPoint x="630" y="365" />
+            </Array>
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="GsFwuIZayCYaH_RebeOi-1" value="" style="endArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#000000;" edge="1" parent="1" source="_5j-xkA9-BKe6-_lW6Nw-2">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="310" y="290" as="sourcePoint" />
+            <mxPoint x="300" y="340" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="GsFwuIZayCYaH_RebeOi-4" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.25;exitDx=0;exitDy=0;strokeColor=#000000;" edge="1" parent="1" source="_5j-xkA9-BKe6-_lW6Nw-6" target="_5j-xkA9-BKe6-_lW6Nw-3">
+          <mxGeometry width="50" height="50" relative="1" as="geometry">
+            <mxPoint x="460" y="290" as="sourcePoint" />
+            <mxPoint x="510" y="240" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+</mxfile>
diff --git a/VMAware/assets/vmaware.drawio.png b/VMAware/assets/vmaware.drawio.png
new file mode 100644
index 0000000000000000000000000000000000000000..6130ce433e6abe51c9299b9170b9e4a49eade417
Binary files /dev/null and b/VMAware/assets/vmaware.drawio.png differ
diff --git a/VMAware/assets/vmaware.drawio.svg b/VMAware/assets/vmaware.drawio.svg
new file mode 100644
index 0000000000000000000000000000000000000000..513c9d77e7343dee1b06cf0220314246cd1a1743
--- /dev/null
+++ b/VMAware/assets/vmaware.drawio.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Do not edit this file with editors other than draw.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="881px" height="451px" viewBox="-0.5 -0.5 881 451" content="&lt;mxfile host=&quot;Electron&quot; modified=&quot;2024-02-29T00:38:45.978Z&quot; agent=&quot;Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/23.1.5 Chrome/120.0.6099.109 Electron/28.1.0 Safari/537.36&quot; etag=&quot;nz9cSR9w8KBY_C-dft4F&quot; version=&quot;23.1.5&quot; type=&quot;device&quot; scale=&quot;1&quot; border=&quot;0&quot;&gt;&#10;  &lt;diagram name=&quot;Page-1&quot; id=&quot;tMRFHP5p-LFzW88CfEth&quot;&gt;&#10;    &lt;mxGraphModel dx=&quot;642&quot; dy=&quot;510&quot; grid=&quot;1&quot; gridSize=&quot;10&quot; guides=&quot;1&quot; tooltips=&quot;1&quot; connect=&quot;1&quot; arrows=&quot;1&quot; fold=&quot;1&quot; page=&quot;1&quot; pageScale=&quot;1&quot; pageWidth=&quot;827&quot; pageHeight=&quot;1169&quot; math=&quot;0&quot; shadow=&quot;0&quot;&gt;&#10;      &lt;root&gt;&#10;        &lt;mxCell id=&quot;0&quot; /&gt;&#10;        &lt;mxCell id=&quot;1&quot; parent=&quot;0&quot; /&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-1&quot; value=&quot;&amp;lt;h1 style=&amp;quot;line-height: 205%;&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#000000&amp;quot; style=&amp;quot;font-size: 32px;&amp;quot;&amp;gt;&amp;lt;u&amp;gt;VMAware library structure&amp;lt;/u&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;/h1&amp;gt;&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;fillColor=#bac8d3;strokeColor=#23445d;verticalAlign=top;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;70&quot; y=&quot;40&quot; width=&quot;880&quot; height=&quot;450&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-5&quot; value=&quot;&amp;lt;h3 style=&amp;quot;line-height: 30%;&amp;quot;&amp;gt;&amp;lt;font style=&amp;quot;font-size: 15px;&amp;quot; color=&amp;quot;#000000&amp;quot;&amp;gt;PRIVATE COMPONENTS&amp;lt;/font&amp;gt;&amp;lt;/h3&amp;gt;&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;dashed=1;horizontal=1;verticalAlign=top;fillColor=#9EBAD3;strokeColor=#23445d;strokeWidth=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;100&quot; y=&quot;120&quot; width=&quot;390&quot; height=&quot;340&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-2&quot; value=&quot;&amp;lt;font color=&amp;quot;#000000&amp;quot;&amp;gt;&amp;lt;b&amp;gt;utility&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;(for general operations)&amp;lt;br&amp;gt;&amp;lt;/font&amp;gt;&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;fillColor=#fad9d5;strokeColor=#ae4132;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;140&quot; y=&quot;310&quot; width=&quot;140&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-4&quot; value=&quot;&amp;lt;font color=&amp;quot;#000000&amp;quot;&amp;gt;&amp;lt;b&amp;gt;cpu&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;(for CPU operations)&amp;lt;br&amp;gt;&amp;lt;/font&amp;gt;&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;fillColor=#b0e3e6;strokeColor=#0e8088;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;140&quot; y=&quot;240&quot; width=&quot;140&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-3&quot; value=&quot;&amp;lt;font color=&amp;quot;#000000&amp;quot;&amp;gt;&amp;lt;b&amp;gt;memoization&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;(for caching operations)&amp;lt;br&amp;gt;&amp;lt;/font&amp;gt;&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;fillColor=#b1ddf0;strokeColor=#10739e;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;140&quot; y=&quot;168&quot; width=&quot;140&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-6&quot; value=&quot;&amp;lt;font color=&amp;quot;#000000&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;technique table&amp;lt;br&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;(stores all the VM detection techniques)&amp;lt;br&amp;gt;&amp;lt;/font&amp;gt;&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;fillColor=#fad7ac;strokeColor=#b46504;enumerate=0;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;320&quot; y=&quot;165&quot; width=&quot;140&quot; height=&quot;130&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-13&quot; value=&quot;&amp;lt;font color=&amp;quot;#000000&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;u&amp;gt;brand table&amp;lt;br&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;font color=&amp;quot;#000000&amp;quot;&amp;gt;(stores a scoreboard table of every VM brand)&amp;lt;/font&amp;gt;&amp;lt;/div&amp;gt;&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;fillColor=#d0cee2;strokeColor=#56517e;verticalAlign=middle;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;320&quot; y=&quot;330&quot; width=&quot;140&quot; height=&quot;110&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-16&quot; value=&quot;&quot; style=&quot;endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#000000;&quot; parent=&quot;1&quot; source=&quot;_5j-xkA9-BKe6-_lW6Nw-6&quot; target=&quot;_5j-xkA9-BKe6-_lW6Nw-13&quot; edge=&quot;1&quot;&gt;&#10;          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10;            &lt;mxPoint x=&quot;470&quot; y=&quot;230&quot; as=&quot;sourcePoint&quot; /&gt;&#10;            &lt;mxPoint x=&quot;520&quot; y=&quot;180&quot; as=&quot;targetPoint&quot; /&gt;&#10;          &lt;/mxGeometry&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-19&quot; value=&quot;&amp;lt;h3 style=&amp;quot;line-height: 20%;&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#000000&amp;quot;&amp;gt;PUBLIC COMPONENTS&amp;lt;/font&amp;gt;&amp;lt;/h3&amp;gt;&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;dashed=1;horizontal=1;verticalAlign=top;fillColor=#9CA9D3;strokeColor=#23445d;strokeWidth=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;640&quot; y=&quot;120&quot; width=&quot;280&quot; height=&quot;350&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-17&quot; value=&quot;&amp;lt;b&amp;gt;VM::brand()&amp;lt;/b&amp;gt;&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;660&quot; y=&quot;400&quot; width=&quot;119.5&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-23&quot; value=&quot;&quot; style=&quot;endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;strokeColor=#000000;&quot; parent=&quot;1&quot; source=&quot;_5j-xkA9-BKe6-_lW6Nw-13&quot; target=&quot;_5j-xkA9-BKe6-_lW6Nw-17&quot; edge=&quot;1&quot;&gt;&#10;          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10;            &lt;mxPoint x=&quot;550&quot; y=&quot;230&quot; as=&quot;sourcePoint&quot; /&gt;&#10;            &lt;mxPoint x=&quot;600&quot; y=&quot;180&quot; as=&quot;targetPoint&quot; /&gt;&#10;            &lt;Array as=&quot;points&quot;&gt;&#10;              &lt;mxPoint x=&quot;510&quot; y=&quot;385&quot; /&gt;&#10;              &lt;mxPoint x=&quot;510&quot; y=&quot;438&quot; /&gt;&#10;            &lt;/Array&gt;&#10;          &lt;/mxGeometry&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-26&quot; value=&quot;&amp;lt;b&amp;gt;VM::detect()&amp;lt;/b&amp;gt;&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;660&quot; y=&quot;340&quot; width=&quot;119.5&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-30&quot; value=&quot;&amp;lt;b&amp;gt;VM::percentage()&amp;lt;/b&amp;gt;&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;660&quot; y=&quot;280&quot; width=&quot;119.5&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-32&quot; value=&quot;Returns the most likely VM brand&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;779.5&quot; y=&quot;400&quot; width=&quot;119.5&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-34&quot; value=&quot;Returns a boolean &amp;lt;br&amp;gt;true or false value whether it&amp;#39;s a VM&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;779.5&quot; y=&quot;340&quot; width=&quot;119.5&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-36&quot; value=&quot;&amp;lt;b&amp;gt;VM::check()&amp;lt;/b&amp;gt;&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;660&quot; y=&quot;220&quot; width=&quot;119.5&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-38&quot; value=&quot;Run every VM detection technique in the table&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;520&quot; y=&quot;256&quot; width=&quot;80&quot; height=&quot;128&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-45&quot; value=&quot;&quot; style=&quot;endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;strokeColor=#000000;startArrow=classic;startFill=1;&quot; parent=&quot;1&quot; source=&quot;_5j-xkA9-BKe6-_lW6Nw-38&quot; target=&quot;_5j-xkA9-BKe6-_lW6Nw-6&quot; edge=&quot;1&quot;&gt;&#10;          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10;            &lt;mxPoint x=&quot;630&quot; y=&quot;240&quot; as=&quot;sourcePoint&quot; /&gt;&#10;            &lt;mxPoint x=&quot;680&quot; y=&quot;190&quot; as=&quot;targetPoint&quot; /&gt;&#10;            &lt;Array as=&quot;points&quot;&gt;&#10;              &lt;mxPoint x=&quot;500&quot; y=&quot;320&quot; /&gt;&#10;              &lt;mxPoint x=&quot;500&quot; y=&quot;263&quot; /&gt;&#10;            &lt;/Array&gt;&#10;          &lt;/mxGeometry&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-47&quot; value=&quot;Returns a 0 to 100 percentage of how likely it&amp;#39;s a VM&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;779.5&quot; y=&quot;280&quot; width=&quot;119.5&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-48&quot; value=&quot;&quot; style=&quot;endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#000000;startArrow=classic;startFill=1;&quot; parent=&quot;1&quot; source=&quot;_5j-xkA9-BKe6-_lW6Nw-36&quot; target=&quot;_5j-xkA9-BKe6-_lW6Nw-6&quot; edge=&quot;1&quot;&gt;&#10;          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10;            &lt;mxPoint x=&quot;820&quot; y=&quot;260&quot; as=&quot;sourcePoint&quot; /&gt;&#10;            &lt;mxPoint x=&quot;870&quot; y=&quot;210&quot; as=&quot;targetPoint&quot; /&gt;&#10;            &lt;Array as=&quot;points&quot;&gt;&#10;              &lt;mxPoint x=&quot;620&quot; y=&quot;245&quot; /&gt;&#10;              &lt;mxPoint x=&quot;620&quot; y=&quot;230&quot; /&gt;&#10;            &lt;/Array&gt;&#10;          &lt;/mxGeometry&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-49&quot; value=&quot;Returns the result of a single specific technique&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;779.5&quot; y=&quot;220&quot; width=&quot;119.5&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-57&quot; value=&quot;&amp;lt;font color=&amp;quot;#000000&amp;quot;&amp;gt;&amp;lt;b&amp;gt;core&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;(for key operations)&amp;lt;br&amp;gt;&amp;lt;/font&amp;gt;&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;fillColor=#bac8d3;strokeColor=#23445d;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;140&quot; y=&quot;380&quot; width=&quot;140&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-81&quot; value=&quot;&amp;lt;b&amp;gt;VM::add_custom()&amp;lt;/b&amp;gt;&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;660&quot; y=&quot;160&quot; width=&quot;119.5&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-83&quot; value=&quot;Adds a custom VM detection technique&amp;amp;nbsp;&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#eeeeee;strokeColor=#36393d;fontColor=#000000;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;779.5&quot; y=&quot;160&quot; width=&quot;119.5&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-84&quot; value=&quot;&quot; style=&quot;endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;strokeColor=#000000;&quot; parent=&quot;1&quot; source=&quot;_5j-xkA9-BKe6-_lW6Nw-81&quot; target=&quot;_5j-xkA9-BKe6-_lW6Nw-6&quot; edge=&quot;1&quot;&gt;&#10;          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10;            &lt;mxPoint x=&quot;660&quot; y=&quot;310&quot; as=&quot;sourcePoint&quot; /&gt;&#10;            &lt;mxPoint x=&quot;710&quot; y=&quot;260&quot; as=&quot;targetPoint&quot; /&gt;&#10;            &lt;Array as=&quot;points&quot;&gt;&#10;              &lt;mxPoint x=&quot;620&quot; y=&quot;185&quot; /&gt;&#10;              &lt;mxPoint x=&quot;620&quot; y=&quot;198&quot; /&gt;&#10;            &lt;/Array&gt;&#10;          &lt;/mxGeometry&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-91&quot; value=&quot;&quot; style=&quot;endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;sourcePerimeterSpacing=0;strokeColor=#000000;endFill=0;startArrow=classic;startFill=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;&quot; parent=&quot;1&quot; target=&quot;_5j-xkA9-BKe6-_lW6Nw-57&quot; edge=&quot;1&quot; source=&quot;_5j-xkA9-BKe6-_lW6Nw-6&quot;&gt;&#10;          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10;            &lt;mxPoint x=&quot;300&quot; y=&quot;250&quot; as=&quot;sourcePoint&quot; /&gt;&#10;            &lt;mxPoint x=&quot;440&quot; y=&quot;260&quot; as=&quot;targetPoint&quot; /&gt;&#10;            &lt;Array as=&quot;points&quot;&gt;&#10;              &lt;mxPoint x=&quot;300&quot; y=&quot;230&quot; /&gt;&#10;              &lt;mxPoint x=&quot;300&quot; y=&quot;410&quot; /&gt;&#10;            &lt;/Array&gt;&#10;          &lt;/mxGeometry&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;_5j-xkA9-BKe6-_lW6Nw-92&quot; value=&quot;&quot; style=&quot;endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;strokeColor=#000000;&quot; parent=&quot;1&quot; target=&quot;_5j-xkA9-BKe6-_lW6Nw-4&quot; edge=&quot;1&quot;&gt;&#10;          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10;            &lt;mxPoint x=&quot;300&quot; y=&quot;270&quot; as=&quot;sourcePoint&quot; /&gt;&#10;            &lt;mxPoint x=&quot;350&quot; y=&quot;260&quot; as=&quot;targetPoint&quot; /&gt;&#10;          &lt;/mxGeometry&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;cPlAHG-HkCh-T9TprcrS-1&quot; value=&quot;&quot; style=&quot;endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;strokeColor=#000000;&quot; parent=&quot;1&quot; source=&quot;_5j-xkA9-BKe6-_lW6Nw-17&quot; target=&quot;_5j-xkA9-BKe6-_lW6Nw-38&quot; edge=&quot;1&quot;&gt;&#10;          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10;            &lt;mxPoint x=&quot;570&quot; y=&quot;290&quot; as=&quot;sourcePoint&quot; /&gt;&#10;            &lt;mxPoint x=&quot;620&quot; y=&quot;240&quot; as=&quot;targetPoint&quot; /&gt;&#10;            &lt;Array as=&quot;points&quot;&gt;&#10;              &lt;mxPoint x=&quot;620&quot; y=&quot;413&quot; /&gt;&#10;              &lt;mxPoint x=&quot;620&quot; y=&quot;352&quot; /&gt;&#10;            &lt;/Array&gt;&#10;          &lt;/mxGeometry&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;cPlAHG-HkCh-T9TprcrS-2&quot; value=&quot;&quot; style=&quot;endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.25;exitDx=0;exitDy=0;strokeColor=#000000;&quot; parent=&quot;1&quot; source=&quot;_5j-xkA9-BKe6-_lW6Nw-38&quot; target=&quot;_5j-xkA9-BKe6-_lW6Nw-30&quot; edge=&quot;1&quot;&gt;&#10;          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10;            &lt;mxPoint x=&quot;570&quot; y=&quot;290&quot; as=&quot;sourcePoint&quot; /&gt;&#10;            &lt;mxPoint x=&quot;620&quot; y=&quot;240&quot; as=&quot;targetPoint&quot; /&gt;&#10;            &lt;Array as=&quot;points&quot;&gt;&#10;              &lt;mxPoint x=&quot;630&quot; y=&quot;288&quot; /&gt;&#10;              &lt;mxPoint x=&quot;630&quot; y=&quot;305&quot; /&gt;&#10;            &lt;/Array&gt;&#10;          &lt;/mxGeometry&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;cPlAHG-HkCh-T9TprcrS-3&quot; value=&quot;&quot; style=&quot;endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#000000;&quot; parent=&quot;1&quot; source=&quot;_5j-xkA9-BKe6-_lW6Nw-38&quot; target=&quot;_5j-xkA9-BKe6-_lW6Nw-26&quot; edge=&quot;1&quot;&gt;&#10;          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10;            &lt;mxPoint x=&quot;570&quot; y=&quot;290&quot; as=&quot;sourcePoint&quot; /&gt;&#10;            &lt;mxPoint x=&quot;620&quot; y=&quot;240&quot; as=&quot;targetPoint&quot; /&gt;&#10;            &lt;Array as=&quot;points&quot;&gt;&#10;              &lt;mxPoint x=&quot;630&quot; y=&quot;320&quot; /&gt;&#10;              &lt;mxPoint x=&quot;630&quot; y=&quot;365&quot; /&gt;&#10;            &lt;/Array&gt;&#10;          &lt;/mxGeometry&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;GsFwuIZayCYaH_RebeOi-1&quot; value=&quot;&quot; style=&quot;endArrow=none;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#000000;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;_5j-xkA9-BKe6-_lW6Nw-2&quot;&gt;&#10;          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10;            &lt;mxPoint x=&quot;310&quot; y=&quot;290&quot; as=&quot;sourcePoint&quot; /&gt;&#10;            &lt;mxPoint x=&quot;300&quot; y=&quot;340&quot; as=&quot;targetPoint&quot; /&gt;&#10;          &lt;/mxGeometry&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;GsFwuIZayCYaH_RebeOi-4&quot; value=&quot;&quot; style=&quot;endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.25;exitDx=0;exitDy=0;strokeColor=#000000;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;_5j-xkA9-BKe6-_lW6Nw-6&quot; target=&quot;_5j-xkA9-BKe6-_lW6Nw-3&quot;&gt;&#10;          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10;            &lt;mxPoint x=&quot;460&quot; y=&quot;290&quot; as=&quot;sourcePoint&quot; /&gt;&#10;            &lt;mxPoint x=&quot;510&quot; y=&quot;240&quot; as=&quot;targetPoint&quot; /&gt;&#10;          &lt;/mxGeometry&gt;&#10;        &lt;/mxCell&gt;&#10;      &lt;/root&gt;&#10;    &lt;/mxGraphModel&gt;&#10;  &lt;/diagram&gt;&#10;&lt;/mxfile&gt;&#10;" style="background-color: rgb(24, 20, 29);"><defs/><rect fill="#18141D" width="100%" height="100%" x="0" y="0"/><g><rect x="0" y="0" width="880" height="450" rx="67.5" ry="67.5" fill="#bac8d3" stroke="#23445d" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 878px; height: 1px; padding-top: 7px; margin-left: 1px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><h1 style="line-height: 205%;"><font style="font-size: 32px;" color="#000000"><u>VMAware library structure</u></font></h1></div></div></div></foreignObject><text x="440" y="19" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="middle">VMAware library structure</text></switch></g><rect x="30" y="80" width="390" height="340" rx="51" ry="51" fill="#9ebad3" stroke="#23445d" stroke-dasharray="3 3" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 388px; height: 1px; padding-top: 87px; margin-left: 31px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><h3 style="line-height: 30%;"><font color="#000000" style="font-size: 15px;">PRIVATE COMPONENTS</font></h3></div></div></div></foreignObject><text x="225" y="99" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="middle">PRIVATE COMPONENTS</text></switch></g><rect x="70" y="270" width="140" height="60" rx="9" ry="9" fill="#fad9d5" stroke="#ae4132" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 300px; margin-left: 71px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font color="#000000"><b>utility</b><br />(for general operations)<br /></font></div></div></div></foreignObject><text x="140" y="304" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="middle">utility...</text></switch></g><rect x="70" y="200" width="140" height="60" rx="9" ry="9" fill="#b0e3e6" stroke="#0e8088" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 230px; margin-left: 71px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font color="#000000"><b>cpu</b><br />(for CPU operations)<br /></font></div></div></div></foreignObject><text x="140" y="234" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="middle">cpu...</text></switch></g><rect x="70" y="128" width="140" height="60" rx="9" ry="9" fill="#b1ddf0" stroke="#10739e" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 158px; margin-left: 71px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font color="#000000"><b>memoization</b><br />(for caching operations)<br /></font></div></div></div></foreignObject><text x="140" y="162" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="middle">memoization...</text></switch></g><rect x="250" y="125" width="140" height="130" rx="19.5" ry="19.5" fill="#fad7ac" stroke="#b46504" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 190px; margin-left: 251px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font color="#000000"><b><u>technique table<br /></u></b><br />(stores all the VM detection techniques)<br /></font></div></div></div></foreignObject><text x="320" y="194" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="middle">technique table...</text></switch></g><rect x="250" y="290" width="140" height="110" rx="16.5" ry="16.5" fill="#d0cee2" stroke="#56517e" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 345px; margin-left: 251px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font color="#000000"><b><u>brand table<br /></u></b></font><div><br /><font color="#000000">(stores a scoreboard table of every VM brand)</font></div></div></div></div></foreignObject><text x="320" y="349" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="middle">brand table...</text></switch></g><path d="M 320 255 L 320 283.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 320 288.88 L 316.5 281.88 L 320 283.63 L 323.5 281.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="570" y="80" width="280" height="350" rx="42" ry="42" fill="#9ca9d3" stroke="#23445d" stroke-dasharray="3 3" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 278px; height: 1px; padding-top: 87px; margin-left: 571px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><h3 style="line-height: 20%;"><font color="#000000">PUBLIC COMPONENTS</font></h3></div></div></div></foreignObject><text x="710" y="99" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="middle">PUBLIC COMPONENTS</text></switch></g><rect x="590" y="360" width="119.5" height="50" fill="#eeeeee" stroke="#36393d" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 385px; margin-left: 591px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>VM::brand()</b></div></div></div></foreignObject><text x="650" y="389" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">VM::brand()</text></switch></g><path d="M 390 345 L 440 345 L 440 398 L 583.63 397.52" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 588.88 397.5 L 581.89 401.03 L 583.63 397.52 L 581.87 394.03 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="590" y="300" width="119.5" height="50" fill="#eeeeee" stroke="#36393d" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 325px; margin-left: 591px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>VM::detect()</b></div></div></div></foreignObject><text x="650" y="329" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">VM::detect()</text></switch></g><rect x="590" y="240" width="119.5" height="50" fill="#eeeeee" stroke="#36393d" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 265px; margin-left: 591px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>VM::percentage()</b></div></div></div></foreignObject><text x="650" y="269" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">VM::percentage()</text></switch></g><rect x="709.5" y="360" width="119.5" height="50" fill="#eeeeee" stroke="#36393d" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 385px; margin-left: 711px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Returns the most likely VM brand</div></div></div></foreignObject><text x="769" y="389" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Returns the most lik...</text></switch></g><rect x="709.5" y="300" width="119.5" height="50" fill="#eeeeee" stroke="#36393d" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 325px; margin-left: 711px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Returns a boolean <br />true or false value whether it's a VM</div></div></div></foreignObject><text x="769" y="329" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Returns a boolean...</text></switch></g><rect x="590" y="180" width="119.5" height="50" fill="#eeeeee" stroke="#36393d" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 205px; margin-left: 591px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>VM::check()</b></div></div></div></foreignObject><text x="650" y="209" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">VM::check()</text></switch></g><rect x="450" y="216" width="80" height="128" rx="12" ry="12" fill="rgb(24, 20, 29)" stroke="rgb(240, 240, 240)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 280px; margin-left: 451px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Run every VM detection technique in the table</div></div></div></foreignObject><text x="490" y="284" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="middle">Run every VM...</text></switch></g><path d="M 443.63 280 L 430 280 L 430 223 L 396.37 222.58" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 448.88 280 L 441.88 283.5 L 443.63 280 L 441.88 276.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 391.12 222.51 L 398.16 219.1 L 396.37 222.58 L 398.07 226.1 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="709.5" y="240" width="119.5" height="50" fill="#eeeeee" stroke="#36393d" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 265px; margin-left: 711px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Returns a 0 to 100 percentage of how likely it's a VM</div></div></div></foreignObject><text x="769" y="269" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Returns a 0 to 100 p...</text></switch></g><path d="M 583.63 205 L 550 205 L 550 190 L 396.37 190" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 588.88 205 L 581.88 208.5 L 583.63 205 L 581.88 201.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 391.12 190 L 398.12 186.5 L 396.37 190 L 398.12 193.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="709.5" y="180" width="119.5" height="50" fill="#eeeeee" stroke="#36393d" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 205px; margin-left: 711px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Returns the result of a single specific technique</div></div></div></foreignObject><text x="769" y="209" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Returns the result o...</text></switch></g><rect x="70" y="340" width="140" height="60" rx="9" ry="9" fill="#bac8d3" stroke="#23445d" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 370px; margin-left: 71px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font color="#000000"><b>core</b><br />(for key operations)<br /></font></div></div></div></foreignObject><text x="140" y="374" fill="rgb(240, 240, 240)" font-family="Helvetica" font-size="12px" text-anchor="middle">core...</text></switch></g><rect x="590" y="120" width="119.5" height="50" fill="#eeeeee" stroke="#36393d" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 145px; margin-left: 591px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><b>VM::add_custom()</b></div></div></div></foreignObject><text x="650" y="149" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">VM::add_custom()</text></switch></g><rect x="709.5" y="120" width="119.5" height="50" fill="#eeeeee" stroke="#36393d" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 145px; margin-left: 711px;"><div data-drawio-colors="color: #000000; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Adds a custom VM detection technique </div></div></div></foreignObject><text x="769" y="149" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Adds a custom VM det...</text></switch></g><path d="M 590 145 L 550 145 L 550 158 L 396.37 157.52" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 391.12 157.5 L 398.13 154.03 L 396.37 157.52 L 398.11 161.03 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 243.63 190 L 230 190 L 230 370 L 210 370" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 248.88 190 L 241.88 193.5 L 243.63 190 L 241.88 186.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 230 230 L 210 230" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 590 372.5 L 550 373 L 550 312 L 536.37 312" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 531.12 312 L 538.12 308.5 L 536.37 312 L 538.12 315.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 536.37 248 L 560 248 L 560 265 L 583.63 265" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 531.12 248 L 538.12 244.5 L 536.37 248 L 538.12 251.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 588.88 265 L 581.88 268.5 L 583.63 265 L 581.88 261.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 536.37 280 L 560 280 L 560 325 L 583.63 325" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 531.12 280 L 538.12 276.5 L 536.37 280 L 538.12 283.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 588.88 325 L 581.88 328.5 L 583.63 325 L 581.88 321.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 210 300 L 230 300" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 243.63 157.58 L 216.37 157.92" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 248.88 157.51 L 241.93 161.1 L 243.63 157.58 L 241.84 154.1 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 211.12 157.99 L 218.07 154.4 L 216.37 157.92 L 218.16 161.4 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/></g></svg>
\ No newline at end of file
diff --git a/VMAware/auxiliary/cpuid_fuzzer.c b/VMAware/auxiliary/cpuid_fuzzer.c
new file mode 100644
index 0000000000000000000000000000000000000000..63a1a9841a328e7539340194cc467aae96bd3475
--- /dev/null
+++ b/VMAware/auxiliary/cpuid_fuzzer.c
@@ -0,0 +1,237 @@
+/**
+ * ██╗   ██╗███╗   ███╗ █████╗ ██╗    ██╗ █████╗ ██████╗ ███████╗
+ * ██║   ██║████╗ ████║██╔══██╗██║    ██║██╔══██╗██╔══██╗██╔════╝
+ * ██║   ██║██╔████╔██║███████║██║ █╗ ██║███████║██████╔╝█████╗  
+ * ╚██╗ ██╔╝██║╚██╔╝██║██╔══██║██║███╗██║██╔══██║██╔══██╗██╔══╝  
+ *  ╚████╔╝ ██║ ╚═╝ ██║██║  ██║╚███╔███╔╝██║  ██║██║  ██║███████╗
+ *   ╚═══╝  ╚═╝     ╚═╝╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝
+ * 
+ *  C++ VM detection library
+ * 
+ * ===============================================================
+ *
+ *  This program serves as an internal tool for fuzzing cpuid values 
+ *  and comparing them between baremetal outputs and VM outputs.
+ * 
+ * ===============================================================
+ * 
+ *  - Made by: @kernelwernel (https://github.com/kernelwernel)
+ *  - Repository: https://github.com/kernelwernel/VMAware
+ *  - License: GPL 3.0
+ */ 
+
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdatomic.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if (defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__))
+    #define MSVC 1
+    #define LINUX 0
+#elif (defined(__GNUC__) || defined(__linux__))
+    #define MSVC 0
+    #define LINUX 1
+#else
+    #error "Unknown OS, aborting"
+#endif
+
+#if (LINUX)
+    #include <cpuid.h>
+    #include <sched.h>
+    #include <pthread.h>
+    #include <unistd.h>
+    #include <sys/sysinfo.h>
+#else 
+    #include <intrin.h>
+#endif
+
+// branching macros
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#define likely(x)   __builtin_expect(!!(x), 1)
+
+// cpu brand shit for ecx idfk
+#define intel_ecx 0x6c65746e
+#define amd_ecx 0x69746e65
+
+// cpuid leaf values
+#define manufacturer 0x00000000
+#define proc_info 0x00000001
+#define cache_tlb 0x00000002
+#define serial 0x00000003
+#define topology 0x00000004
+#define topology2 0x0000000B
+#define management 0x00000006
+#define extended 0x00000007 // ecx = 0
+#define extended2 0x00000007 // ecx = 1
+#define extended3 0x00000007 // ecx = 2
+#define xsave 0x0000000D
+#define xsave2 0x0000000D // ecx = >2
+#define xsave3 0x0000000D // ecx = 0
+#define xsave4 0x0000000D // ecx = 1
+#define sgx 0x00000012 // ecx = 0
+#define sgx2 0x00000012 // ecx = 1
+#define sgx3 0x00000012 // ecx = >2
+#define proc_trace 0x00000014 // ecx = 0
+#define aes 0x00000019
+#define avx10 0x00000024 // ecx = 0
+#define vm0 0x40000000
+#define vm1 0x40000001
+#define vm2 0x40000002
+#define vm3 0x40000003
+#define extended_proc_info 0x80000001
+#define hypervisor 0x40000000
+#define max_leaf 0x80000000
+#define brand1 0x80000002
+#define brand2 0x80000003
+#define brand3 0x80000004
+#define L1_cache 0x80000005
+#define L2_cache 0x80000006
+#define capabilities 0x80000007
+#define virtual 0x80000008
+#define svm 0x8000000A
+#define enc_mem_cap 0x8000001F
+#define ext_info2 0x80000021
+#define amd_easter_egg 0x8fffffff
+#define centaur_ext 0xC0000000
+#define centaur_feature 0xC0000001
+
+// index macros
+#define eax 0
+#define ebx 1
+#define ecx 2
+#define edx 3 
+
+// cli flags
+#define leaf_mode 1
+#define scan_mode 2
+
+// miscellaneous
+#define null_leaf 0xFF
+#define breakpoint 10000000
+
+
+// basic cpuid wrapper
+static void cpuid
+(
+    uint32_t *x,
+    const uint64_t leaf,
+    const uint64_t subleaf
+) {
+    #if (MSVC)
+        __cpuidex((int32_t*)x, (int32_t)(leaf), (int32_t)(subleaf));
+    #elif (LINUX)
+        __cpuid_count(leaf, subleaf, x[0], x[1], x[2], x[3]);
+    #endif
+};
+
+// get highest eax leaf 
+static uint32_t get_highest_leaf() {
+    uint32_t reg[4];
+    cpuid(reg, max_leaf, null_leaf);
+    return (reg[eax]);
+}
+
+// scan for predetermined leafs
+void leaf_mode_fuzzer(const uint64_t p_max_leaf) {
+    uint32_t reg[4];
+    const uint32_t leafs[40] = { 
+        manufacturer, proc_info, cache_tlb, 
+        serial, topology, topology2, 
+        management, extended, extended2, 
+        extended3, xsave, xsave2 , 
+        xsave3, xsave4, sgx, 
+        sgx2, sgx3 , proc_trace, 
+        aes, avx10, extended_proc_info, 
+        hypervisor, max_leaf, brand1, 
+        brand2, brand3, L1_cache, 
+        L2_cache, capabilities, virtual, 
+        svm, enc_mem_cap, ext_info2, 
+        amd_easter_egg, centaur_ext, centaur_feature,
+        vm0, vm1, vm2, vm3
+    };
+
+    const size_t leaf_arr_size = (sizeof(leafs) / sizeof(leafs[0]));    
+
+    for (int i = 0; i < leaf_arr_size; i++) {
+        if (leafs[i] >= p_max_leaf) {
+            continue;
+        }
+
+        cpuid(reg, leafs[i], null_leaf);
+
+        if (likely(
+            reg[eax] || \
+            reg[ebx] || \
+            reg[ecx] || \
+            reg[edx]
+        )) {
+            printf("leaf = %d\n", i);
+            printf("eax = 0x%0X\n", reg[eax]);
+            printf("ebx = 0x%0X\n", reg[ebx]);
+            printf("ecx = 0x%0X\n", reg[ecx]);
+            printf("edx = 0x%0X\n\n", reg[edx]);
+        }
+    }
+}
+
+
+// scan for a range of leafs
+void scan_mode_fuzzer(const uint64_t p_max_leaf) {
+    printf("%s", "Scan mode fuzzer \n");
+    uint32_t reg[4];
+
+    for (int i = 0; i < 0x10000; i++) {
+        cpuid(reg, 0x40000000 + i, null_leaf);
+
+        if (likely(
+            reg[eax] || \
+            reg[ebx] || \
+            reg[ecx] || \
+            reg[edx]
+        )) {
+            printf("leaf = %d\n", i);
+            printf("eax = 0x%0X\n", reg[eax]);
+            printf("ebx = 0x%0X\n", reg[ebx]);
+            printf("ecx = 0x%0X\n", reg[ecx]);
+            printf("edx = 0x%0X\n\n", reg[edx]);
+        }
+    }
+}
+
+
+int main(int argc, char *argv[]) {
+    uint8_t flags = 0;
+
+    if (argc == 1) {
+        flags |= leaf_mode;
+        flags |= scan_mode;
+    } else if (argc == 2) {
+        if (strcmp(argv[2], "--leaf") == 0) {
+            flags |= leaf_mode;
+        } else if (strcmp(argv[2], "--scan") == 0) {
+            flags |= scan_mode;
+        } else {
+            printf("%s", "Unknown flag provided, aborting\n");
+            return 1;
+        }
+    } else {
+        printf("%s", "Too many flags provided, only use either --leaf or --scan\n");
+        return 1;
+    }
+
+    const uint64_t high_leaf = get_highest_leaf();
+    printf("highest leaf = 0x%0lX\n", high_leaf);
+
+    if (flags & leaf_mode) {
+        leaf_mode_fuzzer(high_leaf);
+    }
+    
+    if (flags & scan_mode) {
+        scan_mode_fuzzer(high_leaf);
+    }
+
+    return 0;
+}
\ No newline at end of file
diff --git a/VMAware/auxiliary/idt_scan.cpp b/VMAware/auxiliary/idt_scan.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8ee8844fad29530408da1eeaa93ff33e945ea25b
--- /dev/null
+++ b/VMAware/auxiliary/idt_scan.cpp
@@ -0,0 +1,108 @@
+/**
+ * ██╗   ██╗███╗   ███╗ █████╗ ██╗    ██╗ █████╗ ██████╗ ███████╗
+ * ██║   ██║████╗ ████║██╔══██╗██║    ██║██╔══██╗██╔══██╗██╔════╝
+ * ██║   ██║██╔████╔██║███████║██║ █╗ ██║███████║██████╔╝█████╗  
+ * ╚██╗ ██╔╝██║╚██╔╝██║██╔══██║██║███╗██║██╔══██║██╔══██╗██╔══╝  
+ *  ╚████╔╝ ██║ ╚═╝ ██║██║  ██║╚███╔███╔╝██║  ██║██║  ██║███████╗
+ *   ╚═══╝  ╚═╝     ╚═╝╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝
+ * 
+ *  C++ VM detection library
+ * 
+ * ===============================================================
+ *
+ *  This program will scan for IDT values based on the execution
+ *  of multiple threads, which allows us to collect IDT information
+ *  which could be potentially used for VM detections.
+ * 
+ * ===============================================================
+ * 
+ *  - Made by: @Requiem (https://github.com/NotRequiem)
+ *  - Repository: https://github.com/kernelwernel/VMAware
+ *  - License: GPL 3.0
+ */ 
+
+#include <iostream>
+#include <thread>
+#include <vector>
+#include <pthread.h>
+#include <sched.h>
+#include <unistd.h>
+
+#ifdef _MSC_VER
+#include <intrin.h>
+#else
+#include <x86intrin.h>
+#endif
+
+#pragma pack(push, 1)
+struct IDTR {
+    uint16_t limit;
+    uint64_t base;
+};
+#pragma pack(pop)
+
+void print_idt_base() {
+    IDTR idtr;
+
+#ifdef _MSC_VER
+    __sidt(&idtr);
+#else
+    asm volatile ("sidt %0" : "=m" (idtr));
+#endif
+
+    uint64_t idt_base = idtr.base;
+    std::cout << "Thread ID: " << std::this_thread::get_id() << " | IDT base address: 0x" << std::hex << idt_base << "\n";
+}
+
+// Function to bind a thread to a specific core on Linux
+void set_thread_affinity(unsigned int core_id) {
+    cpu_set_t cpuset;
+    CPU_ZERO(&cpuset);  // Clear the CPU set
+    CPU_SET(core_id, &cpuset);  // Set the desired core
+
+    // Get the current thread
+    pthread_t current_thread = pthread_self();
+
+    // Set thread affinity to the specific core
+    if (pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset) != 0) {
+        std::cerr << "Error setting thread affinity\n";
+    }
+}
+
+// Function to run code on multiple cores
+void run_on_multiple_cores(int times) {
+    unsigned int num_threads = std::thread::hardware_concurrency();
+    std::cout << "Running on " << num_threads << " threads (multiple cores)...\n";
+
+    for (int i = 0; i < times; ++i) {
+        std::vector<std::thread> threads;
+        for (unsigned int j = 0; j < num_threads; ++j) {
+            threads.emplace_back([j]() {
+                set_thread_affinity(j);  // Bind thread to core j
+                print_idt_base();
+            });
+        }
+
+        for (auto& thread : threads) {
+            thread.join();
+        }
+    }
+}
+
+// Function to run code on a single core
+void run_on_single_core(int times) {
+    std::cout << "Running on a single core...\n";
+    set_thread_affinity(0);  // Bind thread to core 0
+
+    for (int i = 0; i < times; ++i) {
+        print_idt_base();
+    }
+}
+
+int main() {
+    int iterations = 5;
+    run_on_multiple_cores(iterations);
+    run_on_single_core(iterations);
+
+    return 0;
+}
\ No newline at end of file
diff --git a/VMAware/auxiliary/test_standards.sh b/VMAware/auxiliary/test_standards.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d52175dabb4b71c1864657c36ceae0c765266eba
--- /dev/null
+++ b/VMAware/auxiliary/test_standards.sh
@@ -0,0 +1,56 @@
+#
+# ██╗   ██╗███╗   ███╗ █████╗ ██╗    ██╗ █████╗ ██████╗ ███████╗
+# ██║   ██║████╗ ████║██╔══██╗██║    ██║██╔══██╗██╔══██╗██╔════╝
+# ██║   ██║██╔████╔██║███████║██║ █╗ ██║███████║██████╔╝█████╗  
+# ╚██╗ ██╔╝██║╚██╔╝██║██╔══██║██║███╗██║██╔══██║██╔══██╗██╔══╝  
+#  ╚████╔╝ ██║ ╚═╝ ██║██║  ██║╚███╔███╔╝██║  ██║██║  ██║███████╗
+#   ╚═══╝  ╚═╝     ╚═╝╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝
+# 
+#  C++ VM detection library
+# 
+# ===============================================================
+#
+#  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
\ No newline at end of file
diff --git a/VMAware/auxiliary/updater.py b/VMAware/auxiliary/updater.py
new file mode 100644
index 0000000000000000000000000000000000000000..e36fa6036f9efe00d881165bd1a48acf1246ddbf
--- /dev/null
+++ b/VMAware/auxiliary/updater.py
@@ -0,0 +1,435 @@
+# 
+# ██╗   ██╗███╗   ███╗ █████╗ ██╗    ██╗ █████╗ ██████╗ ███████╗
+# ██║   ██║████╗ ████║██╔══██╗██║    ██║██╔══██╗██╔══██╗██╔════╝
+# ██║   ██║██╔████╔██║███████║██║ █╗ ██║███████║██████╔╝█████╗  
+# ╚██╗ ██╔╝██║╚██╔╝██║██╔══██║██║███╗██║██╔══██║██╔══██╗██╔══╝  
+#  ╚████╔╝ ██║ ╚═╝ ██║██║  ██║╚███╔███╔╝██║  ██║██║  ██║███████╗
+#   ╚═══╝  ╚═╝     ╚═╝╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝
+# 
+#  C++ VM detection library
+# 
+# ===============================================================
+# 
+#  This is an internal script to update various stuff of the project:
+#    1.  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.
+# 
+#    2.  Update the line numbers for the sections header based on what
+#        line they are located, so it's a (tiny) bit easier to understand
+#        the structure of the headers for anybody reading it for the first
+#        time, it's more of a guide to point which parts are this and that.
+# 
+#    3.  Convert the GPL file (vmaware.hpp) into an MIT file (vmaware_MIT.hpp).
+#        In other words, it'll remove all the GPL code so that it qualifies 
+#        as MIT compliant.  
+# 
+#    4. Update the dates in the banner, example: "1.9 (Septmber 2024)"
+# 
+# ===============================================================
+# 
+#  - Made by: @kernelwernel (https://github.com/kernelwernel)
+#  - Repository: https://github.com/kernelwernel/VMAware
+#  - License: GPL 3.0
+
+
+import sys
+import re
+from datetime import datetime
+
+red = "\033[31m"
+bold = "\033[1m"
+ansi_exit = "\033[0m"
+
+def arg_check():
+    def fetch():
+        # fetch file content
+        with open("../src/vmaware.hpp", 'r') as vmaware:
+            header_content = vmaware.readlines()
+
+        # reversed since the table is at the very end of the vmaware.hpp file 
+        header_content.reverse()
+
+        # breakpoint
+        keyword = "const std::map<VM::enum_flags, VM::core::technique> VM::core::technique_table = {"
+
+        # fetch index of breakpoint
+        index_of_keyword = next((i for i, line in enumerate(header_content) if keyword in line), None)
+
+        # remove everything before the breakpoint for simplification
+        if index_of_keyword is not None:
+            header_content = header_content[:index_of_keyword + 1]
+
+        return header_content
+
+
+
+    def filter(raw_content):
+        trimmed_content = []
+
+        # filter
+        trimmed_content = [s for s in raw_content if not (
+            s.isspace() or 
+            "//" in s or 
+            ";" in s or
+            "VM::core::technique" in s
+        )]
+
+        # strip all whitespace
+        trimmed_content = [s.strip() for s in trimmed_content]
+
+        return trimmed_content
+
+
+
+    def tokenize(trimmed_content):
+        flag_array = []
+
+        # pattern for VM::FLAG_EXAMPLE1
+        pattern = r'\bVM::([A-Z0-9_]+)\b'
+
+        # match and push to flag_array[]
+        for line in trimmed_content:
+            match = re.search(pattern, line)
+
+            if match:
+                flag_array.append(match.group(0))
+            else:
+                print(f"Unable to find flag variable for " + red + bold + line + ansi_exit)
+                sys.exit(1)
+
+        return flag_array
+
+
+
+    def check_docs(flag_array):
+        # fetch docs content
+        with open("../docs/documentation.md", 'r') as docs:
+            docs_content = docs.readlines()
+
+        # strip whitespace
+        docs_content = [s.strip() for s in docs_content]
+
+        # find indices
+        start = "# Flag table"
+        end = "# Non-technique flags"
+
+        # extract the indexes
+        try:
+            start_index = docs_content.index(start)
+            end_index = docs_content.index(end)
+        except ValueError:
+            print(f"Couldn't find range index point {red}{bold}\"# Flag table\"{ansi_exit} or {red}{bold}\"# Non-technique flags\"{ansi_exit}")
+            start_index = end_index = None
+            sys.exit(1)
+
+        # extract the range between the aforementioned indexes
+        if start_index is not None and end_index is not None:
+            extracted_range = docs_content[start_index + 1:end_index]
+            docs_content = extracted_range
+
+        # filter elements with whitespace
+        docs_content = [s for s in docs_content if not s.isspace() and s and "VM::" in s]
+
+        # extract flag string for every line
+        docs_flags = []
+        pattern = r'`([^`]+)`'
+        for line in docs_content:
+            match = re.search(pattern, line)
+
+            if match:
+                docs_flags.append(match.group(1))
+            else:
+                print(f"Pattern not found in the line {red}{bold}\"" + line + "\"{ansi_exit}")
+                sys.exit(1)
+
+        set1 = set(docs_flags)
+        set2 = set(flag_array)
+
+        # Check if every element in set1 has a corresponding element in set2
+        all_elements_have_pair = set1.issubset(set2) and set2.issubset(set1)
+
+        not_paired = set1.symmetric_difference(set2)
+
+        if not_paired:
+            if "VM::ANYRUN_DIRECTORY" in not_paired or "VM::ANYRUN_DRIVER" in not_paired:
+                return
+
+            print(f"Mismatched elements found in {red}{bold}documentation.md{bold} and {red}{bold}vmaware.hpp{bold}, make sure to include the technique in both files")
+            print("Elements without a pair:", not_paired)
+            sys.exit(1)
+
+
+
+
+    def check_cli(flag_array):
+        # fetch docs content
+        with open("../src/cli.cpp", 'r') as cli:
+            cli_content = cli.readlines()
+
+        # strip whitespace
+        cli_content = [s.strip() for s in cli_content]
+
+        # filter elements with whitespace
+        cli_content = [s for s in cli_content if ("checker(" in s)]
+
+        # extract the flags
+        cli_flags = []
+        pattern = r'checker\((.*?),'
+        for line in cli_content:
+            match = re.search(pattern, line)
+
+            if match:
+                cli_flags.append(match.group(1).strip())
+            else:
+                print(f"{red}{bold}Pattern not found in the string.{ansi_exit}")
+        
+        set1 = set(cli_flags)
+        set2 = set(flag_array)
+
+        # check if every element in set1 has a corresponding element in set2
+        not_paired = set1.symmetric_difference(set2)
+
+        if not_paired:
+            if "anyrun_directory" in not_paired or "anyrun_driver" in not_paired:
+                return
+
+            print(f"Mismatched elements found in {red}{bold}cli.cpp{ansi_exit} and {red}{bold}vmaware.hpp{ansi_exit}, make sure to include the technique in both files")
+            print("Elements without a pair:", not_paired)
+            sys.exit(1)
+
+
+    raw_content = fetch()
+    trimmed_content = filter(raw_content)
+    flags = tokenize(trimmed_content)
+
+    check_docs(flags)
+    check_cli(flags)
+
+
+
+
+
+
+
+
+
+
+
+def update_MIT():
+    original = '../src/vmaware.hpp'
+    mit = '../src/vmaware_MIT.hpp'
+    gpl_string = '/* GPL */'
+    license_string = ' *  - License: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)'
+    mit_full_license = ''' *  - License: MIT
+ * 
+ *                               MIT License
+ *  
+ *  Copyright (c) 2024 kernelwernel
+ *  
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to deal
+ *  in the Software without restriction, including without limitation the rights
+ *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *  copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *  
+ *  The above copyright notice and this permission notice shall be included in all
+ *  copies or substantial portions of the Software.
+ *  
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ *  SOFTWARE.
+'''
+
+    with open(original, 'r') as file:
+        lines = file.readlines()
+
+    add_string_added = False
+
+    filtered_lines = []
+    for line in lines:
+        if gpl_string in line:
+            # skip
+            continue
+        if license_string in line:
+            filtered_lines.append(mit_full_license)
+        else:
+            filtered_lines.append(line)
+
+    with open(mit, 'w') as file:
+        file.writelines(filtered_lines)
+
+
+
+def update_sections(filename):
+    with open(filename, 'r') as vmaware_read:
+        header_content = vmaware_read.readlines()
+
+    # fetch important portions
+    enum = "enum enum_flags"
+    cpu  = "struct cpu {"
+    memo = "struct memo {"
+    util = "struct util {"
+    techniques = "private: // START OF PRIVATE VM DETECTION TECHNIQUE DEFINITIONS"
+    core = "struct core {"
+    public = "public: // START OF PUBLIC FUNCTIONS"
+    external = "// ============= EXTERNAL DEFINITIONS ============="
+
+    # set up the arrays
+    pointer_array = []
+    pair_array = []
+    keywords = [enum, cpu, memo, util, techniques, core, public, external]
+    scanner_keywords = [
+        "__ENUM__",
+        "__CPU__",
+        "__MEMO__",
+        "__UTIL__",
+        "__TECHNIQUES__",
+        "__CORE__",
+        "__PUBLIC__",
+        "__EXTERNAL__"
+    ]
+
+    # set the indexes
+    file_pointer = 0
+    array_index = 0
+
+
+    # loop and append if keyword is found
+    for line in header_content:
+        if keywords[array_index] in line:
+            if array_index != len(keywords) - 1:
+                array_index += 1
+
+            pointer_array.append(file_pointer)
+
+        file_pointer += 1
+
+
+    # create the pair array
+    i = 0
+    for scanner in scanner_keywords:
+        tmp_pair = (scanner, pointer_array[i])
+        pair_array.append(tmp_pair)
+        if i != len(pointer_array) - 1:
+            i += 1
+
+
+    MACRO = 0
+    FILE_LINE = 1
+    index = 0
+    banner = [
+        " * - enums for publicly accessible techniques  => line __ENUM__",
+        " * - struct for internal cpu operations        => line __CPU__",
+        " * - struct for internal memoization           => line __MEMO__",
+        " * - struct for internal utility functions     => line __UTIL__",
+        " * - start of internal VM detection techniques => line __TECHNIQUES__",
+        " * - struct for internal core components       => line __CORE__",
+        " * - start of public VM detection functions    => line __PUBLIC__",
+        " * - start of externally defined variables     => line __EXTERNAL__"
+    ]
+
+    # replace the macro strings with the file line numbers
+    for pair in pair_array:
+        for line in banner:
+            if pair[MACRO] in line:
+                banner[index] = line.replace(pair[MACRO], str(pair[FILE_LINE]))
+                index += 1
+                continue
+        
+    # manual filters
+    tmp = banner[4]
+    banner[4] = banner[5]
+    banner[5] = tmp
+
+    # get the index file line of the section string
+    section_line = 0
+    section_str = " * ================================ SECTIONS =================================="
+    for line in header_content:
+        if section_str in line:
+            break
+        section_line += 1
+    section_line += 1
+
+    # write to the header file
+    for i in range(len(banner)):
+        header_content[section_line + i] = banner[i] + '\n'
+    with open(filename, 'w') as file:
+        file.writelines(header_content)
+
+
+
+def update_date(filename):
+    # fetch the first arg, which is supposed to be the new version number for a new release
+    args = sys.argv
+    first_arg = args[1] if len(args) > 1 else None
+
+
+    with open(filename, 'r') as file:
+        header_content = file.readlines()
+
+    index = 0
+    banner_line = " *   ╚═══╝  ╚═╝     ╚═╝╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝ "
+
+    # fetch the index of where the line should be updated
+    for line in header_content:
+        if (banner_line not in line):
+            index += 1
+        else:
+            break
+
+    # find "X.X", where X is an integral
+    def find_pattern(base_str):
+        pattern = r'\d+\.\d+'
+
+        # Search for the pattern in the text
+        match = re.search(pattern, base_str)
+
+        # find match
+        if match:
+            return match.group()
+            print("match found")
+        else:
+            print(f"Version number not found for {red}{bold}{base_str}{ansi_exit}, aborting")
+            sys.exit(1)
+
+
+    # fetch the new version
+    header_version = find_pattern(header_content[index])
+    if first_arg == None:
+        arg_version = header_version
+    else:
+        arg_version = find_pattern(first_arg)
+
+    new_version = ""
+    new_date = ""
+
+    # set the version and date
+    new_version = arg_version
+    new_date = datetime.now().strftime("%B") + " " + str(datetime.now().year)
+
+    # this will be the new content
+    new_content = banner_line + new_version + " (" + new_date + ")"
+
+    if 0 < index <= len(header_content):
+        header_content[index] = new_content + '\n'
+    else:
+        print(f"Line number {red}{line_number} is out of range.")
+        sys.exit(1)
+
+    with open(filename, 'w') as file:
+        file.writelines(header_content)    
+
+
+
+arg_check()
+update_MIT()
+update_sections("../src/vmaware.hpp")
+update_sections("../src/vmaware_MIT.hpp")
+update_date("../src/vmaware.hpp")
+update_date("../src/vmaware_MIT.hpp")
\ No newline at end of file
diff --git a/VMAware/auxiliary/vmtest.cpp b/VMAware/auxiliary/vmtest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..36fd2c99e8a48badbb8e19793a5c5def80b2d992
--- /dev/null
+++ b/VMAware/auxiliary/vmtest.cpp
@@ -0,0 +1,45 @@
+/**
+ * ██╗   ██╗███╗   ███╗ █████╗ ██╗    ██╗ █████╗ ██████╗ ███████╗
+ * ██║   ██║████╗ ████║██╔══██╗██║    ██║██╔══██╗██╔══██╗██╔════╝
+ * ██║   ██║██╔████╔██║███████║██║ █╗ ██║███████║██████╔╝█████╗  
+ * ╚██╗ ██╔╝██║╚██╔╝██║██╔══██║██║███╗██║██╔══██║██╔══██╗██╔══╝  
+ *  ╚████╔╝ ██║ ╚═╝ ██║██║  ██║╚███╔███╔╝██║  ██║██║  ██║███████╗
+ *   ╚═══╝  ╚═╝     ╚═╝╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝
+ * 
+ *  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) {
+    //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::ENABLE_HYPERV_HOST);
+    //const std::string test8 = VM::brand();
+    //const uint8_t test9 = VM::percentage(VM::SPOOFABLE);
+    //std::cout << (int)test9 << "\n";
+
+    VM::vmaware vm;
+
+    std::cout << "Is this a VM? = " << vm.is_vm << "\n";
+    std::cout << "How many techniques detected a VM? = " << static_cast<int>(vm.detected_count) << "\n";
+    std::cout << "What's the overview in a human-readable message? = " << vm.conclusion << "\n";
+
+    return 0;
+}
\ No newline at end of file
diff --git a/VMAware/build/CMakeCache.txt b/VMAware/build/CMakeCache.txt
new file mode 100644
index 0000000000000000000000000000000000000000..df72bc5c7307a54582baeffa2b8a4fae503fcb21
--- /dev/null
+++ b/VMAware/build/CMakeCache.txt
@@ -0,0 +1,389 @@
+# This is the CMakeCache file.
+# For build in directory: /home/rickyy/Documents/incognito-vm/VMAware/build
+# It was generated by CMake: /usr/bin/cmake
+# You can edit this file to change values found and used by cmake.
+# If you do not want to change any of the values, simply exit the editor.
+# If you do want to change a value, simply edit, save, and exit the editor.
+# The syntax for the file is as follows:
+# KEY:TYPE=VALUE
+# KEY is the name of a variable in the cache.
+# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
+# VALUE is the current value for the KEY.
+
+########################
+# EXTERNAL cache entries
+########################
+
+//Build the testing tree.
+BUILD_TESTING:BOOL=ON
+
+//Path to a program.
+CMAKE_ADDR2LINE:FILEPATH=/usr/bin/addr2line
+
+//Path to a program.
+CMAKE_AR:FILEPATH=/usr/bin/ar
+
+//Choose the type of build (Debug or Release)
+CMAKE_BUILD_TYPE:STRING=Release
+
+//Enable/Disable color output during build.
+CMAKE_COLOR_MAKEFILE:BOOL=ON
+
+//CXX compiler
+CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++
+
+//A wrapper around 'ar' adding the appropriate '--plugin' option
+// for the GCC compiler
+CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar
+
+//A wrapper around 'ranlib' adding the appropriate '--plugin' option
+// for the GCC compiler
+CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib
+
+//Flags used by the CXX compiler during all build types.
+CMAKE_CXX_FLAGS:STRING=
+
+//Flags used by the CXX compiler during DEBUG builds.
+CMAKE_CXX_FLAGS_DEBUG:STRING=-g
+
+//Flags used by the CXX compiler during MINSIZEREL builds.
+CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
+
+//Flags used by the CXX compiler during RELEASE builds.
+CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
+
+//Flags used by the CXX compiler during RELWITHDEBINFO builds.
+CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
+
+//Path to a program.
+CMAKE_DLLTOOL:FILEPATH=CMAKE_DLLTOOL-NOTFOUND
+
+//Flags used by the linker during all build types.
+CMAKE_EXE_LINKER_FLAGS:STRING=
+
+//Flags used by the linker during DEBUG builds.
+CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
+
+//Flags used by the linker during MINSIZEREL builds.
+CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
+
+//Flags used by the linker during RELEASE builds.
+CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
+
+//Flags used by the linker during RELWITHDEBINFO builds.
+CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
+
+//Enable/Disable output of compile commands during generation.
+CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=
+
+//Value Computed by CMake.
+CMAKE_FIND_PACKAGE_REDIRECTS_DIR:STATIC=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/pkgRedirects
+
+//Install path prefix, prepended onto install directories.
+CMAKE_INSTALL_PREFIX:PATH=/usr/local
+
+//Path to a program.
+CMAKE_LINKER:FILEPATH=/usr/bin/ld
+
+//Path to a program.
+CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make
+
+//Flags used by the linker during the creation of modules during
+// all build types.
+CMAKE_MODULE_LINKER_FLAGS:STRING=
+
+//Flags used by the linker during the creation of modules during
+// DEBUG builds.
+CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
+
+//Flags used by the linker during the creation of modules during
+// MINSIZEREL builds.
+CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
+
+//Flags used by the linker during the creation of modules during
+// RELEASE builds.
+CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
+
+//Flags used by the linker during the creation of modules during
+// RELWITHDEBINFO builds.
+CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
+
+//Path to a program.
+CMAKE_NM:FILEPATH=/usr/bin/nm
+
+//Path to a program.
+CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy
+
+//Path to a program.
+CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump
+
+//Value Computed by CMake
+CMAKE_PROJECT_DESCRIPTION:STATIC=VM detection library
+
+//Value Computed by CMake
+CMAKE_PROJECT_HOMEPAGE_URL:STATIC=
+
+//Value Computed by CMake
+CMAKE_PROJECT_NAME:STATIC=VMAware
+
+//Path to a program.
+CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib
+
+//Path to a program.
+CMAKE_READELF:FILEPATH=/usr/bin/readelf
+
+//Flags used by the linker during the creation of shared libraries
+// during all build types.
+CMAKE_SHARED_LINKER_FLAGS:STRING=
+
+//Flags used by the linker during the creation of shared libraries
+// during DEBUG builds.
+CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
+
+//Flags used by the linker during the creation of shared libraries
+// during MINSIZEREL builds.
+CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
+
+//Flags used by the linker during the creation of shared libraries
+// during RELEASE builds.
+CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
+
+//Flags used by the linker during the creation of shared libraries
+// during RELWITHDEBINFO builds.
+CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
+
+//If set, runtime paths are not added when installing shared libraries,
+// but are added when building.
+CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
+
+//If set, runtime paths are not added when using shared libraries.
+CMAKE_SKIP_RPATH:BOOL=NO
+
+//Flags used by the linker during the creation of static libraries
+// during all build types.
+CMAKE_STATIC_LINKER_FLAGS:STRING=
+
+//Flags used by the linker during the creation of static libraries
+// during DEBUG builds.
+CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
+
+//Flags used by the linker during the creation of static libraries
+// during MINSIZEREL builds.
+CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
+
+//Flags used by the linker during the creation of static libraries
+// during RELEASE builds.
+CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
+
+//Flags used by the linker during the creation of static libraries
+// during RELWITHDEBINFO builds.
+CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
+
+//Path to a program.
+CMAKE_STRIP:FILEPATH=/usr/bin/strip
+
+//Path to a program.
+CMAKE_TAPI:FILEPATH=CMAKE_TAPI-NOTFOUND
+
+//If this value is on, makefiles will be generated without the
+// .SILENT directive, and all commands will be echoed to the console
+// during the make.  This is useful for debugging only. With Visual
+// Studio IDE projects all commands are done without /nologo.
+CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
+
+//Path to the coverage program that CTest uses for performing coverage
+// inspection
+COVERAGE_COMMAND:FILEPATH=/usr/bin/gcov
+
+//Extra command line flags to pass to the coverage tool
+COVERAGE_EXTRA_FLAGS:STRING=-l
+
+//How many times to retry timed-out CTest submissions.
+CTEST_SUBMIT_RETRY_COUNT:STRING=3
+
+//How long to wait between timed-out CTest submissions.
+CTEST_SUBMIT_RETRY_DELAY:STRING=5
+
+//Maximum time allowed before CTest will kill the test.
+DART_TESTING_TIMEOUT:STRING=1500
+
+//Command to build the project
+MAKECOMMAND:STRING=/usr/bin/cmake --build . --config "${CTEST_CONFIGURATION_TYPE}"
+
+//Path to the memory checking command, used for memory error detection.
+MEMORYCHECK_COMMAND:FILEPATH=MEMORYCHECK_COMMAND-NOTFOUND
+
+//File that contains suppressions for the memory checker
+MEMORYCHECK_SUPPRESSIONS_FILE:FILEPATH=
+
+//Name of the computer/site where compile is being run
+SITE:STRING=arch-laptop
+
+//Value Computed by CMake
+VMAware_BINARY_DIR:STATIC=/home/rickyy/Documents/incognito-vm/VMAware/build
+
+//Value Computed by CMake
+VMAware_IS_TOP_LEVEL:STATIC=ON
+
+//Value Computed by CMake
+VMAware_SOURCE_DIR:STATIC=/home/rickyy/Documents/incognito-vm/VMAware
+
+
+########################
+# INTERNAL cache entries
+########################
+
+//ADVANCED property for variable: CMAKE_ADDR2LINE
+CMAKE_ADDR2LINE-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_AR
+CMAKE_AR-ADVANCED:INTERNAL=1
+//This is the directory where this CMakeCache.txt was created
+CMAKE_CACHEFILE_DIR:INTERNAL=/home/rickyy/Documents/incognito-vm/VMAware/build
+//Major version of cmake used to create the current loaded cache
+CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
+//Minor version of cmake used to create the current loaded cache
+CMAKE_CACHE_MINOR_VERSION:INTERNAL=30
+//Patch version of cmake used to create the current loaded cache
+CMAKE_CACHE_PATCH_VERSION:INTERNAL=5
+//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE
+CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1
+//Path to CMake executable.
+CMAKE_COMMAND:INTERNAL=/usr/bin/cmake
+//Path to cpack program executable.
+CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack
+//ADVANCED property for variable: CMAKE_CTEST_COMMAND
+CMAKE_CTEST_COMMAND-ADVANCED:INTERNAL=1
+//Path to ctest program executable.
+CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest
+//ADVANCED property for variable: CMAKE_CXX_COMPILER
+CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR
+CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB
+CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_CXX_FLAGS
+CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
+CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
+CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
+CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
+CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_DLLTOOL
+CMAKE_DLLTOOL-ADVANCED:INTERNAL=1
+//Path to cache edit program executable.
+CMAKE_EDIT_COMMAND:INTERNAL=/usr/bin/ccmake
+//Executable file format
+CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF
+//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
+CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
+CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
+CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
+CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
+CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS
+CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1
+//Name of external makefile project generator.
+CMAKE_EXTRA_GENERATOR:INTERNAL=
+//Name of generator.
+CMAKE_GENERATOR:INTERNAL=Unix Makefiles
+//Generator instance identifier.
+CMAKE_GENERATOR_INSTANCE:INTERNAL=
+//Name of generator platform.
+CMAKE_GENERATOR_PLATFORM:INTERNAL=
+//Name of generator toolset.
+CMAKE_GENERATOR_TOOLSET:INTERNAL=
+//Source directory with the top level CMakeLists.txt file for this
+// project
+CMAKE_HOME_DIRECTORY:INTERNAL=/home/rickyy/Documents/incognito-vm/VMAware
+//Install .so files without execute permission.
+CMAKE_INSTALL_SO_NO_EXE:INTERNAL=0
+//ADVANCED property for variable: CMAKE_LINKER
+CMAKE_LINKER-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_MAKE_PROGRAM
+CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
+CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
+CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
+CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
+CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
+CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_NM
+CMAKE_NM-ADVANCED:INTERNAL=1
+//number of local generators
+CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1
+//ADVANCED property for variable: CMAKE_OBJCOPY
+CMAKE_OBJCOPY-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_OBJDUMP
+CMAKE_OBJDUMP-ADVANCED:INTERNAL=1
+//Platform information initialized
+CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_RANLIB
+CMAKE_RANLIB-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_READELF
+CMAKE_READELF-ADVANCED:INTERNAL=1
+//Path to CMake installation.
+CMAKE_ROOT:INTERNAL=/usr/share/cmake
+//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
+CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
+CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
+CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
+CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
+CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
+CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_SKIP_RPATH
+CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
+CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
+CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
+CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
+CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
+CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_STRIP
+CMAKE_STRIP-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CMAKE_TAPI
+CMAKE_TAPI-ADVANCED:INTERNAL=1
+//uname command
+CMAKE_UNAME:INTERNAL=/usr/bin/uname
+//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
+CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: COVERAGE_COMMAND
+COVERAGE_COMMAND-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: COVERAGE_EXTRA_FLAGS
+COVERAGE_EXTRA_FLAGS-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CTEST_SUBMIT_RETRY_COUNT
+CTEST_SUBMIT_RETRY_COUNT-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: CTEST_SUBMIT_RETRY_DELAY
+CTEST_SUBMIT_RETRY_DELAY-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: DART_TESTING_TIMEOUT
+DART_TESTING_TIMEOUT-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: MAKECOMMAND
+MAKECOMMAND-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: MEMORYCHECK_COMMAND
+MEMORYCHECK_COMMAND-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: MEMORYCHECK_SUPPRESSIONS_FILE
+MEMORYCHECK_SUPPRESSIONS_FILE-ADVANCED:INTERNAL=1
+//ADVANCED property for variable: SITE
+SITE-ADVANCED:INTERNAL=1
+//linker supports push/pop state
+_CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED:INTERNAL=TRUE
+
diff --git a/VMAware/build/CMakeFiles/3.30.5/CMakeCXXCompiler.cmake b/VMAware/build/CMakeFiles/3.30.5/CMakeCXXCompiler.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..735f65f42b34e2186c1972dcb89ca1b15643b1d8
--- /dev/null
+++ b/VMAware/build/CMakeFiles/3.30.5/CMakeCXXCompiler.cmake
@@ -0,0 +1,105 @@
+set(CMAKE_CXX_COMPILER "/usr/bin/c++")
+set(CMAKE_CXX_COMPILER_ARG1 "")
+set(CMAKE_CXX_COMPILER_ID "GNU")
+set(CMAKE_CXX_COMPILER_VERSION "14.2.1")
+set(CMAKE_CXX_COMPILER_VERSION_INTERNAL "")
+set(CMAKE_CXX_COMPILER_WRAPPER "")
+set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "17")
+set(CMAKE_CXX_EXTENSIONS_COMPUTED_DEFAULT "ON")
+set(CMAKE_CXX_STANDARD_LATEST "26")
+set(CMAKE_CXX_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17;cxx_std_20;cxx_std_23;cxx_std_26")
+set(CMAKE_CXX98_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters")
+set(CMAKE_CXX11_COMPILE_FEATURES "cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates")
+set(CMAKE_CXX14_COMPILE_FEATURES "cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates")
+set(CMAKE_CXX17_COMPILE_FEATURES "cxx_std_17")
+set(CMAKE_CXX20_COMPILE_FEATURES "cxx_std_20")
+set(CMAKE_CXX23_COMPILE_FEATURES "cxx_std_23")
+set(CMAKE_CXX26_COMPILE_FEATURES "cxx_std_26")
+
+set(CMAKE_CXX_PLATFORM_ID "Linux")
+set(CMAKE_CXX_SIMULATE_ID "")
+set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "GNU")
+set(CMAKE_CXX_SIMULATE_VERSION "")
+
+
+
+
+set(CMAKE_AR "/usr/bin/ar")
+set(CMAKE_CXX_COMPILER_AR "/usr/bin/gcc-ar")
+set(CMAKE_RANLIB "/usr/bin/ranlib")
+set(CMAKE_CXX_COMPILER_RANLIB "/usr/bin/gcc-ranlib")
+set(CMAKE_LINKER "/usr/bin/ld")
+set(CMAKE_LINKER_LINK "")
+set(CMAKE_LINKER_LLD "")
+set(CMAKE_CXX_COMPILER_LINKER "/usr/bin/ld")
+set(CMAKE_CXX_COMPILER_LINKER_ID "GNU")
+set(CMAKE_CXX_COMPILER_LINKER_VERSION 2.43.0)
+set(CMAKE_CXX_COMPILER_LINKER_FRONTEND_VARIANT GNU)
+set(CMAKE_MT "")
+set(CMAKE_TAPI "CMAKE_TAPI-NOTFOUND")
+set(CMAKE_COMPILER_IS_GNUCXX 1)
+set(CMAKE_CXX_COMPILER_LOADED 1)
+set(CMAKE_CXX_COMPILER_WORKS TRUE)
+set(CMAKE_CXX_ABI_COMPILED TRUE)
+
+set(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
+
+set(CMAKE_CXX_COMPILER_ID_RUN 1)
+set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;mpp;CPP;ixx;cppm;ccm;cxxm;c++m)
+set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
+
+foreach (lang IN ITEMS C OBJC OBJCXX)
+  if (CMAKE_${lang}_COMPILER_ID_RUN)
+    foreach(extension IN LISTS CMAKE_${lang}_SOURCE_FILE_EXTENSIONS)
+      list(REMOVE_ITEM CMAKE_CXX_SOURCE_FILE_EXTENSIONS ${extension})
+    endforeach()
+  endif()
+endforeach()
+
+set(CMAKE_CXX_LINKER_PREFERENCE 30)
+set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
+set(CMAKE_CXX_LINKER_DEPFILE_SUPPORTED FALSE)
+
+# Save compiler ABI information.
+set(CMAKE_CXX_SIZEOF_DATA_PTR "8")
+set(CMAKE_CXX_COMPILER_ABI "ELF")
+set(CMAKE_CXX_BYTE_ORDER "LITTLE_ENDIAN")
+set(CMAKE_CXX_LIBRARY_ARCHITECTURE "")
+
+if(CMAKE_CXX_SIZEOF_DATA_PTR)
+  set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
+endif()
+
+if(CMAKE_CXX_COMPILER_ABI)
+  set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
+endif()
+
+if(CMAKE_CXX_LIBRARY_ARCHITECTURE)
+  set(CMAKE_LIBRARY_ARCHITECTURE "")
+endif()
+
+set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "")
+if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX)
+  set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}")
+endif()
+
+
+
+
+
+set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include/c++/14.2.1;/usr/include/c++/14.2.1/x86_64-pc-linux-gnu;/usr/include/c++/14.2.1/backward;/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include;/usr/local/include;/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include-fixed;/usr/include")
+set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;gcc_s;gcc;c;gcc_s;gcc")
+set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1;/usr/lib;/lib")
+set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
+set(CMAKE_CXX_COMPILER_CLANG_RESOURCE_DIR "")
+
+set(CMAKE_CXX_COMPILER_IMPORT_STD "")
+### Imported target for C++23 standard library
+set(CMAKE_CXX23_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE "Unsupported generator: Unix Makefiles")
+
+
+### Imported target for C++26 standard library
+set(CMAKE_CXX26_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE "Unsupported generator: Unix Makefiles")
+
+
+
diff --git a/VMAware/build/CMakeFiles/3.30.5/CMakeDetermineCompilerABI_CXX.bin b/VMAware/build/CMakeFiles/3.30.5/CMakeDetermineCompilerABI_CXX.bin
new file mode 100755
index 0000000000000000000000000000000000000000..66c99e8612cf056b64d38a16057ec51886004a16
Binary files /dev/null and b/VMAware/build/CMakeFiles/3.30.5/CMakeDetermineCompilerABI_CXX.bin differ
diff --git a/VMAware/build/CMakeFiles/3.30.5/CMakeSystem.cmake b/VMAware/build/CMakeFiles/3.30.5/CMakeSystem.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..65546ad88d7de0c37cd28a319d9bd36bea2dd328
--- /dev/null
+++ b/VMAware/build/CMakeFiles/3.30.5/CMakeSystem.cmake
@@ -0,0 +1,15 @@
+set(CMAKE_HOST_SYSTEM "Linux-6.11.5-arch1-1")
+set(CMAKE_HOST_SYSTEM_NAME "Linux")
+set(CMAKE_HOST_SYSTEM_VERSION "6.11.5-arch1-1")
+set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64")
+
+
+
+set(CMAKE_SYSTEM "Linux-6.11.5-arch1-1")
+set(CMAKE_SYSTEM_NAME "Linux")
+set(CMAKE_SYSTEM_VERSION "6.11.5-arch1-1")
+set(CMAKE_SYSTEM_PROCESSOR "x86_64")
+
+set(CMAKE_CROSSCOMPILING "FALSE")
+
+set(CMAKE_SYSTEM_LOADED 1)
diff --git a/VMAware/build/CMakeFiles/3.30.5/CompilerIdCXX/CMakeCXXCompilerId.cpp b/VMAware/build/CMakeFiles/3.30.5/CompilerIdCXX/CMakeCXXCompilerId.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..da6c824af3adbe6b0940fcfbec0885ea53ee54af
--- /dev/null
+++ b/VMAware/build/CMakeFiles/3.30.5/CompilerIdCXX/CMakeCXXCompilerId.cpp
@@ -0,0 +1,919 @@
+/* This source file must have a .cpp extension so that all C++ compilers
+   recognize the extension without flags.  Borland does not know .cxx for
+   example.  */
+#ifndef __cplusplus
+# error "A C compiler has been selected for C++."
+#endif
+
+#if !defined(__has_include)
+/* If the compiler does not have __has_include, pretend the answer is
+   always no.  */
+#  define __has_include(x) 0
+#endif
+
+
+/* Version number components: V=Version, R=Revision, P=Patch
+   Version date components:   YYYY=Year, MM=Month,   DD=Day  */
+
+#if defined(__INTEL_COMPILER) || defined(__ICC)
+# define COMPILER_ID "Intel"
+# if defined(_MSC_VER)
+#  define SIMULATE_ID "MSVC"
+# endif
+# if defined(__GNUC__)
+#  define SIMULATE_ID "GNU"
+# endif
+  /* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
+     except that a few beta releases use the old format with V=2021.  */
+# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
+#  define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
+#  define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
+#  if defined(__INTEL_COMPILER_UPDATE)
+#   define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
+#  else
+#   define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER   % 10)
+#  endif
+# else
+#  define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
+#  define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
+   /* The third version component from --version is an update index,
+      but no macro is provided for it.  */
+#  define COMPILER_VERSION_PATCH DEC(0)
+# endif
+# if defined(__INTEL_COMPILER_BUILD_DATE)
+   /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
+#  define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
+# endif
+# if defined(_MSC_VER)
+   /* _MSC_VER = VVRR */
+#  define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
+#  define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
+# endif
+# if defined(__GNUC__)
+#  define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
+# elif defined(__GNUG__)
+#  define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
+# endif
+# if defined(__GNUC_MINOR__)
+#  define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
+# endif
+# if defined(__GNUC_PATCHLEVEL__)
+#  define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
+# endif
+
+#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
+# define COMPILER_ID "IntelLLVM"
+#if defined(_MSC_VER)
+# define SIMULATE_ID "MSVC"
+#endif
+#if defined(__GNUC__)
+# define SIMULATE_ID "GNU"
+#endif
+/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
+ * later.  Look for 6 digit vs. 8 digit version number to decide encoding.
+ * VVVV is no smaller than the current year when a version is released.
+ */
+#if __INTEL_LLVM_COMPILER < 1000000L
+# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
+# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
+# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER    % 10)
+#else
+# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
+# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
+# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER     % 100)
+#endif
+#if defined(_MSC_VER)
+  /* _MSC_VER = VVRR */
+# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
+# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
+#endif
+#if defined(__GNUC__)
+# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
+#elif defined(__GNUG__)
+# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
+#endif
+#if defined(__GNUC_MINOR__)
+# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
+#endif
+#if defined(__GNUC_PATCHLEVEL__)
+# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
+#endif
+
+#elif defined(__PATHCC__)
+# define COMPILER_ID "PathScale"
+# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
+# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
+# if defined(__PATHCC_PATCHLEVEL__)
+#  define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
+# endif
+
+#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
+# define COMPILER_ID "Embarcadero"
+# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
+# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
+# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__     & 0xFFFF)
+
+#elif defined(__BORLANDC__)
+# define COMPILER_ID "Borland"
+  /* __BORLANDC__ = 0xVRR */
+# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
+# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
+
+#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
+# define COMPILER_ID "Watcom"
+   /* __WATCOMC__ = VVRR */
+# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
+# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
+# if (__WATCOMC__ % 10) > 0
+#  define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
+# endif
+
+#elif defined(__WATCOMC__)
+# define COMPILER_ID "OpenWatcom"
+   /* __WATCOMC__ = VVRP + 1100 */
+# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
+# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
+# if (__WATCOMC__ % 10) > 0
+#  define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
+# endif
+
+#elif defined(__SUNPRO_CC)
+# define COMPILER_ID "SunPro"
+# if __SUNPRO_CC >= 0x5100
+   /* __SUNPRO_CC = 0xVRRP */
+#  define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
+#  define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
+#  define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC    & 0xF)
+# else
+   /* __SUNPRO_CC = 0xVRP */
+#  define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
+#  define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
+#  define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC    & 0xF)
+# endif
+
+#elif defined(__HP_aCC)
+# define COMPILER_ID "HP"
+  /* __HP_aCC = VVRRPP */
+# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
+# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
+# define COMPILER_VERSION_PATCH DEC(__HP_aCC     % 100)
+
+#elif defined(__DECCXX)
+# define COMPILER_ID "Compaq"
+  /* __DECCXX_VER = VVRRTPPPP */
+# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
+# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000  % 100)
+# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER         % 10000)
+
+#elif defined(__IBMCPP__) && defined(__COMPILER_VER__)
+# define COMPILER_ID "zOS"
+  /* __IBMCPP__ = VRP */
+# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
+# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
+# define COMPILER_VERSION_PATCH DEC(__IBMCPP__    % 10)
+
+#elif defined(__open_xl__) && defined(__clang__)
+# define COMPILER_ID "IBMClang"
+# define COMPILER_VERSION_MAJOR DEC(__open_xl_version__)
+# define COMPILER_VERSION_MINOR DEC(__open_xl_release__)
+# define COMPILER_VERSION_PATCH DEC(__open_xl_modification__)
+# define COMPILER_VERSION_TWEAK DEC(__open_xl_ptf_fix_level__)
+
+
+#elif defined(__ibmxl__) && defined(__clang__)
+# define COMPILER_ID "XLClang"
+# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
+# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
+# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
+# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
+
+
+#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800
+# define COMPILER_ID "XL"
+  /* __IBMCPP__ = VRP */
+# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
+# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
+# define COMPILER_VERSION_PATCH DEC(__IBMCPP__    % 10)
+
+#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800
+# define COMPILER_ID "VisualAge"
+  /* __IBMCPP__ = VRP */
+# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
+# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
+# define COMPILER_VERSION_PATCH DEC(__IBMCPP__    % 10)
+
+#elif defined(__NVCOMPILER)
+# define COMPILER_ID "NVHPC"
+# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
+# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
+# if defined(__NVCOMPILER_PATCHLEVEL__)
+#  define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
+# endif
+
+#elif defined(__PGI)
+# define COMPILER_ID "PGI"
+# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
+# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
+# if defined(__PGIC_PATCHLEVEL__)
+#  define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
+# endif
+
+#elif defined(__clang__) && defined(__cray__)
+# define COMPILER_ID "CrayClang"
+# define COMPILER_VERSION_MAJOR DEC(__cray_major__)
+# define COMPILER_VERSION_MINOR DEC(__cray_minor__)
+# define COMPILER_VERSION_PATCH DEC(__cray_patchlevel__)
+# define COMPILER_VERSION_INTERNAL_STR __clang_version__
+
+
+#elif defined(_CRAYC)
+# define COMPILER_ID "Cray"
+# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
+# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
+
+#elif defined(__TI_COMPILER_VERSION__)
+# define COMPILER_ID "TI"
+  /* __TI_COMPILER_VERSION__ = VVVRRRPPP */
+# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
+# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000   % 1000)
+# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__        % 1000)
+
+#elif defined(__CLANG_FUJITSU)
+# define COMPILER_ID "FujitsuClang"
+# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
+# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
+# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
+# define COMPILER_VERSION_INTERNAL_STR __clang_version__
+
+
+#elif defined(__FUJITSU)
+# define COMPILER_ID "Fujitsu"
+# if defined(__FCC_version__)
+#   define COMPILER_VERSION __FCC_version__
+# elif defined(__FCC_major__)
+#   define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
+#   define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
+#   define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
+# endif
+# if defined(__fcc_version)
+#   define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
+# elif defined(__FCC_VERSION)
+#   define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
+# endif
+
+
+#elif defined(__ghs__)
+# define COMPILER_ID "GHS"
+/* __GHS_VERSION_NUMBER = VVVVRP */
+# ifdef __GHS_VERSION_NUMBER
+# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
+# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
+# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER      % 10)
+# endif
+
+#elif defined(__TASKING__)
+# define COMPILER_ID "Tasking"
+  # define COMPILER_VERSION_MAJOR DEC(__VERSION__/1000)
+  # define COMPILER_VERSION_MINOR DEC(__VERSION__ % 100)
+# define COMPILER_VERSION_INTERNAL DEC(__VERSION__)
+
+#elif defined(__ORANGEC__)
+# define COMPILER_ID "OrangeC"
+# define COMPILER_VERSION_MAJOR DEC(__ORANGEC_MAJOR__)
+# define COMPILER_VERSION_MINOR DEC(__ORANGEC_MINOR__)
+# define COMPILER_VERSION_PATCH DEC(__ORANGEC_PATCHLEVEL__)
+
+#elif defined(__SCO_VERSION__)
+# define COMPILER_ID "SCO"
+
+#elif defined(__ARMCC_VERSION) && !defined(__clang__)
+# define COMPILER_ID "ARMCC"
+#if __ARMCC_VERSION >= 1000000
+  /* __ARMCC_VERSION = VRRPPPP */
+  # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
+  # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
+  # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION     % 10000)
+#else
+  /* __ARMCC_VERSION = VRPPPP */
+  # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
+  # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
+  # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION    % 10000)
+#endif
+
+
+#elif defined(__clang__) && defined(__apple_build_version__)
+# define COMPILER_ID "AppleClang"
+# if defined(_MSC_VER)
+#  define SIMULATE_ID "MSVC"
+# endif
+# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
+# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
+# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
+# if defined(_MSC_VER)
+   /* _MSC_VER = VVRR */
+#  define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
+#  define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
+# endif
+# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
+
+#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
+# define COMPILER_ID "ARMClang"
+  # define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
+  # define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
+  # define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION/100   % 100)
+# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
+
+#elif defined(__clang__) && defined(__ti__)
+# define COMPILER_ID "TIClang"
+  # define COMPILER_VERSION_MAJOR DEC(__ti_major__)
+  # define COMPILER_VERSION_MINOR DEC(__ti_minor__)
+  # define COMPILER_VERSION_PATCH DEC(__ti_patchlevel__)
+# define COMPILER_VERSION_INTERNAL DEC(__ti_version__)
+
+#elif defined(__clang__)
+# define COMPILER_ID "Clang"
+# if defined(_MSC_VER)
+#  define SIMULATE_ID "MSVC"
+# endif
+# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
+# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
+# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
+# if defined(_MSC_VER)
+   /* _MSC_VER = VVRR */
+#  define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
+#  define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
+# endif
+
+#elif defined(__LCC__) && (defined(__GNUC__) || defined(__GNUG__) || defined(__MCST__))
+# define COMPILER_ID "LCC"
+# define COMPILER_VERSION_MAJOR DEC(__LCC__ / 100)
+# define COMPILER_VERSION_MINOR DEC(__LCC__ % 100)
+# if defined(__LCC_MINOR__)
+#  define COMPILER_VERSION_PATCH DEC(__LCC_MINOR__)
+# endif
+# if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#  define SIMULATE_ID "GNU"
+#  define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
+#  define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
+#  if defined(__GNUC_PATCHLEVEL__)
+#   define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
+#  endif
+# endif
+
+#elif defined(__GNUC__) || defined(__GNUG__)
+# define COMPILER_ID "GNU"
+# if defined(__GNUC__)
+#  define COMPILER_VERSION_MAJOR DEC(__GNUC__)
+# else
+#  define COMPILER_VERSION_MAJOR DEC(__GNUG__)
+# endif
+# if defined(__GNUC_MINOR__)
+#  define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
+# endif
+# if defined(__GNUC_PATCHLEVEL__)
+#  define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
+# endif
+
+#elif defined(_MSC_VER)
+# define COMPILER_ID "MSVC"
+  /* _MSC_VER = VVRR */
+# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
+# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
+# if defined(_MSC_FULL_VER)
+#  if _MSC_VER >= 1400
+    /* _MSC_FULL_VER = VVRRPPPPP */
+#   define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
+#  else
+    /* _MSC_FULL_VER = VVRRPPPP */
+#   define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
+#  endif
+# endif
+# if defined(_MSC_BUILD)
+#  define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
+# endif
+
+#elif defined(_ADI_COMPILER)
+# define COMPILER_ID "ADSP"
+#if defined(__VERSIONNUM__)
+  /* __VERSIONNUM__ = 0xVVRRPPTT */
+#  define COMPILER_VERSION_MAJOR DEC(__VERSIONNUM__ >> 24 & 0xFF)
+#  define COMPILER_VERSION_MINOR DEC(__VERSIONNUM__ >> 16 & 0xFF)
+#  define COMPILER_VERSION_PATCH DEC(__VERSIONNUM__ >> 8 & 0xFF)
+#  define COMPILER_VERSION_TWEAK DEC(__VERSIONNUM__ & 0xFF)
+#endif
+
+#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
+# define COMPILER_ID "IAR"
+# if defined(__VER__) && defined(__ICCARM__)
+#  define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
+#  define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
+#  define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
+#  define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
+# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
+#  define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
+#  define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
+#  define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
+#  define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
+# endif
+
+
+/* These compilers are either not known or too old to define an
+  identification macro.  Try to identify the platform and guess that
+  it is the native compiler.  */
+#elif defined(__hpux) || defined(__hpua)
+# define COMPILER_ID "HP"
+
+#else /* unknown compiler */
+# define COMPILER_ID ""
+#endif
+
+/* Construct the string literal in pieces to prevent the source from
+   getting matched.  Store it in a pointer rather than an array
+   because some compilers will just produce instructions to fill the
+   array rather than assigning a pointer to a static array.  */
+char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
+#ifdef SIMULATE_ID
+char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
+#endif
+
+#ifdef __QNXNTO__
+char const* qnxnto = "INFO" ":" "qnxnto[]";
+#endif
+
+#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
+char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
+#endif
+
+#define STRINGIFY_HELPER(X) #X
+#define STRINGIFY(X) STRINGIFY_HELPER(X)
+
+/* Identify known platforms by name.  */
+#if defined(__linux) || defined(__linux__) || defined(linux)
+# define PLATFORM_ID "Linux"
+
+#elif defined(__MSYS__)
+# define PLATFORM_ID "MSYS"
+
+#elif defined(__CYGWIN__)
+# define PLATFORM_ID "Cygwin"
+
+#elif defined(__MINGW32__)
+# define PLATFORM_ID "MinGW"
+
+#elif defined(__APPLE__)
+# define PLATFORM_ID "Darwin"
+
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+# define PLATFORM_ID "Windows"
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD)
+# define PLATFORM_ID "FreeBSD"
+
+#elif defined(__NetBSD__) || defined(__NetBSD)
+# define PLATFORM_ID "NetBSD"
+
+#elif defined(__OpenBSD__) || defined(__OPENBSD)
+# define PLATFORM_ID "OpenBSD"
+
+#elif defined(__sun) || defined(sun)
+# define PLATFORM_ID "SunOS"
+
+#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
+# define PLATFORM_ID "AIX"
+
+#elif defined(__hpux) || defined(__hpux__)
+# define PLATFORM_ID "HP-UX"
+
+#elif defined(__HAIKU__)
+# define PLATFORM_ID "Haiku"
+
+#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
+# define PLATFORM_ID "BeOS"
+
+#elif defined(__QNX__) || defined(__QNXNTO__)
+# define PLATFORM_ID "QNX"
+
+#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
+# define PLATFORM_ID "Tru64"
+
+#elif defined(__riscos) || defined(__riscos__)
+# define PLATFORM_ID "RISCos"
+
+#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
+# define PLATFORM_ID "SINIX"
+
+#elif defined(__UNIX_SV__)
+# define PLATFORM_ID "UNIX_SV"
+
+#elif defined(__bsdos__)
+# define PLATFORM_ID "BSDOS"
+
+#elif defined(_MPRAS) || defined(MPRAS)
+# define PLATFORM_ID "MP-RAS"
+
+#elif defined(__osf) || defined(__osf__)
+# define PLATFORM_ID "OSF1"
+
+#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
+# define PLATFORM_ID "SCO_SV"
+
+#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
+# define PLATFORM_ID "ULTRIX"
+
+#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
+# define PLATFORM_ID "Xenix"
+
+#elif defined(__WATCOMC__)
+# if defined(__LINUX__)
+#  define PLATFORM_ID "Linux"
+
+# elif defined(__DOS__)
+#  define PLATFORM_ID "DOS"
+
+# elif defined(__OS2__)
+#  define PLATFORM_ID "OS2"
+
+# elif defined(__WINDOWS__)
+#  define PLATFORM_ID "Windows3x"
+
+# elif defined(__VXWORKS__)
+#  define PLATFORM_ID "VxWorks"
+
+# else /* unknown platform */
+#  define PLATFORM_ID
+# endif
+
+#elif defined(__INTEGRITY)
+# if defined(INT_178B)
+#  define PLATFORM_ID "Integrity178"
+
+# else /* regular Integrity */
+#  define PLATFORM_ID "Integrity"
+# endif
+
+# elif defined(_ADI_COMPILER)
+#  define PLATFORM_ID "ADSP"
+
+#else /* unknown platform */
+# define PLATFORM_ID
+
+#endif
+
+/* For windows compilers MSVC and Intel we can determine
+   the architecture of the compiler being used.  This is because
+   the compilers do not have flags that can change the architecture,
+   but rather depend on which compiler is being used
+*/
+#if defined(_WIN32) && defined(_MSC_VER)
+# if defined(_M_IA64)
+#  define ARCHITECTURE_ID "IA64"
+
+# elif defined(_M_ARM64EC)
+#  define ARCHITECTURE_ID "ARM64EC"
+
+# elif defined(_M_X64) || defined(_M_AMD64)
+#  define ARCHITECTURE_ID "x64"
+
+# elif defined(_M_IX86)
+#  define ARCHITECTURE_ID "X86"
+
+# elif defined(_M_ARM64)
+#  define ARCHITECTURE_ID "ARM64"
+
+# elif defined(_M_ARM)
+#  if _M_ARM == 4
+#   define ARCHITECTURE_ID "ARMV4I"
+#  elif _M_ARM == 5
+#   define ARCHITECTURE_ID "ARMV5I"
+#  else
+#   define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
+#  endif
+
+# elif defined(_M_MIPS)
+#  define ARCHITECTURE_ID "MIPS"
+
+# elif defined(_M_SH)
+#  define ARCHITECTURE_ID "SHx"
+
+# else /* unknown architecture */
+#  define ARCHITECTURE_ID ""
+# endif
+
+#elif defined(__WATCOMC__)
+# if defined(_M_I86)
+#  define ARCHITECTURE_ID "I86"
+
+# elif defined(_M_IX86)
+#  define ARCHITECTURE_ID "X86"
+
+# else /* unknown architecture */
+#  define ARCHITECTURE_ID ""
+# endif
+
+#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
+# if defined(__ICCARM__)
+#  define ARCHITECTURE_ID "ARM"
+
+# elif defined(__ICCRX__)
+#  define ARCHITECTURE_ID "RX"
+
+# elif defined(__ICCRH850__)
+#  define ARCHITECTURE_ID "RH850"
+
+# elif defined(__ICCRL78__)
+#  define ARCHITECTURE_ID "RL78"
+
+# elif defined(__ICCRISCV__)
+#  define ARCHITECTURE_ID "RISCV"
+
+# elif defined(__ICCAVR__)
+#  define ARCHITECTURE_ID "AVR"
+
+# elif defined(__ICC430__)
+#  define ARCHITECTURE_ID "MSP430"
+
+# elif defined(__ICCV850__)
+#  define ARCHITECTURE_ID "V850"
+
+# elif defined(__ICC8051__)
+#  define ARCHITECTURE_ID "8051"
+
+# elif defined(__ICCSTM8__)
+#  define ARCHITECTURE_ID "STM8"
+
+# else /* unknown architecture */
+#  define ARCHITECTURE_ID ""
+# endif
+
+#elif defined(__ghs__)
+# if defined(__PPC64__)
+#  define ARCHITECTURE_ID "PPC64"
+
+# elif defined(__ppc__)
+#  define ARCHITECTURE_ID "PPC"
+
+# elif defined(__ARM__)
+#  define ARCHITECTURE_ID "ARM"
+
+# elif defined(__x86_64__)
+#  define ARCHITECTURE_ID "x64"
+
+# elif defined(__i386__)
+#  define ARCHITECTURE_ID "X86"
+
+# else /* unknown architecture */
+#  define ARCHITECTURE_ID ""
+# endif
+
+#elif defined(__clang__) && defined(__ti__)
+# if defined(__ARM_ARCH)
+#  define ARCHITECTURE_ID "Arm"
+
+# else /* unknown architecture */
+#  define ARCHITECTURE_ID ""
+# endif
+
+#elif defined(__TI_COMPILER_VERSION__)
+# if defined(__TI_ARM__)
+#  define ARCHITECTURE_ID "ARM"
+
+# elif defined(__MSP430__)
+#  define ARCHITECTURE_ID "MSP430"
+
+# elif defined(__TMS320C28XX__)
+#  define ARCHITECTURE_ID "TMS320C28x"
+
+# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
+#  define ARCHITECTURE_ID "TMS320C6x"
+
+# else /* unknown architecture */
+#  define ARCHITECTURE_ID ""
+# endif
+
+# elif defined(__ADSPSHARC__)
+#  define ARCHITECTURE_ID "SHARC"
+
+# elif defined(__ADSPBLACKFIN__)
+#  define ARCHITECTURE_ID "Blackfin"
+
+#elif defined(__TASKING__)
+
+# if defined(__CTC__) || defined(__CPTC__)
+#  define ARCHITECTURE_ID "TriCore"
+
+# elif defined(__CMCS__)
+#  define ARCHITECTURE_ID "MCS"
+
+# elif defined(__CARM__)
+#  define ARCHITECTURE_ID "ARM"
+
+# elif defined(__CARC__)
+#  define ARCHITECTURE_ID "ARC"
+
+# elif defined(__C51__)
+#  define ARCHITECTURE_ID "8051"
+
+# elif defined(__CPCP__)
+#  define ARCHITECTURE_ID "PCP"
+
+# else
+#  define ARCHITECTURE_ID ""
+# endif
+
+#else
+#  define ARCHITECTURE_ID
+#endif
+
+/* Convert integer to decimal digit literals.  */
+#define DEC(n)                   \
+  ('0' + (((n) / 10000000)%10)), \
+  ('0' + (((n) / 1000000)%10)),  \
+  ('0' + (((n) / 100000)%10)),   \
+  ('0' + (((n) / 10000)%10)),    \
+  ('0' + (((n) / 1000)%10)),     \
+  ('0' + (((n) / 100)%10)),      \
+  ('0' + (((n) / 10)%10)),       \
+  ('0' +  ((n) % 10))
+
+/* Convert integer to hex digit literals.  */
+#define HEX(n)             \
+  ('0' + ((n)>>28 & 0xF)), \
+  ('0' + ((n)>>24 & 0xF)), \
+  ('0' + ((n)>>20 & 0xF)), \
+  ('0' + ((n)>>16 & 0xF)), \
+  ('0' + ((n)>>12 & 0xF)), \
+  ('0' + ((n)>>8  & 0xF)), \
+  ('0' + ((n)>>4  & 0xF)), \
+  ('0' + ((n)     & 0xF))
+
+/* Construct a string literal encoding the version number. */
+#ifdef COMPILER_VERSION
+char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
+
+/* Construct a string literal encoding the version number components. */
+#elif defined(COMPILER_VERSION_MAJOR)
+char const info_version[] = {
+  'I', 'N', 'F', 'O', ':',
+  'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
+  COMPILER_VERSION_MAJOR,
+# ifdef COMPILER_VERSION_MINOR
+  '.', COMPILER_VERSION_MINOR,
+#  ifdef COMPILER_VERSION_PATCH
+   '.', COMPILER_VERSION_PATCH,
+#   ifdef COMPILER_VERSION_TWEAK
+    '.', COMPILER_VERSION_TWEAK,
+#   endif
+#  endif
+# endif
+  ']','\0'};
+#endif
+
+/* Construct a string literal encoding the internal version number. */
+#ifdef COMPILER_VERSION_INTERNAL
+char const info_version_internal[] = {
+  'I', 'N', 'F', 'O', ':',
+  'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
+  'i','n','t','e','r','n','a','l','[',
+  COMPILER_VERSION_INTERNAL,']','\0'};
+#elif defined(COMPILER_VERSION_INTERNAL_STR)
+char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
+#endif
+
+/* Construct a string literal encoding the version number components. */
+#ifdef SIMULATE_VERSION_MAJOR
+char const info_simulate_version[] = {
+  'I', 'N', 'F', 'O', ':',
+  's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
+  SIMULATE_VERSION_MAJOR,
+# ifdef SIMULATE_VERSION_MINOR
+  '.', SIMULATE_VERSION_MINOR,
+#  ifdef SIMULATE_VERSION_PATCH
+   '.', SIMULATE_VERSION_PATCH,
+#   ifdef SIMULATE_VERSION_TWEAK
+    '.', SIMULATE_VERSION_TWEAK,
+#   endif
+#  endif
+# endif
+  ']','\0'};
+#endif
+
+/* Construct the string literal in pieces to prevent the source from
+   getting matched.  Store it in a pointer rather than an array
+   because some compilers will just produce instructions to fill the
+   array rather than assigning a pointer to a static array.  */
+char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
+char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
+
+
+
+#define CXX_STD_98 199711L
+#define CXX_STD_11 201103L
+#define CXX_STD_14 201402L
+#define CXX_STD_17 201703L
+#define CXX_STD_20 202002L
+#define CXX_STD_23 202302L
+
+#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG)
+#  if _MSVC_LANG > CXX_STD_17
+#    define CXX_STD _MSVC_LANG
+#  elif _MSVC_LANG == CXX_STD_17 && defined(__cpp_aggregate_paren_init)
+#    define CXX_STD CXX_STD_20
+#  elif _MSVC_LANG > CXX_STD_14 && __cplusplus > CXX_STD_17
+#    define CXX_STD CXX_STD_20
+#  elif _MSVC_LANG > CXX_STD_14
+#    define CXX_STD CXX_STD_17
+#  elif defined(__INTEL_CXX11_MODE__) && defined(__cpp_aggregate_nsdmi)
+#    define CXX_STD CXX_STD_14
+#  elif defined(__INTEL_CXX11_MODE__)
+#    define CXX_STD CXX_STD_11
+#  else
+#    define CXX_STD CXX_STD_98
+#  endif
+#elif defined(_MSC_VER) && defined(_MSVC_LANG)
+#  if _MSVC_LANG > __cplusplus
+#    define CXX_STD _MSVC_LANG
+#  else
+#    define CXX_STD __cplusplus
+#  endif
+#elif defined(__NVCOMPILER)
+#  if __cplusplus == CXX_STD_17 && defined(__cpp_aggregate_paren_init)
+#    define CXX_STD CXX_STD_20
+#  else
+#    define CXX_STD __cplusplus
+#  endif
+#elif defined(__INTEL_COMPILER) || defined(__PGI)
+#  if __cplusplus == CXX_STD_11 && defined(__cpp_namespace_attributes)
+#    define CXX_STD CXX_STD_17
+#  elif __cplusplus == CXX_STD_11 && defined(__cpp_aggregate_nsdmi)
+#    define CXX_STD CXX_STD_14
+#  else
+#    define CXX_STD __cplusplus
+#  endif
+#elif (defined(__IBMCPP__) || defined(__ibmxl__)) && defined(__linux__)
+#  if __cplusplus == CXX_STD_11 && defined(__cpp_aggregate_nsdmi)
+#    define CXX_STD CXX_STD_14
+#  else
+#    define CXX_STD __cplusplus
+#  endif
+#elif __cplusplus == 1 && defined(__GXX_EXPERIMENTAL_CXX0X__)
+#  define CXX_STD CXX_STD_11
+#else
+#  define CXX_STD __cplusplus
+#endif
+
+const char* info_language_standard_default = "INFO" ":" "standard_default["
+#if CXX_STD > CXX_STD_23
+  "26"
+#elif CXX_STD > CXX_STD_20
+  "23"
+#elif CXX_STD > CXX_STD_17
+  "20"
+#elif CXX_STD > CXX_STD_14
+  "17"
+#elif CXX_STD > CXX_STD_11
+  "14"
+#elif CXX_STD >= CXX_STD_11
+  "11"
+#else
+  "98"
+#endif
+"]";
+
+const char* info_language_extensions_default = "INFO" ":" "extensions_default["
+#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) ||           \
+     defined(__TI_COMPILER_VERSION__)) &&                                     \
+  !defined(__STRICT_ANSI__)
+  "ON"
+#else
+  "OFF"
+#endif
+"]";
+
+/*--------------------------------------------------------------------------*/
+
+int main(int argc, char* argv[])
+{
+  int require = 0;
+  require += info_compiler[argc];
+  require += info_platform[argc];
+  require += info_arch[argc];
+#ifdef COMPILER_VERSION_MAJOR
+  require += info_version[argc];
+#endif
+#ifdef COMPILER_VERSION_INTERNAL
+  require += info_version_internal[argc];
+#endif
+#ifdef SIMULATE_ID
+  require += info_simulate[argc];
+#endif
+#ifdef SIMULATE_VERSION_MAJOR
+  require += info_simulate_version[argc];
+#endif
+#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
+  require += info_cray[argc];
+#endif
+  require += info_language_standard_default[argc];
+  require += info_language_extensions_default[argc];
+  (void)argv;
+  return require;
+}
diff --git a/VMAware/build/CMakeFiles/CMakeConfigureLog.yaml b/VMAware/build/CMakeFiles/CMakeConfigureLog.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..24cdd88c30abe303c0ad625698eabcf57f6125fa
--- /dev/null
+++ b/VMAware/build/CMakeFiles/CMakeConfigureLog.yaml
@@ -0,0 +1,270 @@
+
+---
+events:
+  -
+    kind: "message-v1"
+    backtrace:
+      - "/usr/share/cmake/Modules/CMakeDetermineSystem.cmake:205 (message)"
+      - "CMakeLists.txt:3 (project)"
+    message: |
+      The system is: Linux - 6.11.5-arch1-1 - x86_64
+  -
+    kind: "message-v1"
+    backtrace:
+      - "/usr/share/cmake/Modules/CMakeDetermineCompilerId.cmake:17 (message)"
+      - "/usr/share/cmake/Modules/CMakeDetermineCompilerId.cmake:64 (__determine_compiler_id_test)"
+      - "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake:126 (CMAKE_DETERMINE_COMPILER_ID)"
+      - "CMakeLists.txt:3 (project)"
+    message: |
+      Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded.
+      Compiler: /usr/bin/c++ 
+      Build flags: 
+      Id flags:  
+      
+      The output was:
+      0
+      
+      
+      Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out"
+      
+      The CXX compiler identification is GNU, found in:
+        /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/3.30.5/CompilerIdCXX/a.out
+      
+  -
+    kind: "try_compile-v1"
+    backtrace:
+      - "/usr/share/cmake/Modules/CMakeDetermineCompilerABI.cmake:74 (try_compile)"
+      - "/usr/share/cmake/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)"
+      - "CMakeLists.txt:3 (project)"
+    checks:
+      - "Detecting CXX compiler ABI info"
+    directories:
+      source: "/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/CMakeScratch/TryCompile-unVLJQ"
+      binary: "/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/CMakeScratch/TryCompile-unVLJQ"
+    cmakeVariables:
+      CMAKE_CXX_FLAGS: ""
+      CMAKE_CXX_FLAGS_DEBUG: "-g"
+      CMAKE_CXX_SCAN_FOR_MODULES: "OFF"
+      CMAKE_EXE_LINKER_FLAGS: ""
+    buildResult:
+      variable: "CMAKE_CXX_ABI_COMPILED"
+      cached: true
+      stdout: |
+        Change Dir: '/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/CMakeScratch/TryCompile-unVLJQ'
+        
+        Run Build Command(s): /usr/bin/cmake -E env VERBOSE=1 /usr/bin/make -f Makefile cmTC_cf24e/fast
+        /usr/bin/make  -f CMakeFiles/cmTC_cf24e.dir/build.make CMakeFiles/cmTC_cf24e.dir/build
+        make[1]: Entering directory '/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/CMakeScratch/TryCompile-unVLJQ'
+        Building CXX object CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o
+        /usr/bin/c++   -v -o CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp
+        Using built-in specs.
+        COLLECT_GCC=/usr/bin/c++
+        Target: x86_64-pc-linux-gnu
+        Configured with: /build/gcc/src/gcc/configure --enable-languages=ada,c,c++,d,fortran,go,lto,m2,objc,obj-c++,rust --enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://gitlab.archlinux.org/archlinux/packaging/packages/gcc/-/issues --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror
+        Thread model: posix
+        Supported LTO compression algorithms: zlib zstd
+        gcc version 14.2.1 20240910 (GCC) 
+        COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_cf24e.dir/'
+         /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/cc1plus -quiet -v -D_GNU_SOURCE /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpdir CMakeFiles/cmTC_cf24e.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -version -o /tmp/ccFdZ269.s
+        GNU C++17 (GCC) version 14.2.1 20240910 (x86_64-pc-linux-gnu)
+        	compiled by GNU C version 14.2.1 20240910, GMP version 6.3.0, MPFR version 4.2.1, MPC version 1.3.1, isl version isl-0.27-GMP
+        
+        GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
+        ignoring nonexistent directory "/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../x86_64-pc-linux-gnu/include"
+        #include "..." search starts here:
+        #include <...> search starts here:
+         /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1
+         /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/x86_64-pc-linux-gnu
+         /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/backward
+         /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include
+         /usr/local/include
+         /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include-fixed
+         /usr/include
+        End of search list.
+        Compiler executable checksum: fce5a105c47978e141f61a441742cadf
+        COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_cf24e.dir/'
+         as -v --64 -o CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccFdZ269.s
+        GNU assembler version 2.43.0 (x86_64-pc-linux-gnu) using BFD version (GNU Binutils) 2.43.0
+        COMPILER_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/
+        LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../:/lib/:/usr/lib/
+        COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.'
+        Linking CXX executable cmTC_cf24e
+        /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_cf24e.dir/link.txt --verbose=1
+        /usr/bin/c++  -v -Wl,-v CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_cf24e
+        Using built-in specs.
+        COLLECT_GCC=/usr/bin/c++
+        COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/lto-wrapper
+        Target: x86_64-pc-linux-gnu
+        Configured with: /build/gcc/src/gcc/configure --enable-languages=ada,c,c++,d,fortran,go,lto,m2,objc,obj-c++,rust --enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://gitlab.archlinux.org/archlinux/packaging/packages/gcc/-/issues --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror
+        Thread model: posix
+        Supported LTO compression algorithms: zlib zstd
+        gcc version 14.2.1 20240910 (GCC) 
+        COMPILER_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/
+        LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../:/lib/:/usr/lib/
+        COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_cf24e' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_cf24e.'
+         /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/collect2 -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccsW12Ci.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_cf24e /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../.. -v CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crtn.o
+        collect2 version 14.2.1 20240910
+        /usr/bin/ld -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccsW12Ci.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_cf24e /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../.. -v CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crtn.o
+        GNU ld (GNU Binutils) 2.43.0
+        COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_cf24e' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_cf24e.'
+        make[1]: Leaving directory '/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/CMakeScratch/TryCompile-unVLJQ'
+        
+      exitCode: 0
+  -
+    kind: "message-v1"
+    backtrace:
+      - "/usr/share/cmake/Modules/CMakeDetermineCompilerABI.cmake:182 (message)"
+      - "/usr/share/cmake/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)"
+      - "CMakeLists.txt:3 (project)"
+    message: |
+      Parsed CXX implicit include dir info: rv=done
+        found start of include info
+        found start of implicit include info
+          add: [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1]
+          add: [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/x86_64-pc-linux-gnu]
+          add: [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/backward]
+          add: [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include]
+          add: [/usr/local/include]
+          add: [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include-fixed]
+          add: [/usr/include]
+        end of search list found
+        collapse include dir [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1] ==> [/usr/include/c++/14.2.1]
+        collapse include dir [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/x86_64-pc-linux-gnu] ==> [/usr/include/c++/14.2.1/x86_64-pc-linux-gnu]
+        collapse include dir [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/backward] ==> [/usr/include/c++/14.2.1/backward]
+        collapse include dir [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include] ==> [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include]
+        collapse include dir [/usr/local/include] ==> [/usr/local/include]
+        collapse include dir [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include-fixed] ==> [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include-fixed]
+        collapse include dir [/usr/include] ==> [/usr/include]
+        implicit include dirs: [/usr/include/c++/14.2.1;/usr/include/c++/14.2.1/x86_64-pc-linux-gnu;/usr/include/c++/14.2.1/backward;/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include;/usr/local/include;/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include-fixed;/usr/include]
+      
+      
+  -
+    kind: "message-v1"
+    backtrace:
+      - "/usr/share/cmake/Modules/CMakeDetermineCompilerABI.cmake:218 (message)"
+      - "/usr/share/cmake/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)"
+      - "CMakeLists.txt:3 (project)"
+    message: |
+      Parsed CXX implicit link information:
+        link line regex: [^( *|.*[/\\])(ld[0-9]*(\\.[a-z]+)?|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\\]+-)?ld|collect2)[^/\\]*( |$)]
+        linker tool regex: [^[ 	]*(->|")?[ 	]*(([^"]*[/\\])?(ld[0-9]*(\\.[a-z]+)?))("|,| |$)]
+        ignore line: [Change Dir: '/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/CMakeScratch/TryCompile-unVLJQ']
+        ignore line: []
+        ignore line: [Run Build Command(s): /usr/bin/cmake -E env VERBOSE=1 /usr/bin/make -f Makefile cmTC_cf24e/fast]
+        ignore line: [/usr/bin/make  -f CMakeFiles/cmTC_cf24e.dir/build.make CMakeFiles/cmTC_cf24e.dir/build]
+        ignore line: [make[1]: Entering directory '/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/CMakeScratch/TryCompile-unVLJQ']
+        ignore line: [Building CXX object CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o]
+        ignore line: [/usr/bin/c++   -v -o CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp]
+        ignore line: [Using built-in specs.]
+        ignore line: [COLLECT_GCC=/usr/bin/c++]
+        ignore line: [Target: x86_64-pc-linux-gnu]
+        ignore line: [Configured with: /build/gcc/src/gcc/configure --enable-languages=ada c c++ d fortran go lto m2 objc obj-c++ rust --enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://gitlab.archlinux.org/archlinux/packaging/packages/gcc/-/issues --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror]
+        ignore line: [Thread model: posix]
+        ignore line: [Supported LTO compression algorithms: zlib zstd]
+        ignore line: [gcc version 14.2.1 20240910 (GCC) ]
+        ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_cf24e.dir/']
+        ignore line: [ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/cc1plus -quiet -v -D_GNU_SOURCE /usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpdir CMakeFiles/cmTC_cf24e.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -version -o /tmp/ccFdZ269.s]
+        ignore line: [GNU C++17 (GCC) version 14.2.1 20240910 (x86_64-pc-linux-gnu)]
+        ignore line: [	compiled by GNU C version 14.2.1 20240910  GMP version 6.3.0  MPFR version 4.2.1  MPC version 1.3.1  isl version isl-0.27-GMP]
+        ignore line: []
+        ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072]
+        ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../x86_64-pc-linux-gnu/include"]
+        ignore line: [#include "..." search starts here:]
+        ignore line: [#include <...> search starts here:]
+        ignore line: [ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1]
+        ignore line: [ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/x86_64-pc-linux-gnu]
+        ignore line: [ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/backward]
+        ignore line: [ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include]
+        ignore line: [ /usr/local/include]
+        ignore line: [ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include-fixed]
+        ignore line: [ /usr/include]
+        ignore line: [End of search list.]
+        ignore line: [Compiler executable checksum: fce5a105c47978e141f61a441742cadf]
+        ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_cf24e.dir/']
+        ignore line: [ as -v --64 -o CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccFdZ269.s]
+        ignore line: [GNU assembler version 2.43.0 (x86_64-pc-linux-gnu) using BFD version (GNU Binutils) 2.43.0]
+        ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/]
+        ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../:/lib/:/usr/lib/]
+        ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.']
+        ignore line: [Linking CXX executable cmTC_cf24e]
+        ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_cf24e.dir/link.txt --verbose=1]
+        ignore line: [/usr/bin/c++  -v -Wl -v CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_cf24e]
+        ignore line: [Using built-in specs.]
+        ignore line: [COLLECT_GCC=/usr/bin/c++]
+        ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/lto-wrapper]
+        ignore line: [Target: x86_64-pc-linux-gnu]
+        ignore line: [Configured with: /build/gcc/src/gcc/configure --enable-languages=ada c c++ d fortran go lto m2 objc obj-c++ rust --enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://gitlab.archlinux.org/archlinux/packaging/packages/gcc/-/issues --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror]
+        ignore line: [Thread model: posix]
+        ignore line: [Supported LTO compression algorithms: zlib zstd]
+        ignore line: [gcc version 14.2.1 20240910 (GCC) ]
+        ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/]
+        ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../:/lib/:/usr/lib/]
+        ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_cf24e' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_cf24e.']
+        link line: [ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/collect2 -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccsW12Ci.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_cf24e /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../.. -v CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crtn.o]
+          arg [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/collect2] ==> ignore
+          arg [-plugin] ==> ignore
+          arg [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/liblto_plugin.so] ==> ignore
+          arg [-plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/lto-wrapper] ==> ignore
+          arg [-plugin-opt=-fresolution=/tmp/ccsW12Ci.res] ==> ignore
+          arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
+          arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
+          arg [-plugin-opt=-pass-through=-lc] ==> ignore
+          arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
+          arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
+          arg [--build-id] ==> ignore
+          arg [--eh-frame-hdr] ==> ignore
+          arg [--hash-style=gnu] ==> ignore
+          arg [-m] ==> ignore
+          arg [elf_x86_64] ==> ignore
+          arg [-dynamic-linker] ==> ignore
+          arg [/lib64/ld-linux-x86-64.so.2] ==> ignore
+          arg [-pie] ==> ignore
+          arg [-o] ==> ignore
+          arg [cmTC_cf24e] ==> ignore
+          arg [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/Scrt1.o] ==> obj [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/Scrt1.o]
+          arg [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crti.o] ==> obj [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crti.o]
+          arg [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtbeginS.o] ==> obj [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtbeginS.o]
+          arg [-L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1] ==> dir [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1]
+          arg [-L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib]
+          arg [-L/lib/../lib] ==> dir [/lib/../lib]
+          arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib]
+          arg [-L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../..] ==> dir [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../..]
+          arg [-v] ==> ignore
+          arg [CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore
+          arg [-lstdc++] ==> lib [stdc++]
+          arg [-lm] ==> lib [m]
+          arg [-lgcc_s] ==> lib [gcc_s]
+          arg [-lgcc] ==> lib [gcc]
+          arg [-lc] ==> lib [c]
+          arg [-lgcc_s] ==> lib [gcc_s]
+          arg [-lgcc] ==> lib [gcc]
+          arg [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtendS.o] ==> obj [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtendS.o]
+          arg [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crtn.o] ==> obj [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crtn.o]
+        ignore line: [collect2 version 14.2.1 20240910]
+        ignore line: [/usr/bin/ld -plugin /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccsW12Ci.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_cf24e /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/Scrt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../.. -v CMakeFiles/cmTC_cf24e.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crtn.o]
+        linker tool for 'CXX': /usr/bin/ld
+        collapse obj [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/Scrt1.o] ==> [/usr/lib/Scrt1.o]
+        collapse obj [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crti.o] ==> [/usr/lib/crti.o]
+        collapse obj [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib/crtn.o] ==> [/usr/lib/crtn.o]
+        collapse library dir [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1] ==> [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1]
+        collapse library dir [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../lib] ==> [/usr/lib]
+        collapse library dir [/lib/../lib] ==> [/lib]
+        collapse library dir [/usr/lib/../lib] ==> [/usr/lib]
+        collapse library dir [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/../../..] ==> [/usr/lib]
+        implicit libs: [stdc++;m;gcc_s;gcc;c;gcc_s;gcc]
+        implicit objs: [/usr/lib/Scrt1.o;/usr/lib/crti.o;/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtbeginS.o;/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/crtendS.o;/usr/lib/crtn.o]
+        implicit dirs: [/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1;/usr/lib;/lib]
+        implicit fwks: []
+      
+      
+  -
+    kind: "message-v1"
+    backtrace:
+      - "/usr/share/cmake/Modules/Internal/CMakeDetermineLinkerId.cmake:40 (message)"
+      - "/usr/share/cmake/Modules/CMakeDetermineCompilerABI.cmake:255 (cmake_determine_linker_id)"
+      - "/usr/share/cmake/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)"
+      - "CMakeLists.txt:3 (project)"
+    message: |
+      Running the CXX compiler's linker: "/usr/bin/ld" "-v"
+      GNU ld (GNU Binutils) 2.43.0
+...
diff --git a/VMAware/build/CMakeFiles/CMakeDirectoryInformation.cmake b/VMAware/build/CMakeFiles/CMakeDirectoryInformation.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..cd00348d3340efb50a8e767663712667f58ad205
--- /dev/null
+++ b/VMAware/build/CMakeFiles/CMakeDirectoryInformation.cmake
@@ -0,0 +1,16 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Relative path conversion top directories.
+set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/rickyy/Documents/incognito-vm/VMAware")
+set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/rickyy/Documents/incognito-vm/VMAware/build")
+
+# Force unix paths in dependencies.
+set(CMAKE_FORCE_UNIX_PATHS 1)
+
+
+# The C and CXX include file regular expressions for this directory.
+set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$")
+set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$")
+set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN})
+set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN})
diff --git a/VMAware/build/CMakeFiles/CMakeRuleHashes.txt b/VMAware/build/CMakeFiles/CMakeRuleHashes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1790daa0fd30003cbe65d8225206f62bb4d133f9
--- /dev/null
+++ b/VMAware/build/CMakeFiles/CMakeRuleHashes.txt
@@ -0,0 +1,29 @@
+# Hashes of file build rules.
+4b663aa3fab4faa50b6bb11831c4ba7b CMakeFiles/Continuous
+435cc946ed3a7861de0718e768e3c1d1 CMakeFiles/ContinuousBuild
+f98c76fecb7f8ece3cde922ab1df62c3 CMakeFiles/ContinuousConfigure
+fde26594ff50af6950734629831a27f8 CMakeFiles/ContinuousCoverage
+abc1540d672af46c296cfb75b6d2946d CMakeFiles/ContinuousMemCheck
+e8c8a8b118e95f769355cc4d7b69067f CMakeFiles/ContinuousStart
+1e4422e5708df33b4dffa35368a64d72 CMakeFiles/ContinuousSubmit
+44c2c09844e438aed59f41d11d6ac1f1 CMakeFiles/ContinuousTest
+4de172b8e5f9ba74806c00bc13529b69 CMakeFiles/ContinuousUpdate
+851356c0dc8bcb9a1269e25e6052c53e CMakeFiles/Experimental
+e0f5d0f2fdc3c8cafdf6a5c9beed1550 CMakeFiles/ExperimentalBuild
+973a37262eb8e481759ef101fa06ab7b CMakeFiles/ExperimentalConfigure
+d02413156da767418069b9aac42cdcad CMakeFiles/ExperimentalCoverage
+b850b6425b20e1663e745e3fa51f9d57 CMakeFiles/ExperimentalMemCheck
+1361435b5595c83579dffa974188cd07 CMakeFiles/ExperimentalStart
+7eaa83f9f79b8362878799caa5fa733d CMakeFiles/ExperimentalSubmit
+55dd6a59ed3352c91e614a37b8a0b4f6 CMakeFiles/ExperimentalTest
+163cc19ca3902a87079c67dcf3cf4d5c CMakeFiles/ExperimentalUpdate
+cacfb55ec312ff645bdf0d04a890f950 CMakeFiles/Nightly
+181dcfc3895b704bb63aa046c836033c CMakeFiles/NightlyBuild
+35e2b46a583be4524db4bab87dfead3b CMakeFiles/NightlyConfigure
+81010e40f2e0d5ff3cf95e7518d8b9bc CMakeFiles/NightlyCoverage
+a54db0a3017519239fe444766be0ef39 CMakeFiles/NightlyMemCheck
+0257b5280eaed8ba234e09bd08c4c691 CMakeFiles/NightlyMemoryCheck
+32f0ccb8110699ec820d60b305feaafe CMakeFiles/NightlyStart
+de4d52eac791965b33f109a13d342811 CMakeFiles/NightlySubmit
+77f89fd36e9b146044585044938e080a CMakeFiles/NightlyTest
+d732696e12566da9f95a0b139bb46058 CMakeFiles/NightlyUpdate
diff --git a/VMAware/build/CMakeFiles/Continuous.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/Continuous.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Continuous.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/Continuous.dir/build.make b/VMAware/build/CMakeFiles/Continuous.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..9ab0f0a6b1638cb05be922d03d0d09e61700407b
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Continuous.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for Continuous.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/Continuous.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/Continuous.dir/progress.make
+
+CMakeFiles/Continuous:
+	/usr/bin/ctest -D Continuous
+
+Continuous: CMakeFiles/Continuous
+Continuous: CMakeFiles/Continuous.dir/build.make
+.PHONY : Continuous
+
+# Rule to build all files generated by this target.
+CMakeFiles/Continuous.dir/build: Continuous
+.PHONY : CMakeFiles/Continuous.dir/build
+
+CMakeFiles/Continuous.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/Continuous.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/Continuous.dir/clean
+
+CMakeFiles/Continuous.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/Continuous.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/Continuous.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/Continuous.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/Continuous.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..7e1791cf8177d6f06e873e59e56292f12816be7f
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Continuous.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/Continuous"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/Continuous.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/Continuous.dir/compiler_depend.make b/VMAware/build/CMakeFiles/Continuous.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..4e014e0810f6c4573aafec81b46feaf0d739ae5f
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Continuous.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for Continuous.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/Continuous.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/Continuous.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..86303622dcfd463b0ee108a835ce391b2100c2dd
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Continuous.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for Continuous.
diff --git a/VMAware/build/CMakeFiles/Continuous.dir/progress.make b/VMAware/build/CMakeFiles/Continuous.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Continuous.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ContinuousBuild.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ContinuousBuild.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousBuild.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ContinuousBuild.dir/build.make b/VMAware/build/CMakeFiles/ContinuousBuild.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..c7f1af7ed940e9b84828fa6a84d1224be5d36e01
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousBuild.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ContinuousBuild.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ContinuousBuild.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ContinuousBuild.dir/progress.make
+
+CMakeFiles/ContinuousBuild:
+	/usr/bin/ctest -D ContinuousBuild
+
+ContinuousBuild: CMakeFiles/ContinuousBuild
+ContinuousBuild: CMakeFiles/ContinuousBuild.dir/build.make
+.PHONY : ContinuousBuild
+
+# Rule to build all files generated by this target.
+CMakeFiles/ContinuousBuild.dir/build: ContinuousBuild
+.PHONY : CMakeFiles/ContinuousBuild.dir/build
+
+CMakeFiles/ContinuousBuild.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ContinuousBuild.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ContinuousBuild.dir/clean
+
+CMakeFiles/ContinuousBuild.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousBuild.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ContinuousBuild.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ContinuousBuild.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ContinuousBuild.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..afccd13683f11eeb51e1a07941748ada51842402
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousBuild.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ContinuousBuild"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ContinuousBuild.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ContinuousBuild.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ContinuousBuild.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..00b62ad4d704565063d1ad52fcd11352e64a5a0a
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousBuild.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ContinuousBuild.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ContinuousBuild.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ContinuousBuild.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1cb8618262ee3601338a901719a30c0d06e1efad
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousBuild.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ContinuousBuild.
diff --git a/VMAware/build/CMakeFiles/ContinuousBuild.dir/progress.make b/VMAware/build/CMakeFiles/ContinuousBuild.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousBuild.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ContinuousConfigure.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ContinuousConfigure.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousConfigure.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ContinuousConfigure.dir/build.make b/VMAware/build/CMakeFiles/ContinuousConfigure.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..c29f2e10ea6ed7241608b7424a595dc9728b29f2
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousConfigure.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ContinuousConfigure.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ContinuousConfigure.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ContinuousConfigure.dir/progress.make
+
+CMakeFiles/ContinuousConfigure:
+	/usr/bin/ctest -D ContinuousConfigure
+
+ContinuousConfigure: CMakeFiles/ContinuousConfigure
+ContinuousConfigure: CMakeFiles/ContinuousConfigure.dir/build.make
+.PHONY : ContinuousConfigure
+
+# Rule to build all files generated by this target.
+CMakeFiles/ContinuousConfigure.dir/build: ContinuousConfigure
+.PHONY : CMakeFiles/ContinuousConfigure.dir/build
+
+CMakeFiles/ContinuousConfigure.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ContinuousConfigure.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ContinuousConfigure.dir/clean
+
+CMakeFiles/ContinuousConfigure.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousConfigure.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ContinuousConfigure.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ContinuousConfigure.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ContinuousConfigure.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..eb51e20488797514d126ef55573faa6ea6f8c69b
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousConfigure.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ContinuousConfigure"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ContinuousConfigure.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ContinuousConfigure.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ContinuousConfigure.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..584c8bb3f9b0b66cfd4db26bab3d82d6943e28f6
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousConfigure.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ContinuousConfigure.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ContinuousConfigure.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ContinuousConfigure.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c8a342772f52fb62ee6f99e07623d970da5b4d86
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousConfigure.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ContinuousConfigure.
diff --git a/VMAware/build/CMakeFiles/ContinuousConfigure.dir/progress.make b/VMAware/build/CMakeFiles/ContinuousConfigure.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousConfigure.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ContinuousCoverage.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ContinuousCoverage.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousCoverage.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ContinuousCoverage.dir/build.make b/VMAware/build/CMakeFiles/ContinuousCoverage.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..371970f15a971a92f1ebf055e1face319711610b
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousCoverage.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ContinuousCoverage.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ContinuousCoverage.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ContinuousCoverage.dir/progress.make
+
+CMakeFiles/ContinuousCoverage:
+	/usr/bin/ctest -D ContinuousCoverage
+
+ContinuousCoverage: CMakeFiles/ContinuousCoverage
+ContinuousCoverage: CMakeFiles/ContinuousCoverage.dir/build.make
+.PHONY : ContinuousCoverage
+
+# Rule to build all files generated by this target.
+CMakeFiles/ContinuousCoverage.dir/build: ContinuousCoverage
+.PHONY : CMakeFiles/ContinuousCoverage.dir/build
+
+CMakeFiles/ContinuousCoverage.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ContinuousCoverage.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ContinuousCoverage.dir/clean
+
+CMakeFiles/ContinuousCoverage.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousCoverage.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ContinuousCoverage.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ContinuousCoverage.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ContinuousCoverage.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..6115f89bdf791f3b3260f7b39ad9f8fefcfc0d1f
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousCoverage.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ContinuousCoverage"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ContinuousCoverage.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ContinuousCoverage.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ContinuousCoverage.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..8d1a807b14c177b3d98680c588a967311eaa7d78
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousCoverage.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ContinuousCoverage.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ContinuousCoverage.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ContinuousCoverage.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..23d476b9f12f7c15337c4506c898ea5bbff2b2b3
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousCoverage.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ContinuousCoverage.
diff --git a/VMAware/build/CMakeFiles/ContinuousCoverage.dir/progress.make b/VMAware/build/CMakeFiles/ContinuousCoverage.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousCoverage.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/build.make b/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..258a75cd062333202a574f75ecb82d5f1e7d8db9
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ContinuousMemCheck.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ContinuousMemCheck.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ContinuousMemCheck.dir/progress.make
+
+CMakeFiles/ContinuousMemCheck:
+	/usr/bin/ctest -D ContinuousMemCheck
+
+ContinuousMemCheck: CMakeFiles/ContinuousMemCheck
+ContinuousMemCheck: CMakeFiles/ContinuousMemCheck.dir/build.make
+.PHONY : ContinuousMemCheck
+
+# Rule to build all files generated by this target.
+CMakeFiles/ContinuousMemCheck.dir/build: ContinuousMemCheck
+.PHONY : CMakeFiles/ContinuousMemCheck.dir/build
+
+CMakeFiles/ContinuousMemCheck.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ContinuousMemCheck.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ContinuousMemCheck.dir/clean
+
+CMakeFiles/ContinuousMemCheck.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ContinuousMemCheck.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..ad69e7ff4553b55cfc354485edd47d4ad01ea363
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ContinuousMemCheck"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ContinuousMemCheck.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..930bb6168100a15d5e39f90ddc312ba74ab5c718
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ContinuousMemCheck.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4f4fc23fcbab3b887380e8831186dc0ed313cd0e
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ContinuousMemCheck.
diff --git a/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/progress.make b/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousMemCheck.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ContinuousStart.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ContinuousStart.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousStart.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ContinuousStart.dir/build.make b/VMAware/build/CMakeFiles/ContinuousStart.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..b157a15ed6ab5904c627c26332436d19feaa17c8
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousStart.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ContinuousStart.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ContinuousStart.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ContinuousStart.dir/progress.make
+
+CMakeFiles/ContinuousStart:
+	/usr/bin/ctest -D ContinuousStart
+
+ContinuousStart: CMakeFiles/ContinuousStart
+ContinuousStart: CMakeFiles/ContinuousStart.dir/build.make
+.PHONY : ContinuousStart
+
+# Rule to build all files generated by this target.
+CMakeFiles/ContinuousStart.dir/build: ContinuousStart
+.PHONY : CMakeFiles/ContinuousStart.dir/build
+
+CMakeFiles/ContinuousStart.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ContinuousStart.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ContinuousStart.dir/clean
+
+CMakeFiles/ContinuousStart.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousStart.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ContinuousStart.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ContinuousStart.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ContinuousStart.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..13d5b2bcc3bcf36afa7a3e45cb8da752b90d76a5
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousStart.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ContinuousStart"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ContinuousStart.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ContinuousStart.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ContinuousStart.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..af626145dde9b6c5889aeb738d30d2b1e766685c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousStart.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ContinuousStart.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ContinuousStart.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ContinuousStart.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fcc8893db867422d5add04a817f9f16d83bf2469
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousStart.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ContinuousStart.
diff --git a/VMAware/build/CMakeFiles/ContinuousStart.dir/progress.make b/VMAware/build/CMakeFiles/ContinuousStart.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousStart.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ContinuousSubmit.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ContinuousSubmit.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousSubmit.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ContinuousSubmit.dir/build.make b/VMAware/build/CMakeFiles/ContinuousSubmit.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..960f4c3dcafe48c5de8a83fb297b12e481a3e044
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousSubmit.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ContinuousSubmit.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ContinuousSubmit.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ContinuousSubmit.dir/progress.make
+
+CMakeFiles/ContinuousSubmit:
+	/usr/bin/ctest -D ContinuousSubmit
+
+ContinuousSubmit: CMakeFiles/ContinuousSubmit
+ContinuousSubmit: CMakeFiles/ContinuousSubmit.dir/build.make
+.PHONY : ContinuousSubmit
+
+# Rule to build all files generated by this target.
+CMakeFiles/ContinuousSubmit.dir/build: ContinuousSubmit
+.PHONY : CMakeFiles/ContinuousSubmit.dir/build
+
+CMakeFiles/ContinuousSubmit.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ContinuousSubmit.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ContinuousSubmit.dir/clean
+
+CMakeFiles/ContinuousSubmit.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousSubmit.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ContinuousSubmit.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ContinuousSubmit.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ContinuousSubmit.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..cc66ba37777ccbac292828077290fbd248bb8aac
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousSubmit.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ContinuousSubmit"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ContinuousSubmit.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ContinuousSubmit.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ContinuousSubmit.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..338091693ef428fefff14d76daef474e33fce6e7
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousSubmit.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ContinuousSubmit.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ContinuousSubmit.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ContinuousSubmit.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..73d7404b91a9d0fad7b056a6ffc404831bdeed8c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousSubmit.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ContinuousSubmit.
diff --git a/VMAware/build/CMakeFiles/ContinuousSubmit.dir/progress.make b/VMAware/build/CMakeFiles/ContinuousSubmit.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousSubmit.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ContinuousTest.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ContinuousTest.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousTest.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ContinuousTest.dir/build.make b/VMAware/build/CMakeFiles/ContinuousTest.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..2791b6a1b72abb827ce5258a9ef330405512dd83
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousTest.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ContinuousTest.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ContinuousTest.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ContinuousTest.dir/progress.make
+
+CMakeFiles/ContinuousTest:
+	/usr/bin/ctest -D ContinuousTest
+
+ContinuousTest: CMakeFiles/ContinuousTest
+ContinuousTest: CMakeFiles/ContinuousTest.dir/build.make
+.PHONY : ContinuousTest
+
+# Rule to build all files generated by this target.
+CMakeFiles/ContinuousTest.dir/build: ContinuousTest
+.PHONY : CMakeFiles/ContinuousTest.dir/build
+
+CMakeFiles/ContinuousTest.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ContinuousTest.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ContinuousTest.dir/clean
+
+CMakeFiles/ContinuousTest.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousTest.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ContinuousTest.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ContinuousTest.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ContinuousTest.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..ff11d485d8ab87784c4450edc72bc5d423d2f884
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousTest.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ContinuousTest"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ContinuousTest.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ContinuousTest.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ContinuousTest.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..24d664a29feab92b647c6293cd0efc385dc39ef9
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousTest.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ContinuousTest.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ContinuousTest.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ContinuousTest.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bd7c1d1f5ab8524ac039d86bcc38640e6353793e
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousTest.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ContinuousTest.
diff --git a/VMAware/build/CMakeFiles/ContinuousTest.dir/progress.make b/VMAware/build/CMakeFiles/ContinuousTest.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousTest.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ContinuousUpdate.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ContinuousUpdate.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousUpdate.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ContinuousUpdate.dir/build.make b/VMAware/build/CMakeFiles/ContinuousUpdate.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..59f332312f8f1741d81f31d155de04729731765a
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousUpdate.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ContinuousUpdate.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ContinuousUpdate.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ContinuousUpdate.dir/progress.make
+
+CMakeFiles/ContinuousUpdate:
+	/usr/bin/ctest -D ContinuousUpdate
+
+ContinuousUpdate: CMakeFiles/ContinuousUpdate
+ContinuousUpdate: CMakeFiles/ContinuousUpdate.dir/build.make
+.PHONY : ContinuousUpdate
+
+# Rule to build all files generated by this target.
+CMakeFiles/ContinuousUpdate.dir/build: ContinuousUpdate
+.PHONY : CMakeFiles/ContinuousUpdate.dir/build
+
+CMakeFiles/ContinuousUpdate.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ContinuousUpdate.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ContinuousUpdate.dir/clean
+
+CMakeFiles/ContinuousUpdate.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousUpdate.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ContinuousUpdate.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ContinuousUpdate.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ContinuousUpdate.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..7a77a24c329433762bf3f6526ec1749016e5420d
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousUpdate.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ContinuousUpdate"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ContinuousUpdate.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ContinuousUpdate.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ContinuousUpdate.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..b37322694ea9827fa102afa6bfe62a771105a02d
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousUpdate.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ContinuousUpdate.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ContinuousUpdate.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ContinuousUpdate.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ed8de925658f103a9ecc392a4036fe7ea89f0b3c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousUpdate.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ContinuousUpdate.
diff --git a/VMAware/build/CMakeFiles/ContinuousUpdate.dir/progress.make b/VMAware/build/CMakeFiles/ContinuousUpdate.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ContinuousUpdate.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/Experimental.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/Experimental.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Experimental.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/Experimental.dir/build.make b/VMAware/build/CMakeFiles/Experimental.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..3d2f02cdecf5e0220038a60a43b34b55177e4d1d
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Experimental.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for Experimental.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/Experimental.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/Experimental.dir/progress.make
+
+CMakeFiles/Experimental:
+	/usr/bin/ctest -D Experimental
+
+Experimental: CMakeFiles/Experimental
+Experimental: CMakeFiles/Experimental.dir/build.make
+.PHONY : Experimental
+
+# Rule to build all files generated by this target.
+CMakeFiles/Experimental.dir/build: Experimental
+.PHONY : CMakeFiles/Experimental.dir/build
+
+CMakeFiles/Experimental.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/Experimental.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/Experimental.dir/clean
+
+CMakeFiles/Experimental.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/Experimental.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/Experimental.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/Experimental.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/Experimental.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..799e7082f2b793f2322e0d90b70651a0d51fdc41
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Experimental.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/Experimental"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/Experimental.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/Experimental.dir/compiler_depend.make b/VMAware/build/CMakeFiles/Experimental.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..df83d58ef39902b388c0336178ccae0758ee67f4
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Experimental.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for Experimental.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/Experimental.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/Experimental.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2619b9b517364e22e399c52a75202a7f48c2259a
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Experimental.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for Experimental.
diff --git a/VMAware/build/CMakeFiles/Experimental.dir/progress.make b/VMAware/build/CMakeFiles/Experimental.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Experimental.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalBuild.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ExperimentalBuild.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalBuild.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ExperimentalBuild.dir/build.make b/VMAware/build/CMakeFiles/ExperimentalBuild.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..969a6b8ca71aab5781073f15bb0f97d4b8be4e6a
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalBuild.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ExperimentalBuild.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ExperimentalBuild.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ExperimentalBuild.dir/progress.make
+
+CMakeFiles/ExperimentalBuild:
+	/usr/bin/ctest -D ExperimentalBuild
+
+ExperimentalBuild: CMakeFiles/ExperimentalBuild
+ExperimentalBuild: CMakeFiles/ExperimentalBuild.dir/build.make
+.PHONY : ExperimentalBuild
+
+# Rule to build all files generated by this target.
+CMakeFiles/ExperimentalBuild.dir/build: ExperimentalBuild
+.PHONY : CMakeFiles/ExperimentalBuild.dir/build
+
+CMakeFiles/ExperimentalBuild.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ExperimentalBuild.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ExperimentalBuild.dir/clean
+
+CMakeFiles/ExperimentalBuild.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalBuild.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ExperimentalBuild.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalBuild.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ExperimentalBuild.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..3354e3f1c027423f504d335ab0922234b465279c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalBuild.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ExperimentalBuild"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ExperimentalBuild.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ExperimentalBuild.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ExperimentalBuild.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..7608631423ffd1d316182f2fc00e48ceacf013d2
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalBuild.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ExperimentalBuild.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ExperimentalBuild.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ExperimentalBuild.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..34d91606300131a468dcfdab021438c97e4197b4
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalBuild.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ExperimentalBuild.
diff --git a/VMAware/build/CMakeFiles/ExperimentalBuild.dir/progress.make b/VMAware/build/CMakeFiles/ExperimentalBuild.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalBuild.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/build.make b/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..39eae9b57932cf060c771a20f6ae8aa3b413ac2e
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ExperimentalConfigure.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ExperimentalConfigure.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ExperimentalConfigure.dir/progress.make
+
+CMakeFiles/ExperimentalConfigure:
+	/usr/bin/ctest -D ExperimentalConfigure
+
+ExperimentalConfigure: CMakeFiles/ExperimentalConfigure
+ExperimentalConfigure: CMakeFiles/ExperimentalConfigure.dir/build.make
+.PHONY : ExperimentalConfigure
+
+# Rule to build all files generated by this target.
+CMakeFiles/ExperimentalConfigure.dir/build: ExperimentalConfigure
+.PHONY : CMakeFiles/ExperimentalConfigure.dir/build
+
+CMakeFiles/ExperimentalConfigure.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ExperimentalConfigure.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ExperimentalConfigure.dir/clean
+
+CMakeFiles/ExperimentalConfigure.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ExperimentalConfigure.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..69e4a71991fdd9cb942e4401fd019d2c5f7fedc3
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ExperimentalConfigure"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ExperimentalConfigure.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..073879663cd4999b7aa8cb27a976a2a4c069b6b0
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ExperimentalConfigure.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..51fc32c423789bcb2a256b3c758d0c562b64c1ec
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ExperimentalConfigure.
diff --git a/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/progress.make b/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalConfigure.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/build.make b/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..d99da03aebe1ed6d47b1b00ea2aebd3f15291d0f
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ExperimentalCoverage.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ExperimentalCoverage.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ExperimentalCoverage.dir/progress.make
+
+CMakeFiles/ExperimentalCoverage:
+	/usr/bin/ctest -D ExperimentalCoverage
+
+ExperimentalCoverage: CMakeFiles/ExperimentalCoverage
+ExperimentalCoverage: CMakeFiles/ExperimentalCoverage.dir/build.make
+.PHONY : ExperimentalCoverage
+
+# Rule to build all files generated by this target.
+CMakeFiles/ExperimentalCoverage.dir/build: ExperimentalCoverage
+.PHONY : CMakeFiles/ExperimentalCoverage.dir/build
+
+CMakeFiles/ExperimentalCoverage.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ExperimentalCoverage.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ExperimentalCoverage.dir/clean
+
+CMakeFiles/ExperimentalCoverage.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ExperimentalCoverage.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..b8d6597a57093393ae4dd09108c0efa7b196ded2
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ExperimentalCoverage"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ExperimentalCoverage.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..4c327cbb35a23f563c6c11c84e7013b0becc797e
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ExperimentalCoverage.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d3bffd388e150073fd2c3378bb97cae63f4def7d
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ExperimentalCoverage.
diff --git a/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/progress.make b/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalCoverage.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/build.make b/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..244975b99aaf93c6e002292a2f260942d5774379
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ExperimentalMemCheck.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ExperimentalMemCheck.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ExperimentalMemCheck.dir/progress.make
+
+CMakeFiles/ExperimentalMemCheck:
+	/usr/bin/ctest -D ExperimentalMemCheck
+
+ExperimentalMemCheck: CMakeFiles/ExperimentalMemCheck
+ExperimentalMemCheck: CMakeFiles/ExperimentalMemCheck.dir/build.make
+.PHONY : ExperimentalMemCheck
+
+# Rule to build all files generated by this target.
+CMakeFiles/ExperimentalMemCheck.dir/build: ExperimentalMemCheck
+.PHONY : CMakeFiles/ExperimentalMemCheck.dir/build
+
+CMakeFiles/ExperimentalMemCheck.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ExperimentalMemCheck.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ExperimentalMemCheck.dir/clean
+
+CMakeFiles/ExperimentalMemCheck.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ExperimentalMemCheck.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..ed3f7bc0d2aa68a4a79efc34462b4627ed820838
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ExperimentalMemCheck"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ExperimentalMemCheck.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..ab194c2b9206a5fa008d8ee3900fdddeed1c9e1a
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ExperimentalMemCheck.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5d0d9acc87fbbd32048643dee2548eb5118a9f51
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ExperimentalMemCheck.
diff --git a/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/progress.make b/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalStart.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ExperimentalStart.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalStart.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ExperimentalStart.dir/build.make b/VMAware/build/CMakeFiles/ExperimentalStart.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..f346d99da7e1a28dab6ed675e6d28aa300f71e56
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalStart.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ExperimentalStart.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ExperimentalStart.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ExperimentalStart.dir/progress.make
+
+CMakeFiles/ExperimentalStart:
+	/usr/bin/ctest -D ExperimentalStart
+
+ExperimentalStart: CMakeFiles/ExperimentalStart
+ExperimentalStart: CMakeFiles/ExperimentalStart.dir/build.make
+.PHONY : ExperimentalStart
+
+# Rule to build all files generated by this target.
+CMakeFiles/ExperimentalStart.dir/build: ExperimentalStart
+.PHONY : CMakeFiles/ExperimentalStart.dir/build
+
+CMakeFiles/ExperimentalStart.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ExperimentalStart.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ExperimentalStart.dir/clean
+
+CMakeFiles/ExperimentalStart.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalStart.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ExperimentalStart.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalStart.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ExperimentalStart.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..4e2736b1b868f5fd19b5bae524ae0a78f5331665
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalStart.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ExperimentalStart"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ExperimentalStart.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ExperimentalStart.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ExperimentalStart.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..29aab519f60f934007fca885d7871eb30168d693
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalStart.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ExperimentalStart.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ExperimentalStart.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ExperimentalStart.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a636e5c05ed17e9bc18ef5edf5c26364c2534cc5
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalStart.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ExperimentalStart.
diff --git a/VMAware/build/CMakeFiles/ExperimentalStart.dir/progress.make b/VMAware/build/CMakeFiles/ExperimentalStart.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalStart.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/build.make b/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..bbb3da08eab04b6dadf365a513268f60be6259d5
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ExperimentalSubmit.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ExperimentalSubmit.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ExperimentalSubmit.dir/progress.make
+
+CMakeFiles/ExperimentalSubmit:
+	/usr/bin/ctest -D ExperimentalSubmit
+
+ExperimentalSubmit: CMakeFiles/ExperimentalSubmit
+ExperimentalSubmit: CMakeFiles/ExperimentalSubmit.dir/build.make
+.PHONY : ExperimentalSubmit
+
+# Rule to build all files generated by this target.
+CMakeFiles/ExperimentalSubmit.dir/build: ExperimentalSubmit
+.PHONY : CMakeFiles/ExperimentalSubmit.dir/build
+
+CMakeFiles/ExperimentalSubmit.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ExperimentalSubmit.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ExperimentalSubmit.dir/clean
+
+CMakeFiles/ExperimentalSubmit.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ExperimentalSubmit.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..d130e45a3ca86f262efb965f2d63e1da56772ed7
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ExperimentalSubmit"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ExperimentalSubmit.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..444017272764d5b504a543c6ba7c8ce48953d4af
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ExperimentalSubmit.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7fa97b1601cbb8c04048a8391ed3e9b1ba9b2e34
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ExperimentalSubmit.
diff --git a/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/progress.make b/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalSubmit.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalTest.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ExperimentalTest.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalTest.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ExperimentalTest.dir/build.make b/VMAware/build/CMakeFiles/ExperimentalTest.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..0092829e252a26124c8fd9075aab474445e8c988
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalTest.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ExperimentalTest.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ExperimentalTest.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ExperimentalTest.dir/progress.make
+
+CMakeFiles/ExperimentalTest:
+	/usr/bin/ctest -D ExperimentalTest
+
+ExperimentalTest: CMakeFiles/ExperimentalTest
+ExperimentalTest: CMakeFiles/ExperimentalTest.dir/build.make
+.PHONY : ExperimentalTest
+
+# Rule to build all files generated by this target.
+CMakeFiles/ExperimentalTest.dir/build: ExperimentalTest
+.PHONY : CMakeFiles/ExperimentalTest.dir/build
+
+CMakeFiles/ExperimentalTest.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ExperimentalTest.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ExperimentalTest.dir/clean
+
+CMakeFiles/ExperimentalTest.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalTest.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ExperimentalTest.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalTest.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ExperimentalTest.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..4348aa36d03d852cad3229df1db21029afb3c573
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalTest.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ExperimentalTest"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ExperimentalTest.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ExperimentalTest.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ExperimentalTest.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..fab28a9448f84ce74cd09f30db9fff5d89f7e6e7
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalTest.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ExperimentalTest.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ExperimentalTest.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ExperimentalTest.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fbeb091d4c343d8e4c0c99123429a26297407341
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalTest.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ExperimentalTest.
diff --git a/VMAware/build/CMakeFiles/ExperimentalTest.dir/progress.make b/VMAware/build/CMakeFiles/ExperimentalTest.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalTest.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/build.make b/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..f8ad57b762eb289bc91b1b6c1089f53f869a77f5
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for ExperimentalUpdate.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/ExperimentalUpdate.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/ExperimentalUpdate.dir/progress.make
+
+CMakeFiles/ExperimentalUpdate:
+	/usr/bin/ctest -D ExperimentalUpdate
+
+ExperimentalUpdate: CMakeFiles/ExperimentalUpdate
+ExperimentalUpdate: CMakeFiles/ExperimentalUpdate.dir/build.make
+.PHONY : ExperimentalUpdate
+
+# Rule to build all files generated by this target.
+CMakeFiles/ExperimentalUpdate.dir/build: ExperimentalUpdate
+.PHONY : CMakeFiles/ExperimentalUpdate.dir/build
+
+CMakeFiles/ExperimentalUpdate.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/ExperimentalUpdate.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/ExperimentalUpdate.dir/clean
+
+CMakeFiles/ExperimentalUpdate.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/ExperimentalUpdate.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..23190494323c3f610ef3f4706149811c4fb9c9cd
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/ExperimentalUpdate"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/ExperimentalUpdate.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/compiler_depend.make b/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..30e8f2cac2f5a3b5bd03df79206d32ba1dcd7629
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for ExperimentalUpdate.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..aa7a97edf195dd442c6a81de115112ad5860c0d8
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for ExperimentalUpdate.
diff --git a/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/progress.make b/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/ExperimentalUpdate.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/Makefile.cmake b/VMAware/build/CMakeFiles/Makefile.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..a9cb215f3f8735fd8bd724dd80df954c7fc3eb7e
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Makefile.cmake
@@ -0,0 +1,140 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# The generator used is:
+set(CMAKE_DEPENDS_GENERATOR "Unix Makefiles")
+
+# The top level Makefile was generated from the following files:
+set(CMAKE_MAKEFILE_DEPENDS
+  "CMakeCache.txt"
+  "/home/rickyy/Documents/incognito-vm/VMAware/CMakeLists.txt"
+  "CMakeFiles/3.30.5/CMakeCXXCompiler.cmake"
+  "CMakeFiles/3.30.5/CMakeSystem.cmake"
+  "/usr/share/cmake/Modules/CMakeCXXCompiler.cmake.in"
+  "/usr/share/cmake/Modules/CMakeCXXCompilerABI.cpp"
+  "/usr/share/cmake/Modules/CMakeCXXInformation.cmake"
+  "/usr/share/cmake/Modules/CMakeCommonLanguageInclude.cmake"
+  "/usr/share/cmake/Modules/CMakeCompilerIdDetection.cmake"
+  "/usr/share/cmake/Modules/CMakeDetermineCXXCompiler.cmake"
+  "/usr/share/cmake/Modules/CMakeDetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/CMakeDetermineCompilerABI.cmake"
+  "/usr/share/cmake/Modules/CMakeDetermineCompilerId.cmake"
+  "/usr/share/cmake/Modules/CMakeDetermineCompilerSupport.cmake"
+  "/usr/share/cmake/Modules/CMakeDetermineSystem.cmake"
+  "/usr/share/cmake/Modules/CMakeFindBinUtils.cmake"
+  "/usr/share/cmake/Modules/CMakeGenericSystem.cmake"
+  "/usr/share/cmake/Modules/CMakeInitializeConfigs.cmake"
+  "/usr/share/cmake/Modules/CMakeLanguageInformation.cmake"
+  "/usr/share/cmake/Modules/CMakeParseImplicitIncludeInfo.cmake"
+  "/usr/share/cmake/Modules/CMakeParseImplicitLinkInfo.cmake"
+  "/usr/share/cmake/Modules/CMakeParseLibraryArchitecture.cmake"
+  "/usr/share/cmake/Modules/CMakeSystem.cmake.in"
+  "/usr/share/cmake/Modules/CMakeSystemSpecificInformation.cmake"
+  "/usr/share/cmake/Modules/CMakeSystemSpecificInitialize.cmake"
+  "/usr/share/cmake/Modules/CMakeTestCXXCompiler.cmake"
+  "/usr/share/cmake/Modules/CMakeTestCompilerCommon.cmake"
+  "/usr/share/cmake/Modules/CMakeUnixFindMake.cmake"
+  "/usr/share/cmake/Modules/CTest.cmake"
+  "/usr/share/cmake/Modules/CTestTargets.cmake"
+  "/usr/share/cmake/Modules/CTestUseLaunchers.cmake"
+  "/usr/share/cmake/Modules/Compiler/ADSP-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/ARMCC-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/ARMClang-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/AppleClang-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/Borland-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/CMakeCommonCompilerMacros.cmake"
+  "/usr/share/cmake/Modules/Compiler/Clang-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
+  "/usr/share/cmake/Modules/Compiler/Compaq-CXX-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/Cray-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/CrayClang-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/Embarcadero-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/Fujitsu-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/FujitsuClang-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/GHS-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/GNU-CXX-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/GNU-CXX.cmake"
+  "/usr/share/cmake/Modules/Compiler/GNU-FindBinUtils.cmake"
+  "/usr/share/cmake/Modules/Compiler/GNU.cmake"
+  "/usr/share/cmake/Modules/Compiler/HP-CXX-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/IAR-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake"
+  "/usr/share/cmake/Modules/Compiler/IBMClang-CXX-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/Intel-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/IntelLLVM-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/LCC-CXX-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/MSVC-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/NVHPC-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/NVIDIA-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/OpenWatcom-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/OrangeC-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/PGI-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/PathScale-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/SCO-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/SunPro-CXX-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/TI-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/TIClang-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/Tasking-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/VisualAge-CXX-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/Watcom-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/XL-CXX-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/XLClang-CXX-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/Compiler/zOS-CXX-DetermineCompiler.cmake"
+  "/usr/share/cmake/Modules/DartConfiguration.tcl.in"
+  "/usr/share/cmake/Modules/Internal/CMakeDetermineLinkerId.cmake"
+  "/usr/share/cmake/Modules/Internal/FeatureTesting.cmake"
+  "/usr/share/cmake/Modules/Platform/Linux-Determine-CXX.cmake"
+  "/usr/share/cmake/Modules/Platform/Linux-GNU-CXX.cmake"
+  "/usr/share/cmake/Modules/Platform/Linux-GNU.cmake"
+  "/usr/share/cmake/Modules/Platform/Linux-Initialize.cmake"
+  "/usr/share/cmake/Modules/Platform/Linux.cmake"
+  "/usr/share/cmake/Modules/Platform/UnixPaths.cmake"
+  )
+
+# The corresponding makefile is:
+set(CMAKE_MAKEFILE_OUTPUTS
+  "Makefile"
+  "CMakeFiles/cmake.check_cache"
+  )
+
+# Byproducts of CMake generate step:
+set(CMAKE_MAKEFILE_PRODUCTS
+  "CMakeFiles/3.30.5/CMakeSystem.cmake"
+  "CMakeFiles/3.30.5/CMakeCXXCompiler.cmake"
+  "CMakeFiles/3.30.5/CMakeCXXCompiler.cmake"
+  "DartConfiguration.tcl"
+  "CMakeFiles/CMakeDirectoryInformation.cmake"
+  )
+
+# Dependency information for all targets:
+set(CMAKE_DEPEND_INFO_FILES
+  "CMakeFiles/vmaware.dir/DependInfo.cmake"
+  "CMakeFiles/Experimental.dir/DependInfo.cmake"
+  "CMakeFiles/Nightly.dir/DependInfo.cmake"
+  "CMakeFiles/Continuous.dir/DependInfo.cmake"
+  "CMakeFiles/NightlyMemoryCheck.dir/DependInfo.cmake"
+  "CMakeFiles/NightlyStart.dir/DependInfo.cmake"
+  "CMakeFiles/NightlyUpdate.dir/DependInfo.cmake"
+  "CMakeFiles/NightlyConfigure.dir/DependInfo.cmake"
+  "CMakeFiles/NightlyBuild.dir/DependInfo.cmake"
+  "CMakeFiles/NightlyTest.dir/DependInfo.cmake"
+  "CMakeFiles/NightlyCoverage.dir/DependInfo.cmake"
+  "CMakeFiles/NightlyMemCheck.dir/DependInfo.cmake"
+  "CMakeFiles/NightlySubmit.dir/DependInfo.cmake"
+  "CMakeFiles/ExperimentalStart.dir/DependInfo.cmake"
+  "CMakeFiles/ExperimentalUpdate.dir/DependInfo.cmake"
+  "CMakeFiles/ExperimentalConfigure.dir/DependInfo.cmake"
+  "CMakeFiles/ExperimentalBuild.dir/DependInfo.cmake"
+  "CMakeFiles/ExperimentalTest.dir/DependInfo.cmake"
+  "CMakeFiles/ExperimentalCoverage.dir/DependInfo.cmake"
+  "CMakeFiles/ExperimentalMemCheck.dir/DependInfo.cmake"
+  "CMakeFiles/ExperimentalSubmit.dir/DependInfo.cmake"
+  "CMakeFiles/ContinuousStart.dir/DependInfo.cmake"
+  "CMakeFiles/ContinuousUpdate.dir/DependInfo.cmake"
+  "CMakeFiles/ContinuousConfigure.dir/DependInfo.cmake"
+  "CMakeFiles/ContinuousBuild.dir/DependInfo.cmake"
+  "CMakeFiles/ContinuousTest.dir/DependInfo.cmake"
+  "CMakeFiles/ContinuousCoverage.dir/DependInfo.cmake"
+  "CMakeFiles/ContinuousMemCheck.dir/DependInfo.cmake"
+  "CMakeFiles/ContinuousSubmit.dir/DependInfo.cmake"
+  )
diff --git a/VMAware/build/CMakeFiles/Makefile2 b/VMAware/build/CMakeFiles/Makefile2
new file mode 100644
index 0000000000000000000000000000000000000000..5cc72416cf1823d061b5373a19b6ac776ca357fa
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Makefile2
@@ -0,0 +1,868 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Default target executed when no arguments are given to make.
+default_target: all
+.PHONY : default_target
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+#=============================================================================
+# Directory level rules for the build root directory
+
+# The main recursive "all" target.
+all: CMakeFiles/vmaware.dir/all
+.PHONY : all
+
+# The main recursive "preinstall" target.
+preinstall:
+.PHONY : preinstall
+
+# The main recursive "clean" target.
+clean: CMakeFiles/vmaware.dir/clean
+clean: CMakeFiles/Experimental.dir/clean
+clean: CMakeFiles/Nightly.dir/clean
+clean: CMakeFiles/Continuous.dir/clean
+clean: CMakeFiles/NightlyMemoryCheck.dir/clean
+clean: CMakeFiles/NightlyStart.dir/clean
+clean: CMakeFiles/NightlyUpdate.dir/clean
+clean: CMakeFiles/NightlyConfigure.dir/clean
+clean: CMakeFiles/NightlyBuild.dir/clean
+clean: CMakeFiles/NightlyTest.dir/clean
+clean: CMakeFiles/NightlyCoverage.dir/clean
+clean: CMakeFiles/NightlyMemCheck.dir/clean
+clean: CMakeFiles/NightlySubmit.dir/clean
+clean: CMakeFiles/ExperimentalStart.dir/clean
+clean: CMakeFiles/ExperimentalUpdate.dir/clean
+clean: CMakeFiles/ExperimentalConfigure.dir/clean
+clean: CMakeFiles/ExperimentalBuild.dir/clean
+clean: CMakeFiles/ExperimentalTest.dir/clean
+clean: CMakeFiles/ExperimentalCoverage.dir/clean
+clean: CMakeFiles/ExperimentalMemCheck.dir/clean
+clean: CMakeFiles/ExperimentalSubmit.dir/clean
+clean: CMakeFiles/ContinuousStart.dir/clean
+clean: CMakeFiles/ContinuousUpdate.dir/clean
+clean: CMakeFiles/ContinuousConfigure.dir/clean
+clean: CMakeFiles/ContinuousBuild.dir/clean
+clean: CMakeFiles/ContinuousTest.dir/clean
+clean: CMakeFiles/ContinuousCoverage.dir/clean
+clean: CMakeFiles/ContinuousMemCheck.dir/clean
+clean: CMakeFiles/ContinuousSubmit.dir/clean
+.PHONY : clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/vmaware.dir
+
+# All Build rule for target.
+CMakeFiles/vmaware.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/vmaware.dir/build.make CMakeFiles/vmaware.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/vmaware.dir/build.make CMakeFiles/vmaware.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num=1,2 "Built target vmaware"
+.PHONY : CMakeFiles/vmaware.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/vmaware.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 2
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/vmaware.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/vmaware.dir/rule
+
+# Convenience name for target.
+vmaware: CMakeFiles/vmaware.dir/rule
+.PHONY : vmaware
+
+# clean rule for target.
+CMakeFiles/vmaware.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/vmaware.dir/build.make CMakeFiles/vmaware.dir/clean
+.PHONY : CMakeFiles/vmaware.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/Experimental.dir
+
+# All Build rule for target.
+CMakeFiles/Experimental.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Experimental.dir/build.make CMakeFiles/Experimental.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Experimental.dir/build.make CMakeFiles/Experimental.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target Experimental"
+.PHONY : CMakeFiles/Experimental.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/Experimental.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/Experimental.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/Experimental.dir/rule
+
+# Convenience name for target.
+Experimental: CMakeFiles/Experimental.dir/rule
+.PHONY : Experimental
+
+# clean rule for target.
+CMakeFiles/Experimental.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Experimental.dir/build.make CMakeFiles/Experimental.dir/clean
+.PHONY : CMakeFiles/Experimental.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/Nightly.dir
+
+# All Build rule for target.
+CMakeFiles/Nightly.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Nightly.dir/build.make CMakeFiles/Nightly.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Nightly.dir/build.make CMakeFiles/Nightly.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target Nightly"
+.PHONY : CMakeFiles/Nightly.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/Nightly.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/Nightly.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/Nightly.dir/rule
+
+# Convenience name for target.
+Nightly: CMakeFiles/Nightly.dir/rule
+.PHONY : Nightly
+
+# clean rule for target.
+CMakeFiles/Nightly.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Nightly.dir/build.make CMakeFiles/Nightly.dir/clean
+.PHONY : CMakeFiles/Nightly.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/Continuous.dir
+
+# All Build rule for target.
+CMakeFiles/Continuous.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Continuous.dir/build.make CMakeFiles/Continuous.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Continuous.dir/build.make CMakeFiles/Continuous.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target Continuous"
+.PHONY : CMakeFiles/Continuous.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/Continuous.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/Continuous.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/Continuous.dir/rule
+
+# Convenience name for target.
+Continuous: CMakeFiles/Continuous.dir/rule
+.PHONY : Continuous
+
+# clean rule for target.
+CMakeFiles/Continuous.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Continuous.dir/build.make CMakeFiles/Continuous.dir/clean
+.PHONY : CMakeFiles/Continuous.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/NightlyMemoryCheck.dir
+
+# All Build rule for target.
+CMakeFiles/NightlyMemoryCheck.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyMemoryCheck.dir/build.make CMakeFiles/NightlyMemoryCheck.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyMemoryCheck.dir/build.make CMakeFiles/NightlyMemoryCheck.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target NightlyMemoryCheck"
+.PHONY : CMakeFiles/NightlyMemoryCheck.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/NightlyMemoryCheck.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/NightlyMemoryCheck.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/NightlyMemoryCheck.dir/rule
+
+# Convenience name for target.
+NightlyMemoryCheck: CMakeFiles/NightlyMemoryCheck.dir/rule
+.PHONY : NightlyMemoryCheck
+
+# clean rule for target.
+CMakeFiles/NightlyMemoryCheck.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyMemoryCheck.dir/build.make CMakeFiles/NightlyMemoryCheck.dir/clean
+.PHONY : CMakeFiles/NightlyMemoryCheck.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/NightlyStart.dir
+
+# All Build rule for target.
+CMakeFiles/NightlyStart.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyStart.dir/build.make CMakeFiles/NightlyStart.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyStart.dir/build.make CMakeFiles/NightlyStart.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target NightlyStart"
+.PHONY : CMakeFiles/NightlyStart.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/NightlyStart.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/NightlyStart.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/NightlyStart.dir/rule
+
+# Convenience name for target.
+NightlyStart: CMakeFiles/NightlyStart.dir/rule
+.PHONY : NightlyStart
+
+# clean rule for target.
+CMakeFiles/NightlyStart.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyStart.dir/build.make CMakeFiles/NightlyStart.dir/clean
+.PHONY : CMakeFiles/NightlyStart.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/NightlyUpdate.dir
+
+# All Build rule for target.
+CMakeFiles/NightlyUpdate.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyUpdate.dir/build.make CMakeFiles/NightlyUpdate.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyUpdate.dir/build.make CMakeFiles/NightlyUpdate.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target NightlyUpdate"
+.PHONY : CMakeFiles/NightlyUpdate.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/NightlyUpdate.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/NightlyUpdate.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/NightlyUpdate.dir/rule
+
+# Convenience name for target.
+NightlyUpdate: CMakeFiles/NightlyUpdate.dir/rule
+.PHONY : NightlyUpdate
+
+# clean rule for target.
+CMakeFiles/NightlyUpdate.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyUpdate.dir/build.make CMakeFiles/NightlyUpdate.dir/clean
+.PHONY : CMakeFiles/NightlyUpdate.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/NightlyConfigure.dir
+
+# All Build rule for target.
+CMakeFiles/NightlyConfigure.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyConfigure.dir/build.make CMakeFiles/NightlyConfigure.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyConfigure.dir/build.make CMakeFiles/NightlyConfigure.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target NightlyConfigure"
+.PHONY : CMakeFiles/NightlyConfigure.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/NightlyConfigure.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/NightlyConfigure.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/NightlyConfigure.dir/rule
+
+# Convenience name for target.
+NightlyConfigure: CMakeFiles/NightlyConfigure.dir/rule
+.PHONY : NightlyConfigure
+
+# clean rule for target.
+CMakeFiles/NightlyConfigure.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyConfigure.dir/build.make CMakeFiles/NightlyConfigure.dir/clean
+.PHONY : CMakeFiles/NightlyConfigure.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/NightlyBuild.dir
+
+# All Build rule for target.
+CMakeFiles/NightlyBuild.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyBuild.dir/build.make CMakeFiles/NightlyBuild.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyBuild.dir/build.make CMakeFiles/NightlyBuild.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target NightlyBuild"
+.PHONY : CMakeFiles/NightlyBuild.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/NightlyBuild.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/NightlyBuild.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/NightlyBuild.dir/rule
+
+# Convenience name for target.
+NightlyBuild: CMakeFiles/NightlyBuild.dir/rule
+.PHONY : NightlyBuild
+
+# clean rule for target.
+CMakeFiles/NightlyBuild.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyBuild.dir/build.make CMakeFiles/NightlyBuild.dir/clean
+.PHONY : CMakeFiles/NightlyBuild.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/NightlyTest.dir
+
+# All Build rule for target.
+CMakeFiles/NightlyTest.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyTest.dir/build.make CMakeFiles/NightlyTest.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyTest.dir/build.make CMakeFiles/NightlyTest.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target NightlyTest"
+.PHONY : CMakeFiles/NightlyTest.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/NightlyTest.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/NightlyTest.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/NightlyTest.dir/rule
+
+# Convenience name for target.
+NightlyTest: CMakeFiles/NightlyTest.dir/rule
+.PHONY : NightlyTest
+
+# clean rule for target.
+CMakeFiles/NightlyTest.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyTest.dir/build.make CMakeFiles/NightlyTest.dir/clean
+.PHONY : CMakeFiles/NightlyTest.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/NightlyCoverage.dir
+
+# All Build rule for target.
+CMakeFiles/NightlyCoverage.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyCoverage.dir/build.make CMakeFiles/NightlyCoverage.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyCoverage.dir/build.make CMakeFiles/NightlyCoverage.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target NightlyCoverage"
+.PHONY : CMakeFiles/NightlyCoverage.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/NightlyCoverage.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/NightlyCoverage.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/NightlyCoverage.dir/rule
+
+# Convenience name for target.
+NightlyCoverage: CMakeFiles/NightlyCoverage.dir/rule
+.PHONY : NightlyCoverage
+
+# clean rule for target.
+CMakeFiles/NightlyCoverage.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyCoverage.dir/build.make CMakeFiles/NightlyCoverage.dir/clean
+.PHONY : CMakeFiles/NightlyCoverage.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/NightlyMemCheck.dir
+
+# All Build rule for target.
+CMakeFiles/NightlyMemCheck.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyMemCheck.dir/build.make CMakeFiles/NightlyMemCheck.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyMemCheck.dir/build.make CMakeFiles/NightlyMemCheck.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target NightlyMemCheck"
+.PHONY : CMakeFiles/NightlyMemCheck.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/NightlyMemCheck.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/NightlyMemCheck.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/NightlyMemCheck.dir/rule
+
+# Convenience name for target.
+NightlyMemCheck: CMakeFiles/NightlyMemCheck.dir/rule
+.PHONY : NightlyMemCheck
+
+# clean rule for target.
+CMakeFiles/NightlyMemCheck.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyMemCheck.dir/build.make CMakeFiles/NightlyMemCheck.dir/clean
+.PHONY : CMakeFiles/NightlyMemCheck.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/NightlySubmit.dir
+
+# All Build rule for target.
+CMakeFiles/NightlySubmit.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlySubmit.dir/build.make CMakeFiles/NightlySubmit.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlySubmit.dir/build.make CMakeFiles/NightlySubmit.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target NightlySubmit"
+.PHONY : CMakeFiles/NightlySubmit.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/NightlySubmit.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/NightlySubmit.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/NightlySubmit.dir/rule
+
+# Convenience name for target.
+NightlySubmit: CMakeFiles/NightlySubmit.dir/rule
+.PHONY : NightlySubmit
+
+# clean rule for target.
+CMakeFiles/NightlySubmit.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlySubmit.dir/build.make CMakeFiles/NightlySubmit.dir/clean
+.PHONY : CMakeFiles/NightlySubmit.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ExperimentalStart.dir
+
+# All Build rule for target.
+CMakeFiles/ExperimentalStart.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalStart.dir/build.make CMakeFiles/ExperimentalStart.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalStart.dir/build.make CMakeFiles/ExperimentalStart.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ExperimentalStart"
+.PHONY : CMakeFiles/ExperimentalStart.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ExperimentalStart.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ExperimentalStart.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ExperimentalStart.dir/rule
+
+# Convenience name for target.
+ExperimentalStart: CMakeFiles/ExperimentalStart.dir/rule
+.PHONY : ExperimentalStart
+
+# clean rule for target.
+CMakeFiles/ExperimentalStart.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalStart.dir/build.make CMakeFiles/ExperimentalStart.dir/clean
+.PHONY : CMakeFiles/ExperimentalStart.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ExperimentalUpdate.dir
+
+# All Build rule for target.
+CMakeFiles/ExperimentalUpdate.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalUpdate.dir/build.make CMakeFiles/ExperimentalUpdate.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalUpdate.dir/build.make CMakeFiles/ExperimentalUpdate.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ExperimentalUpdate"
+.PHONY : CMakeFiles/ExperimentalUpdate.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ExperimentalUpdate.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ExperimentalUpdate.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ExperimentalUpdate.dir/rule
+
+# Convenience name for target.
+ExperimentalUpdate: CMakeFiles/ExperimentalUpdate.dir/rule
+.PHONY : ExperimentalUpdate
+
+# clean rule for target.
+CMakeFiles/ExperimentalUpdate.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalUpdate.dir/build.make CMakeFiles/ExperimentalUpdate.dir/clean
+.PHONY : CMakeFiles/ExperimentalUpdate.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ExperimentalConfigure.dir
+
+# All Build rule for target.
+CMakeFiles/ExperimentalConfigure.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalConfigure.dir/build.make CMakeFiles/ExperimentalConfigure.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalConfigure.dir/build.make CMakeFiles/ExperimentalConfigure.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ExperimentalConfigure"
+.PHONY : CMakeFiles/ExperimentalConfigure.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ExperimentalConfigure.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ExperimentalConfigure.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ExperimentalConfigure.dir/rule
+
+# Convenience name for target.
+ExperimentalConfigure: CMakeFiles/ExperimentalConfigure.dir/rule
+.PHONY : ExperimentalConfigure
+
+# clean rule for target.
+CMakeFiles/ExperimentalConfigure.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalConfigure.dir/build.make CMakeFiles/ExperimentalConfigure.dir/clean
+.PHONY : CMakeFiles/ExperimentalConfigure.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ExperimentalBuild.dir
+
+# All Build rule for target.
+CMakeFiles/ExperimentalBuild.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalBuild.dir/build.make CMakeFiles/ExperimentalBuild.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalBuild.dir/build.make CMakeFiles/ExperimentalBuild.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ExperimentalBuild"
+.PHONY : CMakeFiles/ExperimentalBuild.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ExperimentalBuild.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ExperimentalBuild.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ExperimentalBuild.dir/rule
+
+# Convenience name for target.
+ExperimentalBuild: CMakeFiles/ExperimentalBuild.dir/rule
+.PHONY : ExperimentalBuild
+
+# clean rule for target.
+CMakeFiles/ExperimentalBuild.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalBuild.dir/build.make CMakeFiles/ExperimentalBuild.dir/clean
+.PHONY : CMakeFiles/ExperimentalBuild.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ExperimentalTest.dir
+
+# All Build rule for target.
+CMakeFiles/ExperimentalTest.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalTest.dir/build.make CMakeFiles/ExperimentalTest.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalTest.dir/build.make CMakeFiles/ExperimentalTest.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ExperimentalTest"
+.PHONY : CMakeFiles/ExperimentalTest.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ExperimentalTest.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ExperimentalTest.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ExperimentalTest.dir/rule
+
+# Convenience name for target.
+ExperimentalTest: CMakeFiles/ExperimentalTest.dir/rule
+.PHONY : ExperimentalTest
+
+# clean rule for target.
+CMakeFiles/ExperimentalTest.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalTest.dir/build.make CMakeFiles/ExperimentalTest.dir/clean
+.PHONY : CMakeFiles/ExperimentalTest.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ExperimentalCoverage.dir
+
+# All Build rule for target.
+CMakeFiles/ExperimentalCoverage.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalCoverage.dir/build.make CMakeFiles/ExperimentalCoverage.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalCoverage.dir/build.make CMakeFiles/ExperimentalCoverage.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ExperimentalCoverage"
+.PHONY : CMakeFiles/ExperimentalCoverage.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ExperimentalCoverage.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ExperimentalCoverage.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ExperimentalCoverage.dir/rule
+
+# Convenience name for target.
+ExperimentalCoverage: CMakeFiles/ExperimentalCoverage.dir/rule
+.PHONY : ExperimentalCoverage
+
+# clean rule for target.
+CMakeFiles/ExperimentalCoverage.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalCoverage.dir/build.make CMakeFiles/ExperimentalCoverage.dir/clean
+.PHONY : CMakeFiles/ExperimentalCoverage.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ExperimentalMemCheck.dir
+
+# All Build rule for target.
+CMakeFiles/ExperimentalMemCheck.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalMemCheck.dir/build.make CMakeFiles/ExperimentalMemCheck.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalMemCheck.dir/build.make CMakeFiles/ExperimentalMemCheck.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ExperimentalMemCheck"
+.PHONY : CMakeFiles/ExperimentalMemCheck.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ExperimentalMemCheck.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ExperimentalMemCheck.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ExperimentalMemCheck.dir/rule
+
+# Convenience name for target.
+ExperimentalMemCheck: CMakeFiles/ExperimentalMemCheck.dir/rule
+.PHONY : ExperimentalMemCheck
+
+# clean rule for target.
+CMakeFiles/ExperimentalMemCheck.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalMemCheck.dir/build.make CMakeFiles/ExperimentalMemCheck.dir/clean
+.PHONY : CMakeFiles/ExperimentalMemCheck.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ExperimentalSubmit.dir
+
+# All Build rule for target.
+CMakeFiles/ExperimentalSubmit.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalSubmit.dir/build.make CMakeFiles/ExperimentalSubmit.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalSubmit.dir/build.make CMakeFiles/ExperimentalSubmit.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ExperimentalSubmit"
+.PHONY : CMakeFiles/ExperimentalSubmit.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ExperimentalSubmit.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ExperimentalSubmit.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ExperimentalSubmit.dir/rule
+
+# Convenience name for target.
+ExperimentalSubmit: CMakeFiles/ExperimentalSubmit.dir/rule
+.PHONY : ExperimentalSubmit
+
+# clean rule for target.
+CMakeFiles/ExperimentalSubmit.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalSubmit.dir/build.make CMakeFiles/ExperimentalSubmit.dir/clean
+.PHONY : CMakeFiles/ExperimentalSubmit.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ContinuousStart.dir
+
+# All Build rule for target.
+CMakeFiles/ContinuousStart.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousStart.dir/build.make CMakeFiles/ContinuousStart.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousStart.dir/build.make CMakeFiles/ContinuousStart.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ContinuousStart"
+.PHONY : CMakeFiles/ContinuousStart.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ContinuousStart.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ContinuousStart.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ContinuousStart.dir/rule
+
+# Convenience name for target.
+ContinuousStart: CMakeFiles/ContinuousStart.dir/rule
+.PHONY : ContinuousStart
+
+# clean rule for target.
+CMakeFiles/ContinuousStart.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousStart.dir/build.make CMakeFiles/ContinuousStart.dir/clean
+.PHONY : CMakeFiles/ContinuousStart.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ContinuousUpdate.dir
+
+# All Build rule for target.
+CMakeFiles/ContinuousUpdate.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousUpdate.dir/build.make CMakeFiles/ContinuousUpdate.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousUpdate.dir/build.make CMakeFiles/ContinuousUpdate.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ContinuousUpdate"
+.PHONY : CMakeFiles/ContinuousUpdate.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ContinuousUpdate.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ContinuousUpdate.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ContinuousUpdate.dir/rule
+
+# Convenience name for target.
+ContinuousUpdate: CMakeFiles/ContinuousUpdate.dir/rule
+.PHONY : ContinuousUpdate
+
+# clean rule for target.
+CMakeFiles/ContinuousUpdate.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousUpdate.dir/build.make CMakeFiles/ContinuousUpdate.dir/clean
+.PHONY : CMakeFiles/ContinuousUpdate.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ContinuousConfigure.dir
+
+# All Build rule for target.
+CMakeFiles/ContinuousConfigure.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousConfigure.dir/build.make CMakeFiles/ContinuousConfigure.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousConfigure.dir/build.make CMakeFiles/ContinuousConfigure.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ContinuousConfigure"
+.PHONY : CMakeFiles/ContinuousConfigure.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ContinuousConfigure.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ContinuousConfigure.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ContinuousConfigure.dir/rule
+
+# Convenience name for target.
+ContinuousConfigure: CMakeFiles/ContinuousConfigure.dir/rule
+.PHONY : ContinuousConfigure
+
+# clean rule for target.
+CMakeFiles/ContinuousConfigure.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousConfigure.dir/build.make CMakeFiles/ContinuousConfigure.dir/clean
+.PHONY : CMakeFiles/ContinuousConfigure.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ContinuousBuild.dir
+
+# All Build rule for target.
+CMakeFiles/ContinuousBuild.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousBuild.dir/build.make CMakeFiles/ContinuousBuild.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousBuild.dir/build.make CMakeFiles/ContinuousBuild.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ContinuousBuild"
+.PHONY : CMakeFiles/ContinuousBuild.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ContinuousBuild.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ContinuousBuild.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ContinuousBuild.dir/rule
+
+# Convenience name for target.
+ContinuousBuild: CMakeFiles/ContinuousBuild.dir/rule
+.PHONY : ContinuousBuild
+
+# clean rule for target.
+CMakeFiles/ContinuousBuild.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousBuild.dir/build.make CMakeFiles/ContinuousBuild.dir/clean
+.PHONY : CMakeFiles/ContinuousBuild.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ContinuousTest.dir
+
+# All Build rule for target.
+CMakeFiles/ContinuousTest.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousTest.dir/build.make CMakeFiles/ContinuousTest.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousTest.dir/build.make CMakeFiles/ContinuousTest.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ContinuousTest"
+.PHONY : CMakeFiles/ContinuousTest.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ContinuousTest.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ContinuousTest.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ContinuousTest.dir/rule
+
+# Convenience name for target.
+ContinuousTest: CMakeFiles/ContinuousTest.dir/rule
+.PHONY : ContinuousTest
+
+# clean rule for target.
+CMakeFiles/ContinuousTest.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousTest.dir/build.make CMakeFiles/ContinuousTest.dir/clean
+.PHONY : CMakeFiles/ContinuousTest.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ContinuousCoverage.dir
+
+# All Build rule for target.
+CMakeFiles/ContinuousCoverage.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousCoverage.dir/build.make CMakeFiles/ContinuousCoverage.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousCoverage.dir/build.make CMakeFiles/ContinuousCoverage.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ContinuousCoverage"
+.PHONY : CMakeFiles/ContinuousCoverage.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ContinuousCoverage.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ContinuousCoverage.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ContinuousCoverage.dir/rule
+
+# Convenience name for target.
+ContinuousCoverage: CMakeFiles/ContinuousCoverage.dir/rule
+.PHONY : ContinuousCoverage
+
+# clean rule for target.
+CMakeFiles/ContinuousCoverage.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousCoverage.dir/build.make CMakeFiles/ContinuousCoverage.dir/clean
+.PHONY : CMakeFiles/ContinuousCoverage.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ContinuousMemCheck.dir
+
+# All Build rule for target.
+CMakeFiles/ContinuousMemCheck.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousMemCheck.dir/build.make CMakeFiles/ContinuousMemCheck.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousMemCheck.dir/build.make CMakeFiles/ContinuousMemCheck.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ContinuousMemCheck"
+.PHONY : CMakeFiles/ContinuousMemCheck.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ContinuousMemCheck.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ContinuousMemCheck.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ContinuousMemCheck.dir/rule
+
+# Convenience name for target.
+ContinuousMemCheck: CMakeFiles/ContinuousMemCheck.dir/rule
+.PHONY : ContinuousMemCheck
+
+# clean rule for target.
+CMakeFiles/ContinuousMemCheck.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousMemCheck.dir/build.make CMakeFiles/ContinuousMemCheck.dir/clean
+.PHONY : CMakeFiles/ContinuousMemCheck.dir/clean
+
+#=============================================================================
+# Target rules for target CMakeFiles/ContinuousSubmit.dir
+
+# All Build rule for target.
+CMakeFiles/ContinuousSubmit.dir/all:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousSubmit.dir/build.make CMakeFiles/ContinuousSubmit.dir/depend
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousSubmit.dir/build.make CMakeFiles/ContinuousSubmit.dir/build
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num= "Built target ContinuousSubmit"
+.PHONY : CMakeFiles/ContinuousSubmit.dir/all
+
+# Build rule for subdir invocation for target.
+CMakeFiles/ContinuousSubmit.dir/rule: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ContinuousSubmit.dir/all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : CMakeFiles/ContinuousSubmit.dir/rule
+
+# Convenience name for target.
+ContinuousSubmit: CMakeFiles/ContinuousSubmit.dir/rule
+.PHONY : ContinuousSubmit
+
+# clean rule for target.
+CMakeFiles/ContinuousSubmit.dir/clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousSubmit.dir/build.make CMakeFiles/ContinuousSubmit.dir/clean
+.PHONY : CMakeFiles/ContinuousSubmit.dir/clean
+
+#=============================================================================
+# Special targets to cleanup operation of make.
+
+# Special rule to run CMake to check the build system integrity.
+# No rule that depends on this can have commands that come from listfiles
+# because they might be regenerated.
+cmake_check_build_system:
+	$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
+.PHONY : cmake_check_build_system
+
diff --git a/VMAware/build/CMakeFiles/Nightly.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/Nightly.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Nightly.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/Nightly.dir/build.make b/VMAware/build/CMakeFiles/Nightly.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..13fb093828958a6e6b7a2a7a8e49c266369c2f91
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Nightly.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for Nightly.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/Nightly.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/Nightly.dir/progress.make
+
+CMakeFiles/Nightly:
+	/usr/bin/ctest -D Nightly
+
+Nightly: CMakeFiles/Nightly
+Nightly: CMakeFiles/Nightly.dir/build.make
+.PHONY : Nightly
+
+# Rule to build all files generated by this target.
+CMakeFiles/Nightly.dir/build: Nightly
+.PHONY : CMakeFiles/Nightly.dir/build
+
+CMakeFiles/Nightly.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/Nightly.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/Nightly.dir/clean
+
+CMakeFiles/Nightly.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/Nightly.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/Nightly.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/Nightly.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/Nightly.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..99a4ac149fbc87eaff43f33138bf97d980167986
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Nightly.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/Nightly"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/Nightly.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/Nightly.dir/compiler_depend.make b/VMAware/build/CMakeFiles/Nightly.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..b53ef7a75d20d77c9484b1a6c2d7208b4a485e2d
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Nightly.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for Nightly.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/Nightly.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/Nightly.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a85d2c815e0c948f05b0c844306861447908f59f
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Nightly.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for Nightly.
diff --git a/VMAware/build/CMakeFiles/Nightly.dir/progress.make b/VMAware/build/CMakeFiles/Nightly.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/Nightly.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/NightlyBuild.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/NightlyBuild.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyBuild.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/NightlyBuild.dir/build.make b/VMAware/build/CMakeFiles/NightlyBuild.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..d1a8dfff22ba14c8c716a390dd8be06d2b74d910
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyBuild.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for NightlyBuild.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/NightlyBuild.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/NightlyBuild.dir/progress.make
+
+CMakeFiles/NightlyBuild:
+	/usr/bin/ctest -D NightlyBuild
+
+NightlyBuild: CMakeFiles/NightlyBuild
+NightlyBuild: CMakeFiles/NightlyBuild.dir/build.make
+.PHONY : NightlyBuild
+
+# Rule to build all files generated by this target.
+CMakeFiles/NightlyBuild.dir/build: NightlyBuild
+.PHONY : CMakeFiles/NightlyBuild.dir/build
+
+CMakeFiles/NightlyBuild.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/NightlyBuild.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/NightlyBuild.dir/clean
+
+CMakeFiles/NightlyBuild.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyBuild.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/NightlyBuild.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/NightlyBuild.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/NightlyBuild.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..7aa38a7847f108b629144b324ece47f81eb950dd
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyBuild.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/NightlyBuild"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/NightlyBuild.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/NightlyBuild.dir/compiler_depend.make b/VMAware/build/CMakeFiles/NightlyBuild.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..da2f347558e17fc36e441ffd69ba6e38d315b1df
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyBuild.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for NightlyBuild.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/NightlyBuild.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/NightlyBuild.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..89e696096246844f328561b5cadf467a7c8a4077
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyBuild.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for NightlyBuild.
diff --git a/VMAware/build/CMakeFiles/NightlyBuild.dir/progress.make b/VMAware/build/CMakeFiles/NightlyBuild.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyBuild.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/NightlyConfigure.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/NightlyConfigure.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyConfigure.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/NightlyConfigure.dir/build.make b/VMAware/build/CMakeFiles/NightlyConfigure.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..e7019a67ce03d4d91e2ba8e08c14c0535def62e9
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyConfigure.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for NightlyConfigure.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/NightlyConfigure.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/NightlyConfigure.dir/progress.make
+
+CMakeFiles/NightlyConfigure:
+	/usr/bin/ctest -D NightlyConfigure
+
+NightlyConfigure: CMakeFiles/NightlyConfigure
+NightlyConfigure: CMakeFiles/NightlyConfigure.dir/build.make
+.PHONY : NightlyConfigure
+
+# Rule to build all files generated by this target.
+CMakeFiles/NightlyConfigure.dir/build: NightlyConfigure
+.PHONY : CMakeFiles/NightlyConfigure.dir/build
+
+CMakeFiles/NightlyConfigure.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/NightlyConfigure.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/NightlyConfigure.dir/clean
+
+CMakeFiles/NightlyConfigure.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyConfigure.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/NightlyConfigure.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/NightlyConfigure.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/NightlyConfigure.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..080c729b98b5ed38cc09b968dcc69760292f7d1a
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyConfigure.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/NightlyConfigure"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/NightlyConfigure.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/NightlyConfigure.dir/compiler_depend.make b/VMAware/build/CMakeFiles/NightlyConfigure.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..973bd2a5ba166e06b0551e4578671158c59f5d45
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyConfigure.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for NightlyConfigure.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/NightlyConfigure.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/NightlyConfigure.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3e550dad8e1286ef78ce5a05d1d8908f8300e7bb
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyConfigure.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for NightlyConfigure.
diff --git a/VMAware/build/CMakeFiles/NightlyConfigure.dir/progress.make b/VMAware/build/CMakeFiles/NightlyConfigure.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyConfigure.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/NightlyCoverage.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/NightlyCoverage.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyCoverage.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/NightlyCoverage.dir/build.make b/VMAware/build/CMakeFiles/NightlyCoverage.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..8f35012dda270b5a9e553e31ffc3aec661e3ac6b
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyCoverage.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for NightlyCoverage.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/NightlyCoverage.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/NightlyCoverage.dir/progress.make
+
+CMakeFiles/NightlyCoverage:
+	/usr/bin/ctest -D NightlyCoverage
+
+NightlyCoverage: CMakeFiles/NightlyCoverage
+NightlyCoverage: CMakeFiles/NightlyCoverage.dir/build.make
+.PHONY : NightlyCoverage
+
+# Rule to build all files generated by this target.
+CMakeFiles/NightlyCoverage.dir/build: NightlyCoverage
+.PHONY : CMakeFiles/NightlyCoverage.dir/build
+
+CMakeFiles/NightlyCoverage.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/NightlyCoverage.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/NightlyCoverage.dir/clean
+
+CMakeFiles/NightlyCoverage.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyCoverage.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/NightlyCoverage.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/NightlyCoverage.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/NightlyCoverage.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..d6cba89b076ae520aa072d721e25a138891aa1a2
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyCoverage.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/NightlyCoverage"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/NightlyCoverage.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/NightlyCoverage.dir/compiler_depend.make b/VMAware/build/CMakeFiles/NightlyCoverage.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..9f188a1ee6a56130d2892f59e5b20b6315f1817f
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyCoverage.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for NightlyCoverage.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/NightlyCoverage.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/NightlyCoverage.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3092ba3e90fb4ac3eae62da09a1e5dd2de242850
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyCoverage.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for NightlyCoverage.
diff --git a/VMAware/build/CMakeFiles/NightlyCoverage.dir/progress.make b/VMAware/build/CMakeFiles/NightlyCoverage.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyCoverage.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/NightlyMemCheck.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/NightlyMemCheck.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyMemCheck.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/NightlyMemCheck.dir/build.make b/VMAware/build/CMakeFiles/NightlyMemCheck.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..de17ce1e6c998d8ee64729bab9ec2bcde96a1171
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyMemCheck.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for NightlyMemCheck.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/NightlyMemCheck.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/NightlyMemCheck.dir/progress.make
+
+CMakeFiles/NightlyMemCheck:
+	/usr/bin/ctest -D NightlyMemCheck
+
+NightlyMemCheck: CMakeFiles/NightlyMemCheck
+NightlyMemCheck: CMakeFiles/NightlyMemCheck.dir/build.make
+.PHONY : NightlyMemCheck
+
+# Rule to build all files generated by this target.
+CMakeFiles/NightlyMemCheck.dir/build: NightlyMemCheck
+.PHONY : CMakeFiles/NightlyMemCheck.dir/build
+
+CMakeFiles/NightlyMemCheck.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/NightlyMemCheck.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/NightlyMemCheck.dir/clean
+
+CMakeFiles/NightlyMemCheck.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyMemCheck.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/NightlyMemCheck.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/NightlyMemCheck.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/NightlyMemCheck.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..3c0e881a0a6d8cc082fa0ae04d307c72a3f5dd9b
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyMemCheck.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/NightlyMemCheck"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/NightlyMemCheck.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/NightlyMemCheck.dir/compiler_depend.make b/VMAware/build/CMakeFiles/NightlyMemCheck.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..6c54911b9c84729ad6e0261b2e9ad56a36e1d315
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyMemCheck.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for NightlyMemCheck.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/NightlyMemCheck.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/NightlyMemCheck.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c176eda13a96db5bc16eca13a6219061e1f71039
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyMemCheck.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for NightlyMemCheck.
diff --git a/VMAware/build/CMakeFiles/NightlyMemCheck.dir/progress.make b/VMAware/build/CMakeFiles/NightlyMemCheck.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyMemCheck.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/build.make b/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..974979aaf9e78d9d6bddc9e8a073ed07279ade7f
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for NightlyMemoryCheck.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/NightlyMemoryCheck.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/NightlyMemoryCheck.dir/progress.make
+
+CMakeFiles/NightlyMemoryCheck:
+	/usr/bin/ctest -D NightlyMemoryCheck
+
+NightlyMemoryCheck: CMakeFiles/NightlyMemoryCheck
+NightlyMemoryCheck: CMakeFiles/NightlyMemoryCheck.dir/build.make
+.PHONY : NightlyMemoryCheck
+
+# Rule to build all files generated by this target.
+CMakeFiles/NightlyMemoryCheck.dir/build: NightlyMemoryCheck
+.PHONY : CMakeFiles/NightlyMemoryCheck.dir/build
+
+CMakeFiles/NightlyMemoryCheck.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/NightlyMemoryCheck.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/NightlyMemoryCheck.dir/clean
+
+CMakeFiles/NightlyMemoryCheck.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/NightlyMemoryCheck.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..884661158ff4d39174862beefa390daa8d12f1f0
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/NightlyMemoryCheck"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/NightlyMemoryCheck.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/compiler_depend.make b/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..3aa41e77c274e797340d6d506af64b8bcbb81eb5
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for NightlyMemoryCheck.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..38e1ae0cf5e10cf901b8f38f92f78950c2f14541
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for NightlyMemoryCheck.
diff --git a/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/progress.make b/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/NightlyStart.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/NightlyStart.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyStart.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/NightlyStart.dir/build.make b/VMAware/build/CMakeFiles/NightlyStart.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..338d2416b826b908b89912c45c84ae246b75f2c3
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyStart.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for NightlyStart.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/NightlyStart.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/NightlyStart.dir/progress.make
+
+CMakeFiles/NightlyStart:
+	/usr/bin/ctest -D NightlyStart
+
+NightlyStart: CMakeFiles/NightlyStart
+NightlyStart: CMakeFiles/NightlyStart.dir/build.make
+.PHONY : NightlyStart
+
+# Rule to build all files generated by this target.
+CMakeFiles/NightlyStart.dir/build: NightlyStart
+.PHONY : CMakeFiles/NightlyStart.dir/build
+
+CMakeFiles/NightlyStart.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/NightlyStart.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/NightlyStart.dir/clean
+
+CMakeFiles/NightlyStart.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyStart.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/NightlyStart.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/NightlyStart.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/NightlyStart.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..6a2c6c6f434243a9d9d1ba9f5ee1aaa9815e8580
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyStart.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/NightlyStart"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/NightlyStart.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/NightlyStart.dir/compiler_depend.make b/VMAware/build/CMakeFiles/NightlyStart.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..b72de2db368df34063331ccd85efc45f3d95c385
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyStart.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for NightlyStart.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/NightlyStart.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/NightlyStart.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2f7f077a9bb9b2c1c0ddd88038ddd384b647a21f
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyStart.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for NightlyStart.
diff --git a/VMAware/build/CMakeFiles/NightlyStart.dir/progress.make b/VMAware/build/CMakeFiles/NightlyStart.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyStart.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/NightlySubmit.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/NightlySubmit.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlySubmit.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/NightlySubmit.dir/build.make b/VMAware/build/CMakeFiles/NightlySubmit.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..f51218fe922a06fbe9fa092346ded7b60b4a8f83
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlySubmit.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for NightlySubmit.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/NightlySubmit.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/NightlySubmit.dir/progress.make
+
+CMakeFiles/NightlySubmit:
+	/usr/bin/ctest -D NightlySubmit
+
+NightlySubmit: CMakeFiles/NightlySubmit
+NightlySubmit: CMakeFiles/NightlySubmit.dir/build.make
+.PHONY : NightlySubmit
+
+# Rule to build all files generated by this target.
+CMakeFiles/NightlySubmit.dir/build: NightlySubmit
+.PHONY : CMakeFiles/NightlySubmit.dir/build
+
+CMakeFiles/NightlySubmit.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/NightlySubmit.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/NightlySubmit.dir/clean
+
+CMakeFiles/NightlySubmit.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlySubmit.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/NightlySubmit.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/NightlySubmit.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/NightlySubmit.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..6f88ccc7daf558e237b04461ff25efd51a26e3e7
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlySubmit.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/NightlySubmit"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/NightlySubmit.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/NightlySubmit.dir/compiler_depend.make b/VMAware/build/CMakeFiles/NightlySubmit.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..d2f674865ffc6a49d7a7c4587dc9922ffd922302
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlySubmit.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for NightlySubmit.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/NightlySubmit.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/NightlySubmit.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..773bf4b08bf7ad8a9331d1ed722b315efa8588a3
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlySubmit.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for NightlySubmit.
diff --git a/VMAware/build/CMakeFiles/NightlySubmit.dir/progress.make b/VMAware/build/CMakeFiles/NightlySubmit.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlySubmit.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/NightlyTest.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/NightlyTest.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyTest.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/NightlyTest.dir/build.make b/VMAware/build/CMakeFiles/NightlyTest.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..36b730901b3a30591299150f1ebdb5908feaf07f
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyTest.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for NightlyTest.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/NightlyTest.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/NightlyTest.dir/progress.make
+
+CMakeFiles/NightlyTest:
+	/usr/bin/ctest -D NightlyTest
+
+NightlyTest: CMakeFiles/NightlyTest
+NightlyTest: CMakeFiles/NightlyTest.dir/build.make
+.PHONY : NightlyTest
+
+# Rule to build all files generated by this target.
+CMakeFiles/NightlyTest.dir/build: NightlyTest
+.PHONY : CMakeFiles/NightlyTest.dir/build
+
+CMakeFiles/NightlyTest.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/NightlyTest.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/NightlyTest.dir/clean
+
+CMakeFiles/NightlyTest.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyTest.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/NightlyTest.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/NightlyTest.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/NightlyTest.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..8f40bb87e4eaa3647e5882d961cd2e3063d371c4
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyTest.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/NightlyTest"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/NightlyTest.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/NightlyTest.dir/compiler_depend.make b/VMAware/build/CMakeFiles/NightlyTest.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..03d9c29c01a8360701131279af4904d85dbdb854
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyTest.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for NightlyTest.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/NightlyTest.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/NightlyTest.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8bb891c6fefee505b62d036283cbe281f725de74
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyTest.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for NightlyTest.
diff --git a/VMAware/build/CMakeFiles/NightlyTest.dir/progress.make b/VMAware/build/CMakeFiles/NightlyTest.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyTest.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/NightlyUpdate.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/NightlyUpdate.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..29b95a515e51db792a1019bc6c3419b6d78ec34c
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyUpdate.dir/DependInfo.cmake
@@ -0,0 +1,22 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/NightlyUpdate.dir/build.make b/VMAware/build/CMakeFiles/NightlyUpdate.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..b054ea31c185d8ac438999241c90188bc3249498
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyUpdate.dir/build.make
@@ -0,0 +1,87 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Utility rule file for NightlyUpdate.
+
+# Include any custom commands dependencies for this target.
+include CMakeFiles/NightlyUpdate.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/NightlyUpdate.dir/progress.make
+
+CMakeFiles/NightlyUpdate:
+	/usr/bin/ctest -D NightlyUpdate
+
+NightlyUpdate: CMakeFiles/NightlyUpdate
+NightlyUpdate: CMakeFiles/NightlyUpdate.dir/build.make
+.PHONY : NightlyUpdate
+
+# Rule to build all files generated by this target.
+CMakeFiles/NightlyUpdate.dir/build: NightlyUpdate
+.PHONY : CMakeFiles/NightlyUpdate.dir/build
+
+CMakeFiles/NightlyUpdate.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/NightlyUpdate.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/NightlyUpdate.dir/clean
+
+CMakeFiles/NightlyUpdate.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyUpdate.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/NightlyUpdate.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/NightlyUpdate.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/NightlyUpdate.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..0f10e8272faa906d248095765c50439ec8a711f7
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyUpdate.dir/cmake_clean.cmake
@@ -0,0 +1,8 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/NightlyUpdate"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang )
+  include(CMakeFiles/NightlyUpdate.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/NightlyUpdate.dir/compiler_depend.make b/VMAware/build/CMakeFiles/NightlyUpdate.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..924c826bcf8e657ed62df5366047db95ae771a56
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyUpdate.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty custom commands generated dependencies file for NightlyUpdate.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/NightlyUpdate.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/NightlyUpdate.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7cf66de73aad6f37fd56660fb1e0363b05d96093
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyUpdate.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for custom commands dependencies management for NightlyUpdate.
diff --git a/VMAware/build/CMakeFiles/NightlyUpdate.dir/progress.make b/VMAware/build/CMakeFiles/NightlyUpdate.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/VMAware/build/CMakeFiles/NightlyUpdate.dir/progress.make
@@ -0,0 +1 @@
+
diff --git a/VMAware/build/CMakeFiles/TargetDirectories.txt b/VMAware/build/CMakeFiles/TargetDirectories.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f48cc6f42074ebdeb150d8ee619e10c70d2a1628
--- /dev/null
+++ b/VMAware/build/CMakeFiles/TargetDirectories.txt
@@ -0,0 +1,36 @@
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/vmaware.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/Experimental.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/Nightly.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/Continuous.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyMemoryCheck.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyStart.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyUpdate.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyConfigure.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyBuild.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyTest.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyCoverage.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlyMemCheck.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/NightlySubmit.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalStart.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalUpdate.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalConfigure.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalBuild.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalTest.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalCoverage.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalMemCheck.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ExperimentalSubmit.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousStart.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousUpdate.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousConfigure.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousBuild.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousTest.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousCoverage.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousMemCheck.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/ContinuousSubmit.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/test.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/edit_cache.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/rebuild_cache.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/list_install_components.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/install.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/install/local.dir
+/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/install/strip.dir
diff --git a/VMAware/build/CMakeFiles/cmake.check_cache b/VMAware/build/CMakeFiles/cmake.check_cache
new file mode 100644
index 0000000000000000000000000000000000000000..3dccd731726d7faa8b29d8d7dba3b981a53ca497
--- /dev/null
+++ b/VMAware/build/CMakeFiles/cmake.check_cache
@@ -0,0 +1 @@
+# This file is generated by cmake for dependency checking of the CMakeCache.txt file
diff --git a/VMAware/build/CMakeFiles/progress.marks b/VMAware/build/CMakeFiles/progress.marks
new file mode 100644
index 0000000000000000000000000000000000000000..0cfbf08886fca9a91cb753ec8734c84fcbe52c9f
--- /dev/null
+++ b/VMAware/build/CMakeFiles/progress.marks
@@ -0,0 +1 @@
+2
diff --git a/VMAware/build/CMakeFiles/vmaware.dir/DependInfo.cmake b/VMAware/build/CMakeFiles/vmaware.dir/DependInfo.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..068988b0e1c1e39805ddb83f69856044998cbd40
--- /dev/null
+++ b/VMAware/build/CMakeFiles/vmaware.dir/DependInfo.cmake
@@ -0,0 +1,23 @@
+
+# Consider dependencies only in project.
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
+
+# The set of languages for which implicit dependencies are needed:
+set(CMAKE_DEPENDS_LANGUAGES
+  )
+
+# The set of dependency files which are needed:
+set(CMAKE_DEPENDS_DEPENDENCY_FILES
+  "/home/rickyy/Documents/incognito-vm/VMAware/src/cli.cpp" "CMakeFiles/vmaware.dir/src/cli.cpp.o" "gcc" "CMakeFiles/vmaware.dir/src/cli.cpp.o.d"
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES
+  )
+
+# Targets to which this target links which contain Fortran sources.
+set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES
+  )
+
+# Fortran module output directory.
+set(CMAKE_Fortran_TARGET_MODULE_DIR "")
diff --git a/VMAware/build/CMakeFiles/vmaware.dir/build.make b/VMAware/build/CMakeFiles/vmaware.dir/build.make
new file mode 100644
index 0000000000000000000000000000000000000000..bb8c51b2262c356fa3dcd8c565c3167b703355fd
--- /dev/null
+++ b/VMAware/build/CMakeFiles/vmaware.dir/build.make
@@ -0,0 +1,110 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Delete rule output on recipe failure.
+.DELETE_ON_ERROR:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Include any dependencies generated for this target.
+include CMakeFiles/vmaware.dir/depend.make
+# Include any dependencies generated by the compiler for this target.
+include CMakeFiles/vmaware.dir/compiler_depend.make
+
+# Include the progress variables for this target.
+include CMakeFiles/vmaware.dir/progress.make
+
+# Include the compile flags for this target's objects.
+include CMakeFiles/vmaware.dir/flags.make
+
+CMakeFiles/vmaware.dir/src/cli.cpp.o: CMakeFiles/vmaware.dir/flags.make
+CMakeFiles/vmaware.dir/src/cli.cpp.o: /home/rickyy/Documents/incognito-vm/VMAware/src/cli.cpp
+CMakeFiles/vmaware.dir/src/cli.cpp.o: CMakeFiles/vmaware.dir/compiler_depend.ts
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/vmaware.dir/src/cli.cpp.o"
+	/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/vmaware.dir/src/cli.cpp.o -MF CMakeFiles/vmaware.dir/src/cli.cpp.o.d -o CMakeFiles/vmaware.dir/src/cli.cpp.o -c /home/rickyy/Documents/incognito-vm/VMAware/src/cli.cpp
+
+CMakeFiles/vmaware.dir/src/cli.cpp.i: cmake_force
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/vmaware.dir/src/cli.cpp.i"
+	/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/rickyy/Documents/incognito-vm/VMAware/src/cli.cpp > CMakeFiles/vmaware.dir/src/cli.cpp.i
+
+CMakeFiles/vmaware.dir/src/cli.cpp.s: cmake_force
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/vmaware.dir/src/cli.cpp.s"
+	/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/rickyy/Documents/incognito-vm/VMAware/src/cli.cpp -o CMakeFiles/vmaware.dir/src/cli.cpp.s
+
+# Object files for target vmaware
+vmaware_OBJECTS = \
+"CMakeFiles/vmaware.dir/src/cli.cpp.o"
+
+# External object files for target vmaware
+vmaware_EXTERNAL_OBJECTS =
+
+vmaware: CMakeFiles/vmaware.dir/src/cli.cpp.o
+vmaware: CMakeFiles/vmaware.dir/build.make
+vmaware: CMakeFiles/vmaware.dir/link.txt
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable vmaware"
+	$(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/vmaware.dir/link.txt --verbose=$(VERBOSE)
+
+# Rule to build all files generated by this target.
+CMakeFiles/vmaware.dir/build: vmaware
+.PHONY : CMakeFiles/vmaware.dir/build
+
+CMakeFiles/vmaware.dir/clean:
+	$(CMAKE_COMMAND) -P CMakeFiles/vmaware.dir/cmake_clean.cmake
+.PHONY : CMakeFiles/vmaware.dir/clean
+
+CMakeFiles/vmaware.dir/depend:
+	cd /home/rickyy/Documents/incognito-vm/VMAware/build && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/vmaware.dir/DependInfo.cmake "--color=$(COLOR)"
+.PHONY : CMakeFiles/vmaware.dir/depend
+
diff --git a/VMAware/build/CMakeFiles/vmaware.dir/cmake_clean.cmake b/VMAware/build/CMakeFiles/vmaware.dir/cmake_clean.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..625dd6cc7b3c09714f1c2f815e20fa28e34c5ece
--- /dev/null
+++ b/VMAware/build/CMakeFiles/vmaware.dir/cmake_clean.cmake
@@ -0,0 +1,11 @@
+file(REMOVE_RECURSE
+  "CMakeFiles/vmaware.dir/src/cli.cpp.o"
+  "CMakeFiles/vmaware.dir/src/cli.cpp.o.d"
+  "vmaware"
+  "vmaware.pdb"
+)
+
+# Per-language clean rules from dependency scanning.
+foreach(lang CXX)
+  include(CMakeFiles/vmaware.dir/cmake_clean_${lang}.cmake OPTIONAL)
+endforeach()
diff --git a/VMAware/build/CMakeFiles/vmaware.dir/compiler_depend.make b/VMAware/build/CMakeFiles/vmaware.dir/compiler_depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..296188679d57d7af0972316cdb8aa3fc27780a07
--- /dev/null
+++ b/VMAware/build/CMakeFiles/vmaware.dir/compiler_depend.make
@@ -0,0 +1,2 @@
+# Empty compiler generated dependencies file for vmaware.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/vmaware.dir/compiler_depend.ts b/VMAware/build/CMakeFiles/vmaware.dir/compiler_depend.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4f7f9f78c5f40210811e04a5eca6bb693fa09c38
--- /dev/null
+++ b/VMAware/build/CMakeFiles/vmaware.dir/compiler_depend.ts
@@ -0,0 +1,2 @@
+# CMAKE generated file: DO NOT EDIT!
+# Timestamp file for compiler generated dependencies management for vmaware.
diff --git a/VMAware/build/CMakeFiles/vmaware.dir/depend.make b/VMAware/build/CMakeFiles/vmaware.dir/depend.make
new file mode 100644
index 0000000000000000000000000000000000000000..31b96159de001d10c57fd0edd64fbeff9bae4302
--- /dev/null
+++ b/VMAware/build/CMakeFiles/vmaware.dir/depend.make
@@ -0,0 +1,2 @@
+# Empty dependencies file for vmaware.
+# This may be replaced when dependencies are built.
diff --git a/VMAware/build/CMakeFiles/vmaware.dir/flags.make b/VMAware/build/CMakeFiles/vmaware.dir/flags.make
new file mode 100644
index 0000000000000000000000000000000000000000..257c9a1e7a704a224682d2bf8803f253d76c3102
--- /dev/null
+++ b/VMAware/build/CMakeFiles/vmaware.dir/flags.make
@@ -0,0 +1,10 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# compile CXX with /usr/bin/c++
+CXX_DEFINES = -D__VMAWARE_RELEASE__
+
+CXX_INCLUDES = 
+
+CXX_FLAGS = -Wextra -Wall -Wextra -Wconversion -Wdouble-promotion -Wno-unused-parameter -Wno-unused-function -Wno-sign-conversion -g0 -O2 -march=native -mtune=native -O3 -DNDEBUG -std=c++20
+
diff --git a/VMAware/build/CMakeFiles/vmaware.dir/link.txt b/VMAware/build/CMakeFiles/vmaware.dir/link.txt
new file mode 100644
index 0000000000000000000000000000000000000000..039c2f828255ddfaeb8c85263fc55762c7ae1dac
--- /dev/null
+++ b/VMAware/build/CMakeFiles/vmaware.dir/link.txt
@@ -0,0 +1 @@
+/usr/bin/c++ -Wextra -Wall -Wextra -Wconversion -Wdouble-promotion -Wno-unused-parameter -Wno-unused-function -Wno-sign-conversion -g0 -O2 -march=native -mtune=native -O3 -DNDEBUG CMakeFiles/vmaware.dir/src/cli.cpp.o -o vmaware
diff --git a/VMAware/build/CMakeFiles/vmaware.dir/progress.make b/VMAware/build/CMakeFiles/vmaware.dir/progress.make
new file mode 100644
index 0000000000000000000000000000000000000000..abadeb0c3abaa81d622026fcd3ae096d03dd29b7
--- /dev/null
+++ b/VMAware/build/CMakeFiles/vmaware.dir/progress.make
@@ -0,0 +1,3 @@
+CMAKE_PROGRESS_1 = 1
+CMAKE_PROGRESS_2 = 2
+
diff --git a/VMAware/build/CMakeFiles/vmaware.dir/src/cli.cpp.o b/VMAware/build/CMakeFiles/vmaware.dir/src/cli.cpp.o
new file mode 100644
index 0000000000000000000000000000000000000000..25a79fac14b04aee2f1cc4dc585fc8fee3da3b83
Binary files /dev/null and b/VMAware/build/CMakeFiles/vmaware.dir/src/cli.cpp.o differ
diff --git a/VMAware/build/CMakeFiles/vmaware.dir/src/cli.cpp.o.d b/VMAware/build/CMakeFiles/vmaware.dir/src/cli.cpp.o.d
new file mode 100644
index 0000000000000000000000000000000000000000..69563d33f54fe63f744466d8b79232dd216d1c85
--- /dev/null
+++ b/VMAware/build/CMakeFiles/vmaware.dir/src/cli.cpp.o.d
@@ -0,0 +1,411 @@
+CMakeFiles/vmaware.dir/src/cli.cpp.o: \
+ /home/rickyy/Documents/incognito-vm/VMAware/src/cli.cpp \
+ /usr/include/stdc-predef.h /usr/include/c++/14.2.1/string \
+ /usr/include/c++/14.2.1/bits/requires_hosted.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/c++config.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/os_defines.h \
+ /usr/include/features.h /usr/include/features-time64.h \
+ /usr/include/bits/wordsize.h /usr/include/bits/timesize.h \
+ /usr/include/sys/cdefs.h /usr/include/bits/long-double.h \
+ /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/cpu_defines.h \
+ /usr/include/c++/14.2.1/pstl/pstl_config.h \
+ /usr/include/c++/14.2.1/bits/stringfwd.h \
+ /usr/include/c++/14.2.1/bits/memoryfwd.h \
+ /usr/include/c++/14.2.1/bits/char_traits.h \
+ /usr/include/c++/14.2.1/bits/postypes.h /usr/include/c++/14.2.1/cwchar \
+ /usr/include/wchar.h /usr/include/bits/libc-header-start.h \
+ /usr/include/bits/floatn.h /usr/include/bits/floatn-common.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/stddef.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/stdarg.h \
+ /usr/include/bits/wchar.h /usr/include/bits/types/wint_t.h \
+ /usr/include/bits/types/mbstate_t.h \
+ /usr/include/bits/types/__mbstate_t.h /usr/include/bits/types/__FILE.h \
+ /usr/include/bits/types/FILE.h /usr/include/bits/types/locale_t.h \
+ /usr/include/bits/types/__locale_t.h /usr/include/c++/14.2.1/type_traits \
+ /usr/include/c++/14.2.1/bits/version.h /usr/include/c++/14.2.1/compare \
+ /usr/include/c++/14.2.1/concepts \
+ /usr/include/c++/14.2.1/bits/stl_construct.h /usr/include/c++/14.2.1/new \
+ /usr/include/c++/14.2.1/bits/exception.h \
+ /usr/include/c++/14.2.1/bits/move.h \
+ /usr/include/c++/14.2.1/bits/stl_iterator_base_types.h \
+ /usr/include/c++/14.2.1/bits/iterator_concepts.h \
+ /usr/include/c++/14.2.1/bits/ptr_traits.h \
+ /usr/include/c++/14.2.1/bits/ranges_cmp.h \
+ /usr/include/c++/14.2.1/bits/stl_iterator_base_funcs.h \
+ /usr/include/c++/14.2.1/bits/concept_check.h \
+ /usr/include/c++/14.2.1/debug/assertions.h \
+ /usr/include/c++/14.2.1/bits/allocator.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/c++allocator.h \
+ /usr/include/c++/14.2.1/bits/new_allocator.h \
+ /usr/include/c++/14.2.1/bits/functexcept.h \
+ /usr/include/c++/14.2.1/bits/exception_defines.h \
+ /usr/include/c++/14.2.1/bits/cpp_type_traits.h \
+ /usr/include/c++/14.2.1/bits/localefwd.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/c++locale.h \
+ /usr/include/c++/14.2.1/clocale /usr/include/locale.h \
+ /usr/include/bits/locale.h /usr/include/c++/14.2.1/iosfwd \
+ /usr/include/c++/14.2.1/cctype /usr/include/ctype.h \
+ /usr/include/bits/types.h /usr/include/bits/typesizes.h \
+ /usr/include/bits/time64.h /usr/include/bits/endian.h \
+ /usr/include/bits/endianness.h \
+ /usr/include/c++/14.2.1/bits/ostream_insert.h \
+ /usr/include/c++/14.2.1/bits/cxxabi_forced.h \
+ /usr/include/c++/14.2.1/bits/stl_iterator.h \
+ /usr/include/c++/14.2.1/ext/type_traits.h \
+ /usr/include/c++/14.2.1/bits/stl_function.h \
+ /usr/include/c++/14.2.1/backward/binders.h \
+ /usr/include/c++/14.2.1/ext/numeric_traits.h \
+ /usr/include/c++/14.2.1/bits/stl_algobase.h \
+ /usr/include/c++/14.2.1/bits/stl_pair.h \
+ /usr/include/c++/14.2.1/bits/utility.h \
+ /usr/include/c++/14.2.1/debug/debug.h \
+ /usr/include/c++/14.2.1/bits/predefined_ops.h \
+ /usr/include/c++/14.2.1/bit /usr/include/c++/14.2.1/bits/refwrap.h \
+ /usr/include/c++/14.2.1/bits/invoke.h \
+ /usr/include/c++/14.2.1/bits/range_access.h \
+ /usr/include/c++/14.2.1/initializer_list \
+ /usr/include/c++/14.2.1/bits/basic_string.h \
+ /usr/include/c++/14.2.1/ext/alloc_traits.h \
+ /usr/include/c++/14.2.1/bits/alloc_traits.h \
+ /usr/include/c++/14.2.1/string_view \
+ /usr/include/c++/14.2.1/bits/functional_hash.h \
+ /usr/include/c++/14.2.1/bits/hash_bytes.h \
+ /usr/include/c++/14.2.1/bits/ranges_base.h \
+ /usr/include/c++/14.2.1/bits/max_size_type.h \
+ /usr/include/c++/14.2.1/numbers \
+ /usr/include/c++/14.2.1/bits/string_view.tcc \
+ /usr/include/c++/14.2.1/ext/string_conversions.h \
+ /usr/include/c++/14.2.1/cstdlib /usr/include/stdlib.h \
+ /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \
+ /usr/include/sys/types.h /usr/include/bits/types/clock_t.h \
+ /usr/include/bits/types/clockid_t.h /usr/include/bits/types/time_t.h \
+ /usr/include/bits/types/timer_t.h /usr/include/bits/stdint-intn.h \
+ /usr/include/endian.h /usr/include/bits/byteswap.h \
+ /usr/include/bits/uintn-identity.h /usr/include/sys/select.h \
+ /usr/include/bits/select.h /usr/include/bits/types/sigset_t.h \
+ /usr/include/bits/types/__sigset_t.h \
+ /usr/include/bits/types/struct_timeval.h \
+ /usr/include/bits/types/struct_timespec.h \
+ /usr/include/bits/pthreadtypes.h /usr/include/bits/thread-shared-types.h \
+ /usr/include/bits/pthreadtypes-arch.h \
+ /usr/include/bits/atomic_wide_counter.h /usr/include/bits/struct_mutex.h \
+ /usr/include/bits/struct_rwlock.h /usr/include/alloca.h \
+ /usr/include/bits/stdlib-bsearch.h /usr/include/bits/stdlib-float.h \
+ /usr/include/c++/14.2.1/bits/std_abs.h /usr/include/c++/14.2.1/cstdio \
+ /usr/include/stdio.h /usr/include/bits/types/__fpos_t.h \
+ /usr/include/bits/types/__fpos64_t.h \
+ /usr/include/bits/types/struct_FILE.h \
+ /usr/include/bits/types/cookie_io_functions_t.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/stdio.h \
+ /usr/include/c++/14.2.1/cerrno /usr/include/errno.h \
+ /usr/include/bits/errno.h /usr/include/linux/errno.h \
+ /usr/include/asm/errno.h /usr/include/asm-generic/errno.h \
+ /usr/include/asm-generic/errno-base.h /usr/include/bits/types/error_t.h \
+ /usr/include/c++/14.2.1/bits/charconv.h \
+ /usr/include/c++/14.2.1/bits/basic_string.tcc \
+ /usr/include/c++/14.2.1/bits/memory_resource.h \
+ /usr/include/c++/14.2.1/cstddef \
+ /usr/include/c++/14.2.1/bits/uses_allocator.h \
+ /usr/include/c++/14.2.1/bits/uses_allocator_args.h \
+ /usr/include/c++/14.2.1/tuple /usr/include/c++/14.2.1/bits/ranges_util.h \
+ /usr/include/c++/14.2.1/iostream /usr/include/c++/14.2.1/ostream \
+ /usr/include/c++/14.2.1/ios /usr/include/c++/14.2.1/exception \
+ /usr/include/c++/14.2.1/bits/exception_ptr.h \
+ /usr/include/c++/14.2.1/bits/cxxabi_init_exception.h \
+ /usr/include/c++/14.2.1/typeinfo \
+ /usr/include/c++/14.2.1/bits/nested_exception.h \
+ /usr/include/c++/14.2.1/bits/ios_base.h \
+ /usr/include/c++/14.2.1/ext/atomicity.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/gthr.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/gthr-default.h \
+ /usr/include/pthread.h /usr/include/sched.h /usr/include/bits/sched.h \
+ /usr/include/bits/types/struct_sched_param.h /usr/include/bits/cpu-set.h \
+ /usr/include/time.h /usr/include/bits/time.h /usr/include/bits/timex.h \
+ /usr/include/bits/types/struct_tm.h \
+ /usr/include/bits/types/struct_itimerspec.h /usr/include/bits/setjmp.h \
+ /usr/include/bits/types/struct___jmp_buf_tag.h \
+ /usr/include/bits/pthread_stack_min-dynamic.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/atomic_word.h \
+ /usr/include/sys/single_threaded.h \
+ /usr/include/c++/14.2.1/bits/locale_classes.h \
+ /usr/include/c++/14.2.1/bits/locale_classes.tcc \
+ /usr/include/c++/14.2.1/system_error \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/error_constants.h \
+ /usr/include/c++/14.2.1/stdexcept /usr/include/c++/14.2.1/streambuf \
+ /usr/include/c++/14.2.1/bits/streambuf.tcc \
+ /usr/include/c++/14.2.1/bits/basic_ios.h \
+ /usr/include/c++/14.2.1/bits/locale_facets.h \
+ /usr/include/c++/14.2.1/cwctype /usr/include/wctype.h \
+ /usr/include/bits/wctype-wchar.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/ctype_base.h \
+ /usr/include/c++/14.2.1/bits/streambuf_iterator.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/ctype_inline.h \
+ /usr/include/c++/14.2.1/bits/locale_facets.tcc \
+ /usr/include/c++/14.2.1/bits/basic_ios.tcc \
+ /usr/include/c++/14.2.1/bits/ostream.tcc /usr/include/c++/14.2.1/istream \
+ /usr/include/c++/14.2.1/bits/istream.tcc /usr/include/c++/14.2.1/vector \
+ /usr/include/c++/14.2.1/bits/stl_uninitialized.h \
+ /usr/include/c++/14.2.1/bits/stl_vector.h \
+ /usr/include/c++/14.2.1/bits/stl_bvector.h \
+ /usr/include/c++/14.2.1/bits/vector.tcc /usr/include/c++/14.2.1/cstdint \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/stdint.h \
+ /usr/include/stdint.h /usr/include/bits/stdint-uintn.h \
+ /usr/include/bits/stdint-least.h /usr/include/unistd.h \
+ /usr/include/bits/posix_opt.h /usr/include/bits/environments.h \
+ /usr/include/bits/confname.h /usr/include/bits/getopt_posix.h \
+ /usr/include/bits/getopt_core.h /usr/include/bits/unistd_ext.h \
+ /usr/include/linux/close_range.h \
+ /home/rickyy/Documents/incognito-vm/VMAware/src/vmaware.hpp \
+ /usr/include/c++/14.2.1/ranges /usr/include/c++/14.2.1/iterator \
+ /usr/include/c++/14.2.1/bits/stream_iterator.h \
+ /usr/include/c++/14.2.1/optional \
+ /usr/include/c++/14.2.1/bits/enable_special_members.h \
+ /usr/include/c++/14.2.1/span /usr/include/c++/14.2.1/array \
+ /usr/include/c++/14.2.1/source_location \
+ /usr/include/c++/14.2.1/filesystem /usr/include/c++/14.2.1/bits/fs_fwd.h \
+ /usr/include/c++/14.2.1/bits/chrono.h /usr/include/c++/14.2.1/ratio \
+ /usr/include/c++/14.2.1/limits /usr/include/c++/14.2.1/ctime \
+ /usr/include/c++/14.2.1/bits/parse_numbers.h \
+ /usr/include/c++/14.2.1/bits/fs_path.h /usr/include/c++/14.2.1/locale \
+ /usr/include/c++/14.2.1/bits/locale_facets_nonio.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/time_members.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/messages_members.h \
+ /usr/include/libintl.h /usr/include/c++/14.2.1/bits/codecvt.h \
+ /usr/include/c++/14.2.1/bits/locale_facets_nonio.tcc \
+ /usr/include/c++/14.2.1/bits/locale_conv.h \
+ /usr/include/c++/14.2.1/iomanip \
+ /usr/include/c++/14.2.1/bits/quoted_string.h \
+ /usr/include/c++/14.2.1/sstream /usr/include/c++/14.2.1/bits/sstream.tcc \
+ /usr/include/c++/14.2.1/codecvt \
+ /usr/include/c++/14.2.1/ext/concurrence.h \
+ /usr/include/c++/14.2.1/bits/shared_ptr.h \
+ /usr/include/c++/14.2.1/bits/shared_ptr_base.h \
+ /usr/include/c++/14.2.1/bits/allocated_ptr.h \
+ /usr/include/c++/14.2.1/bits/unique_ptr.h \
+ /usr/include/c++/14.2.1/ext/aligned_buffer.h \
+ /usr/include/c++/14.2.1/bits/align.h \
+ /usr/include/c++/14.2.1/bits/fs_dir.h \
+ /usr/include/c++/14.2.1/bits/fs_ops.h /usr/include/c++/14.2.1/functional \
+ /usr/include/c++/14.2.1/bits/std_function.h \
+ /usr/include/c++/14.2.1/unordered_map \
+ /usr/include/c++/14.2.1/bits/unordered_map.h \
+ /usr/include/c++/14.2.1/bits/hashtable.h \
+ /usr/include/c++/14.2.1/bits/hashtable_policy.h \
+ /usr/include/c++/14.2.1/bits/node_handle.h \
+ /usr/include/c++/14.2.1/bits/erase_if.h /usr/include/c++/14.2.1/cstring \
+ /usr/include/string.h /usr/include/strings.h \
+ /usr/include/c++/14.2.1/fstream \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/basic_file.h \
+ /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/c++io.h \
+ /usr/include/c++/14.2.1/bits/fstream.tcc /usr/include/c++/14.2.1/regex \
+ /usr/include/c++/14.2.1/bitset /usr/include/c++/14.2.1/stack \
+ /usr/include/c++/14.2.1/deque /usr/include/c++/14.2.1/bits/stl_deque.h \
+ /usr/include/c++/14.2.1/bits/deque.tcc \
+ /usr/include/c++/14.2.1/bits/stl_stack.h \
+ /usr/include/c++/14.2.1/bits/stl_algo.h \
+ /usr/include/c++/14.2.1/bits/algorithmfwd.h \
+ /usr/include/c++/14.2.1/bits/stl_heap.h \
+ /usr/include/c++/14.2.1/bits/uniform_int_dist.h \
+ /usr/include/c++/14.2.1/bits/stl_tempbuf.h \
+ /usr/include/c++/14.2.1/bits/stl_tree.h \
+ /usr/include/c++/14.2.1/bits/stl_map.h \
+ /usr/include/c++/14.2.1/bits/regex_constants.h \
+ /usr/include/c++/14.2.1/bits/regex_error.h \
+ /usr/include/c++/14.2.1/bits/regex_automaton.h \
+ /usr/include/c++/14.2.1/bits/regex_automaton.tcc \
+ /usr/include/c++/14.2.1/bits/regex_scanner.h \
+ /usr/include/c++/14.2.1/bits/regex_scanner.tcc \
+ /usr/include/c++/14.2.1/bits/regex_compiler.h \
+ /usr/include/c++/14.2.1/bits/regex_compiler.tcc \
+ /usr/include/c++/14.2.1/bits/regex.h \
+ /usr/include/c++/14.2.1/bits/regex.tcc \
+ /usr/include/c++/14.2.1/bits/regex_executor.h \
+ /usr/include/c++/14.2.1/bits/regex_executor.tcc \
+ /usr/include/c++/14.2.1/thread /usr/include/c++/14.2.1/stop_token \
+ /usr/include/c++/14.2.1/atomic \
+ /usr/include/c++/14.2.1/bits/atomic_base.h \
+ /usr/include/c++/14.2.1/bits/atomic_lockfree_defines.h \
+ /usr/include/c++/14.2.1/bits/atomic_wait.h \
+ /usr/include/c++/14.2.1/climits \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/limits.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/syslimits.h \
+ /usr/include/limits.h /usr/include/bits/posix1_lim.h \
+ /usr/include/bits/local_lim.h /usr/include/linux/limits.h \
+ /usr/include/bits/posix2_lim.h /usr/include/bits/xopen_lim.h \
+ /usr/include/bits/uio_lim.h /usr/include/syscall.h \
+ /usr/include/sys/syscall.h /usr/include/asm/unistd.h \
+ /usr/include/asm/unistd_64.h /usr/include/bits/syscall.h \
+ /usr/include/c++/14.2.1/bits/std_mutex.h \
+ /usr/include/c++/14.2.1/bits/std_thread.h \
+ /usr/include/c++/14.2.1/semaphore \
+ /usr/include/c++/14.2.1/bits/semaphore_base.h \
+ /usr/include/c++/14.2.1/bits/atomic_timed_wait.h \
+ /usr/include/c++/14.2.1/bits/this_thread_sleep.h /usr/include/sys/time.h \
+ /usr/include/semaphore.h /usr/include/bits/semaphore.h \
+ /usr/include/c++/14.2.1/map /usr/include/c++/14.2.1/bits/stl_multimap.h \
+ /usr/include/c++/14.2.1/algorithm \
+ /usr/include/c++/14.2.1/bits/ranges_algo.h \
+ /usr/include/c++/14.2.1/bits/ranges_algobase.h \
+ /usr/include/c++/14.2.1/pstl/glue_algorithm_defs.h \
+ /usr/include/c++/14.2.1/pstl/execution_defs.h \
+ /usr/include/c++/14.2.1/cassert /usr/include/assert.h \
+ /usr/include/c++/14.2.1/cmath /usr/include/math.h \
+ /usr/include/bits/math-vector.h /usr/include/bits/libm-simd-decl-stubs.h \
+ /usr/include/bits/flt-eval-method.h /usr/include/bits/fp-logb.h \
+ /usr/include/bits/fp-fast.h \
+ /usr/include/bits/mathcalls-helper-functions.h \
+ /usr/include/bits/mathcalls.h /usr/include/bits/mathcalls-narrow.h \
+ /usr/include/bits/iscanonical.h /usr/include/c++/14.2.1/bits/specfun.h \
+ /usr/include/c++/14.2.1/tr1/gamma.tcc \
+ /usr/include/c++/14.2.1/tr1/special_function_util.h \
+ /usr/include/c++/14.2.1/tr1/bessel_function.tcc \
+ /usr/include/c++/14.2.1/tr1/beta_function.tcc \
+ /usr/include/c++/14.2.1/tr1/ell_integral.tcc \
+ /usr/include/c++/14.2.1/tr1/exp_integral.tcc \
+ /usr/include/c++/14.2.1/tr1/hypergeometric.tcc \
+ /usr/include/c++/14.2.1/tr1/legendre_function.tcc \
+ /usr/include/c++/14.2.1/tr1/modified_bessel_func.tcc \
+ /usr/include/c++/14.2.1/tr1/poly_hermite.tcc \
+ /usr/include/c++/14.2.1/tr1/poly_laguerre.tcc \
+ /usr/include/c++/14.2.1/tr1/riemann_zeta.tcc \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/cpuid.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/x86intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/x86gprintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/ia32intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/adxintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/bmiintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/bmi2intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/cetintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/cldemoteintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/clflushoptintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/clwbintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/clzerointrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/cmpccxaddintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/enqcmdintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/fxsrintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/lzcntintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/lwpintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/movdirintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/mwaitintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/mwaitxintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/pconfigintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/popcntintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/pkuintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/prfchiintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/raointintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/rdseedintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/rtmintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/serializeintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/sgxintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/tbmintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/tsxldtrkintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/uintrintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/waitpkgintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/wbnoinvdintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/xsaveintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/xsavecintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/xsaveoptintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/xsavesintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/xtestintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/hresetintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/usermsrintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/immintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/mmintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/xmmintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/mm_malloc.h \
+ /usr/include/c++/14.2.1/stdlib.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/emmintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/pmmintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/tmmintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/smmintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/wmmintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avxintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avxvnniintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avxifmaintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avxvnniint8intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avxvnniint16intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx2intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512fintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512erintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512pfintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512cdintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vlintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512bwintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512dqintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vlbwintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vldqintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512ifmaintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512ifmavlintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vbmiintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vbmivlintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx5124fmapsintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx5124vnniwintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vpopcntdqintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vbmi2intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vbmi2vlintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vnniintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vnnivlintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vpopcntdqvlintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512bitalgintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512bitalgvlintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vp2intersectintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512vp2intersectvlintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512fp16intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512fp16vlintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/shaintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/sm3intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/sha512intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/sm4intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/fmaintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/f16cintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/gfniintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/vaesintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/vpclmulqdqintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512bf16vlintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avx512bf16intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/avxneconvertintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/amxtileintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/amxint8intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/amxbf16intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/amxcomplexintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/prfchwintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/keylockerintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/amxfp16intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/mm3dnow.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/fma4intrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/ammintrin.h \
+ /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.1/include/xopintrin.h \
+ /usr/include/sys/stat.h /usr/include/bits/stat.h \
+ /usr/include/bits/struct_stat.h /usr/include/bits/statx.h \
+ /usr/include/linux/stat.h /usr/include/linux/types.h \
+ /usr/include/asm/types.h /usr/include/asm-generic/types.h \
+ /usr/include/asm-generic/int-ll64.h /usr/include/asm/bitsperlong.h \
+ /usr/include/asm-generic/bitsperlong.h /usr/include/linux/posix_types.h \
+ /usr/include/linux/stddef.h /usr/include/asm/posix_types.h \
+ /usr/include/asm/posix_types_64.h /usr/include/asm-generic/posix_types.h \
+ /usr/include/bits/statx-generic.h \
+ /usr/include/bits/types/struct_statx_timestamp.h \
+ /usr/include/bits/types/struct_statx.h /usr/include/sys/statvfs.h \
+ /usr/include/bits/statvfs.h /usr/include/sys/ioctl.h \
+ /usr/include/bits/ioctls.h /usr/include/asm/ioctls.h \
+ /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \
+ /usr/include/asm/ioctl.h /usr/include/asm-generic/ioctl.h \
+ /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h \
+ /usr/include/sys/sysinfo.h /usr/include/linux/kernel.h \
+ /usr/include/linux/sysinfo.h /usr/include/linux/const.h \
+ /usr/include/net/if.h /usr/include/sys/socket.h \
+ /usr/include/bits/types/struct_iovec.h /usr/include/bits/socket.h \
+ /usr/include/bits/socket_type.h /usr/include/bits/sockaddr.h \
+ /usr/include/asm/socket.h /usr/include/asm-generic/socket.h \
+ /usr/include/asm/sockios.h /usr/include/asm-generic/sockios.h \
+ /usr/include/bits/types/struct_osockaddr.h /usr/include/netinet/in.h \
+ /usr/include/bits/in.h /usr/include/dirent.h /usr/include/bits/dirent.h \
+ /usr/include/bits/dirent_ext.h /usr/include/c++/14.2.1/memory \
+ /usr/include/c++/14.2.1/bits/stl_raw_storage_iter.h \
+ /usr/include/c++/14.2.1/bits/shared_ptr_atomic.h \
+ /usr/include/c++/14.2.1/backward/auto_ptr.h \
+ /usr/include/c++/14.2.1/bits/ranges_uninitialized.h \
+ /usr/include/c++/14.2.1/pstl/glue_memory_defs.h /usr/include/fcntl.h \
+ /usr/include/bits/fcntl.h /usr/include/bits/fcntl-linux.h \
+ /usr/include/linux/falloc.h
diff --git a/VMAware/build/CTestTestfile.cmake b/VMAware/build/CTestTestfile.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..0a7719a1eca7439ed7e6112adfd778cfb8285556
--- /dev/null
+++ b/VMAware/build/CTestTestfile.cmake
@@ -0,0 +1,8 @@
+# CMake generated Testfile for 
+# Source directory: /home/rickyy/Documents/incognito-vm/VMAware
+# Build directory: /home/rickyy/Documents/incognito-vm/VMAware/build
+# 
+# This file includes the relevant testing commands required for 
+# testing this directory and lists subdirectories to be tested as well.
+add_test([=[TARGET]=] "/home/rickyy/Documents/incognito-vm/VMAware/build/vmaware" "--all")
+set_tests_properties([=[TARGET]=] PROPERTIES  _BACKTRACE_TRIPLES "/home/rickyy/Documents/incognito-vm/VMAware/CMakeLists.txt;96;add_test;/home/rickyy/Documents/incognito-vm/VMAware/CMakeLists.txt;0;")
diff --git a/VMAware/build/DartConfiguration.tcl b/VMAware/build/DartConfiguration.tcl
new file mode 100644
index 0000000000000000000000000000000000000000..850c4a0d1643074be81d9696150622781a4d48bd
--- /dev/null
+++ b/VMAware/build/DartConfiguration.tcl
@@ -0,0 +1,109 @@
+# This file is configured by CMake automatically as DartConfiguration.tcl
+# If you choose not to use CMake, this file may be hand configured, by
+# filling in the required variables.
+
+
+# Configuration directories and files
+SourceDirectory: /home/rickyy/Documents/incognito-vm/VMAware
+BuildDirectory: /home/rickyy/Documents/incognito-vm/VMAware/build
+
+# Where to place the cost data store
+CostDataFile: 
+
+# Site is something like machine.domain, i.e. pragmatic.crd
+Site: arch-laptop
+
+# Build name is osname-revision-compiler, i.e. Linux-2.4.2-2smp-c++
+BuildName: Linux-c++
+
+# Subprojects
+LabelsForSubprojects: 
+
+# Submission information
+SubmitURL: http://
+SubmitInactivityTimeout: 
+
+# Dashboard start time
+NightlyStartTime: 00:00:00 EDT
+
+# Commands for the build/test/submit cycle
+ConfigureCommand: "/usr/bin/cmake" "/home/rickyy/Documents/incognito-vm/VMAware"
+MakeCommand: /usr/bin/cmake --build . --config "${CTEST_CONFIGURATION_TYPE}"
+DefaultCTestConfigurationType: Release
+
+# version control
+UpdateVersionOnly: 
+
+# CVS options
+# Default is "-d -P -A"
+CVSCommand: 
+CVSUpdateOptions: 
+
+# Subversion options
+SVNCommand: 
+SVNOptions: 
+SVNUpdateOptions: 
+
+# Git options
+GITCommand: 
+GITInitSubmodules: 
+GITUpdateOptions: 
+GITUpdateCustom: 
+
+# Perforce options
+P4Command: 
+P4Client: 
+P4Options: 
+P4UpdateOptions: 
+P4UpdateCustom: 
+
+# Generic update command
+UpdateCommand: 
+UpdateOptions: 
+UpdateType: 
+
+# Compiler info
+Compiler: /usr/bin/c++
+CompilerVersion: 14.2.1
+
+# Dynamic analysis (MemCheck)
+PurifyCommand: 
+ValgrindCommand: 
+ValgrindCommandOptions: 
+DrMemoryCommand: 
+DrMemoryCommandOptions: 
+CudaSanitizerCommand: 
+CudaSanitizerCommandOptions: 
+MemoryCheckType: 
+MemoryCheckSanitizerOptions: 
+MemoryCheckCommand: MEMORYCHECK_COMMAND-NOTFOUND
+MemoryCheckCommandOptions: 
+MemoryCheckSuppressionFile: 
+
+# Coverage
+CoverageCommand: /usr/bin/gcov
+CoverageExtraFlags: -l
+
+# Testing options
+# TimeOut is the amount of time in seconds to wait for processes
+# to complete during testing.  After TimeOut seconds, the
+# process will be summarily terminated.
+# Currently set to 25 minutes
+TimeOut: 1500
+
+# During parallel testing CTest will not start a new test if doing
+# so would cause the system load to exceed this value.
+TestLoad: 
+
+TLSVerify: 
+TLSVersion: 
+
+UseLaunchers: 
+CurlOptions: 
+# warning, if you add new options here that have to do with submit,
+# you have to update cmCTestSubmitCommand.cxx
+
+# For CTest submissions that timeout, these options
+# specify behavior for retrying the submission
+CTestSubmitRetryDelay: 5
+CTestSubmitRetryCount: 3
diff --git a/VMAware/build/Makefile b/VMAware/build/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d9401e9cad92ec9f7e3d02088d9b068fa8ed8af4
--- /dev/null
+++ b/VMAware/build/Makefile
@@ -0,0 +1,633 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 3.30
+
+# Default target executed when no arguments are given to make.
+default_target: all
+.PHONY : default_target
+
+# Allow only one "make -f Makefile2" at a time, but pass parallelism.
+.NOTPARALLEL:
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canonical targets will work.
+.SUFFIXES:
+
+# Disable VCS-based implicit rules.
+% : %,v
+
+# Disable VCS-based implicit rules.
+% : RCS/%
+
+# Disable VCS-based implicit rules.
+% : RCS/%,v
+
+# Disable VCS-based implicit rules.
+% : SCCS/s.%
+
+# Disable VCS-based implicit rules.
+% : s.%
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Command-line flag to silence nested $(MAKE).
+$(VERBOSE)MAKESILENT = -s
+
+#Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E rm -f
+
+# Escaping for special characters.
+EQUALS = =
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/rickyy/Documents/incognito-vm/VMAware
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/rickyy/Documents/incognito-vm/VMAware/build
+
+#=============================================================================
+# Targets provided globally by CMake.
+
+# Special rule for the target test
+test:
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running tests..."
+	/usr/bin/ctest --force-new-ctest-process $(ARGS)
+.PHONY : test
+
+# Special rule for the target test
+test/fast: test
+.PHONY : test/fast
+
+# Special rule for the target edit_cache
+edit_cache:
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake cache editor..."
+	/usr/bin/ccmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
+.PHONY : edit_cache
+
+# Special rule for the target edit_cache
+edit_cache/fast: edit_cache
+.PHONY : edit_cache/fast
+
+# Special rule for the target rebuild_cache
+rebuild_cache:
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake to regenerate build system..."
+	/usr/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
+.PHONY : rebuild_cache
+
+# Special rule for the target rebuild_cache
+rebuild_cache/fast: rebuild_cache
+.PHONY : rebuild_cache/fast
+
+# Special rule for the target list_install_components
+list_install_components:
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Available install components are: \"Unspecified\""
+.PHONY : list_install_components
+
+# Special rule for the target list_install_components
+list_install_components/fast: list_install_components
+.PHONY : list_install_components/fast
+
+# Special rule for the target install
+install: preinstall
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Install the project..."
+	/usr/bin/cmake -P cmake_install.cmake
+.PHONY : install
+
+# Special rule for the target install
+install/fast: preinstall/fast
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Install the project..."
+	/usr/bin/cmake -P cmake_install.cmake
+.PHONY : install/fast
+
+# Special rule for the target install/local
+install/local: preinstall
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Installing only the local directory..."
+	/usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
+.PHONY : install/local
+
+# Special rule for the target install/local
+install/local/fast: preinstall/fast
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Installing only the local directory..."
+	/usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
+.PHONY : install/local/fast
+
+# Special rule for the target install/strip
+install/strip: preinstall
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Installing the project stripped..."
+	/usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
+.PHONY : install/strip
+
+# Special rule for the target install/strip
+install/strip/fast: preinstall/fast
+	@$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Installing the project stripped..."
+	/usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
+.PHONY : install/strip/fast
+
+# The main all target
+all: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles /home/rickyy/Documents/incognito-vm/VMAware/build//CMakeFiles/progress.marks
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles 0
+.PHONY : all
+
+# The main clean target
+clean:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 clean
+.PHONY : clean
+
+# The main clean target
+clean/fast: clean
+.PHONY : clean/fast
+
+# Prepare targets for installation.
+preinstall: all
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall
+.PHONY : preinstall
+
+# Prepare targets for installation.
+preinstall/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall
+.PHONY : preinstall/fast
+
+# clear depends
+depend:
+	$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
+.PHONY : depend
+
+#=============================================================================
+# Target rules for targets named vmaware
+
+# Build rule for target.
+vmaware: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 vmaware
+.PHONY : vmaware
+
+# fast build rule for target.
+vmaware/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/vmaware.dir/build.make CMakeFiles/vmaware.dir/build
+.PHONY : vmaware/fast
+
+#=============================================================================
+# Target rules for targets named Experimental
+
+# Build rule for target.
+Experimental: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 Experimental
+.PHONY : Experimental
+
+# fast build rule for target.
+Experimental/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Experimental.dir/build.make CMakeFiles/Experimental.dir/build
+.PHONY : Experimental/fast
+
+#=============================================================================
+# Target rules for targets named Nightly
+
+# Build rule for target.
+Nightly: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 Nightly
+.PHONY : Nightly
+
+# fast build rule for target.
+Nightly/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Nightly.dir/build.make CMakeFiles/Nightly.dir/build
+.PHONY : Nightly/fast
+
+#=============================================================================
+# Target rules for targets named Continuous
+
+# Build rule for target.
+Continuous: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 Continuous
+.PHONY : Continuous
+
+# fast build rule for target.
+Continuous/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Continuous.dir/build.make CMakeFiles/Continuous.dir/build
+.PHONY : Continuous/fast
+
+#=============================================================================
+# Target rules for targets named NightlyMemoryCheck
+
+# Build rule for target.
+NightlyMemoryCheck: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 NightlyMemoryCheck
+.PHONY : NightlyMemoryCheck
+
+# fast build rule for target.
+NightlyMemoryCheck/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyMemoryCheck.dir/build.make CMakeFiles/NightlyMemoryCheck.dir/build
+.PHONY : NightlyMemoryCheck/fast
+
+#=============================================================================
+# Target rules for targets named NightlyStart
+
+# Build rule for target.
+NightlyStart: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 NightlyStart
+.PHONY : NightlyStart
+
+# fast build rule for target.
+NightlyStart/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyStart.dir/build.make CMakeFiles/NightlyStart.dir/build
+.PHONY : NightlyStart/fast
+
+#=============================================================================
+# Target rules for targets named NightlyUpdate
+
+# Build rule for target.
+NightlyUpdate: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 NightlyUpdate
+.PHONY : NightlyUpdate
+
+# fast build rule for target.
+NightlyUpdate/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyUpdate.dir/build.make CMakeFiles/NightlyUpdate.dir/build
+.PHONY : NightlyUpdate/fast
+
+#=============================================================================
+# Target rules for targets named NightlyConfigure
+
+# Build rule for target.
+NightlyConfigure: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 NightlyConfigure
+.PHONY : NightlyConfigure
+
+# fast build rule for target.
+NightlyConfigure/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyConfigure.dir/build.make CMakeFiles/NightlyConfigure.dir/build
+.PHONY : NightlyConfigure/fast
+
+#=============================================================================
+# Target rules for targets named NightlyBuild
+
+# Build rule for target.
+NightlyBuild: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 NightlyBuild
+.PHONY : NightlyBuild
+
+# fast build rule for target.
+NightlyBuild/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyBuild.dir/build.make CMakeFiles/NightlyBuild.dir/build
+.PHONY : NightlyBuild/fast
+
+#=============================================================================
+# Target rules for targets named NightlyTest
+
+# Build rule for target.
+NightlyTest: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 NightlyTest
+.PHONY : NightlyTest
+
+# fast build rule for target.
+NightlyTest/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyTest.dir/build.make CMakeFiles/NightlyTest.dir/build
+.PHONY : NightlyTest/fast
+
+#=============================================================================
+# Target rules for targets named NightlyCoverage
+
+# Build rule for target.
+NightlyCoverage: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 NightlyCoverage
+.PHONY : NightlyCoverage
+
+# fast build rule for target.
+NightlyCoverage/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyCoverage.dir/build.make CMakeFiles/NightlyCoverage.dir/build
+.PHONY : NightlyCoverage/fast
+
+#=============================================================================
+# Target rules for targets named NightlyMemCheck
+
+# Build rule for target.
+NightlyMemCheck: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 NightlyMemCheck
+.PHONY : NightlyMemCheck
+
+# fast build rule for target.
+NightlyMemCheck/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlyMemCheck.dir/build.make CMakeFiles/NightlyMemCheck.dir/build
+.PHONY : NightlyMemCheck/fast
+
+#=============================================================================
+# Target rules for targets named NightlySubmit
+
+# Build rule for target.
+NightlySubmit: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 NightlySubmit
+.PHONY : NightlySubmit
+
+# fast build rule for target.
+NightlySubmit/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/NightlySubmit.dir/build.make CMakeFiles/NightlySubmit.dir/build
+.PHONY : NightlySubmit/fast
+
+#=============================================================================
+# Target rules for targets named ExperimentalStart
+
+# Build rule for target.
+ExperimentalStart: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ExperimentalStart
+.PHONY : ExperimentalStart
+
+# fast build rule for target.
+ExperimentalStart/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalStart.dir/build.make CMakeFiles/ExperimentalStart.dir/build
+.PHONY : ExperimentalStart/fast
+
+#=============================================================================
+# Target rules for targets named ExperimentalUpdate
+
+# Build rule for target.
+ExperimentalUpdate: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ExperimentalUpdate
+.PHONY : ExperimentalUpdate
+
+# fast build rule for target.
+ExperimentalUpdate/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalUpdate.dir/build.make CMakeFiles/ExperimentalUpdate.dir/build
+.PHONY : ExperimentalUpdate/fast
+
+#=============================================================================
+# Target rules for targets named ExperimentalConfigure
+
+# Build rule for target.
+ExperimentalConfigure: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ExperimentalConfigure
+.PHONY : ExperimentalConfigure
+
+# fast build rule for target.
+ExperimentalConfigure/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalConfigure.dir/build.make CMakeFiles/ExperimentalConfigure.dir/build
+.PHONY : ExperimentalConfigure/fast
+
+#=============================================================================
+# Target rules for targets named ExperimentalBuild
+
+# Build rule for target.
+ExperimentalBuild: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ExperimentalBuild
+.PHONY : ExperimentalBuild
+
+# fast build rule for target.
+ExperimentalBuild/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalBuild.dir/build.make CMakeFiles/ExperimentalBuild.dir/build
+.PHONY : ExperimentalBuild/fast
+
+#=============================================================================
+# Target rules for targets named ExperimentalTest
+
+# Build rule for target.
+ExperimentalTest: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ExperimentalTest
+.PHONY : ExperimentalTest
+
+# fast build rule for target.
+ExperimentalTest/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalTest.dir/build.make CMakeFiles/ExperimentalTest.dir/build
+.PHONY : ExperimentalTest/fast
+
+#=============================================================================
+# Target rules for targets named ExperimentalCoverage
+
+# Build rule for target.
+ExperimentalCoverage: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ExperimentalCoverage
+.PHONY : ExperimentalCoverage
+
+# fast build rule for target.
+ExperimentalCoverage/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalCoverage.dir/build.make CMakeFiles/ExperimentalCoverage.dir/build
+.PHONY : ExperimentalCoverage/fast
+
+#=============================================================================
+# Target rules for targets named ExperimentalMemCheck
+
+# Build rule for target.
+ExperimentalMemCheck: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ExperimentalMemCheck
+.PHONY : ExperimentalMemCheck
+
+# fast build rule for target.
+ExperimentalMemCheck/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalMemCheck.dir/build.make CMakeFiles/ExperimentalMemCheck.dir/build
+.PHONY : ExperimentalMemCheck/fast
+
+#=============================================================================
+# Target rules for targets named ExperimentalSubmit
+
+# Build rule for target.
+ExperimentalSubmit: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ExperimentalSubmit
+.PHONY : ExperimentalSubmit
+
+# fast build rule for target.
+ExperimentalSubmit/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ExperimentalSubmit.dir/build.make CMakeFiles/ExperimentalSubmit.dir/build
+.PHONY : ExperimentalSubmit/fast
+
+#=============================================================================
+# Target rules for targets named ContinuousStart
+
+# Build rule for target.
+ContinuousStart: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ContinuousStart
+.PHONY : ContinuousStart
+
+# fast build rule for target.
+ContinuousStart/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousStart.dir/build.make CMakeFiles/ContinuousStart.dir/build
+.PHONY : ContinuousStart/fast
+
+#=============================================================================
+# Target rules for targets named ContinuousUpdate
+
+# Build rule for target.
+ContinuousUpdate: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ContinuousUpdate
+.PHONY : ContinuousUpdate
+
+# fast build rule for target.
+ContinuousUpdate/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousUpdate.dir/build.make CMakeFiles/ContinuousUpdate.dir/build
+.PHONY : ContinuousUpdate/fast
+
+#=============================================================================
+# Target rules for targets named ContinuousConfigure
+
+# Build rule for target.
+ContinuousConfigure: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ContinuousConfigure
+.PHONY : ContinuousConfigure
+
+# fast build rule for target.
+ContinuousConfigure/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousConfigure.dir/build.make CMakeFiles/ContinuousConfigure.dir/build
+.PHONY : ContinuousConfigure/fast
+
+#=============================================================================
+# Target rules for targets named ContinuousBuild
+
+# Build rule for target.
+ContinuousBuild: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ContinuousBuild
+.PHONY : ContinuousBuild
+
+# fast build rule for target.
+ContinuousBuild/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousBuild.dir/build.make CMakeFiles/ContinuousBuild.dir/build
+.PHONY : ContinuousBuild/fast
+
+#=============================================================================
+# Target rules for targets named ContinuousTest
+
+# Build rule for target.
+ContinuousTest: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ContinuousTest
+.PHONY : ContinuousTest
+
+# fast build rule for target.
+ContinuousTest/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousTest.dir/build.make CMakeFiles/ContinuousTest.dir/build
+.PHONY : ContinuousTest/fast
+
+#=============================================================================
+# Target rules for targets named ContinuousCoverage
+
+# Build rule for target.
+ContinuousCoverage: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ContinuousCoverage
+.PHONY : ContinuousCoverage
+
+# fast build rule for target.
+ContinuousCoverage/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousCoverage.dir/build.make CMakeFiles/ContinuousCoverage.dir/build
+.PHONY : ContinuousCoverage/fast
+
+#=============================================================================
+# Target rules for targets named ContinuousMemCheck
+
+# Build rule for target.
+ContinuousMemCheck: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ContinuousMemCheck
+.PHONY : ContinuousMemCheck
+
+# fast build rule for target.
+ContinuousMemCheck/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousMemCheck.dir/build.make CMakeFiles/ContinuousMemCheck.dir/build
+.PHONY : ContinuousMemCheck/fast
+
+#=============================================================================
+# Target rules for targets named ContinuousSubmit
+
+# Build rule for target.
+ContinuousSubmit: cmake_check_build_system
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ContinuousSubmit
+.PHONY : ContinuousSubmit
+
+# fast build rule for target.
+ContinuousSubmit/fast:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/ContinuousSubmit.dir/build.make CMakeFiles/ContinuousSubmit.dir/build
+.PHONY : ContinuousSubmit/fast
+
+src/cli.o: src/cli.cpp.o
+.PHONY : src/cli.o
+
+# target to build an object file
+src/cli.cpp.o:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/vmaware.dir/build.make CMakeFiles/vmaware.dir/src/cli.cpp.o
+.PHONY : src/cli.cpp.o
+
+src/cli.i: src/cli.cpp.i
+.PHONY : src/cli.i
+
+# target to preprocess a source file
+src/cli.cpp.i:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/vmaware.dir/build.make CMakeFiles/vmaware.dir/src/cli.cpp.i
+.PHONY : src/cli.cpp.i
+
+src/cli.s: src/cli.cpp.s
+.PHONY : src/cli.s
+
+# target to generate assembly for a file
+src/cli.cpp.s:
+	$(MAKE) $(MAKESILENT) -f CMakeFiles/vmaware.dir/build.make CMakeFiles/vmaware.dir/src/cli.cpp.s
+.PHONY : src/cli.cpp.s
+
+# Help Target
+help:
+	@echo "The following are some of the valid targets for this Makefile:"
+	@echo "... all (the default if no target is provided)"
+	@echo "... clean"
+	@echo "... depend"
+	@echo "... edit_cache"
+	@echo "... install"
+	@echo "... install/local"
+	@echo "... install/strip"
+	@echo "... list_install_components"
+	@echo "... rebuild_cache"
+	@echo "... test"
+	@echo "... Continuous"
+	@echo "... ContinuousBuild"
+	@echo "... ContinuousConfigure"
+	@echo "... ContinuousCoverage"
+	@echo "... ContinuousMemCheck"
+	@echo "... ContinuousStart"
+	@echo "... ContinuousSubmit"
+	@echo "... ContinuousTest"
+	@echo "... ContinuousUpdate"
+	@echo "... Experimental"
+	@echo "... ExperimentalBuild"
+	@echo "... ExperimentalConfigure"
+	@echo "... ExperimentalCoverage"
+	@echo "... ExperimentalMemCheck"
+	@echo "... ExperimentalStart"
+	@echo "... ExperimentalSubmit"
+	@echo "... ExperimentalTest"
+	@echo "... ExperimentalUpdate"
+	@echo "... Nightly"
+	@echo "... NightlyBuild"
+	@echo "... NightlyConfigure"
+	@echo "... NightlyCoverage"
+	@echo "... NightlyMemCheck"
+	@echo "... NightlyMemoryCheck"
+	@echo "... NightlyStart"
+	@echo "... NightlySubmit"
+	@echo "... NightlyTest"
+	@echo "... NightlyUpdate"
+	@echo "... vmaware"
+	@echo "... src/cli.o"
+	@echo "... src/cli.i"
+	@echo "... src/cli.s"
+.PHONY : help
+
+
+
+#=============================================================================
+# Special targets to cleanup operation of make.
+
+# Special rule to run CMake to check the build system integrity.
+# No rule that depends on this can have commands that come from listfiles
+# because they might be regenerated.
+cmake_check_build_system:
+	$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
+.PHONY : cmake_check_build_system
+
diff --git a/VMAware/build/cmake_install.cmake b/VMAware/build/cmake_install.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..5bc4a77734df5567452d99f2731ed49f2636fcee
--- /dev/null
+++ b/VMAware/build/cmake_install.cmake
@@ -0,0 +1,102 @@
+# Install script for directory: /home/rickyy/Documents/incognito-vm/VMAware
+
+# Set the install prefix
+if(NOT DEFINED CMAKE_INSTALL_PREFIX)
+  set(CMAKE_INSTALL_PREFIX "/usr/local")
+endif()
+string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
+
+# Set the install configuration name.
+if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
+  if(BUILD_TYPE)
+    string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
+           CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
+  else()
+    set(CMAKE_INSTALL_CONFIG_NAME "Release")
+  endif()
+  message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
+endif()
+
+# Set the component getting installed.
+if(NOT CMAKE_INSTALL_COMPONENT)
+  if(COMPONENT)
+    message(STATUS "Install component: \"${COMPONENT}\"")
+    set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
+  else()
+    set(CMAKE_INSTALL_COMPONENT)
+  endif()
+endif()
+
+# Install shared libraries without execute permission?
+if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
+  set(CMAKE_INSTALL_SO_NO_EXE "0")
+endif()
+
+# Is this installation the result of a crosscompile?
+if(NOT DEFINED CMAKE_CROSSCOMPILING)
+  set(CMAKE_CROSSCOMPILING "FALSE")
+endif()
+
+# Set path to fallback-tool for dependency-resolution.
+if(NOT DEFINED CMAKE_OBJDUMP)
+  set(CMAKE_OBJDUMP "/usr/bin/objdump")
+endif()
+
+if(CMAKE_INSTALL_COMPONENT STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT)
+  if(EXISTS "$ENV{DESTDIR}/usr/local/bin/vmaware" AND
+     NOT IS_SYMLINK "$ENV{DESTDIR}/usr/local/bin/vmaware")
+    file(RPATH_CHECK
+         FILE "$ENV{DESTDIR}/usr/local/bin/vmaware"
+         RPATH "")
+  endif()
+  list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES
+   "/usr/local/bin/vmaware")
+  if(CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)
+    message(WARNING "ABSOLUTE path INSTALL DESTINATION : ${CMAKE_ABSOLUTE_DESTINATION_FILES}")
+  endif()
+  if(CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)
+    message(FATAL_ERROR "ABSOLUTE path INSTALL DESTINATION forbidden (by caller): ${CMAKE_ABSOLUTE_DESTINATION_FILES}")
+  endif()
+  file(INSTALL DESTINATION "/usr/local/bin" TYPE EXECUTABLE FILES "/home/rickyy/Documents/incognito-vm/VMAware/build/vmaware")
+  if(EXISTS "$ENV{DESTDIR}/usr/local/bin/vmaware" AND
+     NOT IS_SYMLINK "$ENV{DESTDIR}/usr/local/bin/vmaware")
+    if(CMAKE_INSTALL_DO_STRIP)
+      execute_process(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}/usr/local/bin/vmaware")
+    endif()
+  endif()
+endif()
+
+if(CMAKE_INSTALL_COMPONENT STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT)
+  include("/home/rickyy/Documents/incognito-vm/VMAware/build/CMakeFiles/vmaware.dir/install-cxx-module-bmi-Release.cmake" OPTIONAL)
+endif()
+
+if(CMAKE_INSTALL_COMPONENT STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT)
+  list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES
+   "/usr/include/vmaware.hpp")
+  if(CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)
+    message(WARNING "ABSOLUTE path INSTALL DESTINATION : ${CMAKE_ABSOLUTE_DESTINATION_FILES}")
+  endif()
+  if(CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)
+    message(FATAL_ERROR "ABSOLUTE path INSTALL DESTINATION forbidden (by caller): ${CMAKE_ABSOLUTE_DESTINATION_FILES}")
+  endif()
+  file(INSTALL DESTINATION "/usr/include" TYPE FILE FILES "/home/rickyy/Documents/incognito-vm/VMAware/src/vmaware.hpp")
+endif()
+
+if(CMAKE_INSTALL_COMPONENT)
+  if(CMAKE_INSTALL_COMPONENT MATCHES "^[a-zA-Z0-9_.+-]+$")
+    set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
+  else()
+    string(MD5 CMAKE_INST_COMP_HASH "${CMAKE_INSTALL_COMPONENT}")
+    set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INST_COMP_HASH}.txt")
+    unset(CMAKE_INST_COMP_HASH)
+  endif()
+else()
+  set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
+endif()
+
+if(NOT CMAKE_INSTALL_LOCAL_ONLY)
+  string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
+       "${CMAKE_INSTALL_MANIFEST_FILES}")
+  file(WRITE "/home/rickyy/Documents/incognito-vm/VMAware/build/${CMAKE_INSTALL_MANIFEST}"
+     "${CMAKE_INSTALL_MANIFEST_CONTENT}")
+endif()
diff --git a/VMAware/build/vmaware b/VMAware/build/vmaware
new file mode 100755
index 0000000000000000000000000000000000000000..e67eca042a96e7670b54b99995bf92d1049dac76
Binary files /dev/null and b/VMAware/build/vmaware differ
diff --git a/VMAware/docs/documentation.md b/VMAware/docs/documentation.md
new file mode 100644
index 0000000000000000000000000000000000000000..545d7b4b1d97789bc3845af7e06425036587ffae
--- /dev/null
+++ b/VMAware/docs/documentation.md
@@ -0,0 +1,558 @@
+# Documentation
+
+## Contents
+- [`VM::detect()`](#vmdetect)
+- [`VM::percentage()`](#vmpercentage)
+- [`VM::brand()`](#vmbrand)
+- [`VM::check()`](#vmcheck)
+- [`VM::add_custom()`](#vmaddcustom)
+- [`VM::type()`](#vmtype)
+- [`VM::conclusion()`](#vmconclusion)
+- [`VM::detected_count()`](#vmdetected_count)
+- [`VM::vmaware struct`](#vmaware-struct)
+- [Flag table](#flag-table)
+- [Non-technique flags](#non-technique-flags)
+- [Variables](#variables)
+- [CLI arguments](#cli-documentation)
+
+
+<br>
+
+## `VM::detect()`
+
+This is basically the main function you're looking for, which returns a bool. If the parameter is set to nothing, all the recommended checks will be performed. But you can optionally set what techniques are used.
+
+```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 library.
+     */ 
+    bool is_vm = VM::detect();
+
+
+    /**
+     * This does the exact same as above, but as an explicit alternative.
+     */ 
+    bool is_vm2 = VM::detect(VM::DEFAULT);
+
+
+    /**
+     * 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_vm3 = VM::detect(VM::CPU_BRAND, VM::MAC, VM::HYPERVISOR_BIT);
+
+
+    /**
+     * There are roughly 1/3 of all techniques that are considered to be "spoofable",
+     * meaning that anybody can potentially cause a false positive by exploiting the
+     * fact that the spoofable techniques checks for things that anybody can modify
+     * (file data, registry, directories, etc...). This category of techniques are disabled 
+     * by default, but they can be enabled with the VM::SPOOFABLE flag.
+     */
+    bool is_vm4 = VM::detect(VM::SPOOFABLE);
+
+
+    /**
+     * 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_vm5 = 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_vm6 = 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_vm7 = VM::detect(VM::HIGH_THRESHOLD);
+
+
+    /**
+     * 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_vm8 = VM::detect(VM::DISABLE(VM::RDTSC));
+
+
+    /**
+     * Same as above, but you can disable multiple techniques at the same time.
+     */ 
+    bool is_vm9 = 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_vm10 = VM::detect(VM::DEFAULT, VM::NO_MEMO, VM::HIGH_THRESHOLD, VM::DISABLE(VM::RDTSC, VM::VMID));
+
+}
+```
+
+<br>
+
+## `VM::percentage()`
+This will return a `std::uint8_t` between 0 and 100. It'll return the certainty of whether it has detected a VM based on all the techniques available as a percentage. The lower the value, the less chance it's a VM. The higher the value, the more likely it is. 
+
+```cpp
+#include "vmaware.hpp"
+#include <iostream>
+#include <cstdint>
+
+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<std::uint32_t>(percent) << "%\n"; 
+}
+```
+
+> [!NOTE]
+> you can use the same flag system as shown with `VM::detect()` for this function.
+
+<br>
+
+## `VM::brand()`
+This will essentially return the VM brand as a `std::string`. The exact possible brand string return values are: 
+- `VirtualBox`
+- `VMware`
+- `VMware Express`
+- `VMware ESX`
+- `VMware GSX`
+- `VMware Workstation`
+- `VMware Fusion`
+- `bhyve`
+- `QEMU`
+- `KVM`
+- `QEMU+KVM`
+- `KVM Hyper-V Enlightenment`
+- `QEMU+KVM Hyper-V Enlightenment`
+- `Virtual PC`
+- `Microsoft Hyper-V`
+- `Microsoft Virtual PC/Hyper-V`
+- `Microsoft x86-to-ARM`
+- `Parallels`
+- `Xen HVM`
+- `ACRN`
+- `QNX hypervisor`
+- `Hybrid Analysis`
+- `Sandboxie`
+- `Docker`
+- `Wine`
+- `Virtual Apple`
+- `Anubis`
+- `JoeBox`
+- `ThreatExpert`
+- `CWSandbox`
+- `Comodo`
+- `Bochs`
+- `Lockheed Martin LMHS`   (yes, you read that right. The library can detect VMs running on US military fighter jets)
+- `NVMM`
+- `OpenBSD VMM`
+- `Intel HAXM`
+- `Unisys s-Par`
+- `Cuckoo`
+- `BlueStacks`
+- `Jailhouse`
+- `Apple VZ`
+- `Intel KGT (Trusty)`
+- `Microsoft Azure Hyper-V`
+- `Xbox NanoVisor (Hyper-V)`
+- `SimpleVisor`
+- `Hyper-V artifact (not an actual VM)`
+- `User-mode Linux`
+- `IBM PowerVM`
+- `Google Compute Engine (KVM)`
+- `OpenStack (KVM)`
+- `KubeVirt (KVM)`
+- `AWS Nitro System (KVM-based)`
+- `Podman`
+- `WSL`
+- `OpenVZ`
+- `ANY.RUN`
+
+If none were detected, it will return `Unknown`. It's often NOT going to produce a satisfying result due to technical difficulties with accomplishing this, on top of being highly dependent on what mechanisms detected a VM. This is especially true for VMware sub-versions (ESX, GSX, Fusion, etc...) Don't rely on this function for critical operations as if it's your golden bullet. It's arguably unreliable and it'll most likely return `Unknown` (assuming it is actually running under a VM).
+
+```cpp
+#include "vmaware.hpp"
+#include <string>
+
+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
+    }
+}
+```
+
+
+On rare occasions, there might be cases where there's multiple brands that have been detected, which might cause a conflicting output with an inaccurate result. To prevent this, you can use the `VM::MULTIPLE` flag that returns a **message** rather than a **VM brand string**. For example, if it found 2 conflicting brands, it will return `VMware or VirtualBox`. For 3 conflicts, it's `VMware or VirtualBox or QEMU` and so on.
+
+
+```cpp
+#include "vmaware.hpp"
+#include <string>
+
+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
+}
+```
+
+> [!NOTE]
+> you can use the same flag system as shown with `VM::detect()` for `VM::brand()`
+
+> [!IMPORTANT]
+> `VM::MULTIPLE` has no effect for any other function other than `VM::brand()`
+
+
+<br>
+
+## `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 weights or anything extra. It very simply just gives you what the technique has found on its own. For example:
+
+```cpp
+#include "vmaware.hpp"
+#include <iostream>
+
+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";
+    }
+}
+```
+
+<br>
+
+## `VM::add_custom()`
+This function allows you to add your own custom VM detection techniques to the scoring system. The first parameter is the percentage score (0 to 100) of how likely it's a VM if your custom code returns `true`, and the second parameter should either be a lambda, a function pointer, or a `std::function<bool()>`
+
+```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<bool()> new_technique = []() -> bool {
+    // add your VM detection code here
+    return true;
+};
+
+VM::add_custom(50, new_technique);
+```
+
+<br>
+
+## `VM::type()`
+This will return the VM type as a `std::string` based on the brand found. The possible return values can be:
+- `Hypervisor (type 1)`
+- `Hypervisor (type 2)`
+- `Sandbox`
+- `Emulator`
+- `Emulator/Hypervisor (type 2)`
+- `Partitioning Hypervisor`
+- `Container`
+- `Hypervisor (either type 1 or 2)`
+- `Hypervisor (unknown type)`
+- `Compatibility layer`
+- `Paravirtualised/Hypervisor (type 2)`
+- `Hybrid Hyper-V (type 1 and 2)`
+- `Binary Translation Layer/Emulator`
+- `Unknown`
+
+<br>
+
+## `VM::conclusion()`
+This will return the "conclusion" message of what the overall result is as a `std::string`. The `[brand]` part might contain a brand or may as well be empty, depending on whether a brand has been found.
+- `Running in baremetal`
+- `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`
+
+<br>
+
+## `VM::detected_count()`
+This will fetch the number of techniques that have been detected as a `std::uint8_t`. Can't get any more simpler than that ¯\_(ツ)_/¯
+
+<br>
+
+# vmaware struct
+If you prefer having an object to store all the relevant information about the program's environment instead of calling static member functions, you can use the `VM::vmaware` struct:
+
+```cpp
+struct vmaware {
+    std::string brand;
+    std::string type;
+    std::string conclusion;
+    bool is_vm;
+    std::uint8_t percentage;
+    std::uint8_t detected_count;
+    std::uint8_t technique_count;
+}; 
+```
+
+example:
+```cpp
+#include "vmaware.hpp"
+#include <iostream>
+
+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 overview in a human-readable message?" << vm.conclusion << "\n";
+}
+```
+
+> [!NOTE]
+> the flag system is compatible for the struct constructor.
+
+
+<br>
+
+
+# Flag table
+VMAware provides a convenient way to not only check for VMs, but also have the flexibility and freedom for the end-user to choose what techniques are used with complete control over what gets executed or not. This is handled with a flag system.
+
+
+| Flag alias | Description | Cross-platform? (empty = yes) | Certainty | Admin? | GPL-3.0? | 32-bit only? | Spoofable? | Notes |
+| ---------- | ----------- | ----------------------------- | --------- | ------ | -------- | ------------ | ---------- | ----- |
+| `VM::VMID` | Check CPUID output of manufacturer ID for known VMs/hypervisors at leaf 0 |  | 100% |  |  |  |  |  |
+| `VM::CPU_BRAND` | Check if CPU brand model contains any VM-specific string snippets |  | 50% |  |  |  |  |  |
+| `VM::HYPERVISOR_BIT` | Check if hypervisor feature bit in CPUID eax bit 31 is enabled (always false for physical CPUs) |  | 100% |  |  |  |  |  |
+| `VM::HYPERVISOR_STR` | Check for hypervisor brand string length (would be around 2 characters in a host machine) |  | 45% |  |  |  |  |  |
+| `VM::RDTSC` | Benchmark RDTSC and evaluate its speed, usually it's very slow in VMs | Linux and Windows | 10% |  |  |  |  | Disabled by default |
+| `VM::THREADCOUNT` | Check if there are only 1 or 2 threads, which is a common pattern in VMs with default settings (nowadays physical CPUs should have at least 4 threads for modern CPUs) |  | 35% |  |  |  |  |  |
+| `VM::MAC` | Check if mac address starts with certain VM designated values | Linux and Windows | 60% |  |  |  | Spoofable |  |
+| `VM::TEMPERATURE` | Check if thermal directory in linux is present, might not be present in VMs | Linux | 15% |    |  |  |  |
+| `VM::SYSTEMD` | Check result from systemd-detect-virt tool | Linux | 70% |  |  |  |  |  |
+| `VM::CVENDOR` | Check if the chassis vendor is a VM vendor | Linux | 65% |  |  |  |  |  |
+| `VM::CTYPE` | Check if the chassis type is valid (it's very often invalid in VMs) | Linux | 10% |  |  |  |  |  |
+| `VM::DOCKERENV` | Check if /.dockerenv or /.dockerinit file is present | Linux | 80% |  |  |  | Spoofable |  |
+| `VM::DMIDECODE` | Check if dmidecode output matches a VM brand | Linux | 55% | Admin |  |  |  |  |
+| `VM::DMESG` | Check if dmesg output matches a VM brand | Linux | 55% | Admin |  |  |  |  |
+| `VM::HWMON` | Check if /sys/class/hwmon/ directory is present. If not, likely a VM | Linux | 75% |  |  |  | Spoofable |  |
+| `VM::SIDT5` | Check if the 5th byte after sidt is null | Linux | 45% |  |  |  |  |  |
+| `VM::CURSOR` |  Check if cursor isn't active for 5 seconds (sign of automated VM environment) | Windows | 5% |  |  |  | Spoofable | Disabled by default |
+| `VM::VMWARE_REG` | Check for VBox RdrDN | Windows | 65% |  |  |  | Spoofable |  |
+| `VM::VBOX_REG` | Look for any VirtualBox-specific registry data | Windows | 65% |  |  |  | Spoofable |  |
+| `VM::USER` | checks for default usernames, often a sign of a VM | Windows | 35% |  |  |  | Spoofable |  |
+| `VM::DLL` | Check for VM-specific DLLs | Windows | 50% |  |  |  | Spoofable |  |
+| `VM::REGISTRY` |  Check for VM-specific registry values | Windows | 75% |  |  |  | Spoofable |  |
+| `VM::CWSANDBOX_VM` | Check if CWSandbox-specific file exists | Windows | 10% |  |  |  | Spoofable |  |
+| `VM::VM_FILES` | Find for VMware and VBox specific files | Windows | 10% |  |  |  | Spoofable |  |
+| `VM::HWMODEL` | Check if the sysctl for the hwmodel does not contain the "Mac" string | MacOS | 75% |  |  |  | Spoofable |  |
+| `VM::DISK_SIZE` | Check if disk size is under or equal to 50GB | Linux | 60% |  |  |  |  |  |
+| `VM::VBOX_DEFAULT` | Check for default RAM and DISK sizes set by VirtualBox | Linux and Windows | 55% | Admin |  |  |  |  |
+| `VM::VBOX_NETWORK` | Check for VirtualBox network provider string | Windows | 70% |  |  |   |  |  |
+| `VM::COMPUTER_NAME` | Check if the computer name (not username to be clear) is VM-specific | Windows | 40% |  | GPL |  | Spoofable |  |
+| `VM::WINE_CHECK` | Check wine_get_unix_file_name file for Wine | Windows | 85% |  | GPL |  |  |  |
+| `VM::HOSTNAME` | Check if hostname is specific | Windows | 25% |  | GPL |  | Spoofable |  |
+| `VM::MEMORY` | Check if memory space is far too low for a physical machine | Windows | 35% |  | GPL |  |  |  |
+| `VM::VBOX_WINDOW_CLASS` | Check for the window class for VirtualBox | Windows | 10% |  | GPL |  |  |  |
+| `VM::LOADED_DLLS` | Check for loaded DLLs in the process | Windows | 75% |  | GPL |  | Spoofable |  |
+| `VM::KVM_REG` | Check for KVM-specific registry strings | Windows | 75% |  | GPL |  | Spoofable |  |
+| `VM::KVM_DRIVERS` | Check for KVM-specific .sys files in system driver directory | Windows | 55% |  | GPL |  | Spoofable |  |
+| `VM::KVM_DIRS` | Check for KVM directory "Virtio-Win" | Windows | 55% |  | GPL |  | Spoofable |  |
+| `VM::AUDIO` | Check if audio device is present | Windows | 35% |  | GPL |  |  |  |
+| `VM::QEMU_DIR` | Check for QEMU-specific blacklisted directories | Windows | 45% |  | GPL |  | Spoofable |  |
+| `VM::MOUSE_DEVICE` | Check for the presence of a mouse device | Windows | 20% |  | GPL |  | Spoofable |  |
+| `VM::VM_PROCESSES` | Check for any VM processes that are active | Windows | 30% |  |  |  | Spoofable |  |
+| `VM::LINUX_USER_HOST` | Check for default VM username and hostname for linux | Linux | 25% |  |  |  | Spoofable |  |
+| `VM::GAMARUE` | Check for Gamarue ransomware technique which compares VM-specific Window product IDs | Windows | 40% |  |  |  | Spoofable |  |
+| `VM::VMID_0X4` | Check if the CPU manufacturer ID matches that of a VM brand with leaf 0x40000000 |  | 100% |  |  |  |  |  |
+| `VM::PARALLELS_VM` | Check for any indication of Parallels VM through BIOS data | Windows | 50% |  |  |  |  |  |
+| `VM::RDTSC_VMEXIT` | check through alternative RDTSC technique with VMEXIT |  | 25% |  |  |  |  | Disabled by default |
+| `VM::QEMU_BRAND` | Match for QEMU CPU brands with "QEMU Virtual CPU" string |  | 100% |  |  |  |  |  |
+| `VM::BOCHS_CPU` | Check for various Bochs-related emulation oversights through CPU checks |  | 95% |  |  |  |  |  |
+| `VM::VPC_BOARD` | Check through the motherboard and match for VirtualPC-specific string | Windows | 20% |  |  |  |  |  |
+| `VM::HYPERV_WMI` | Check WMI query for "Hyper-V RAW" string | Windows | 80% |  |  |  |  |  |
+| `VM::HYPERV_REG` | Check presence for Hyper-V specific string in registry | Windows | 80% |  |  |  | Spoofable |  |
+| `VM::BIOS_SERIAL` | Check if the BIOS serial is valid (null = VM) | Windows | 60% |  |  |  |  |  |
+| `VM::VBOX_FOLDERS` | Check for VirtualBox-specific string for shared folder ID | Windows | 45% |  |  |  |  |  |
+| `VM::MSSMBIOS` | Check MSSMBIOS registry for VM-specific strings | Windows | 75% |  |  |  |  |  |
+| `VM::MAC_MEMSIZE` | Check if memory is too low for MacOS system | MacOS | 30% |  |  |  | Spoofable |  |
+| `VM::MAC_IOKIT` | Check MacOS' IO kit registry for VM-specific strings | MacOS | 80% |  |  |  | Spoofable |  |
+| `VM::IOREG_GREP` | Check for VM-strings in ioreg commands for MacOS | MacOS | 75% |  |  |  | Spoofable |  |
+| `VM::MAC_SIP` | Check if System Integrity Protection is disabled (likely a VM if it is) | MacOS | 85% |  |  |  | Spoofable |  |
+| `VM::HKLM_REGISTRIES` | Check HKLM registries for specific VM strings | Windows | 70% |  |  |  | Spoofable |  |
+| `VM::QEMU_GA` | Check for "qemu-ga" process | Linux | 20% |  |  |  | Spoofable |  |
+| `VM::VALID_MSR` | check for valid MSR value 0x40000000 | Windows | 35% |  |  |  |  |  |
+| `VM::QEMU_PROC` | Check for QEMU processes | Windows | 30% |  |  |  | Spoofable |  |
+| `VM::VPC_PROC` | Check for VPC processes | Windows | 30% |  |  |  | Spoofable |  |
+| `VM::VPC_INVALID` | Check for official VPC method | Windows | 75% |  |  | 32-bit |  |  |
+| `VM::SIDT` | Check for sidt instruction method | Linux, Windows | 30% |  |  |  |  |  |
+| `VM::SGDT` | Check for sgdt instruction method | Windows | 30% |  |  | 32-bit |  |  |
+| `VM::SLDT` | Check for sldt instruction method | Windows | 15% |  |  | 32-bit |  |  |
+| `VM::OFFSEC_SIDT` | Check for Offensive Security SIDT method | Windows | 60% |  |  | 32-bit |  |  |
+| `VM::OFFSEC_SGDT` | Check for Offensive Security SGDT method | Windows | 60% |  |  | 32-bit |  |  |
+| `VM::OFFSEC_SLDT` | Check for Offensive Security SLDT method | Windows | 20% |  |  | 32-bit |  |  |
+| `VM::HYPERV_BOARD` | Check for Hyper-V specific string in motherboard | Windows | 45% |  |  |  |  |  |
+| `VM::VM_FILES_EXTRA` | Check for VPC and Parallels files | Windows | 70% |  |  |  | Spoofable |  |
+| `VM::VPC_SIDT` | Check for sidt method with VPC's 0xE8XXXXXX range | Windows | 15% |  |  | 32-bit |  |  |
+| `VM::VMWARE_IOMEM` | Check for VMware string in /proc/iomem | Linux | 65% |  |  |  |  |  |
+| `VM::VMWARE_IOPORTS` | Check for VMware string in /proc/ioports | Linux | 70% |  |  |  |  |  |
+| `VM::VMWARE_SCSI` | Check for VMware string in /proc/scsi/scsi | Linux | 40% |  |  |  |  |  |
+| `VM::VMWARE_DMESG` | Check for VMware-specific device name in dmesg output | Linux | 65% | Admin |  |  |  | Disabled by default |
+| `VM::VMWARE_STR` | Check str assembly instruction method for VMware | Windows | 35% |  |  |  |  |  |
+| `VM::VMWARE_BACKDOOR` | Check for official VMware io port backdoor technique | Windows | 100% |  |  | 32-bit |  |  |
+| `VM::VMWARE_PORT_MEM` | Check for VMware memory using IO port backdoor | Windows | 85% |  |  | 32-bit |  |  |
+| `VM::SMSW` | Check for SMSW assembly instruction technique | Windows | 30% |  |  | 32-bit |  |  |
+| `VM::MUTEX` | Check for mutex strings of VM brands | Windows | 85% |  |  |  |  |  |
+| `VM::UPTIME` | Check if uptime is less than or equal to 2 minutes |  | 10% |  |  |  | Spoofable |  |
+| `VM::ODD_CPU_THREADS` | Check for odd CPU threads, usually a sign of modification through VM setting because 99% of CPUs have even numbers of threads |  | 80% |  |  |  |  |  |
+| `VM::INTEL_THREAD_MISMATCH` | Check for Intel CPU thread count database if it matches the system's thread count |  | 60% |  |  |  |  |  |
+| `VM::XEON_THREAD_MISMATCH` | Same as above, but for Xeon Intel CPUs |  | 85% |  |  |  |  |  |
+| `VM::NETTITUDE_VM_MEMORY` | Check for memory regions to detect VM-specific brands | Windows | 75% |  |  |  |  |  |
+| `VM::CPUID_BITSET` |  Check for CPUID technique by checking whether all the bits equate to more than 4000 |  | 20% |  |  |  |  |  |
+| `VM::CUCKOO_DIR` | Check for cuckoo directory using crt and WIN API directory functions | Windows | 15% |  |  |  | Spoofable |  |
+| `VM::CUCKOO_PIPE` | Check for Cuckoo specific piping mechanism | Windows | 20% |  |  |  | Spoofable |  |
+| `VM::HYPERV_HOSTNAME` | Check for default Azure hostname format regex (Azure uses Hyper-V as their base VM brand) | Windows, Linux | 50% |  |  |  | Spoofable |  |
+| `VM::GENERAL_HOSTNAME` | Check for commonly set hostnames by certain VM brands | Windows, Linux | 20% |  |  |  | Spoofable |  |
+| `VM::SCREEN_RESOLUTION` | Check for pre-set screen resolutions commonly found in VMs | Windows | 10% |  |  |  |  |  |
+| `VM::DEVICE_STRING` | Check if bogus device string would be accepted | Windows | 25% |  |  |  |  |  |
+| `VM::BLUESTACKS_FOLDERS` |  Check for the presence of BlueStacks-specific folders | Linux | 15% |  |  |  | Spoofable |  |
+| `VM::CPUID_SIGNATURE` | Check for signatures in leaf 0x40000001 in CPUID |  | 95% |  |  |  |  |  |
+| `VM::HYPERV_BITMASK` | Check for Hyper-V CPUID bitmask range for reserved values |  | 20% |  |  |  |  |  |
+| `VM::KVM_BITMASK` | Check for KVM CPUID bitmask range for reserved values |  | 40% |  |  |  |  |  |
+| `VM::KGT_SIGNATURE` | Check for Intel KGT (Trusty branch) hypervisor signature in CPUID |  | 80% |  |  |  |  |  |
+| `VM::VMWARE_DMI` | Check for VMware DMI strings in BIOS serial number | Windows | 30% |  |  |  |  |  |
+| `VM::EVENT_LOGS` | Check for presence of Hyper-V in the Windows Event Logs | Windows | 30% |  |  |  | Spoofable |  |
+| `VM::QEMU_VIRTUAL_DMI` | Check for presence of QEMU in the /sys/devices/virtual/dmi/id directory | Linux | 40% |  |  |  |  |  |
+| `VM::QEMU_USB` | Check for presence of QEMU in the /sys/kernel/debug/usb/devices directory | Linux | 20% |  |  |  |  |  |
+| `VM::HYPERVISOR_DIR` | Check for presence of any files in /sys/hypervisor directory | Linux | 20% |  |  |  |  |  |
+| `VM::UML_CPU` | Check for the "UML" string in the CPU brand | Linux | 80% |  |  |  |  |  |
+| `VM::KMSG` | Check for any indications of hypervisors in the kernel message logs | Linux | 10% |  |  |  | Spoofable |  |
+| `VM::VM_PROCS` | Check for a Xen VM process | Linux | 20% |  |  |  | Spoofable |  |
+| `VM::VBOX_MODULE` | Check for a VBox kernel module | Linux | 15% |  |  |  |  |  |
+| `VM::SYSINFO_PROC` | Check for potential VM info in /proc/sysinfo | Linux | 15% |  |  |  |  |  |
+| `VM::DEVICE_TREE` | Check for specific files in /proc/device-tree directory | Linux | 20% |  |  |  |  |  |
+| `VM::DMI_SCAN` | Check for string matches of VM brands in the linux DMI | Linux | 50% |  |  |  |  |  |
+| `VM::SMBIOS_VM_BIT` | Check for the VM bit in the SMBIOS data | Linux | 50% |  |  |  |  |  |
+| `VM::PODMAN_FILE` | Check for podman file in /run/ | Linux | 15% |  |  |  | Spoofable |  |
+| `VM::WSL_PROC` | Check for WSL or microsoft indications in /proc/ subdirectories | Linux | 30% |  |  |  |  |  |
+| `VM::ANYRUN_DRIVER` | Check for any.run driver presence | Windows | 65% |  |  |  |  | Removed from the lib, only available in the CLI |
+| `VM::ANYRUN_DIRECTORY` | Check for any.run directory and handle the status code | Windows | 35% |  |  |  |  | Removed from the lib, only available in the CLI |
+| `VM::GPU_CHIPTYPE` | Check for known VM vendors in the GPU chip manufacturer | Windows | 100% |  |  |  |  |  |
+
+
+
+<br>
+
+# Non-technique flags
+| Flag | Description |
+|------|-------------|
+| `VM::ALL` | This will enable all the technique flags, including spoofable techniques and cursor check that are disabled by default. |
+| `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::DEFAULT` | This represents a range of flags which are enabled if no default argument is provided. |
+| `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. This has no effect if applied to any other functions than `VM::brand()`. |   
+| `VM::HIGH_THRESHOLD` | This is specific to `VM::detect()` and `VM::percentage()`, which will set the threshold bar to confidently detect a VM by 3x higher. |
+| `VM::SPOOFABLE` | This will enable all the "spoofable" techniques (which are 1/3 of the total amount of techniques) |
+
+<br>
+
+# Variables
+| Variable | Type | Description |
+|----------|------|-------------|
+| `VM::technique_count` | `std::uint16_t` | This will store the number of VM detection techniques |
+| `VM::technique_vector` | `std::vector<std::uint8_t>` | This will store all the technique macros as a vector. Useful if you're trying to loop through all the techniques for whatever operation you're performing. |
+
+<br>
+
+# CLI documentation
+| Shorthand | Full command | Description |
+|-----------|--------------|-------------|
+| -h | --help | Prints the help menu |
+| -v | --version | Prints the version and miscellaneous details |
+| -d | --detect | Prints the VM detection result (1 = VM, 0 = baremetal) |
+| -s | --stdout | Returns either 0 or 1 to STDOUT without any text output (0 = VM, 1 = baremetal) |
+| -b | --brand | Prints the most likely brand |
+| -l | --brand-list | Prints all the possible VM brand strings the CLI supports |
+| -c | --conclusion | Prints the conclusion message string |
+| -p | --percent | Prints the VM likeliness percentage between 0 and 100 |
+| -n | --number | Prints the number of VM detection techniques it can performs |
+| -t | --type | Returns the VM type (if a VM was found) |
+|    | --disable-notes | No notes will be provided |
+|    | --spoofable | Allow spoofable techniques to be ran (not included by default) |
+|    | --high-threshold | A higher theshold bar for a VM detection will be applied |
+> [!NOTE]
+> If you want a general result of everything combined above, do not put any arguments. This is the intended way to use the CLI tool.
+>
\ No newline at end of file
diff --git a/VMAware/papers/ Attacks on Virtual Machine Emulators.pdf b/VMAware/papers/ Attacks on Virtual Machine Emulators.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..feb3d52f2cebc52075e6e80172e9b678df14320e
Binary files /dev/null and b/VMAware/papers/ Attacks on Virtual Machine Emulators.pdf differ
diff --git a/VMAware/papers/A Study of IO Performance of Virtual Machines.pdf b/VMAware/papers/A Study of IO Performance of Virtual Machines.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..67a754e89a8820756811467b12afcc9cbc7732a9
Binary files /dev/null and b/VMAware/papers/A Study of IO Performance of Virtual Machines.pdf differ
diff --git a/VMAware/papers/A new post-meltdown attack technique_ how to use speculative instructions for virtualization detection.pdf b/VMAware/papers/A new post-meltdown attack technique_ how to use speculative instructions for virtualization detection.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..5f15917f8290ce8d7e27c210b41a43ee07537b5f
Binary files /dev/null and b/VMAware/papers/A new post-meltdown attack technique_ how to use speculative instructions for virtualization detection.pdf differ
diff --git a/VMAware/papers/Armv8-A virtualization.pdf b/VMAware/papers/Armv8-A virtualization.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..61088834c38fab79d8a0475961f4681ec62ccee7
Binary files /dev/null and b/VMAware/papers/Armv8-A virtualization.pdf differ
diff --git a/VMAware/papers/Detecting the Presence of Virtual  Machines Using the Local Data Table.pdf b/VMAware/papers/Detecting the Presence of Virtual  Machines Using the Local Data Table.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..c6ce54d048cde788e3af7c1f5fa2d00b608cca3c
Binary files /dev/null and b/VMAware/papers/Detecting the Presence of Virtual  Machines Using the Local Data Table.pdf differ
diff --git a/VMAware/papers/Detection of Virtual Machines Based on Thread Scheduling.pdf b/VMAware/papers/Detection of Virtual Machines Based on Thread Scheduling.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..0a8f03296c2e685424e5a83487105e1387583fb0
Binary files /dev/null and b/VMAware/papers/Detection of Virtual Machines Based on Thread Scheduling.pdf differ
diff --git a/VMAware/papers/Invisible Sandbox Evasion - Check Point Research.pdf b/VMAware/papers/Invisible Sandbox Evasion - Check Point Research.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..6d0ef7fc16a491abded63be3302bdc7c729941d7
Binary files /dev/null and b/VMAware/papers/Invisible Sandbox Evasion - Check Point Research.pdf differ
diff --git a/VMAware/papers/Methods for Virtual Machine Detection.pdf b/VMAware/papers/Methods for Virtual Machine Detection.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..1e1de77b21e32336b4e769d53ba72375bedb7baf
Binary files /dev/null and b/VMAware/papers/Methods for Virtual Machine Detection.pdf differ
diff --git a/VMAware/papers/Rethinking anti-emulation techniques for large-scale software deployment.pdf b/VMAware/papers/Rethinking anti-emulation techniques for large-scale software deployment.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..b146ddaed9f1ede9152f3d7a02062ca21b4a50b0
Binary files /dev/null and b/VMAware/papers/Rethinking anti-emulation techniques for large-scale software deployment.pdf differ
diff --git a/VMAware/papers/STEALTH SANDBOX ANALYSIS OF MALWARE.pdf b/VMAware/papers/STEALTH SANDBOX ANALYSIS OF MALWARE.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..6bfe91bcc08140d0e550f23e3d88986e2e2d8164
Binary files /dev/null and b/VMAware/papers/STEALTH SANDBOX ANALYSIS OF MALWARE.pdf differ
diff --git a/VMAware/papers/ThwartingVMDetection_Liston_Skoudis.pdf b/VMAware/papers/ThwartingVMDetection_Liston_Skoudis.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..0a005afff5dcf5cdc0a8e7fd15d5a289c23790f6
Binary files /dev/null and b/VMAware/papers/ThwartingVMDetection_Liston_Skoudis.pdf differ
diff --git a/VMAware/papers/vmde.pdf b/VMAware/papers/vmde.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..295df40cce73dc6546a465e97db7835e8d8f4e1c
Binary files /dev/null and b/VMAware/papers/vmde.pdf differ
diff --git a/VMAware/src/README.md b/VMAware/src/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..8bb46d48eeb6f63b4f6c5525019db695dfe28843
--- /dev/null
+++ b/VMAware/src/README.md
@@ -0,0 +1,5 @@
+| file | purpose |
+|------|---------|
+| `cli.cpp`  | Entire CLI tool code |
+| `vmaware.hpp` | Official and original library header in GPL-3.0, most likely what you're looking for. |
+| `vmaware_MIT.hpp` | Same as above but in MIT. This removes around 10 techniques, however. |
\ No newline at end of file
diff --git a/VMAware/src/cli.cpp b/VMAware/src/cli.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b131ab77a356fa93059d204c879a38c0011c370
--- /dev/null
+++ b/VMAware/src/cli.cpp
@@ -0,0 +1,928 @@
+/**
+ * ██╗   ██╗███╗   ███╗ █████╗ ██╗    ██╗ █████╗ ██████╗ ███████╗
+ * ██║   ██║████╗ ████║██╔══██╗██║    ██║██╔══██╗██╔══██╗██╔════╝
+ * ██║   ██║██╔████╔██║███████║██║ █╗ ██║███████║██████╔╝█████╗  
+ * ╚██╗ ██╔╝██║╚██╔╝██║██╔══██║██║███╗██║██╔══██║██╔══██╗██╔══╝  
+ *  ╚████╔╝ ██║ ╚═╝ ██║██║  ██║╚███╔███╔╝██║  ██║██║  ██║███████╗
+ *   ╚═══╝  ╚═╝     ╚═╝╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝
+ * 
+ *  C++ VM detection library
+ * 
+ * ===============================================================
+ *
+ *  This is the main CLI code, which demonstrates the majority 
+ *  of the library's capabilities while also providing as a
+ *  practical and general VM detection tool for everybody to use
+ * 
+ * ===============================================================
+ * 
+ *  - Made by: @kernelwernel (https://github.com/kernelwernel)
+ *  - Repository: https://github.com/kernelwernel/VMAware
+ *  - License: GPL 3.0
+ */ 
+
+#include <string>
+#include <iostream>
+#include <vector>
+#include <cstdint>
+#include <bit>
+
+#if (defined(__GNUC__) || defined(__linux__))
+    #include <unistd.h>
+    #define LINUX 1
+#else
+    #define LINUX 0
+#endif
+
+#if (defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__))
+    #define MSVC 1
+    #include <windows.h>
+#else
+    #define MSVC 0
+#endif
+
+#include "vmaware.hpp"
+
+constexpr const char* ver = "1.9";
+constexpr const char* date = "September 2024";
+
+constexpr const char* bold = "\033[1m";
+constexpr const char* ansi_exit = "\x1B[0m";
+constexpr const char* red = "\x1B[38;2;239;75;75m"; 
+constexpr const char* orange = "\x1B[38;2;255;180;5m";
+constexpr const char* green = "\x1B[38;2;94;214;114m";
+constexpr const char* red_orange = "\x1B[38;2;247;127;40m";
+constexpr const char* green_orange = "\x1B[38;2;174;197;59m";
+constexpr const char* grey = "\x1B[38;2;108;108;108m";
+
+const std::string detected = ("[  " + std::string(green) + "DETECTED" + std::string(ansi_exit) + "  ]");
+const std::string not_detected = ("[" + std::string(red) + "NOT DETECTED" + std::string(ansi_exit) + "]");
+const std::string spoofable = ("[" + std::string(red) + " EASY SPOOF " + std::string(ansi_exit) + "]");
+const std::string no_perms = ("[" + std::string(grey) + "  NO PERMS  " + std::string(ansi_exit) + "]");
+const std::string note = ("[    NOTE    ]");               
+const std::string disabled = ("[" + std::string(grey) + "  DISABLED  " + std::string(ansi_exit) + "]");
+
+using u8  = std::uint8_t;
+using u32 = std::uint32_t;
+
+enum arg_enum : u8 {
+    HELP,
+    VERSION,
+    ALL,
+    DETECT,
+    STDOUT,
+    BRAND,
+    BRAND_LIST,
+    PERCENT,
+    CONCLUSION,
+    NUMBER,
+    TYPE,
+    NOTES,
+    SPOOFABLE,
+    HIGH_THRESHOLD,
+    NULL_ARG
+};
+
+constexpr u8 max_bits = static_cast<u8>(VM::MULTIPLE) + 1;
+constexpr u8 arg_bits = static_cast<u8>(NULL_ARG) + 1;
+std::bitset<arg_bits> arg_bitset;
+
+#if (MSVC)
+class win_ansi_enabler_t
+{
+public:
+  win_ansi_enabler_t()
+  {
+    m_set = FALSE;
+    m_out = GetStdHandle(STD_OUTPUT_HANDLE);
+    m_old = 0;
+    if(m_out != NULL && m_out != INVALID_HANDLE_VALUE)
+    {
+      if(GetConsoleMode(m_out, &m_old) != FALSE)
+      {
+        m_set = SetConsoleMode(m_out, m_old | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
+      }
+    }
+  }
+  ~win_ansi_enabler_t()
+  {
+    if(m_set != FALSE)
+    {
+      SetConsoleMode(m_out, m_old);
+    }
+  }
+private:
+  win_ansi_enabler_t(win_ansi_enabler_t const&);
+private:
+  BOOL m_set;
+  DWORD m_old;
+  HANDLE m_out;
+};
+#endif
+
+
+[[noreturn]] void help(void) {
+    std::cout << 
+R"(Usage: 
+ vmaware [option] [extra]
+ (do not run with any options if you want the full summary)
+
+Options:
+ -h | --help        prints this help menu
+ -v | --version     print cli version and other details
+ -a | --all         run the result with ALL the techniques enabled (might contain false positives)
+ -d | --detect      returns the result as a boolean (1 = VM, 0 = baremetal)
+ -s | --stdout      returns either 0 or 1 to STDOUT without any text output (0 = VM, 1 = baremetal)
+ -b | --brand       returns the VM brand string
+ -l | --brand-list  returns all the possible VM brand string values
+ -p | --percent     returns the VM percentage between 0 and 100
+ -c | --conclusion  returns the conclusion message string
+ -n | --number      returns the number of VM detection techniques it performs
+ -t | --type        returns the VM type (if a VM was found)
+
+Extra:
+ --disable-notes    no notes will be provided
+ --spoofable        allow spoofable techniques to be ran (not included by default)
+ --high-threshold   a higher theshold bar for a VM detection will be applied
+
+)";
+    std::exit(0);
+}
+
+[[noreturn]] void version(void) {
+    std::cout << "vmaware " << "v" << ver << " (" << date << ")\n\n" <<
+    "Derived project of VMAware library at https://github.com/kernelwernel/VMAware"
+    "License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.\n" << 
+    "This is free software: you are free to change and redistribute it.\n" <<
+    "There is NO WARRANTY, to the extent permitted by law.\n" <<
+    "Developed and maintained by kernelwernel, see https://github.com/kernelwernel\n";
+
+    std::exit(0);
+}
+
+const char* color(const u8 score) {
+    if      (score == 0)   { return red; }
+    else if (score <= 12)  { return red; }
+    else if (score <= 25)  { return red_orange; }
+    else if (score < 50)   { return red_orange; }
+    else if (score <= 62)  { return orange; }
+    else if (score <= 75)  { return green_orange; }
+    else if (score < 100)  { return green; }
+    else if (score == 100) { return green; }
+
+    return "";
+}
+
+
+[[noreturn]] void brand_list() {
+    std::cout << 
+R"(VirtualBox
+VMware
+VMware Express
+VMware ESX
+VMware GSX
+VMware Workstation
+VMware Fusion
+bhyve
+QEMU
+KVM
+KVM Hyper-V Enlightenment
+QEMU+KVM Hyper-V Enlightenment
+QEMU+KVM
+Virtual PC
+Microsoft Hyper-V
+Microsoft Virtual PC/Hyper-V
+Microsoft x86-to-ARM
+Parallels
+Xen HVM
+ACRN
+QNX hypervisor
+Hybrid Analysis
+Sandboxie
+Docker
+Wine
+Apple Rosetta 2
+Anubis
+JoeBox
+ThreatExpert
+CWSandbox
+Comodo
+Bochs
+Lockheed Martin LMHS
+NVMM
+OpenBSD VMM
+Intel HAXM
+Unisys s-Par
+Cuckoo
+BlueStacks
+Jailhouse
+Apple VZ
+Intel KGT (Trusty)
+Microsoft Azure Hyper-V
+Xbox NanoVisor (Hyper-V)
+SimpleVisor
+Hyper-V artifact (not an actual VM)
+User-mode Linux
+IBM PowerVM
+Google Compute Engine (KVM)
+OpenStack (KVM)
+KubeVirt (KVM)
+AWS Nitro System (KVM-based)
+Podman
+WSL
+OpenVZ
+ANY.RUN
+)";
+
+    std::exit(0);
+}
+
+bool is_spoofable(const VM::enum_flags flag) {
+    if (arg_bitset.test(ALL)) {
+        return false;
+    }
+
+    switch (flag) {
+        case VM::MAC:
+        case VM::DOCKERENV:
+        case VM::HWMON:
+        case VM::CURSOR:
+        case VM::VMWARE_REG:
+        case VM::VBOX_REG:
+        case VM::USER:
+        case VM::DLL:
+        case VM::REGISTRY:
+        case VM::CWSANDBOX_VM:
+        case VM::VM_FILES:
+        case VM::HWMODEL:
+        case VM::COMPUTER_NAME:
+        case VM::HOSTNAME:
+        case VM::KVM_REG:
+        case VM::KVM_DRIVERS:
+        case VM::KVM_DIRS:
+        case VM::LOADED_DLLS:
+        case VM::QEMU_DIR:
+        case VM::MOUSE_DEVICE:
+        case VM::VM_PROCESSES:
+        case VM::LINUX_USER_HOST:
+        case VM::HYPERV_REG:
+        case VM::MAC_MEMSIZE:
+        case VM::MAC_IOKIT:
+        case VM::IOREG_GREP:
+        case VM::MAC_SIP:
+        case VM::HKLM_REGISTRIES:
+        case VM::QEMU_GA:
+        case VM::QEMU_PROC:
+        case VM::VPC_PROC:
+        case VM::VM_FILES_EXTRA:
+        case VM::UPTIME:
+        case VM::CUCKOO_DIR:
+        case VM::CUCKOO_PIPE:
+        case VM::HYPERV_HOSTNAME:
+        case VM::GENERAL_HOSTNAME:
+        case VM::BLUESTACKS_FOLDERS: 
+        case VM::EVENT_LOGS: 
+        case VM::KMSG: 
+        case VM::VM_PROCS: 
+        case VM::PODMAN_FILE: return true;
+        default: return false;
+    }
+}
+
+#if (LINUX)
+bool is_admin() {
+    const uid_t uid  = getuid();
+    const uid_t euid = geteuid();
+
+    const bool is_root = (
+        (uid != euid) || 
+        (euid == 0)
+    );
+
+    return is_root;
+}
+#endif
+
+
+bool are_perms_required(const VM::enum_flags flag) {
+#if (LINUX)
+    if (is_admin()) {
+        return false;
+    }
+
+    switch (flag) {
+        case VM::VBOX_DEFAULT: 
+        case VM::VMWARE_DMESG: 
+        case VM::DMIDECODE: 
+        case VM::DMESG: 
+        case VM::QEMU_USB: 
+        case VM::KMSG: 
+        case VM::SMBIOS_VM_BIT: return true;
+        default: return false;
+    }
+#else 
+    (void)flag;
+    return false;
+#endif
+}
+
+
+bool is_disabled(const VM::enum_flags flag) {
+    if (arg_bitset.test(ALL)) {
+        return false;
+    }
+
+    switch (flag) {
+        case VM::RDTSC:
+        case VM::RDTSC_VMEXIT:
+        case VM::CURSOR: return true;
+        default: return false;
+    }
+}
+
+
+std::bitset<max_bits> settings() {
+    std::bitset<max_bits> tmp;
+
+    if (arg_bitset.test(SPOOFABLE)) {
+        tmp.set(VM::SPOOFABLE);
+    }
+
+    if (arg_bitset.test(HIGH_THRESHOLD)) {
+        tmp.set(VM::HIGH_THRESHOLD);
+    }
+
+    if (arg_bitset.test(ALL)) {
+        tmp |= VM::ALL;
+        tmp.set(VM::SPOOFABLE);
+    }
+
+    return tmp;
+}
+
+
+// just a simple string replacer
+void replace(std::string &text, const std::string &original, const std::string &new_brand) {
+    size_t start_pos = 0;
+    while ((start_pos = text.find(original, start_pos)) != std::string::npos) {
+        text.replace(start_pos, original.length(), new_brand);
+        start_pos += new_brand.length();
+    }
+}
+
+
+/**
+ * @brief Check for any.run driver presence
+ * @category Windows
+ * @author kkent030315
+ * @link https://github.com/kkent030315/detect-anyrun/blob/main/detect.cc
+ * @copyright MIT
+ */
+[[nodiscard]] static bool anyrun_driver() {
+#if (!MSVC)
+    return false;
+#else
+    HANDLE hFile;
+
+    hFile = CreateFileA(
+        /*lpFileName*/TEXT("\\\\?\\\\A3E64E55_fl"),
+        /*dwDesiredAccess*/GENERIC_READ,
+        /*dwShareMode*/0,
+        /*lpSecurityAttributes*/NULL,
+        /*dwCreationDisposition*/OPEN_EXISTING,
+        /*dwFlagsAndAttributes*/0,
+        /*hTemplateFile*/NULL
+    );
+
+    if (hFile == INVALID_HANDLE_VALUE) {
+        return false;
+    }
+
+    CloseHandle(hFile);
+
+    return true;
+#endif
+}
+
+
+/**
+ * @brief Check for any.run directory and handle the status code
+ * @category Windows
+ * @author kkent030315
+ * @link https://github.com/kkent030315/detect-anyrun/blob/main/detect.cc
+ * @copyright MIT
+ */
+[[nodiscard]] static bool anyrun_directory() {
+#if (!MSVC)
+    return false;
+#else
+    NTSTATUS status;
+
+    UNICODE_STRING name;
+    RtlInitUnicodeString(&name, L"\\??\\C:\\Program Files\\KernelLogger");
+
+    HANDLE hFile;
+    IO_STATUS_BLOCK iosb = { 0 };
+    OBJECT_ATTRIBUTES attrs{};
+    InitializeObjectAttributes(&attrs, &name, 0, NULL, NULL);
+
+    status = NtCreateFile(
+        /*FileHandle*/&hFile,
+        /*DesiredAccess*/GENERIC_READ | SYNCHRONIZE,
+        /*ObjectAttributes*/&attrs,
+        /*IoStatusBlock*/&iosb,
+        /*AllocationSize*/NULL,
+        /*FileAttributes*/FILE_ATTRIBUTE_DIRECTORY,
+        /*ShareAccess*/FILE_SHARE_READ,
+        /*CreateDisposition*/FILE_OPEN,
+        /*CreateOptions*/FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+        /*EaBuffer*/NULL,
+        /*EaLength*/0
+    );
+
+    // ANY.RUN minifilter returns non-standard status code, STATUS_NO_SUCH_FILE
+    // If this status code is returned, it means that the directory is protected
+    // by the ANY.RUN minifilter driver.
+    // To patch this detection, I would recommend returning STATUS_OBJECT_NAME_NOT_FOUND
+    // that is a standard status code for this situation.
+    if (status == 0xC000000F) // STATUS_NOT_SUCH_FILE
+        return true;
+
+    // Not actually the case, maybe conflict with other software installation.
+    if (NT_SUCCESS(status))
+        NtClose(hFile);
+
+    return false;
+#endif
+} 
+
+
+void checker(const VM::enum_flags flag, const char* message) {
+    if (is_spoofable(flag)) {
+        if (!arg_bitset.test(SPOOFABLE)) {
+            std::cout << spoofable << " Skipped " << message << "\n";
+            return;
+        }
+    }
+
+#if (LINUX)
+    if (are_perms_required(flag)) {
+        std::cout << no_perms << " Skipped " << message << "\n";
+
+        // memoize it, it's going to be ran later anyway with stuff like VM::detect()
+        VM::check(flag);
+
+        return;
+    }
+#endif
+
+    if (is_disabled(flag)) {
+        std::cout << disabled << " Skipped " << message << "\n";
+        return;
+    }
+
+    std::cout << 
+        (VM::check(flag) ? detected : not_detected) << 
+        " Checking " << 
+        message << 
+        "...\n";
+}
+
+
+// overload for std::function, this is specific for any.run techniques
+// that are embedded in the CLI because it was removed in the lib as of 2.0
+void checker(const std::function<bool()> func, const char* message) {
+    std::cout << 
+        (func() ? detected : not_detected) << 
+        " Checking " << 
+        message << 
+        "...\n";
+}
+
+
+const bool is_anyrun_directory = anyrun_directory();
+const bool is_anyrun_driver = anyrun_driver();
+const bool is_anyrun = (is_anyrun_directory || is_anyrun_driver);
+
+
+void general() {
+    const std::string tip = (std::string(green) + "TIP: " + std::string(ansi_exit));
+
+    bool notes_enabled = false;
+
+    if (arg_bitset.test(NOTES)) {
+        notes_enabled = false;
+    } else {
+        notes_enabled = true;
+    }
+
+    #if (LINUX)
+        if (notes_enabled && !is_admin()) {
+            std::cout << note << " Running under root might give better results\n";
+        }
+    #endif
+
+    checker(VM::VMID, "VMID");
+    checker(VM::CPU_BRAND, "CPU brand");
+    checker(VM::HYPERVISOR_BIT, "CPUID hypervisor bit");
+    checker(VM::HYPERVISOR_STR, "hypervisor str");
+    checker(VM::RDTSC, "RDTSC");
+    checker(VM::SIDT5, "sidt null byte");
+    checker(VM::THREADCOUNT, "processor count");
+    checker(VM::MAC, "MAC address");
+    checker(VM::TEMPERATURE, "temperature");
+    checker(VM::SYSTEMD, "systemd virtualisation");
+    checker(VM::CVENDOR, "chassis vendor");
+    checker(VM::CTYPE, "chassis type");
+    checker(VM::DOCKERENV, "Dockerenv");
+    checker(VM::DMIDECODE, "dmidecode output");
+    checker(VM::DMESG, "dmesg output");
+    checker(VM::HWMON, "hwmon presence");
+    checker(VM::CURSOR, "cursor");
+    checker(VM::VMWARE_REG, "VMware registry");
+    checker(VM::VBOX_REG, "VBox registry");
+    checker(VM::USER, "users");
+    checker(VM::DLL, "DLLs");
+    checker(VM::REGISTRY, "registry");
+    checker(VM::CWSANDBOX_VM, "Sunbelt CWSandbox directory");
+    checker(VM::WINE_CHECK, "Wine");
+    checker(VM::VM_FILES, "VM files");
+    checker(VM::HWMODEL, "hw.model");
+    checker(VM::DISK_SIZE, "disk size");
+    checker(VM::VBOX_DEFAULT, "VBox default specs");
+    checker(VM::VBOX_NETWORK, "VBox network provider match");
+    checker(VM::COMPUTER_NAME, "computer name");
+    checker(VM::HOSTNAME, "hostname");
+    checker(VM::MEMORY, "low memory space");
+    checker(VM::VM_PROCESSES, "VM processes");
+    checker(VM::LINUX_USER_HOST, "default Linux user/host");
+    checker(VM::VBOX_WINDOW_CLASS, "VBox window class");
+    checker(VM::GAMARUE, "gamarue ransomware technique");
+    checker(VM::VMID_0X4, "0x4 leaf of VMID");
+    checker(VM::PARALLELS_VM, "Parallels techniques");
+    checker(VM::RDTSC_VMEXIT, "RDTSC VMEXIT");
+    checker(VM::LOADED_DLLS, "loaded DLLs");
+    checker(VM::QEMU_BRAND, "QEMU CPU brand");
+    checker(VM::BOCHS_CPU, "BOCHS CPU techniques");
+    checker(VM::VPC_BOARD, "VirtualPC motherboard");
+    checker(VM::BIOS_SERIAL, "BIOS serial number");
+    checker(VM::VBOX_FOLDERS, "VirtualBox shared folders");
+    checker(VM::MSSMBIOS, "MSSMBIOS");
+    checker(VM::MAC_MEMSIZE, "MacOS hw.memsize");
+    checker(VM::MAC_IOKIT, "MacOS registry IO-kit");
+    checker(VM::IOREG_GREP, "IO registry grep");
+    checker(VM::MAC_SIP, "MacOS SIP");
+    checker(VM::KVM_REG, "KVM registries");
+    checker(VM::KVM_DRIVERS, "KVM drivers");
+    checker(VM::KVM_DIRS, "KVM directories");
+    checker(VM::HKLM_REGISTRIES, "HKLM registries");
+    checker(VM::AUDIO, "Audio device");
+    checker(VM::QEMU_GA, "qemu-ga process");
+    checker(VM::VALID_MSR, "MSR validity");
+    checker(VM::QEMU_PROC, "QEMU processes");
+    checker(VM::QEMU_DIR, "QEMU directories");
+    checker(VM::VPC_PROC, "VPC processes");
+    checker(VM::VPC_INVALID, "VPC invalid instructions");
+    checker(VM::SIDT, "SIDT");
+    checker(VM::SGDT, "SGDT");
+    checker(VM::SLDT, "SLDT");
+    checker(VM::OFFSEC_SIDT, "Offensive Security SIDT");
+    checker(VM::OFFSEC_SGDT, "Offensive Security SGDT");
+    checker(VM::OFFSEC_SLDT, "Offensive Security SLDT");
+    checker(VM::VPC_SIDT, "VirtualPC SIDT");
+    checker(VM::HYPERV_BOARD, "Hyper-V motherboard");
+    checker(VM::VM_FILES_EXTRA, "Extra VM files");
+    checker(VM::VMWARE_IOMEM, "/proc/iomem file");
+    checker(VM::VMWARE_IOPORTS, "/proc/ioports file");
+    checker(VM::VMWARE_SCSI, "/proc/scsi/scsi file");
+    checker(VM::VMWARE_DMESG, "VMware dmesg");
+    checker(VM::VMWARE_STR, "STR instruction");
+    checker(VM::VMWARE_BACKDOOR, "VMware IO port backdoor");
+    checker(VM::VMWARE_PORT_MEM, "VMware port memory");
+    checker(VM::SMSW, "SMSW instruction");
+    checker(VM::MUTEX, "mutex strings");
+    checker(VM::UPTIME, "uptime");
+    checker(VM::ODD_CPU_THREADS, "unusual thread count");
+    checker(VM::INTEL_THREAD_MISMATCH, "Intel thread count mismatch");
+    checker(VM::XEON_THREAD_MISMATCH, "Intel Xeon thread count mismatch");
+    checker(VM::NETTITUDE_VM_MEMORY, "VM memory regions");
+    checker(VM::CPUID_BITSET, "CPUID bitset");
+    checker(VM::CUCKOO_DIR, "Cuckoo directory");
+    checker(VM::CUCKOO_PIPE, "Cuckoo pipe");
+    checker(VM::HYPERV_HOSTNAME, "Hyper-V Azure hostname");
+    checker(VM::GENERAL_HOSTNAME, "general VM hostnames");
+    checker(VM::SCREEN_RESOLUTION, "screen resolution");
+    checker(VM::DEVICE_STRING, "bogus device string");
+    checker(VM::MOUSE_DEVICE, "mouse device");
+    checker(VM::BLUESTACKS_FOLDERS, "BlueStacks folders");
+    checker(VM::CPUID_SIGNATURE, "CPUID signatures");
+    checker(VM::HYPERV_BITMASK, "Hyper-V CPUID reserved bitmask");
+    checker(VM::KVM_BITMASK, "KVM CPUID reserved bitmask");
+    checker(VM::KGT_SIGNATURE, "Intel KGT signature");
+    checker(VM::VMWARE_DMI, "VMware DMI");
+    checker(VM::EVENT_LOGS, "Hyper-V event logs");
+    checker(VM::QEMU_VIRTUAL_DMI, "QEMU virtual DMI directory");
+    checker(VM::QEMU_USB, "QEMU USB");
+    checker(VM::HYPERVISOR_DIR, "Hypervisor directory (Linux)");
+    checker(VM::UML_CPU, "User-mode Linux CPU");
+    checker(VM::KMSG, "/dev/kmsg hypervisor message");
+    checker(VM::VM_PROCS, "various VM files in /proc");
+    checker(VM::VBOX_MODULE, "VBox kernel module");
+    checker(VM::SYSINFO_PROC, "/proc/sysinfo");
+    checker(VM::DEVICE_TREE, "/proc/device-tree");
+    checker(VM::DMI_SCAN, "DMI scan");
+    checker(VM::SMBIOS_VM_BIT, "SMBIOS VM bit");
+    checker(VM::PODMAN_FILE, "Podman file");
+    checker(VM::WSL_PROC, "WSL string in /proc");
+    checker(anyrun_driver, "ANY.RUN driver");
+    checker(anyrun_directory, "ANY.RUN directory");
+    checker(VM::GPU_CHIPTYPE, "GPU chip name");
+    checker(VM::DRIVER_NAMES, "driver names");
+    checker(VM::VBOX_IDT, "VirtualBox SIDT");
+    checker(VM::HDD_SERIAL, "HDD serial number");
+    checker(VM::PORT_CONNECTORS, "Physical connection ports");
+    checker(VM::QEMU_HDD, "QEMU in HDD model");
+
+    std::printf("\n");
+
+#ifdef __VMAWARE_DEBUG__
+    std::cout << "[DEBUG] theoretical maximum points: " << VM::total_points << "\n";
+#endif
+
+    // struct containing the whole overview of the VM data
+    VM::vmaware vm(VM::MULTIPLE, settings());
+
+
+    // brand manager
+    {
+        std::string brand = vm.brand;
+
+        if (is_anyrun && (brand == "Unknown")) {
+            brand = "ANY.RUN";
+        }
+
+        const bool is_red = (
+            (brand == "Unknown") || 
+            (brand == "Hyper-V artifact (not an actual VM)")
+        );
+
+        std::cout << "VM brand: " << (is_red ? red : green) << brand << ansi_exit << "\n";
+    }
+
+
+    // type manager
+    {
+        if (vm.brand.find(" or ") == std::string::npos) {  // meaning "if there's no brand conflicts" 
+            std::string color = "";
+            std::string &type = vm.type;
+
+            if (is_anyrun && (type == "Unknown")) {
+                type = "Sandbox";
+            }
+
+            if (type == "Unknown") {
+                color = red;
+            } else {
+                color = green;
+            }
+
+            std::cout << "VM type: " <<  color << type << ansi_exit << "\n";
+        }
+    }
+
+
+    // percentage manager
+    {
+        const char* percent_color = "";
+
+        if      (vm.percentage == 0) { percent_color = red; }
+        else if (vm.percentage < 25) { percent_color = red_orange; }
+        else if (vm.percentage < 50) { percent_color = orange; }
+        else if (vm.percentage < 75) { percent_color = green_orange; }
+        else                      { percent_color = green; }
+
+        std::cout << "VM likeliness: " << percent_color << static_cast<u32>(vm.percentage) << "%" << ansi_exit << "\n";
+    }
+
+
+    // VM confirmation manager
+    {
+        std::cout << "VM confirmation: " << (vm.is_vm ? green : red) << std::boolalpha << vm.is_vm << std::noboolalpha << ansi_exit << "\n";
+    }
+
+
+    // detection count manager
+    {
+        const char* count_color = "";
+
+        switch (vm.detected_count) {
+            case 0: count_color = red; break;
+            case 1: count_color = red_orange; break;
+            case 2: count_color = orange; break;
+            case 3: count_color = orange; break;
+            case 4: count_color = green_orange; break;
+            default:
+                // anything over 4 is green
+                count_color = green;
+        }
+
+        std::cout << 
+            "VM detections: " << 
+            count_color << 
+            static_cast<u32>(vm.detected_count) << 
+            "/" <<
+            static_cast<u32>(vm.technique_count) << 
+            ansi_exit <<
+            "\n\n";
+    }
+
+
+    // conclusion manager
+    {
+        const char* conclusion_color = color(vm.percentage);
+
+        std::cout
+            << bold
+            << "====== CONCLUSION: "
+            << ansi_exit
+            << conclusion_color << vm.conclusion << " " << ansi_exit
+            << bold
+            << "======"
+            << ansi_exit
+            << "\n\n";
+    }
+    
+
+    // finishing touches with notes
+    if (notes_enabled) {
+        if ((vm.brand == "Hyper-V artifact (not an actual VM)")) {
+            std::cout << note << " The result means that the CLI has found Hyper-V, but as an artifact instead of an actual VM. This means that although the hardware values in fact match with Hyper-V due to how it's designed by Microsoft, the CLI has determined you are NOT in a Hyper-V VM.\n\n";
+        } 
+
+        if (!arg_bitset.test(SPOOFABLE) && !arg_bitset.test(ALL)) {
+            std::cout << tip << "To enable easily spoofable techniques, run with the \"--spoofable\" argument\n\n";
+        } else {
+            std::cout << note << " If you found a false positive, please make sure to create an issue at https://github.com/kernelwernel/VMAware/issues\n\n";
+        }
+    }
+}
+
+
+int main(int argc, char* argv[]) {
+#if (MSVC)
+    win_ansi_enabler_t ansi_enabler;
+#endif
+
+    const std::vector<const char*> args(argv + 1, argv + argc); // easier this way
+    const u32 arg_count = argc - 1;
+
+    // this was removed on the lib due to ethical concerns, 
+    // so it's added in the CLI instead
+    VM::add_custom(65, anyrun_driver);
+    VM::add_custom(35, anyrun_directory);
+
+    if (arg_count == 0) {
+        general();
+        std::exit(0);
+    }
+
+    static constexpr std::array<std::pair<const char*, arg_enum>, 25> table {{
+        { "-h", HELP },
+        { "-v", VERSION },
+        { "-a", ALL },
+        { "-d", DETECT },
+        { "-s", STDOUT },
+        { "-b", BRAND },
+        { "-p", PERCENT },
+        { "-c", CONCLUSION },
+        { "-l", BRAND_LIST },
+        { "-n", NUMBER },
+        { "-t", TYPE },
+        { "--help", HELP },
+        { "--version", VERSION },
+        { "--all", ALL },
+        { "--detect", DETECT },
+        { "--stdout", STDOUT },
+        { "--brand", BRAND },
+        { "--percent", PERCENT },
+        { "--conclusion", CONCLUSION },
+        { "--brand-list", BRAND_LIST },
+        { "--number", NUMBER },
+        { "--type", TYPE },
+        { "--disable-notes", NOTES },
+        { "--spoofable", SPOOFABLE },
+        { "--high-threshold", HIGH_THRESHOLD }
+    }};
+
+    std::string potential_null_arg = "";
+
+    for (const auto arg_string : args) {
+        auto it = std::find_if(table.cbegin(), table.cend(), [&](const auto &p) {
+            return (std::strcmp(p.first, arg_string) == 0);
+        });
+
+        if (it == table.end()) {
+            arg_bitset.set(NULL_ARG);
+            potential_null_arg = arg_string;
+        } else {
+            arg_bitset.set(it->second);
+        }
+    }
+
+
+    // no critical returners
+    if (arg_bitset.test(NULL_ARG)) {
+        std::cerr << "Unknown argument \"" << potential_null_arg << "\", aborting\n";
+        return 1;
+    }
+
+    if (arg_bitset.test(HELP)) {
+        help();
+    } 
+
+    if (arg_bitset.test(VERSION)) {
+        version();
+    }
+
+    if (arg_bitset.test(BRAND_LIST)) {
+        brand_list();
+    }
+
+    if (arg_bitset.test(NUMBER)) {
+        std::cout << static_cast<u32>(VM::technique_count) << "\n";
+        return 0;
+    }
+
+    // critical returners
+    const u32 returners = (
+        static_cast<u8>(arg_bitset.test(STDOUT)) +
+        static_cast<u8>(arg_bitset.test(PERCENT)) +
+        static_cast<u8>(arg_bitset.test(DETECT)) +
+        static_cast<u8>(arg_bitset.test(BRAND)) +
+        static_cast<u8>(arg_bitset.test(TYPE)) +
+        static_cast<u8>(arg_bitset.test(CONCLUSION))
+    );
+
+    if (returners > 0) { // at least one of the options are set
+        if (returners > 1) { // more than 2 options are set
+            std::cerr << "--stdout, --percent, --detect, --brand, --type, and --conclusion must NOT be a combination, choose only a single one\n";
+            return 1;
+        }
+
+        if (arg_bitset.test(STDOUT)) {
+            return (!VM::detect(VM::NO_MEMO, settings()));
+        }
+
+        if (arg_bitset.test(PERCENT)) {
+            std::cout << static_cast<u32>(VM::percentage(VM::NO_MEMO, settings())) << "\n";
+            return 0;
+        }
+
+        if (arg_bitset.test(DETECT)) {
+            std::cout << VM::detect(VM::NO_MEMO, settings()) << "\n";
+            return 0;
+        }
+
+        if (arg_bitset.test(BRAND)) {
+            std::string brand = VM::brand(VM::NO_MEMO, VM::MULTIPLE, settings());
+            
+            if (is_anyrun && (brand == "Unknown")) {
+                brand = "ANY.RUN";
+            }
+
+            std::cout << brand << "\n";
+
+            return 0;
+        }
+
+        if (arg_bitset.test(TYPE)) {
+            std::string type = VM::type(VM::NO_MEMO, VM::MULTIPLE, settings());
+            
+            if (is_anyrun && (type == "Unknown")) {
+                type = "Sandbox";
+            }
+
+            std::cout << type << "\n";
+
+            return 0;
+        }
+
+        if (arg_bitset.test(CONCLUSION)) {
+            std::string conclusion = VM::conclusion(VM::NO_MEMO, VM::MULTIPLE, settings());
+            
+            if (is_anyrun) {
+                const std::string original = "Unknown";
+                const std::string new_brand = "ANY.RUN";
+
+                replace(conclusion, original, new_brand);
+            }
+
+            std::cout << conclusion << "\n";
+            return 0;
+        }
+    }
+
+    // at this point, it's assumed that the user's intention is for the general summary to be ran
+    general();
+    return 0;
+}
\ No newline at end of file
diff --git a/VMAware/src/vmaware.hpp b/VMAware/src/vmaware.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..428ff4d7b8e2e297e619aa27150805f01ddce481
--- /dev/null
+++ b/VMAware/src/vmaware.hpp
@@ -0,0 +1,10404 @@
+/**
+ * ██╗   ██╗███╗   ███╗ █████╗ ██╗    ██╗ █████╗ ██████╗ ███████╗
+ * ██║   ██║████╗ ████║██╔══██╗██║    ██║██╔══██╗██╔══██╗██╔════╝
+ * ██║   ██║██╔████╔██║███████║██║ █╗ ██║███████║██████╔╝█████╗
+ * ╚██╗ ██╔╝██║╚██╔╝██║██╔══██║██║███╗██║██╔══██║██╔══██╗██╔══╝
+ *  ╚████╔╝ ██║ ╚═╝ ██║██║  ██║╚███╔███╔╝██║  ██║██║  ██║███████╗
+ *   ╚═══╝  ╚═╝     ╚═╝╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝ 1.9 (September 2024)
+ *
+ *  C++ VM detection library
+ *
+ *  - Made by: kernelwernel (https://github.com/kernelwernel)
+ *  - Co-maintained by: Requiem (https://github.com/NotRequiem)
+ *  - Contributed by:
+ *      - Alex (https://github.com/greenozon)
+ *      - Marek Knápek (https://github.com/MarekKnapek)
+ *      - Vladyslav Miachkov (https://github.com/fameowner99)
+ *      - Alan Tse (https://github.com/alandtse)
+ *      - Georgii Gennadev (https://github.com/D00Movenok)
+ *      - utoshu (https://github.com/utoshu)
+ *  - Repository: https://github.com/kernelwernel/VMAware
+ *  - Docs: https://github.com/kernelwernel/VMAware/docs/documentation.md
+ *  - Full credits: https://github.com/kernelwernel/VMAware#credits-and-contributors-%EF%B8%8F
+ *  - License: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
+ *
+ *
+ * ================================ SECTIONS ==================================
+ * - enums for publicly accessible techniques  => line 325
+ * - struct for internal cpu operations        => line 589
+ * - struct for internal memoization           => line 1028
+ * - struct for internal utility functions     => line 1368
+ * - struct for internal core components       => line 8536
+ * - start of internal VM detection techniques => line 2591
+ * - start of public VM detection functions    => line 8920
+ * - start of externally defined variables     => line 9786
+ *
+ *
+ * ================================ EXAMPLE ==================================
+ * #include "vmaware.hpp"
+ * #include <iostream>
+ *
+ * int main() {
+ *     if (VM::detect()) {
+ *         std::cout << "Virtual machine detected!" << std::endl;
+ *         std::cout << "VM name: " << VM::brand() << std::endl;
+ *     } else {
+ *         std::cout << "Running in baremetal" << std::endl;
+ *     }
+ *
+ *     std::cout << "VM certainty: " << (int)VM::percentage() << "%" << std::endl;
+ * }
+ */
+
+#pragma once
+
+#if (defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__))
+#define MSVC 1
+#define LINUX 0
+#define APPLE 0
+#elif (defined(__linux__))
+#define MSVC 0
+#define LINUX 1
+#define APPLE 0
+#elif (defined(__APPLE__) || defined(__APPLE_CPP__) || defined(__MACH__) || defined(__DARWIN))
+#define MSVC 0
+#define LINUX 0
+#define APPLE 1
+#else
+#define MSVC 0
+#define LINUX 0
+#define APPLE 0
+#endif
+
+ // shorter and succinct macros
+#if __cplusplus > 202100L
+#define CPP 23
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using post-C++23, set back to C++23 standard")
+#endif
+#elif __cplusplus == 202100L
+#define CPP 23
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using C++23")
+#endif
+#elif __cplusplus == 202002L
+#define CPP 20
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using C++20")
+#endif
+#elif __cplusplus == 201703L
+#define CPP 17
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using C++17")
+#endif
+#elif __cplusplus == 201402L
+#define CPP 14
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using C++14")
+#endif
+#elif __cplusplus == 201103L
+#define CPP 11
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using C++11")
+#endif
+#elif __cplusplus < 201103L
+#define CPP 1
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using pre-C++11")
+#endif
+#else
+#define CPP 0
+#ifdef __VMAWARE_DEBUG__
+#pragma message("Unknown C++ standard")
+#endif
+#endif
+
+#if (CPP < 11 && !MSVC)
+#error "VMAware only supports C++11 or above, set your compiler flag to '-std=c++20' for gcc/clang, or '/std:c++20' for MSVC"
+#endif
+
+// unused for now, maybe in the future idk
+#if (WINVER == 0x0501) // Windows XP, (0x0701 for Windows 7)
+#define WIN_XP 1
+#else 
+#define WIN_XP 0
+#endif
+
+#if (defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64))
+#define x86 1
+#else
+#define x86 0
+#endif
+#if (defined(_M_IX86))
+#define x86_32 1
+#else
+#define x86_32 0
+#endif
+#if (defined(__arm__) || defined(__ARM_LINUX_COMPILER__) || defined(__aarch64__) || defined(_M_ARM64))
+#define ARM 1
+#else
+#define ARM 0
+#endif
+
+#if defined(__clang__)
+#define GCC 0
+#define CLANG 1
+#elif defined(__GNUC__)
+#define GCC 1
+#define CLANG 0
+#else
+#define GCC 0
+#define CLANG 0
+#endif
+
+#if !(defined(MSVC) || defined(LINUX) || defined(APPLE))
+#warning "Unknown OS detected, tests will be severely limited"
+#endif
+
+#if (CPP >= 23)
+#include <limits>
+#endif
+#if (CPP >= 20)
+#include <bit>
+#include <ranges>
+#include <source_location>
+#endif
+#if (CPP >= 17)
+#include <filesystem>
+#endif
+#ifdef __VMAWARE_DEBUG__
+#include <iomanip>
+#include <ios>
+#endif
+
+#if (MSVC)
+#pragma warning(disable : 4244)
+#include <functional>
+#pragma warning(default : 4244)
+
+#pragma warning(push, 0) // disable the windows SDK errors temporarily
+#else
+#include <functional>
+#endif
+
+#include <functional>
+#include <cstring>
+#include <string>
+#include <fstream>
+#include <regex>
+#include <thread>
+#include <cstdint>
+#include <map>
+#include <unordered_map>
+#include <array>
+#include <algorithm>
+#include <iostream>
+#include <cassert>
+#include <cmath>
+#include <sstream>
+#include <bitset>
+#include <type_traits>
+
+
+#if (MSVC)
+#include <windows.h>
+#include <intrin.h>
+#include <tchar.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <Iphlpapi.h>
+#include <Assert.h>
+#include <excpt.h>
+#include <winternl.h>
+#include <winnetwk.h>
+#include <winuser.h>
+#include <psapi.h>
+#include <comdef.h>
+#include <Wbemidl.h>
+#include <shlwapi.h>
+#include <shlobj_core.h>
+#include <strmif.h>
+#include <dshow.h>
+#include <stdio.h>
+#include <io.h>
+#include <winspool.h>
+#include <wtypes.h>
+#include <winevt.h>
+
+#if (!WIN_XP)
+#include <versionhelpers.h>
+#endif
+
+#pragma comment(lib, "wbemuuid.lib")
+#pragma comment(lib, "iphlpapi.lib")
+#pragma comment(lib, "Shlwapi.lib")
+#pragma comment(lib, "MPR")
+#pragma comment(lib, "advapi32.lib")
+#pragma comment(lib, "kernel32.lib")
+#pragma comment(lib, "shell32.lib")
+#pragma comment(lib, "strmiids.lib")
+#pragma comment(lib, "uuid.lib")
+#pragma comment(lib, "ntdll.lib")
+#pragma comment(lib, "wevtapi.lib")
+
+
+#ifdef _UNICODE
+#define tregex std::wregex
+#else
+#define tregex std::regex
+#endif
+
+#elif (LINUX)
+#if (x86)
+#include <cpuid.h>
+#include <x86intrin.h>
+#include <immintrin.h>
+#endif
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/ioctl.h>
+#include <sys/syscall.h>
+#include <sys/sysinfo.h>
+#include <net/if.h> 
+#include <netinet/in.h>
+#include <unistd.h>
+#include <string.h>
+#include <dirent.h>
+#include <memory>
+#include <cctype>
+#include <fcntl.h>
+#include <limits.h>
+#elif (APPLE)
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <chrono>
+#endif
+
+#if (!MSVC)
+#define TCHAR char
+#endif
+
+#if (MSVC)
+#pragma warning(pop) // enable all warnings
+#endif
+
+// macro shortcut to disable MSVC warnings
+#if (MSVC)
+#define MSVC_DISABLE_WARNING(...) __pragma(warning(disable : __VA_ARGS__))
+#define MSVC_ENABLE_WARNING(...) __pragma(warning(default : __VA_ARGS__))
+#else
+#define MSVC_DISABLE_WARNING(...)
+#define MSVC_ENABLE_WARNING(...)
+#endif
+
+// MSVC-specific errors
+#define SPECTRE 5045
+#define ASSIGNMENT_OPERATOR 4626
+#define NO_INLINE_FUNC 4514
+#define PADDING 4820
+#define FS_HANDLE 4733
+
+MSVC_DISABLE_WARNING(ASSIGNMENT_OPERATOR NO_INLINE_FUNC SPECTRE)
+
+#ifdef __VMAWARE_DEBUG__
+#define debug(...) VM::util::debug_msg(__VA_ARGS__)
+#define core_debug(...) VM::util::core_debug_msg(__VA_ARGS__)
+#else
+#define debug(...)
+#define core_debug(...)
+#endif
+
+struct VM {
+private:
+    using u8  = std::uint8_t;
+    using u16 = std::uint16_t;
+    using u32 = std::uint32_t;
+    using u64 = std::uint64_t;
+    using i8  = std::int8_t;
+    using i16 = std::int16_t;
+    using i32 = std::int32_t;
+    using i64 = std::int64_t;
+
+public:
+    enum enum_flags : u8 {
+        VMID = 0,
+        CPU_BRAND,
+        HYPERVISOR_BIT,
+        HYPERVISOR_STR,
+        RDTSC,
+        THREADCOUNT,
+        MAC,
+        TEMPERATURE,
+        SYSTEMD,
+        CVENDOR,
+        CTYPE,
+        DOCKERENV,
+        DMIDECODE,
+        DMESG,
+        HWMON,
+        SIDT5,
+        CURSOR,
+        VMWARE_REG,
+        VBOX_REG,
+        USER,
+        DLL,
+        REGISTRY,
+        CWSANDBOX_VM,
+        VM_FILES,
+        HWMODEL,
+        DISK_SIZE,
+        VBOX_DEFAULT,
+        VBOX_NETWORK,
+/* GPL */ COMPUTER_NAME,
+/* GPL */ WINE_CHECK,
+/* GPL */ HOSTNAME,
+/* GPL */ MEMORY,
+/* GPL */ VBOX_WINDOW_CLASS,
+/* GPL */ LOADED_DLLS,
+/* GPL */ KVM_REG,
+/* GPL */ KVM_DRIVERS,
+/* GPL */ KVM_DIRS,
+/* GPL */ AUDIO,
+/* GPL */ QEMU_DIR,
+/* GPL */ MOUSE_DEVICE,
+        VM_PROCESSES,
+        LINUX_USER_HOST,
+        GAMARUE,
+        VMID_0X4,
+        PARALLELS_VM,
+        RDTSC_VMEXIT,
+        QEMU_BRAND,
+        BOCHS_CPU,
+        VPC_BOARD,
+        HYPERV_WMI,
+        HYPERV_REG,
+        BIOS_SERIAL,
+        VBOX_FOLDERS,
+        MSSMBIOS,
+        MAC_MEMSIZE,
+        MAC_IOKIT,
+        IOREG_GREP,
+        MAC_SIP,
+        HKLM_REGISTRIES,
+        QEMU_GA,
+        VALID_MSR,
+        QEMU_PROC,
+        VPC_PROC,
+        VPC_INVALID,
+        SIDT,
+        SGDT,
+        SLDT,
+        OFFSEC_SIDT,
+        OFFSEC_SGDT,
+        OFFSEC_SLDT,
+        HYPERV_BOARD,
+        VM_FILES_EXTRA,
+        VPC_SIDT,
+        VMWARE_IOMEM,
+        VMWARE_IOPORTS,
+        VMWARE_SCSI,
+        VMWARE_DMESG,
+        VMWARE_STR,
+        VMWARE_BACKDOOR,
+        VMWARE_PORT_MEM,
+        SMSW,
+        MUTEX,
+        UPTIME,
+        ODD_CPU_THREADS,
+        INTEL_THREAD_MISMATCH,
+        XEON_THREAD_MISMATCH,
+        NETTITUDE_VM_MEMORY,
+        CPUID_BITSET,
+        CUCKOO_DIR,
+        CUCKOO_PIPE,
+        HYPERV_HOSTNAME,
+        GENERAL_HOSTNAME,
+        SCREEN_RESOLUTION,
+        DEVICE_STRING,
+        BLUESTACKS_FOLDERS,
+        CPUID_SIGNATURE,
+        HYPERV_BITMASK,
+        KVM_BITMASK,
+        KGT_SIGNATURE,
+        VMWARE_DMI,
+        EVENT_LOGS,
+        QEMU_VIRTUAL_DMI,
+        QEMU_USB,
+        HYPERVISOR_DIR,
+        UML_CPU,
+        KMSG,
+        VM_PROCS,
+        VBOX_MODULE,
+        SYSINFO_PROC,
+        DEVICE_TREE,
+        DMI_SCAN,
+        SMBIOS_VM_BIT,
+        PODMAN_FILE,
+        WSL_PROC,
+        GPU_CHIPTYPE,
+        DRIVER_NAMES,
+        VBOX_IDT,
+        HDD_SERIAL,
+        PORT_CONNECTORS,
+        QEMU_HDD,
+
+        // start of settings technique flags (THE ORDERING IS VERY SPECIFIC HERE AND MIGHT BREAK SOMETHING IF RE-ORDERED)
+        NO_MEMO,
+        HIGH_THRESHOLD,
+        NULL_ARG, // does nothing, just a placeholder flag mainly for the CLI
+        SPOOFABLE,
+        MULTIPLE
+    };
+
+private:
+    static constexpr u8 enum_size = MULTIPLE; // get enum size through value of last element
+    static constexpr u8 non_technique_count = MULTIPLE - NO_MEMO + 1; // get number of settings technique flags like VM::NO_MEMO for example
+    static constexpr u8 INVALID = 255; // explicit invalid technique macro
+    static constexpr u16 base_technique_count = NO_MEMO; // original technique count, constant on purpose
+    static constexpr u16 maximum_points = 4765; // theoretical total points if all VM detections returned true (which is practically impossible)
+    static constexpr u16 high_threshold_score = 300; // new threshold score from 100 to 350 if VM::HIGH_THRESHOLD flag is enabled
+    static constexpr bool SHORTCUT = true; // macro for whether VM::core::run_all() should take a shortcut by skipping the rest of the techniques if the threshold score is already met
+
+
+    // intended for loop indexes
+    static constexpr u8 enum_begin = 0;
+    static constexpr u8 enum_end = enum_size + 1;
+    static constexpr u8 technique_begin = enum_begin;
+    static constexpr u8 technique_end = NO_MEMO;
+    static constexpr u8 non_technique_begin = NO_MEMO;
+    static constexpr u8 non_technique_end = enum_end;
+
+    // this is specifically meant for VM::detected_count() to 
+    // get the total number of techniques that detected a VM
+    static u8 detected_count_num; 
+
+private:
+
+#if (MSVC)
+    using brand_score_t = i32;
+#else
+    using brand_score_t = u8;
+#endif
+
+    // for the flag bitset structure
+    using flagset = std::bitset<enum_size + 1>;
+
+public:
+    // this will allow the enum to be used in the public interface as "VM::TECHNIQUE"
+    enum enum_flags tmp_ignore_this = NO_MEMO;
+
+    // constructor shit ignore this
+    VM() = delete;
+    VM(const VM&) = delete;
+    VM(VM&&) = delete;
+
+    static flagset DEFAULT; // default bitset that will be run if no parameters are specified
+    static flagset ALL; // same as default, but with cursor check included
+
+private:
+
+    /**
+     * Official aliases for VM brands. This is added to avoid accidental typos
+     * which could really fuck up the result. Also, no errors/warnings are
+     * issued if the string is invalid in case of a typo. For example:
+     * scoreboard[VBOX]++;
+     * is much better and safer against typos than:
+     * scoreboard["VirtualBox"]++;
+     * Hopefully this makes sense.
+     *
+     * TL;DR I have wonky fingers :(
+     */
+    static constexpr const char* VBOX = "VirtualBox";
+    static constexpr const char* VMWARE = "VMware";
+    static constexpr const char* VMWARE_EXPRESS = "VMware Express";
+    static constexpr const char* VMWARE_ESX = "VMware ESX";
+    static constexpr const char* VMWARE_GSX = "VMware GSX";
+    static constexpr const char* VMWARE_WORKSTATION = "VMware Workstation";
+    static constexpr const char* VMWARE_FUSION = "VMware Fusion";
+    static constexpr const char* BHYVE = "bhyve";
+    static constexpr const char* KVM = "KVM";
+    static constexpr const char* QEMU = "QEMU";
+    static constexpr const char* QEMU_KVM = "QEMU+KVM";
+    static constexpr const char* KVM_HYPERV = "KVM Hyper-V Enlightenment";
+    static constexpr const char* QEMU_KVM_HYPERV = "QEMU+KVM Hyper-V Enlightenment";
+    static constexpr const char* HYPERV = "Microsoft Hyper-V";
+    static constexpr const char* HYPERV_VPC = "Microsoft Virtual PC/Hyper-V";
+    static constexpr const char* MSXTA = "Microsoft x86-to-ARM";
+    static constexpr const char* PARALLELS = "Parallels";
+    static constexpr const char* XEN = "Xen HVM";
+    static constexpr const char* ACRN = "ACRN";
+    static constexpr const char* QNX = "QNX hypervisor";
+    static constexpr const char* HYBRID = "Hybrid Analysis";
+    static constexpr const char* SANDBOXIE = "Sandboxie";
+    static constexpr const char* DOCKER = "Docker";
+    static constexpr const char* WINE = "Wine";
+    static constexpr const char* APPLE_ROSETTA = "Apple Rosetta 2";
+    static constexpr const char* VPC = "Virtual PC";
+    static constexpr const char* ANUBIS = "Anubis";
+    static constexpr const char* JOEBOX = "JoeBox";
+    static constexpr const char* THREATEXPERT = "ThreatExpert";
+    static constexpr const char* CWSANDBOX = "CWSandbox";
+    static constexpr const char* COMODO = "Comodo";
+    static constexpr const char* BOCHS = "Bochs";
+    static constexpr const char* NVMM = "NetBSD NVMM";
+    static constexpr const char* BSD_VMM = "OpenBSD VMM";
+    static constexpr const char* INTEL_HAXM = "Intel HAXM";
+    static constexpr const char* UNISYS = "Unisys s-Par";
+    static constexpr const char* LMHS = "Lockheed Martin LMHS"; // yes, you read that right. The library can now detect VMs running on US military fighter jets, apparently.
+    static constexpr const char* CUCKOO = "Cuckoo";
+    static constexpr const char* BLUESTACKS = "BlueStacks";
+    static constexpr const char* JAILHOUSE = "Jailhouse";
+    static constexpr const char* APPLE_VZ = "Apple VZ";
+    static constexpr const char* INTEL_KGT = "Intel KGT (Trusty)";
+    static constexpr const char* AZURE_HYPERV = "Microsoft Azure Hyper-V";
+    static constexpr const char* NANOVISOR = "Xbox NanoVisor (Hyper-V)";
+    static constexpr const char* SIMPLEVISOR = "SimpleVisor";
+    static constexpr const char* HYPERV_ARTIFACT = "Hyper-V artifact (not an actual VM)";
+    static constexpr const char* UML = "User-mode Linux";
+    static constexpr const char* POWERVM = "IBM PowerVM";
+    static constexpr const char* GCE = "Google Compute Engine (KVM)";
+    static constexpr const char* OPENSTACK = "OpenStack (KVM)";
+    static constexpr const char* KUBEVIRT = "KubeVirt (KVM)";
+    static constexpr const char* AWS_NITRO = "AWS Nitro System EC2 (KVM-based)";
+    static constexpr const char* PODMAN = "Podman";
+    static constexpr const char* WSL = "WSL";
+    static constexpr const char* OPENVZ = "OpenVZ";
+    static constexpr const char* NULL_BRAND = "Unknown";
+
+
+
+    static flagset global_flags; // for certain techniques where the flags MUST be accessible
+
+    // macro for bypassing unused parameter/variable warnings
+    #define UNUSED(x) ((void)(x))
+
+// likely and unlikely macros
+#if (LINUX)
+#   define VMAWARE_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#   define VMAWARE_LIKELY(x)   __builtin_expect(!!(x), 1)
+#else
+#   define VMAWARE_UNLIKELY
+#   define VMAWARE_LIKELY
+#endif
+
+    // specifically for util::hyper_x() and memo::hyperv
+    enum class hyperx_state : u8 {
+        HYPERV_REAL_VM = 1,
+        HYPERV_ARTIFACT_VM,
+        UNKNOWN
+    };
+
+    // various cpu operation stuff
+    struct cpu {
+        // cpuid leaf values
+        struct leaf {
+            static constexpr u32
+                func_ext = 0x80000000,
+                proc_ext = 0x80000001,
+                brand1 = 0x80000002,
+                brand2 = 0x80000003,
+                brand3 = 0x80000004,
+                hypervisor = 0x40000000,
+                amd_easter_egg = 0x8fffffff;
+        };
+
+        // cross-platform wrapper function for linux and MSVC cpuid
+        static void cpuid
+        (
+            u32& a, u32& b, u32& c, u32& d,
+            const u32 a_leaf,
+            const u32 c_leaf = 0xFF  // dummy value if not set manually
+        ) {
+#if (x86)
+            // may be unmodified for older 32-bit processors, clearing just in case
+            b = 0;
+            c = 0;
+#if (MSVC)
+            int32_t x[4]{};
+            __cpuidex((int32_t*)x, static_cast<int>(a_leaf), static_cast<int>(c_leaf));
+            a = static_cast<u32>(x[0]);
+            b = static_cast<u32>(x[1]);
+            c = static_cast<u32>(x[2]);
+            d = static_cast<u32>(x[3]);
+#elif (LINUX)
+            __cpuid_count(a_leaf, c_leaf, a, b, c, d);
+#endif
+#else
+            return;
+#endif
+        };
+
+        // same as above but for array type parameters (MSVC specific)
+        static void cpuid
+        (
+            int32_t x[4],
+            const u32 a_leaf,
+            const u32 c_leaf = 0xFF
+        ) {
+#if (x86)
+            // may be unmodified for older 32-bit processors, clearing just in case
+            x[1] = 0;
+            x[2] = 0;
+#if (MSVC)
+            __cpuidex((int32_t*)x, static_cast<int>(a_leaf), static_cast<int>(c_leaf));
+#elif (LINUX)
+            __cpuid_count(a_leaf, c_leaf, x[0], x[1], x[2], x[3]);
+#endif
+#else
+            return;
+#endif
+        };
+
+        // check for maximum function leaf
+        static bool is_leaf_supported(const u32 p_leaf) {
+            u32 eax, unused = 0;
+            cpu::cpuid(eax, unused, unused, unused, cpu::leaf::func_ext);
+
+            debug("CPUID function: highest leaf = ", eax);
+
+            return (p_leaf <= eax);
+        }
+
+        // check AMD
+        [[nodiscard]] static bool is_amd() {
+            constexpr u32 amd_ecx = 0x444d4163; // "cAMD"
+
+            u32 unused, ecx = 0;
+            cpuid(unused, unused, ecx, unused, 0);
+
+            return (ecx == amd_ecx);
+        }
+
+        // check Intel
+        [[nodiscard]] static bool is_intel() {
+            constexpr u32 intel_ecx1 = 0x6c65746e; // "ntel"
+            constexpr u32 intel_ecx2 = 0x6c65746f; // "otel", this is because some Intel CPUs have a rare manufacturer string of "GenuineIotel"
+
+            u32 unused, ecx = 0;
+            cpuid(unused, unused, ecx, unused, 0);
+
+            return ((ecx == intel_ecx1) || (ecx == intel_ecx2));
+        }
+
+        // check for POSSIBILITY of hyperthreading, I don't think there's a 
+        // full-proof method to detect if you're actually hyperthreading imo.
+        [[nodiscard]] static bool has_hyperthreading() {
+            u32 unused, ebx, edx;
+
+            cpuid(unused, ebx, unused, edx, 1);
+            UNUSED(unused);
+
+            bool htt_available = (edx & (1 << 28));
+
+            if (!htt_available) {
+                return false;
+            }
+
+            i32 logical_cores = ((ebx >> 16) & 0xFF);
+            i32 physical_cores = 0;
+
+#if (MSVC)
+            SYSTEM_INFO sysinfo;
+            GetSystemInfo(&sysinfo);
+            physical_cores = sysinfo.dwNumberOfProcessors;
+#elif (LINUX)
+            physical_cores = static_cast<i32>(sysconf(_SC_NPROCESSORS_CONF));
+#elif (APPLE)
+            sysctlbyname("hw.physicalcpu", &physical_cores, sizeof(physical_cores), NULL, 0);
+#else
+            return false;
+#endif
+
+            return (logical_cores > physical_cores);
+        }
+
+        // get the CPU product
+        [[nodiscard]] static std::string get_brand() {
+            if (memo::cpu_brand::is_cached()) {
+                return memo::cpu_brand::fetch();
+            }
+
+            if (!core::cpuid_supported) {
+                return "Unknown";
+            }
+
+#if (!x86)
+            return "Unknown";
+#else
+            if (!cpu::is_leaf_supported(cpu::leaf::brand3)) {
+                return "Unknown";
+            }
+
+            std::array<u32, 4> buffer{};
+            constexpr std::size_t buffer_size = sizeof(int32_t) * buffer.size();
+            std::array<char, 64> charbuffer{};
+
+            constexpr std::array<u32, 3> ids = {{
+                cpu::leaf::brand1,
+                cpu::leaf::brand2,
+                cpu::leaf::brand3
+            }};
+
+            std::string brand = "";
+
+            for (const u32& id : ids) {
+                cpu::cpuid(buffer.at(0), buffer.at(1), buffer.at(2), buffer.at(3), id);
+
+                std::memcpy(charbuffer.data(), buffer.data(), buffer_size);
+
+                const char* convert = charbuffer.data();
+                brand += convert;
+            }
+
+            debug("BRAND: ", "cpu brand = ", brand);
+
+            memo::cpu_brand::store(brand);
+
+            return brand;
+#endif
+        }
+
+
+        [[nodiscard]] static std::array<std::string, 2> cpu_manufacturer(const u32 p_leaf) {
+            auto cpuid_thingy = [](const u32 p_leaf, u32* regs, std::size_t start = 0, std::size_t end = 4) -> bool {
+                u32 x[4]{};
+                cpu::cpuid(x[0], x[1], x[2], x[3], p_leaf);
+
+                for (; start < end; start++) {
+                    *regs++ = x[start];
+                }
+
+                return true;
+            };
+
+            u32 sig_reg[3] = { 0 };
+
+            if (
+                (sig_reg[0] == 0) &&
+                (sig_reg[1] == 0) &&
+                (sig_reg[2] == 0)
+            ) {
+                return { "", "" };
+            }
+
+            if (!cpuid_thingy(p_leaf, sig_reg, 1)) {
+                return { "", "" };
+            }
+
+            auto strconvert = [](u64 n) -> std::string {
+                const std::string& str(reinterpret_cast<char*>(&n));
+                return str;
+            };
+
+            // the reason why there's 2 is because depending on the leaf, 
+            // the last 4 characters might be switched with the middle 
+            // characters for some fuckin reason, idk why this is even a thing
+            // so this function basically returns the same string but with 
+            // the 4~8 and 8~12 characters switched for one, and the other isn't.
+            std::stringstream ss;
+            std::stringstream ss2;
+
+            ss << strconvert(sig_reg[0]);
+            ss << strconvert(sig_reg[2]);
+            ss << strconvert(sig_reg[1]);
+
+            ss2 << strconvert(sig_reg[0]);
+            ss2 << strconvert(sig_reg[1]);
+            ss2 << strconvert(sig_reg[2]);
+
+            std::string brand_str = ss.str();
+            std::string brand_str2 = ss2.str();
+
+            const std::array<std::string, 2> result = { brand_str, brand_str2 };
+
+            return result;
+        }
+
+        struct stepping_struct {
+            u8 model;
+            u8 family;
+            u8 extmodel;
+        };
+
+        [[nodiscard]] static stepping_struct fetch_steppings() {
+            struct stepping_struct steps {};
+
+            u32 unused, eax = 0;
+            cpu::cpuid(eax, unused, unused, unused, 1);
+            UNUSED(unused);
+
+            steps.model = ((eax >> 4) & 0b1111);
+            steps.family = ((eax >> 8) & 0b1111);
+            steps.extmodel = ((eax >> 16) & 0b1111);
+
+            return steps;
+        }
+
+        // check if the CPU is an intel celeron
+        [[nodiscard]] static bool is_celeron(const stepping_struct steps) {
+            if (!cpu::is_intel()) {
+                return false;
+            }
+
+            constexpr u8 celeron_model = 0xA;
+            constexpr u8 celeron_family = 0x6;
+            constexpr u8 celeron_extmodel = 0x2;
+
+            return (
+                steps.model == celeron_model &&
+                steps.family == celeron_family &&
+                steps.extmodel == celeron_extmodel
+                );
+        }
+
+
+        struct model_struct {
+            bool found;
+            bool is_xeon;
+            bool is_i_series;
+            bool is_ryzen;
+            std::string string;
+        };
+
+        [[nodiscard]] static model_struct get_model() {
+            const std::string brand = get_brand();
+
+            constexpr const char* intel_i_series_regex = "i[0-9]-[A-Z0-9]{1,7}";
+            constexpr const char* intel_xeon_series_regex = "[DEW]-[A-Z0-9]{1,7}";
+            constexpr const char* amd_ryzen_regex = "^(PRO)?[A-Z0-9]{1,7}";
+
+            std::string match_str = "";
+
+            auto match = [&](const char* regex) -> bool {
+                std::regex pattern(regex);
+
+                auto words_begin = std::sregex_iterator(brand.begin(), brand.end(), pattern);
+                auto words_end = std::sregex_iterator();
+
+                for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
+                    std::smatch match = *i;
+                    match_str = match.str();
+                }
+
+                if (!match_str.empty()) {
+                    return true;
+                }
+
+                return false;
+                };
+
+            bool found = false;
+            bool is_xeon = false;
+            bool is_i_series = false;
+            bool is_ryzen = false;
+
+            if (cpu::is_intel()) {
+                if (match(intel_i_series_regex)) {
+                    found = true;
+                    is_i_series = true;
+                } else if (match(intel_xeon_series_regex)) {
+                    found = true;
+                    is_xeon = true;
+                }
+            }
+
+            if (cpu::is_amd()) {
+                if (match(amd_ryzen_regex)) {
+                    found = true;
+                    is_ryzen = true;
+                }
+            }
+
+            return model_struct{ found, is_xeon, is_i_series, is_ryzen, match_str };
+        };
+
+#if (CPP >= 17)
+        [[nodiscard]] static bool vmid_template(const u32 p_leaf, [[maybe_unused]] const char* technique_name) {
+#else 
+        [[nodiscard]] static bool vmid_template(const u32 p_leaf, const char* technique_name) {
+#endif
+#if (CPP >= 17)
+            constexpr std::string_view
+#else
+            const std::string
+#endif
+                bhyve = "bhyve bhyve ",
+                bhyve2 = "BHyVE BHyVE ",
+                kvm = "KVMKVMKVM\0\0\0",
+                kvm_hyperv = "Linux KVM Hv",
+                qemu = "TCGTCGTCGTCG",
+                hyperv = "Microsoft Hv",
+                xta = "MicrosoftXTA",
+                parallels = " prl hyperv ",
+                parallels2 = " lrpepyh  vr",
+                vmware = "VMwareVMware",
+                vbox = "VBoxVBoxVBox",
+                xen = "XenVMMXenVMM",
+                acrn = "ACRNACRNACRN",
+                qnx = " QNXQVMBSQG ",
+                qnx2 = "QXNQSBMV",
+                nvmm = "___ NVMM ___",
+                openbsd_vmm = "OpenBSDVMM58",
+                intel_haxm = "HAXMHAXMHAXM",
+                virtapple = "VirtualApple",
+                unisys = "UnisysSpar64",
+                lmhs = "SRESRESRESRE",
+                jailhouse = "Jailhouse\0\0\0",
+                apple_vz = "Apple VZ",
+                intel_kgt = "EVMMEVMMEVMM";
+
+            const std::array<std::string, 2> brand_strings = cpu_manufacturer(p_leaf);
+
+            debug(technique_name, brand_strings.at(0));
+            debug(technique_name, brand_strings.at(1));
+
+#if (CPP < 17)
+            // bypass compiler warning about unused parameter, ignore this
+            UNUSED(technique_name);
+#endif
+
+            for (const std::string &brand_str : brand_strings) {
+                if (brand_str == qemu) { return core::add(QEMU); }
+                if (brand_str == vmware) { return core::add(VMWARE); }
+                if (brand_str == vbox) { return core::add(VBOX); }
+                if (brand_str == bhyve) { return core::add(BHYVE); }
+                if (brand_str == bhyve2) { return core::add(BHYVE); }
+                if (brand_str == kvm) { return core::add(KVM); }
+                if (brand_str == kvm_hyperv) { return core::add(KVM_HYPERV); }
+                if (brand_str == xta) { return core::add(MSXTA); }
+                if (brand_str == parallels) { return core::add(PARALLELS); }
+                if (brand_str == parallels2) { return core::add(PARALLELS); }
+                if (brand_str == xen) { return core::add(XEN); }
+                if (brand_str == acrn) { return core::add(ACRN); }
+                if (brand_str == qnx) { return core::add(QNX); }
+                if (brand_str == virtapple) { return core::add(APPLE_ROSETTA); }
+                if (brand_str == nvmm) { return core::add(NVMM); }
+                if (brand_str == openbsd_vmm) { return core::add(BSD_VMM); }
+                if (brand_str == intel_haxm) { return core::add(INTEL_HAXM); }
+                if (brand_str == unisys) { return core::add(UNISYS); }
+                if (brand_str == lmhs) { return core::add(LMHS); }
+                if (brand_str == jailhouse) { return core::add(JAILHOUSE); }
+                if (brand_str == intel_kgt) { return core::add(INTEL_KGT); }
+
+                // both Hyper-V and VirtualPC have the same string value
+                if (brand_str == hyperv) {
+                    if (util::hyper_x()) {
+                        return false;
+                    }
+                    return core::add(HYPERV, VPC);
+                }
+
+                /**
+                 * this is added because there are inconsistent string
+                 * values for KVM's manufacturer ID. For example,
+                 * it gives me "KVMKMVMKV" when I run it under QEMU
+                 * but the Wikipedia article on CPUID says it's
+                 * "KVMKVMKVM\0\0\0", like wtf????
+                 */
+                if (util::find(brand_str, "KVM")) {
+                    return core::add(KVM);
+                }
+
+                /**
+                 * i'm honestly not sure about this one,
+                 * they're supposed to have 12 characters but
+                 * Wikipedia tells me it these brands have
+                 * less characters (both 8), so i'm just
+                 * going to scan for the entire string ig
+                 */
+#if (CPP >= 17)
+                const char* qnx_sample = qnx2.data();
+                const char* applevz_sample = apple_vz.data();
+#else
+                const char* qnx_sample = qnx2.c_str();
+                const char* applevz_sample = apple_vz.c_str();
+#endif
+
+                if (util::find(brand_str, qnx_sample)) {
+                    return core::add(QNX);
+                }
+
+                if (util::find(brand_str, applevz_sample)) {
+                    return core::add(APPLE_VZ);
+                }
+            }
+
+            return false;
+        }
+    };
+
+    // memoization
+    struct memo {
+    private:
+        using result_t = bool;
+        using points_t = u8;
+
+    public:
+        struct data_t {
+            result_t result;
+            points_t points;
+        };
+
+    private:
+        static std::map<u16, data_t> cache_table;
+        static flagset cache_keys;
+
+    public:
+        static void cache_store(const u16 technique_macro, const result_t result, const points_t points) {
+            cache_table[technique_macro] = { result, points };
+            cache_keys.set(technique_macro);
+        }
+
+        static bool is_cached(const u16 technique_macro) {
+            return cache_keys.test(technique_macro);
+        }
+
+        static data_t cache_fetch(const u16 technique_macro) {
+            return cache_table.at(technique_macro);
+        }
+
+        static std::vector<u16> cache_fetch_all() {
+            std::vector<u16> vec;
+
+            for (auto it = cache_table.cbegin(); it != cache_table.cend(); ++it) {
+                const data_t data = it->second;
+
+                if (data.result == true) {
+                    const u16 macro = it->first;
+                    vec.push_back(macro);
+                }
+            }
+
+            return vec;
+        }
+
+        // basically checks whether all the techniques were cached (with exception of techniques disabled by default)
+        static bool all_present() {
+            if (cache_table.size() == technique_count) {
+                return true;
+            } else if (cache_table.size() == static_cast<std::size_t>(technique_count) - 3) {
+                return (
+                    !cache_keys.test(CURSOR) &&
+                    !cache_keys.test(RDTSC_VMEXIT) &&
+                    !cache_keys.test(RDTSC) &&
+                    !cache_keys.test(VMWARE_DMESG)
+                );
+            }
+
+            return false;
+        }
+
+        struct brand {
+            static std::string brand_cache;
+
+            static std::string fetch() {
+                return brand_cache;
+            }
+
+            static void store(const std::string& p_brand) {
+                brand_cache = p_brand;
+            }
+
+            static bool is_cached() {
+                return (!brand_cache.empty());
+            }
+        };
+
+        struct multi_brand {
+            static std::string brand_cache;
+
+            static std::string fetch() {
+                return brand_cache;
+            }
+
+            static void store(const std::string& p_brand) {
+                brand_cache = p_brand;
+            }
+
+            static bool is_cached() {
+                return (!brand_cache.empty());
+            }
+        };
+
+        struct cpu_brand {
+            static std::string brand_cache;
+
+            static std::string fetch() {
+                return brand_cache;
+            }
+
+            static void store(const std::string& p_brand) {
+                brand_cache = p_brand;
+            }
+
+            static bool is_cached() {
+                return (!brand_cache.empty());
+            }
+        };
+
+        struct hyperx {
+            static hyperx_state state;
+            static bool cached;
+
+            static hyperx_state fetch() {
+                return state;
+            }
+
+            static void store(const hyperx_state p_state) {
+                state = p_state;
+                cached = true;
+            }
+
+            static bool is_cached() {
+                return cached;
+            }
+        };
+
+#if (MSVC)
+        struct wmi {
+            static bool cached;
+            static bool status;
+
+            static void store(const bool p_status) {
+                cached = true;
+                status = p_status;
+            }
+
+            static bool is_cached() {
+                return cached;
+            }
+
+            static bool fetch() {
+                return status;
+            }
+        };
+#endif
+    };
+
+#if (MSVC)
+    struct wmi {
+        static IWbemLocator* pLoc;
+        static IWbemServices* pSvc;
+
+        enum class result_type {
+            String,
+            Integer,
+            Double,
+            None
+        };
+
+        struct result {
+            result_type type;
+            union {
+                std::string strValue;
+                int intValue;
+                double doubleValue;
+            };
+
+            result(const std::string& str) : type(result_type::String), strValue(str) {}
+
+            result(int integer) : type(result_type::Integer), intValue(integer) {}
+
+            result(double dbl) : type(result_type::Double), doubleValue(dbl) {}
+
+            result(const result& other) : type(other.type), strValue() {
+                if (type == result_type::String) {
+                    new (&strValue) std::string(other.strValue);
+                }
+                else if (type == result_type::Integer) {
+                    intValue = other.intValue;
+                }
+                else if (type == result_type::Double) {
+                    doubleValue = other.doubleValue;
+                }
+            }
+
+            result& operator=(const result& other) {
+                if (this != &other) {
+                    if (type == result_type::String) {
+                        strValue.~basic_string();
+                    }
+                    type = other.type;
+                    if (type == result_type::String) {
+                        new (&strValue) std::string(other.strValue);
+                    } else if (type == result_type::Integer) {
+                        intValue = other.intValue;
+                    } else if (type == result_type::Double) {
+                        doubleValue = other.doubleValue;
+                    }
+                }
+                return *this;
+            }
+
+            ~result() {
+                if (type == result_type::String) {
+                    strValue.~basic_string();
+                }
+            }
+        };
+
+        static bool initialize() {
+            if (memo::wmi::is_cached()) {
+                return memo::wmi::fetch();
+            }
+
+            // this will clean up wmi when the program terminates
+            std::atexit(wmi::cleanup);
+
+            if (pSvc != nullptr) {
+                memo::wmi::store(true);
+                return true;
+            }
+
+            HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
+            if (FAILED(hres)) {
+                debug("wmi: Failed to initialize COM library. Error code = ", hres);
+                memo::wmi::store(false);
+                return false;
+            }
+
+            hres = CoInitializeSecurity(
+                NULL,
+                -1,
+                NULL,
+                NULL,
+                RPC_C_AUTHN_LEVEL_DEFAULT,
+                RPC_C_IMP_LEVEL_IMPERSONATE,
+                NULL,
+                EOAC_NONE,
+                NULL
+            );
+
+            if (FAILED(hres)) {
+                CoUninitialize();
+                debug("wmi: Failed to initialize security. Error code = ", hres);
+                memo::wmi::store(false);
+                return false;
+            }
+
+            hres = CoCreateInstance(
+                CLSID_WbemLocator,
+                0,
+                CLSCTX_INPROC_SERVER,
+                IID_IWbemLocator,
+                (LPVOID*)&pLoc
+            );
+
+            if (FAILED(hres)) {
+                CoUninitialize();
+                debug("wmi: Failed to create IWbemLocator object. Error code = ", hres);
+                memo::wmi::store(false);
+                return false;
+            }
+
+            hres = pLoc->ConnectServer(
+                _bstr_t(L"ROOT\\CIMV2"),
+                NULL,
+                NULL,
+                0,
+                NULL,
+                0,
+                0,
+                &pSvc
+            );
+
+            if (FAILED(hres)) {
+                pLoc->Release();
+                CoUninitialize();
+                debug("wmi: Could not connect to WMI server. Error code = ", hres);
+                memo::wmi::store(false);
+                return false;
+            }
+
+            hres = CoSetProxyBlanket(
+                pSvc,
+                RPC_C_AUTHN_WINNT,
+                RPC_C_AUTHZ_NONE,
+                NULL,
+                RPC_C_AUTHN_LEVEL_CALL,
+                RPC_C_IMP_LEVEL_IMPERSONATE,
+                NULL,
+                EOAC_NONE
+            );
+
+            if (FAILED(hres)) {
+                pSvc->Release();
+                pLoc->Release();
+                CoUninitialize();
+                debug("wmi: Could not set proxy blanket. Error code = ", hres);
+                memo::wmi::store(false);
+                return false;
+            }
+
+            memo::wmi::store(true);
+            return true;
+        }
+
+        static std::vector<result> execute(const std::wstring& query, const std::vector<std::wstring>& properties) {
+            std::vector<result> results;
+
+            IEnumWbemClassObject* pEnumerator = NULL;
+            HRESULT hres = pSvc->ExecQuery(
+                _bstr_t(L"WQL"),
+                _bstr_t(query.c_str()),
+                WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
+                NULL,
+                &pEnumerator
+            );
+
+            if (FAILED(hres)) {
+                debug("wmi: ExecQuery failed. Error code = ", hres);
+                return results;
+            }
+
+            IWbemClassObject* pclsObj = NULL;
+            ULONG uReturn = 0;
+
+            while (pEnumerator) {
+                HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+
+                if (0 == uReturn || FAILED(hr)) {
+                    break;
+                }
+
+                for (const auto& prop : properties) {
+                    VARIANT vtProp;
+                    VariantInit(&vtProp);
+                    hr = pclsObj->Get(prop.c_str(), 0, &vtProp, 0, 0);
+
+                    if (SUCCEEDED(hr)) {
+                        if (vtProp.vt == VT_BSTR) {
+                            results.emplace_back(_com_util::ConvertBSTRToString(vtProp.bstrVal));
+                        }
+                        else if (vtProp.vt == VT_I4) {
+                            results.emplace_back(vtProp.intVal);
+                        }
+                        else if (vtProp.vt == VT_R8) {
+                            results.emplace_back(vtProp.dblVal);
+                        }
+                    }
+                    VariantClear(&vtProp);
+                }
+
+                pclsObj->Release();
+            }
+
+            pEnumerator->Release();
+            return results;
+        }
+
+        static void cleanup() {
+            if (pSvc) {
+                pSvc->Release();
+                pSvc = nullptr;
+            }
+
+            if (pLoc) {
+                pLoc->Release();
+                pLoc = nullptr;
+            }
+
+            CoUninitialize();
+
+            core_debug("WMI has been cleaned");
+        }
+    };
+
+    using wmi_result = std::vector<wmi::result>;
+#endif
+
+    // miscellaneous functionalities
+    struct util {
+#if (LINUX)
+        // fetch file data
+        [[nodiscard]] static std::string read_file(const char* file_path) {
+            if (!exists(file_path)) {
+                return "";
+            }
+
+            std::ifstream file{};
+            std::string data{};
+            file.open(file_path);
+
+            if (file.is_open()) {
+                file >> data;
+            }
+
+            file.close();
+            return data;
+        }
+#endif
+
+        // fetch the file but in binary form
+        [[nodiscard]] static std::vector<u8> read_file_binary(const char* file_path) {
+            std::ifstream file(file_path, std::ios::binary);
+    
+            if (!file) {
+                std::vector<u8> tmp{};
+                return tmp;
+            }
+
+            std::vector<u8> buffer((std::istreambuf_iterator<char>(file)),
+                                    std::istreambuf_iterator<char>());
+
+            file.close();
+
+            return buffer;
+        }
+
+        // check if file exists
+        [[nodiscard]] static bool exists(const char* path) {
+#if (MSVC)
+            return (GetFileAttributesA(path) != INVALID_FILE_ATTRIBUTES) || (GetLastError() != ERROR_FILE_NOT_FOUND);
+#else 
+#if (CPP >= 17)
+            return std::filesystem::exists(path);
+#elif (CPP >= 11)
+            struct stat buffer;
+            return (stat(path, &buffer) == 0);
+#endif
+#endif
+        }
+
+#if (MSVC) && (_UNICODE)
+        // handle TCHAR conversion
+        [[nodiscard]] static bool exists(const TCHAR* path) {
+            char c_szText[_MAX_PATH]{};
+            size_t convertedChars = 0;
+            wcstombs_s(&convertedChars, c_szText, path, _MAX_PATH);
+            return exists(c_szText);
+        }
+#endif
+
+        // wrapper for std::make_unique because it's not available for C++11
+        template<typename T, typename... Args>
+        [[nodiscard]] static std::unique_ptr<T> make_unique(Args&&... args) {
+#if (CPP < 14)
+            return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+#else
+            return std::make_unique<T>(std::forward<Args>(args)...);
+#endif
+        }
+
+        // self-explanatory
+        [[nodiscard]] static bool is_admin() noexcept {
+#if (LINUX || APPLE)
+            const uid_t uid = getuid();
+            const uid_t euid = geteuid();
+
+            return (
+                (uid != euid) ||
+                (euid == 0)
+            );
+#elif (MSVC)
+            BOOL is_admin = FALSE;
+            HANDLE hToken = NULL;
+            if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
+                DWORD dwSize = 0;
+                if (!GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwSize) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+                    PTOKEN_MANDATORY_LABEL pTIL = (PTOKEN_MANDATORY_LABEL)malloc(dwSize);
+                    if (pTIL != NULL) {
+                        if (GetTokenInformation(hToken, TokenIntegrityLevel, pTIL, dwSize, &dwSize)) {
+                            SID* pSID = (SID*)GetSidSubAuthority(pTIL->Label.Sid, (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1));
+                            DWORD dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid, (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1));
+
+                            if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID) {
+                                is_admin = TRUE;
+                            }
+
+                            UNUSED(pSID);
+                        }
+                        free(pTIL);
+                    }
+                }
+            }
+
+            CloseHandle(hToken); 
+
+            return is_admin;
+#endif
+        }
+
+        // scan for keyword in string
+        [[nodiscard]] static bool find(const std::string& base_str, const char* keyword) noexcept {
+            return (base_str.find(keyword) != std::string::npos);
+        };
+
+        // for debug output
+#ifdef __VMAWARE_DEBUG__
+#if (CPP < 17)
+        // Helper function to handle the recursion
+        static inline void print_to_stream(std::ostream&) noexcept {
+            // Base case: do nothing
+        }
+
+        template <typename T, typename... Args>
+        static void print_to_stream(std::ostream& os, T&& first, Args&&... args) noexcept {
+            os << std::forward<T>(first);
+            using expander = int[];
+            (void)expander {
+                0, (void(os << std::forward<Args>(args)), 0)...
+            };
+        }
+#endif
+
+        template <typename... Args>
+        static inline void debug_msg(Args... message) noexcept {
+#if (LINUX || APPLE)
+            constexpr const char* black_bg = "\x1B[48;2;0;0;0m";
+            constexpr const char* bold = "\033[1m";
+            constexpr const char* blue = "\x1B[38;2;00;59;193m";
+            constexpr const char* ansiexit = "\x1B[0m";
+
+            std::cout.setf(std::ios::fixed, std::ios::floatfield);
+            std::cout.setf(std::ios::showpoint);
+
+            std::cout << black_bg << bold << "[" << blue << "DEBUG" << ansiexit << bold << black_bg << "]" << ansiexit << " ";
+#else       
+            std::cout << "[DEBUG] ";
+#endif
+
+#if (CPP >= 17)
+            ((std::cout << message), ...);
+#else
+            print_to_stream(std::cout, message...);
+#endif
+
+            std::cout << std::dec << "\n";
+        }
+
+        template <typename... Args>
+        static inline void core_debug_msg(Args... message) noexcept {
+#if (LINUX || APPLE)
+            constexpr const char* black_bg = "\x1B[48;2;0;0;0m";
+            constexpr const char* bold = "\033[1m";
+            constexpr const char* blue = "\x1B[38;2;255;180;5m";
+            constexpr const char* ansiexit = "\x1B[0m";
+
+            std::cout.setf(std::ios::fixed, std::ios::floatfield);
+            std::cout.setf(std::ios::showpoint);
+
+            std::cout << black_bg << bold << "[" << blue << "CORE DEBUG" << ansiexit << bold << black_bg << "]" << ansiexit << " ";
+#else       
+            std::cout << "[CORE DEBUG] ";
+#endif
+
+#if (CPP >= 17)
+            ((std::cout << message), ...);
+#else
+            print_to_stream(std::cout, message...);
+#endif
+
+            std::cout << std::dec << "\n";
+        }
+#endif
+
+        // basically std::system but it runs in the background with std::string output
+        [[nodiscard]] static std::unique_ptr<std::string> sys_result(const TCHAR* cmd) {
+#if (CPP < 14)
+            std::unique_ptr<std::string> tmp(nullptr);
+            UNUSED(cmd);
+            return tmp;
+#else
+#if (LINUX || APPLE)
+#if (ARM)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wignored-attributes"
+#endif
+            std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
+
+#if (ARM)
+#pragma GCC diagnostic pop
+#endif
+
+            if (!pipe) {
+                return nullptr;
+            }
+
+            std::string result{};
+            std::array<char, 128> buffer{};
+
+            while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
+                result += buffer.data();
+            }
+
+            result.pop_back();
+
+            return util::make_unique<std::string>(result);
+#elif (MSVC)
+            // Set up the structures for creating the process
+            STARTUPINFO si = { 0 };
+            PROCESS_INFORMATION pi = { 0 };
+            si.cb = sizeof(si);
+
+            // Create a pipe to capture the command output
+            HANDLE hReadPipe, hWritePipe;
+            SECURITY_ATTRIBUTES sa;
+            sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+            sa.bInheritHandle = TRUE;
+            sa.lpSecurityDescriptor = NULL;
+
+            if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) {
+                debug("sys_result: ", "error creating pipe");
+
+                return nullptr;
+            }
+
+            // Set up the startup information with the write end of the pipe as the standard output
+            si.hStdError = hWritePipe;
+            si.hStdOutput = hWritePipe;
+            si.dwFlags |= STARTF_USESTDHANDLES;
+
+            // Create the process
+            if (!CreateProcess(NULL, const_cast<TCHAR*>(cmd), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
+                debug("sys_result: ", "error creating process");
+
+                CloseHandle(hReadPipe);
+                CloseHandle(hWritePipe);
+                return nullptr;
+            }
+
+            // Close the write end of the pipe as it's not needed in this process
+            CloseHandle(hWritePipe);
+
+            // Read the output from the pipe
+            char buffer[4096];
+            DWORD bytesRead;
+            std::string result;
+
+            while (ReadFile(hReadPipe, buffer, sizeof(buffer), &bytesRead, NULL) && bytesRead > 0) {
+                result.append(buffer, bytesRead);
+            }
+
+            // Close handles
+            CloseHandle(hReadPipe);
+            CloseHandle(pi.hProcess);
+            CloseHandle(pi.hThread);
+
+            // Return the result as a unique_ptr<string>
+            return util::make_unique<std::string>(result);
+#endif
+#endif
+        }
+
+        // get disk size in GB
+        [[nodiscard]] static u32 get_disk_size() {
+            u32 size = 0;
+            constexpr u64 GB = (static_cast<u64>(1024 * 1024) * 1024);
+
+#if (LINUX)
+            struct statvfs stat;
+
+            if (statvfs("/", &stat) != 0) {
+                debug("private util::get_disk_size( function: ", "failed to fetch disk size");
+                return false;
+            }
+
+            // in gigabytes
+            size = static_cast<u32>((stat.f_blocks * stat.f_frsize) / GB);
+#elif (MSVC)
+            ULARGE_INTEGER totalNumberOfBytes;
+
+            if (GetDiskFreeSpaceExW(
+                L"C:",                      // Drive or directory path (use wide character string)
+                nullptr,                    // Free bytes available to the caller (not needed for total size)
+                reinterpret_cast<PULARGE_INTEGER>(&totalNumberOfBytes),  // Total number of bytes on the disk
+                nullptr                     // Total number of free bytes on the disk (not needed for total size)
+            )) {
+                size = static_cast<u32>(totalNumberOfBytes.QuadPart) / GB;
+            } else {
+                debug("util::get_disk_size(: ", "failed to fetch size in GB");
+            }
+#endif
+
+            if (size == 0) {
+                return false;
+            }
+
+            // round to the nearest factor of 10
+            const u32 result = static_cast<u32>(std::round((size / 10.0) * 10));
+
+            debug("private util::get_disk_size( function: ", "disk size = ", result, "GB");
+
+            return result;
+        }
+
+        // get physical RAM size in GB
+        [[nodiscard]] static u64 get_physical_ram_size() {
+#if (LINUX)
+            if (!util::is_admin()) {
+                debug("private get_physical_ram_size function: ", "not root, returned 0");
+                return 0;
+            }
+
+            auto result = util::sys_result("dmidecode --type 19 | grep 'Size' | grep '[[:digit:]]*'");
+
+            if (result == nullptr) {
+                debug("private get_physical_ram_size function: ", "invalid system result from dmidecode, returned 0");
+                return 0;
+            }
+
+            const bool MB = (std::regex_search(*result, std::regex("MB")));
+            const bool GB = (std::regex_search(*result, std::regex("GB")));
+
+            if (!(MB || GB)) {
+                debug("private get_physical_ram_size function: ", "neither MB nor GB found, returned 0");
+                return 0;
+            }
+
+            std::string number_str;
+            bool in_number = false;
+
+            for (char c : *result) {
+                if (std::isdigit(c)) {
+                    number_str += c;
+                    in_number = true;
+                } else if (in_number) {
+                    break;
+                }
+            }
+
+            if (number_str.empty()) {
+                debug("private get_physical_ram_size_gb function: ", "string is empty, returned 0");
+                return 0;
+            }
+
+            u64 number = 0;
+
+            number = std::stoull(number_str);
+
+            if (MB == true) {
+                number = static_cast<u64>(std::round(number / 1024));
+            }
+
+            return number; // in GB
+#elif (MSVC)
+            if (!IsWindowsVistaOrGreater()) {
+                return 0;
+            }
+
+            ULONGLONG total_memory_kb = 0;
+
+            if (GetPhysicallyInstalledSystemMemory(&total_memory_kb) == ERROR_INVALID_DATA) {
+                return 0;
+            }
+
+            return (total_memory_kb / (static_cast<unsigned long long>(1024) * 1024)); // MB
+#else
+            return 0;
+#endif
+        }
+
+        // get available memory space
+        [[nodiscard]] static u64 get_memory_space() {
+#if (MSVC)
+            MEMORYSTATUSEX statex = { 0 };
+            statex.dwLength = sizeof(statex);
+            GlobalMemoryStatusEx(&statex); // calls NtQuerySystemInformation
+            return statex.ullTotalPhys;
+#elif (LINUX)
+            const i64 pages = sysconf(_SC_PHYS_PAGES);
+            const i64 page_size = sysconf(_SC_PAGE_SIZE);
+            return (pages * page_size);
+#elif (APPLE)
+            int32_t mib[2] = { CTL_HW, HW_MEMSIZE };
+            u32 namelen = sizeof(mib) / sizeof(mib[0]);
+            u64 size = 0;
+            std::size_t len = sizeof(size);
+
+            if (sysctl(mib, namelen, &size, &len, NULL, 0) < 0) {
+                return 0;
+            }
+
+            return size; // in bytes
+#endif
+        }
+
+
+        [[nodiscard]] static bool is_proc_running(const TCHAR* executable) {
+#if (MSVC)
+            DWORD processes[1024], bytesReturned;
+
+            if (!EnumProcesses(processes, sizeof(processes), &bytesReturned))
+                return false;
+
+            DWORD numProcesses = bytesReturned / sizeof(DWORD);
+
+            for (DWORD i = 0; i < numProcesses; ++i) {
+                const HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processes[i]);
+                if (process != nullptr) {
+                    TCHAR processName[MAX_PATH];
+                    if (GetModuleBaseName(process, nullptr, processName, sizeof(processName) / sizeof(TCHAR))) {
+                        if (!_tcsicmp(processName, executable)) {
+                            CloseHandle(process);
+                            return true;
+                        }
+                    }
+                    CloseHandle(process);
+                }
+            }
+
+            return false;
+#elif (LINUX)
+#if (CPP >= 17)
+            for (const auto& entry : std::filesystem::directory_iterator("/proc")) {
+                if (!(entry.is_directory())) {
+                    continue;
+                }
+
+                const std::string filename = entry.path().filename().string();
+#else
+            //DIR* dir = opendir("/proc/");
+            std::unique_ptr<DIR, decltype(&closedir)> dir(opendir("/proc"), closedir);
+            if (!dir) {
+                debug("util::is_proc_running: ", "failed to open /proc directory");
+                return false;
+            }
+
+            struct dirent* entry;
+            while ((entry = readdir(dir.get())) != nullptr) {
+                std::string filename(entry->d_name);
+                if (filename == "." || filename == "..") {
+                    continue;
+                }
+#endif
+                if (!(std::all_of(filename.begin(), filename.end(), ::isdigit))) {
+                    continue;
+                }
+
+                const std::string cmdline_file = "/proc/" + filename + "/cmdline";
+                std::ifstream cmdline(cmdline_file);
+                if (!(cmdline.is_open())) {
+                    continue;
+                }
+
+                std::string line;
+                std::getline(cmdline, line);
+                cmdline.close();
+
+                if (line.empty()) {
+                    continue;
+                }
+
+                //std::cout << "\n\nLINE = " << line << "\n";
+                if (line.find(executable) == std::string::npos) {
+                    //std::cout << "skipped\n";
+                    continue;
+                }
+
+                //std::cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nNOT SKIPPED\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
+
+                const std::size_t slash_index = line.find_last_of('/');
+
+                if (slash_index == std::string::npos) {
+                    continue;
+                }
+
+                line = line.substr(slash_index + 1);
+
+                const std::size_t space_index = line.find_first_of(' ');
+
+                if (space_index != std::string::npos) {
+                    line = line.substr(0, space_index);
+                }
+
+                if (line != executable) {
+                    continue;
+                }
+                //#if (CPP < 17)
+                //                closedir(dir);
+                //                free(dir);
+                //#endif
+                return true;
+            }
+
+            return false;
+#else
+            return false;
+#endif
+        }
+
+        [[nodiscard]] static std::string get_hostname() {
+#if (MSVC)
+            char ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
+            DWORD cbComputerName = sizeof(ComputerName);
+
+            if (GetComputerNameA(ComputerName, &cbComputerName)) {
+                return std::string(ComputerName);
+            }
+#elif (LINUX)
+            char hostname[HOST_NAME_MAX];
+
+            if (gethostname(hostname, sizeof(hostname)) == 0) {
+                return std::string(hostname);
+            }
+#endif
+
+            return std::string();
+        }
+
+
+        /**
+         * @brief Checks whether Hyper-V host artifacts are present instead of an actual Hyper-V VM
+         * @note Hyper-V has an obscure feature where if it's enabled in the host system, the CPU 
+         *       hardware values makes it look like the whole system is running inside Hyper-V, 
+         *       which isn't true. This makes it a challenge to determine whether the hardware 
+         *       values the library is collecting is either a real Hyper-V VM, or just the artifacts 
+         *       of what Hyper-V has left as a consequence of having it enabled in the host system. 
+         *       The reason why this is a problem is because the library might falsely conclude that 
+         *       your the host system is running in Hyper-V, which is a false positive. This is where 
+         *       the Hyper-X mechanism comes into play to distinguish between these two.
+         * @author idea by Requiem (https://github.com/NotRequiem)
+         * @returns boolean, true = Hyper-V artifact, false = Real Hyper-V VM
+         * @link graph to explain how this works: https://github.com/kernelwernel/VMAware/blob/main/assets/hyper-x/v4/Hyper-X_version_4.drawio.png
+         */
+        [[nodiscard]] static bool hyper_x() {
+#if (!MSVC)
+            return false;
+#else
+            if (memo::hyperx::is_cached()) {
+                core_debug("HYPER_X: returned from cache");
+                return (memo::hyperx::fetch() == hyperx_state::HYPERV_ARTIFACT_VM);
+            }
+
+
+            // SMBIOS check
+            auto is_smbios_hyperv = []() -> bool {
+                const std::string smbios = SMBIOS_string();
+                const bool result = (smbios == "VIRTUAL MACHINE");
+
+                if (result) {
+                    core_debug("HYPER_X: SMBIOS string = ", smbios);
+                    core_debug("HYPER_X: SMBIOS string returned true");
+                }
+
+                return result;
+            };
+
+            // ACPI Data check
+            auto is_acpi_hyperv = []() -> bool {
+                const std::string acpi_data = AcpiData_string();
+                const bool result = (acpi_data == "VRTUAL MICROSFT");
+
+                if (result) {
+                    core_debug("HYPER_X: ACPI string = ", acpi_data);
+                    core_debug("HYPER_X: ACPI string returned true");
+                }
+
+                return result;
+            };
+
+            // motherboard check
+            auto is_motherboard_hyperv = []() -> bool {
+                const bool motherboard = motherboard_string("Microsoft Corporation");
+
+                if (motherboard) {
+                    core_debug("HYPER_X: motherboard string match = ", motherboard);
+                }
+
+                return motherboard;
+            };
+
+
+            // event log check (slow, so in last place)
+            auto is_event_log_hyperv = []() -> bool {
+                std::wstring logName = L"Microsoft-Windows-Kernel-PnP/Configuration";
+                std::vector<std::wstring> searchStrings = { L"Virtual_Machine", L"VMBUS" };
+                const bool result = (util::query_event_logs(logName, searchStrings));
+
+                if (result) {
+                    core_debug("HYPER_X: event log returned true");
+                }
+
+                return result;
+            };
+
+
+            // VMProtect method for Hyper-V artifact detection
+            auto is_root_partition = []() -> bool {
+                u32 ebx, unused = 0;
+                cpu::cpuid(unused, ebx, unused, unused, 0x40000003);
+                const bool result = (ebx & 1);
+
+                if (result) {
+                    core_debug("HYPER_X: root partition returned true");
+                }
+
+                return result;
+            };
+
+
+            // check if eax is either 11 or 12 after running VM::HYPERVISOR_STR technique
+            auto eax = []() -> u32 {
+                char out[sizeof(int32_t) * 4 + 1] = { 0 }; // e*x size + number of e*x registers + null terminator
+                cpu::cpuid((int*)out, cpu::leaf::hypervisor);
+
+                const u32 eax = static_cast<u32>(out[0]);
+
+                core_debug("HYPER_X: eax = ", eax);
+
+                return eax;
+            };
+
+            bool run_mechanism = false;
+
+            switch (eax()) {
+                case 11: run_mechanism = false; break; // real hyper-v vm
+                case 12: run_mechanism = true; break; // artifact hyper-v vm
+                default:
+                    // fallback in case eax fails
+                    if (is_root_partition()) {
+                        run_mechanism = true;
+                    }
+            }
+
+            enum hyperx_state state;
+
+            if (run_mechanism) {
+                const bool has_hyperv_indications = (
+                    is_smbios_hyperv() || 
+                    is_acpi_hyperv() ||
+                    is_motherboard_hyperv() || 
+                    is_event_log_hyperv()
+                );
+
+                const bool eax_result = (eax() == 11 || eax() == 12);
+
+                const bool is_real_hyperv_vm = (eax_result && has_hyperv_indications);
+
+                if (is_real_hyperv_vm) {
+                    state = hyperx_state::HYPERV_REAL_VM;
+                } else {
+                    state = hyperx_state::HYPERV_ARTIFACT_VM;
+                }
+            } else if (eax() == 11) {
+                state = hyperx_state::HYPERV_REAL_VM;
+            } else {
+                core_debug("HYPER_X: none detected");
+                state = hyperx_state::UNKNOWN;
+            }
+
+            memo::hyperx::store(state);
+            core_debug("HYPER_X: cached");
+
+            // false means it's an artifact, which is what the 
+            // point of this whole function is supposed to do
+            switch (state) {
+                case hyperx_state::HYPERV_ARTIFACT_VM:
+                    core_debug("HYPER_X: added Hyper-V artifact VM");
+                    core::add(HYPERV_ARTIFACT);
+                    return true;
+
+                case hyperx_state::HYPERV_REAL_VM:
+                    core_debug("HYPER_X: added Hyper-V real VM");
+                    core::add(HYPERV);
+                    return false;
+
+                case hyperx_state::UNKNOWN:
+                    core_debug("HYPER_X: none detected");
+                    return false;
+
+                default: 
+                    return false;
+            }
+#endif
+        }
+
+#if (MSVC)
+        /**
+         * @link: https://codereview.stackexchange.com/questions/249034/systeminfo-a-c-class-to-retrieve-system-management-data-from-the-bios
+         * @author: arcomber
+         */
+        class sys_info {
+        private:
+#pragma pack(push) 
+#pragma pack(1)
+            /*
+            SMBIOS Structure header (System Management BIOS) spec:
+            https ://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.3.0.pdf
+            */
+            struct SMBIOSHEADER
+            {
+                uint8_t type;
+                uint8_t length;
+                uint16_t handle;
+            };
+
+            /*
+            Structure needed to get the SMBIOS table using GetSystemFirmwareTable API.
+            see https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemfirmwaretable
+            */
+            struct SMBIOSData {
+                uint8_t  Used20CallingMethod;
+                uint8_t  SMBIOSMajorVersion;
+                uint8_t  SMBIOSMinorVersion;
+                uint8_t  DmiRevision;
+                uint32_t  Length;
+                uint8_t  SMBIOSTableData[1];
+            };
+
+            // System Information (Type 1)
+            struct SYSTEMINFORMATION {
+                SMBIOSHEADER Header;
+                uint8_t Manufacturer;
+                uint8_t ProductName;
+                uint8_t Version;
+                uint8_t SerialNumber;
+                uint8_t UUID[16];
+                uint8_t WakeUpType;  // Identifies the event that caused the system to power up
+                uint8_t SKUNumber;   // identifies a particular computer configuration for sale
+                uint8_t Family;
+            };
+#pragma pack(pop) 
+
+            // helper to retrieve string at string offset. Optional null string description can be set.
+            const char* get_string_by_index(const char* str, int index, const char* null_string_text = "")
+            {
+                if (0 == index || 0 == *str) {
+                    return null_string_text;
+                }
+
+                while (--index) {
+                    str += strlen(str) + 1;
+                }
+                return str;
+            }
+
+            // retrieve the BIOS data block from the system
+            SMBIOSData* get_bios_data() {
+                SMBIOSData* bios_data = nullptr;
+
+                // GetSystemFirmwareTable with arg RSMB retrieves raw SMBIOS firmware table
+                // return value is either size of BIOS table or zero if function fails
+                DWORD bios_size = GetSystemFirmwareTable('RSMB', 0, NULL, 0);
+
+                if (bios_size > 0) {
+                    if (bios_data != nullptr) {
+                        bios_data = (SMBIOSData*)malloc(bios_size);
+
+                        // Retrieve the SMBIOS table
+                        DWORD bytes_retrieved = GetSystemFirmwareTable('RSMB', 0, bios_data, bios_size);
+
+                        if (bytes_retrieved != bios_size) {
+                            free(bios_data);
+                            bios_data = nullptr;
+                        }
+                    }
+                }
+
+                return bios_data;
+            }
+
+
+            // locates system information memory block in BIOS table
+            SYSTEMINFORMATION* find_system_information(SMBIOSData* bios_data) {
+                uint8_t* data = bios_data->SMBIOSTableData;
+
+                while (data < bios_data->SMBIOSTableData + bios_data->Length)
+                {
+                    uint8_t* next;
+                    SMBIOSHEADER* header = (SMBIOSHEADER*)data;
+
+                    if (header->length < 4)
+                        break;
+
+                    //Search for System Information structure with type 0x01 (see para 7.2)
+                    if (header->type == 0x01 && header->length >= 0x19)
+                    {
+                        return (SYSTEMINFORMATION*)header;
+                    }
+
+                    //skip over formatted area
+                    next = data + header->length;
+
+                    //skip over unformatted area of the structure (marker is 0000h)
+                    while (next < bios_data->SMBIOSTableData + bios_data->Length && (next[0] != 0 || next[1] != 0)) {
+                        next++;
+                    }
+                    next += 2;
+
+                    data = next;
+                }
+                return nullptr;
+            }
+
+        public:
+            // System information data retrieved on construction and string members populated
+            sys_info() {
+                SMBIOSData* bios_data = get_bios_data();
+
+                if (bios_data) {
+                    SYSTEMINFORMATION* sysinfo = find_system_information(bios_data);
+                    if (sysinfo) {
+                        const char* str = (const char*)sysinfo + sysinfo->Header.length;
+
+                        manufacturer_ = get_string_by_index(str, sysinfo->Manufacturer);
+                        productname_ = get_string_by_index(str, sysinfo->ProductName);
+                        serialnumber_ = get_string_by_index(str, sysinfo->SerialNumber);
+                        version_ = get_string_by_index(str, sysinfo->Version);
+
+                        // for v2.1 and later
+                        if (sysinfo->Header.length > 0x08)
+                        {
+                            static const int max_uuid_size{ 50 };
+                            char uuid[max_uuid_size] = {};
+                            _snprintf_s(uuid, max_uuid_size, static_cast<size_t>(max_uuid_size) - 1, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+                                sysinfo->UUID[0], sysinfo->UUID[1], sysinfo->UUID[2], sysinfo->UUID[3],
+                                sysinfo->UUID[4], sysinfo->UUID[5], sysinfo->UUID[6], sysinfo->UUID[7],
+                                sysinfo->UUID[8], sysinfo->UUID[9], sysinfo->UUID[10], sysinfo->UUID[11],
+                                sysinfo->UUID[12], sysinfo->UUID[13], sysinfo->UUID[14], sysinfo->UUID[15]);
+
+                            uuid_ = uuid;
+                        }
+
+                        if (sysinfo->Header.length > 0x19)
+                        {
+                            // supported in v 2.4 spec
+                            sku_ = get_string_by_index(str, sysinfo->SKUNumber);
+                            family_ = get_string_by_index(str, sysinfo->Family);
+                        }
+                    }
+                    free(bios_data);
+                }
+            }
+
+            // get product family
+            const std::string get_family() const {
+                return family_;
+            }
+
+            // get manufacturer - generally motherboard or system assembler name
+            const std::string get_manufacturer() const {
+                return manufacturer_;
+            }
+
+            // get product name
+            const std::string get_productname() const {
+                return productname_;
+            }
+
+            // get BIOS serial number
+            const std::string get_serialnumber() const {
+                return serialnumber_;
+            }
+
+            // get SKU / system configuration
+            const std::string get_sku() const {
+                return sku_;
+            }
+
+            // get a universally unique identifier for system
+            const std::string get_uuid() const {
+                return uuid_;
+            }
+
+            // get version of system information
+            const std::string get_version() const {
+                return version_;
+            }
+
+            sys_info(sys_info const&) = delete;
+            sys_info& operator=(sys_info const&) = delete;
+
+        private:
+            std::string family_;
+            std::string manufacturer_;
+            std::string productname_;
+            std::string serialnumber_;
+            std::string sku_;
+            std::string uuid_;
+            std::string version_;
+        };
+
+        [[nodiscard]] static bool is_wow64() {
+            BOOL isWow64 = FALSE;
+            BOOL tmp = IsWow64Process(GetCurrentProcess(), &isWow64);
+            return (tmp && isWow64);
+        }
+
+        // backup function in case the main get_windows_version function fails
+        [[nodiscard]] static u8 get_windows_version_backup() {
+            u8 ret = 0;
+            NTSTATUS(WINAPI * RtlGetVersion)(LPOSVERSIONINFOEXW) = nullptr;
+            OSVERSIONINFOEXW osInfo{};
+
+            const HMODULE ntdllModule = GetModuleHandleA("ntdll.dll");
+
+            if (ntdllModule == nullptr) {
+                return false;
+            }
+
+            *(FARPROC*)&RtlGetVersion = GetProcAddress(ntdllModule, "RtlGetVersion");
+
+            if (RtlGetVersion == nullptr) {
+                return false;
+            }
+
+            if (RtlGetVersion != nullptr) {
+                osInfo.dwOSVersionInfoSize = sizeof(osInfo);
+                RtlGetVersion(&osInfo);
+                ret = static_cast<u8>(osInfo.dwMajorVersion);
+            }
+
+            return ret;
+        }
+
+        // credits to @Requiem for the code, thanks man :)
+        [[nodiscard]] static u8 get_windows_version() {
+            typedef NTSTATUS(WINAPI* RtlGetVersionFunc)(PRTL_OSVERSIONINFOW);
+
+            const std::map<DWORD, u8> windowsVersions = {
+                { 6002, static_cast<u8>(6) }, // windows vista, technically no number but this function is just for great than operations anyway so it doesn't matter
+                { 7601, static_cast<u8>(7) },
+                { 9200, static_cast<u8>(8) },
+                { 9600, static_cast<u8>(8) },
+                { 10240, static_cast<u8>(10) },
+                { 10586, static_cast<u8>(10) },
+                { 14393, static_cast<u8>(10) },
+                { 15063, static_cast<u8>(10) },
+                { 16299, static_cast<u8>(10) },
+                { 17134, static_cast<u8>(10) },
+                { 17763, static_cast<u8>(10) },
+                { 18362, static_cast<u8>(10) },
+                { 18363, static_cast<u8>(10) },
+                { 19041, static_cast<u8>(10) },
+                { 19042, static_cast<u8>(10) },
+                { 19043, static_cast<u8>(10) },
+                { 19044, static_cast<u8>(10) },
+                { 19045, static_cast<u8>(10) },
+                { 22000, static_cast<u8>(11) },
+                { 22621, static_cast<u8>(11) },
+                { 22631, static_cast<u8>(11) }
+            };
+
+            const HMODULE ntdll = GetModuleHandleA("ntdll.dll");
+            if (!ntdll) {
+                return util::get_windows_version_backup();
+            }
+
+            RtlGetVersionFunc pRtlGetVersion = (RtlGetVersionFunc)GetProcAddress(ntdll, "RtlGetVersion");
+            if (!pRtlGetVersion) {
+                return util::get_windows_version_backup();
+            }
+
+            RTL_OSVERSIONINFOW osvi{};
+            osvi.dwOSVersionInfoSize = sizeof(osvi);
+
+            if (pRtlGetVersion(&osvi) != 0) {
+                return util::get_windows_version_backup();
+            }
+
+            u8 major_version = 0;
+
+            if (windowsVersions.find(osvi.dwBuildNumber) != windowsVersions.end()) {
+                major_version = windowsVersions.at(osvi.dwBuildNumber);
+            }
+
+            if (major_version == 0) {
+                return util::get_windows_version_backup();
+            }
+
+            return major_version;
+        }
+
+
+        [[nodiscard]] static std::string SMBIOS_string() {
+            HKEY hk = 0;
+            int ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\mssmbios\\Data", 0, KEY_ALL_ACCESS, &hk);
+            if (ret != ERROR_SUCCESS) {
+                debug("SMBIOS_string(): ret = error");
+                return "";
+            }
+
+            unsigned long type = 0;
+            unsigned long length = 0;
+
+            ret = RegQueryValueExA(hk, "SMBiosData", 0, &type, 0, &length);
+
+            if (ret != ERROR_SUCCESS) {
+                RegCloseKey(hk);
+                debug("SMBIOS_string(): ret = error 2");
+                return "";
+            }
+
+            if (length == 0) {
+                RegCloseKey(hk);
+                debug("SMBIOS_string(): length = 0");
+                return "";
+            }
+
+            char* p = static_cast<char*>(LocalAlloc(LMEM_ZEROINIT, length));
+            if (p == nullptr) {
+                RegCloseKey(hk);
+                debug("SMBIOS_string(): p = nullptr");
+                return "";
+            }
+
+            ret = RegQueryValueExA(hk, "SMBiosData", 0, &type, reinterpret_cast<unsigned char*>(p), &length);
+
+            if (ret != ERROR_SUCCESS) {
+                LocalFree(p);
+                RegCloseKey(hk);
+                debug("SMBIOS_string(): ret = error 3");
+                return "";
+            }
+
+            auto ScanDataForString = [](const unsigned char* data, unsigned long data_length, const unsigned char* string2) -> const unsigned char* {
+                std::size_t string_length = strlen(reinterpret_cast<const char*>(string2));
+                for (std::size_t i = 0; i <= (data_length - string_length); i++) {
+                    if (strncmp(reinterpret_cast<const char*>(&data[i]), reinterpret_cast<const char*>(string2), string_length) == 0) {
+                        return &data[i];
+                    }
+                }
+                return nullptr;
+            };
+
+            auto AllToUpper = [](char* str, std::size_t len) {
+                for (std::size_t i = 0; i < len; ++i) {
+                    str[i] = static_cast<char>(std::toupper(static_cast<unsigned char>(str[i])));
+                }
+            };
+
+            AllToUpper(p, length);
+
+            auto cast = [](char* p) -> unsigned char* {
+                return reinterpret_cast<unsigned char*>(p);
+            };
+
+            const unsigned char* x1 = ScanDataForString(cast(p), length, reinterpret_cast<const unsigned char*>("INNOTEK GMBH"));
+            const unsigned char* x2 = ScanDataForString(cast(p), length, reinterpret_cast<const unsigned char*>("VIRTUALBOX"));
+            const unsigned char* x3 = ScanDataForString(cast(p), length, reinterpret_cast<const unsigned char*>("SUN MICROSYSTEMS"));
+            const unsigned char* x4 = ScanDataForString(cast(p), length, reinterpret_cast<const unsigned char*>("VBOXVER"));
+            const unsigned char* x5 = ScanDataForString(cast(p), length, reinterpret_cast<const unsigned char*>("VIRTUAL MACHINE"));
+
+            std::string result = "";
+            bool is_vm = false;
+
+            if (x1 || x2 || x3 || x4 || x5) {
+                is_vm = true;
+#ifdef __VMAWARE_DEBUG__
+                if (x1) { debug("SMBIOS: x1 = ", x1); result = std::string(reinterpret_cast<const char*>(x1)); }
+                if (x2) { debug("SMBIOS: x2 = ", x2); result = std::string(reinterpret_cast<const char*>(x2)); }
+                if (x3) { debug("SMBIOS: x3 = ", x3); result = std::string(reinterpret_cast<const char*>(x3)); }
+                if (x4) { debug("SMBIOS: x4 = ", x4); result = std::string(reinterpret_cast<const char*>(x4)); }
+                if (x5) { debug("SMBIOS: x5 = ", x5); result = std::string(reinterpret_cast<const char*>(x5)); }
+#endif
+            }
+
+            LocalFree(p);
+            RegCloseKey(hk);
+
+            if (is_vm) {
+                return result;
+            }
+
+            return "";
+        }
+
+
+        [[nodiscard]] static std::string AcpiData_string() {
+            HKEY hk = 0;
+            int ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\mssmbios\\Data", 0, KEY_ALL_ACCESS, &hk);
+            if (ret != ERROR_SUCCESS) {
+                debug("AcpiData_string(): ret = error");
+                return "";
+            }
+
+            unsigned long type = 0;
+            unsigned long length = 0;
+
+            ret = RegQueryValueExA(hk, "AcpiData", 0, &type, 0, &length);
+
+            if (ret != ERROR_SUCCESS) {
+                RegCloseKey(hk);
+                debug("AcpiData_string(): ret = error 2");
+                return "";
+            }
+
+            if (length == 0) {
+                RegCloseKey(hk);
+                debug("AcpiData_string(): length = 0");
+                return "";
+            }
+
+            char* p = static_cast<char*>(LocalAlloc(LMEM_ZEROINIT, length));
+            if (p == nullptr) {
+                RegCloseKey(hk);
+                debug("AcpiData_string(): p = nullptr");
+                return "";
+            }
+
+            ret = RegQueryValueExA(hk, "AcpiData", 0, &type, reinterpret_cast<unsigned char*>(p), &length);
+
+            if (ret != ERROR_SUCCESS) {
+                LocalFree(p);
+                RegCloseKey(hk);
+                debug("AcpiData_string(): ret = error 3");
+                return "";
+            }
+
+            auto ScanDataForString = [](const unsigned char* data, unsigned long data_length, const unsigned char* string2) -> const unsigned char* {
+                std::size_t string_length = strlen(reinterpret_cast<const char*>(string2));
+                for (std::size_t i = 0; i <= (data_length - string_length); i++) {
+                    if (strncmp(reinterpret_cast<const char*>(&data[i]), reinterpret_cast<const char*>(string2), string_length) == 0) {
+                        return &data[i];
+                    }
+                }
+                return nullptr;
+                };
+
+            auto AllToUpper = [](char* str, std::size_t len) {
+                for (std::size_t i = 0; i < len; ++i) {
+                    str[i] = static_cast<char>(std::toupper(static_cast<unsigned char>(str[i])));
+                }
+                };
+
+            AllToUpper(p, length);
+
+            auto cast = [](char* p) -> unsigned char* {
+                return reinterpret_cast<unsigned char*>(p);
+                };
+
+            const unsigned char* x1 = ScanDataForString(cast(p), length, reinterpret_cast<const unsigned char*>("VRTUAL MICROSFT"));
+
+            std::string result = "";
+            bool is_virtual = false;
+
+            if (x1) {
+                is_virtual = true;
+#ifdef __VMAWARE_DEBUG__
+                debug("AcpiData: x1 = ", x1);
+                result = std::string(reinterpret_cast<const char*>(x1));
+#endif
+            }
+
+            LocalFree(p);
+            RegCloseKey(hk);
+
+            if (is_virtual) {
+                return result;
+            }
+
+            return "";
+        }
+
+
+        [[nodiscard]] static bool motherboard_string(const char* vm_string) {
+            if (!wmi::initialize()) {
+                std::cerr << "Failed to initialize WMI.\n";
+                return false;
+            }
+
+            wmi_result results = wmi::execute(L"SELECT * FROM Win32_BaseBoard", { L"Manufacturer" });
+
+            for (const auto& res : results) {
+                if (res.type == wmi::result_type::String) {
+                    if (_stricmp(res.strValue.c_str(), vm_string) == 0) {
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+
+        /**
+         * @brief Retrieves the last error message from the Windows API. Useful for __VMAWARE_DEBUG__
+         * 
+         * @author Requiem (https://github.com/NotRequiem)
+         *
+         * @return A std::wstring containing the error message.
+         */
+        [[nodiscard]] static std::wstring GetLastErrorString() {
+            const DWORD error = GetLastError();
+            LPWSTR messageBuffer = nullptr;
+            size_t size = FormatMessageW(
+                FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+                nullptr, error, 0, (LPWSTR)&messageBuffer, 0, nullptr
+            );
+
+            std::wstring message(messageBuffer, size);
+            LocalFree(messageBuffer);
+            return message;
+        }
+
+
+        /**
+         * @brief Searches for specific strings within events in a Windows Event Log.
+         *
+         * @param logName The name or path of the event log to search (e.g., "System", "Application", "Security", or a custom path).
+         * @param searchStrings A vector of strings to search for within the event messages.
+         * @param flags Query flags that define the direction of the search; default is EvtQueryReverseDirection.
+         * @param timeout The maximum amount of time (in milliseconds) to wait for events; default is INFINITE.
+         * @param maxEvents The maximum number of events to process; default is 1000.
+         *
+         * @author Requiem (https://github.com/NotRequiem)
+         * 
+         * @return True if any of the search strings are found in the events; otherwise, false.
+         */
+        [[nodiscard]] static bool query_event_logs(const std::wstring& logName,
+            const std::vector<std::wstring>& searchStrings,
+            DWORD flags = EvtQueryReverseDirection,
+            DWORD timeout = INFINITE,
+            const DWORD maxEvents = 1000) {
+
+            EVT_HANDLE hLog = EvtOpenLog(nullptr, logName.c_str(), EvtOpenChannelPath);
+            if (!hLog) {
+                std::wcerr << L"Failed to open event log: " << logName << L". Error: " << GetLastErrorString() << "\n";
+                return false;
+            }
+
+            EVT_HANDLE hResults = EvtQuery(nullptr, logName.c_str(), nullptr, flags);
+            if (!hResults) {
+                std::wcerr << L"Failed to query event log: " << logName << L". Error: " << GetLastErrorString() << "\n";
+                EvtClose(hLog);
+                return false;
+            }
+
+            EVT_HANDLE hEvent = nullptr;
+            DWORD bufferUsed = 0;
+            DWORD bufferSize = 0;
+            DWORD count = 0;
+            WCHAR* pBuffer = nullptr;
+
+            // Iterate over events up to the maximum number specified
+            for (DWORD eventCount = 0; eventCount < maxEvents; ++eventCount) {
+                if (!EvtNext(hResults, 1, &hEvent, timeout, 0, &count)) {
+                    if (GetLastError() == ERROR_NO_MORE_ITEMS) {
+                        break; // No more events to process
+                    }
+                    std::wcerr << L"EvtNext failed. Error: " << GetLastErrorString() << "\n";
+                    EvtClose(hResults);
+                    EvtClose(hLog);
+                    return false;
+                }
+
+                if (!EvtRender(nullptr, hEvent, EvtRenderEventXml, 0, nullptr, &bufferUsed, &count) &&
+                    GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+                    bufferSize = bufferUsed;
+                    pBuffer = new WCHAR[bufferSize];
+                    if (!pBuffer) {
+                        std::cerr <<"Memory allocation failed.\n";
+                        EvtClose(hResults);
+                        EvtClose(hLog);
+                        return false;
+                    }
+
+                    if (!EvtRender(nullptr, hEvent, EvtRenderEventXml, bufferSize, pBuffer, &bufferUsed, &count)) {
+                        std::wcerr << L"EvtRender failed. Error: " << GetLastErrorString() << "\n";
+                        delete[] pBuffer;
+                        EvtClose(hResults);
+                        EvtClose(hLog);
+                        return false;
+                    }
+                }
+                else {
+                    std::wcerr << L"EvtRender failed. Error: " << GetLastErrorString() << "\n";
+                    EvtClose(hResults);
+                    EvtClose(hLog);
+                    return false;
+                }
+
+                std::wstring eventMessage(pBuffer);
+                delete[] pBuffer;
+
+                // Check if any of the search strings are found in the event message, not in the event name
+                bool found = false;
+                for (const auto& searchString : searchStrings) {
+                    if (eventMessage.find(searchString) != std::wstring::npos) {
+                        found = true;
+                        break;
+                    }
+                }
+
+                if (found) {
+                    EvtClose(hResults);
+                    EvtClose(hLog);
+                    return true;
+                }
+
+                EvtClose(hEvent);
+            }
+
+            EvtClose(hResults);
+            EvtClose(hLog);
+
+            return false;
+        }
+#endif
+    };
+
+
+private: // START OF PRIVATE VM DETECTION TECHNIQUE DEFINITIONS
+    /**
+     * @brief Check CPUID output of manufacturer ID for known VMs/hypervisors at leaf 0
+     * @category x86
+     */
+    [[nodiscard]] static bool vmid() {
+#if (!x86)
+        return false;
+#else
+        if (!core::cpuid_supported) {
+            return false;
+        }
+
+        return cpu::vmid_template(0, "VMID: ");
+#endif
+    }
+
+
+    /**
+     * @brief Check if CPU brand model contains any VM-specific string snippets
+     * @category x86
+     */
+    [[nodiscard]] static bool cpu_brand() {
+#if (!x86)
+        return false;
+#else
+        if (!core::cpuid_supported) {
+            return false;
+        }
+
+        std::string brand = cpu::get_brand();
+
+        // TODO: might add more potential keywords, be aware that it could (theoretically) cause false positives
+        constexpr std::array<const char*, 16> vmkeywords {{
+            "qemu", "kvm", "virtual", "vm",
+            "vbox", "virtualbox", "vmm", "monitor",
+            "bhyve", "hyperv", "hypervisor", "hvisor",
+            "parallels", "vmware", "hvm", "qnx"
+        }};
+
+        u8 match_count = 0;
+
+        for (auto it = vmkeywords.cbegin(); it != vmkeywords.cend(); it++) {
+            const auto regex = std::regex(*it, std::regex::icase);
+            const bool match = std::regex_search(brand, regex);
+
+            if (match) {
+                debug("BRAND_KEYWORDS: ", "match = ", *it);
+                match_count++;
+            }
+        }
+
+        debug("BRAND_KEYWORDS: ", "matches: ", static_cast<u32>(match_count));
+
+        if (match_count > 0) {
+            const auto qemu_regex = std::regex("QEMU", std::regex::icase);
+            const bool qemu_match = std::regex_search(brand, qemu_regex);
+
+            if (qemu_match) {
+                return core::add(QEMU);
+            }
+        }
+
+        return (match_count >= 1);
+#endif
+    }
+
+
+    /**
+     * @brief Check if hypervisor feature bit in CPUID eax bit 31 is enabled (always false for physical CPUs)
+     * @category x86
+     */
+    [[nodiscard]] static bool hypervisor_bit() {
+#if (!x86)
+        return false;
+#else
+        if (!core::cpuid_supported) {
+            return false;
+        }
+
+        if (util::hyper_x()) {
+            return false;
+        }
+
+        u32 unused, ecx = 0;
+        cpu::cpuid(unused, unused, ecx, unused, 1);
+
+        return (ecx & (1 << 31));
+#endif
+    }
+
+
+    /**
+     * @brief Check for hypervisor brand string length (would be around 2 characters in a host machine)
+     * @category x86
+     */
+    [[nodiscard]] static bool hypervisor_str() {
+#if (!x86)
+        return false;
+#else
+        if (util::hyper_x()) {
+            return false;
+        }
+
+        char out[sizeof(int32_t) * 4 + 1] = { 0 }; // e*x size + number of e*x registers + null terminator
+        cpu::cpuid((int*)out, cpu::leaf::hypervisor);
+
+        debug("HYPERVISOR_STR: eax: ", static_cast<u32>(out[0]),
+            "\nebx: ", static_cast<u32>(out[1]),
+            "\necx: ", static_cast<u32>(out[2]),
+            "\nedx: ", static_cast<u32>(out[3])
+        );
+
+        return (std::strlen(out + 4) >= 4);
+#endif
+    }
+
+
+    /**
+     * @brief Benchmark RDTSC and evaluate its speed, usually it's very slow in VMs
+     * @category x86
+     */
+    [[nodiscard]]
+#if (LINUX)
+    // this is added so no sanitizers can potentially cause unwanted delays while measuring rdtsc in a debug compilation
+    __attribute__((no_sanitize("address", "leak", "thread", "undefined")))
+#endif
+        static bool rdtsc_check() {
+#if (!x86)
+        return false;
+#else
+#if (LINUX)
+        u32 a, b, c, d = 0;
+
+        // check if rdtsc is available
+        if (!__get_cpuid(cpu::leaf::proc_ext, &a, &b, &c, &d)) {
+            if (!(d & (1 << 27))) {
+                return false;
+            }
+        }
+
+        u64 s, acc = 0;
+        int32_t out[4];
+
+        for (std::size_t i = 0; i < 100; ++i) {
+            s = __rdtsc();
+            cpu::cpuid(out, 0, 0);
+            acc += __rdtsc() - s;
+        }
+
+        debug("RDTSC: ", "acc = ", acc);
+        debug("RDTSC: ", "acc/100 = ", acc / 100);
+
+        return (acc / 100 > 350);
+#elif (MSVC)
+#define LODWORD(_qw)    ((DWORD)(_qw))
+        u64 tsc1 = 0;
+        u64 tsc2 = 0;
+        u64 tsc3 = 0;
+        for (INT i = 0; i < 10; i++) {
+            tsc1 = __rdtsc();
+            GetProcessHeap();  // delay
+            tsc2 = __rdtsc();
+#pragma warning(push)
+#pragma warning(disable: 6387)
+            CloseHandle(0);
+#pragma warning(pop)
+            tsc3 = __rdtsc();
+            const bool condition = ((LODWORD(tsc3) - LODWORD(tsc2)) / (LODWORD(tsc2) - LODWORD(tsc1)) >= 10);
+            if (condition) {
+                return false;
+            }
+        }
+
+        return true;
+#else
+        return false;
+#endif
+#endif
+    }
+
+
+    /**
+     * @brief Check if there are only 1 or 2 threads, which is a common pattern in VMs with default settings (nowadays physical CPUs should have at least 4 threads for modern CPUs
+     * @category x86 (ARM might have very low thread counts, which si why it should be only for x86)
+     */
+    [[nodiscard]] static bool thread_count() {
+#if (x86)
+        debug("THREADCOUNT: ", "threads = ", std::thread::hardware_concurrency());
+
+        struct cpu::stepping_struct steps = cpu::fetch_steppings();
+
+        if (cpu::is_celeron(steps)) {
+            return false;
+        }
+
+        return (std::thread::hardware_concurrency() <= 2);
+#else 
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if mac address starts with certain VM designated values
+     * @category All systems (I think)
+     */
+    [[nodiscard]] static bool mac_address_check() {
+        // C-style array on purpose
+        u8 mac[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+#if (LINUX)
+        struct ifreq ifr;
+        struct ifconf ifc;
+        char buf[1024];
+        int32_t success = 0;
+
+        int32_t sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+
+        if (sock == -1) {
+            return false;
+        };
+
+        ifc.ifc_len = sizeof(buf);
+        ifc.ifc_buf = buf;
+
+        if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) {
+            return false;
+        }
+
+        struct ifreq* it = ifc.ifc_req;
+        const struct ifreq* end = it + (ifc.ifc_len / sizeof(struct ifreq));
+
+        for (; it != end; ++it) {
+            std::strcpy(ifr.ifr_name, it->ifr_name);
+
+            if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
+                return false;
+            }
+
+            if (!(ifr.ifr_flags & IFF_LOOPBACK)) {
+                if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
+                    success = 1;
+                    break;
+                }
+            }
+        }
+
+        if (success) {
+            std::memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
+        } else {
+            debug("MAC: ", "not successful");
+        }
+#elif (MSVC)
+        PIP_ADAPTER_INFO AdapterInfo;
+        DWORD dwBufLen = sizeof(IP_ADAPTER_INFO);
+
+        AdapterInfo = (IP_ADAPTER_INFO*)std::malloc(sizeof(IP_ADAPTER_INFO));
+
+        if (AdapterInfo == NULL) {
+            return false;
+        }
+
+        if (GetAdaptersInfo(AdapterInfo, &dwBufLen) == ERROR_BUFFER_OVERFLOW) {
+            std::free(AdapterInfo);
+            AdapterInfo = (IP_ADAPTER_INFO*)std::malloc(dwBufLen);
+            if (AdapterInfo == NULL) {
+                return false;
+            }
+        }
+
+        if (GetAdaptersInfo(AdapterInfo, &dwBufLen) == NO_ERROR) {
+            PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo;
+            for (std::size_t i = 0; i < 6; i++) {
+                mac[i] = pAdapterInfo->Address[i];
+            }
+        }
+
+        std::free(AdapterInfo);
+#else
+        return false;
+#endif
+
+#ifdef __VMAWARE_DEBUG__
+        std::stringstream ss;
+        ss << std::setw(2) << std::setfill('0') << std::hex
+            << static_cast<int32_t>(mac[0]) << ":"
+            << static_cast<int32_t>(mac[1]) << ":"
+            << static_cast<int32_t>(mac[2]) << ":XX:XX:XX";
+        // removed for privacy reasons, cuz only the first 3 bytes are needed
+        //<< static_cast<int32_t>(mac[3]) << ":"  
+        //<< static_cast<int32_t>(mac[4]) << ":"
+        //<< static_cast<int32_t>(mac[5]);
+        debug("MAC: ", ss.str());
+#endif
+
+        // better expression to fix code duplication
+        auto compare = [=](const u8 mac1, const u8 mac2, const u8 mac3) noexcept -> bool {
+            return (mac[0] == mac1 && mac[1] == mac2 && mac[2] == mac3);
+            };
+
+        if (compare(0x08, 0x00, 0x27)) {
+            return core::add(VBOX);
+        }
+
+        if (
+            (compare(0x00, 0x0C, 0x29)) ||
+            (compare(0x00, 0x1C, 0x14)) ||
+            (compare(0x00, 0x50, 0x56)) ||
+            (compare(0x00, 0x05, 0x69))
+            ) {
+            return core::add(VMWARE);
+        }
+
+        if (compare(0x00, 0x16, 0xE3)) {
+            return core::add(XEN);
+        }
+
+        if (compare(0x00, 0x1C, 0x42)) {
+            return core::add(PARALLELS);
+        }
+
+        /*
+        see https://github.com/kernelwernel/VMAware/issues/105
+
+        if (compare(0x0A, 0x00, 0x27)) {
+            return core::add(HYBRID);
+        }
+        */
+
+        return false;
+    }
+
+
+    /**
+     * @brief Check if thermal directory in linux is present, might not be present in VMs
+     * @category Linux
+     */
+    [[nodiscard]] static bool temperature() {
+#if (!LINUX)
+        return false;
+#else
+        return (!util::exists("/sys/class/thermal/thermal_zone0/"));
+#endif
+    }
+
+
+    /**
+     * @brief Check result from systemd-detect-virt tool
+     * @category Linux
+     */
+    [[nodiscard]] static bool systemd_virt() {
+#if (!LINUX)
+        return false;
+#else
+        if (!(util::exists("/usr/bin/systemd-detect-virt") || util::exists("/bin/systemd-detect-virt"))) {
+            debug("SYSTEMD: ", "binary doesn't exist");
+            return false;
+        }
+
+        const std::unique_ptr<std::string> result = util::sys_result("systemd-detect-virt");
+
+        if (result == nullptr) {
+            debug("SYSTEMD: ", "invalid stdout output from systemd-detect-virt");
+            return false;
+        }
+
+        debug("SYSTEMD: ", "output = ", *result);
+
+        return (*result != "none");
+#endif
+    }
+
+
+    /**
+     * @brief Check if the chassis vendor is a VM vendor
+     * @category Linux
+     */
+    [[nodiscard]] static bool chassis_vendor() {
+#if (!LINUX)
+        return false;
+#else
+        const char* vendor_file = "/sys/devices/virtual/dmi/id/chassis_vendor";
+
+        if (!util::exists(vendor_file)) {
+            debug("CVENDOR: ", "file doesn't exist");
+            return false;
+        }
+
+        const std::string vendor = util::read_file(vendor_file);
+
+        // TODO: More can definitely be added, I only tried QEMU and VMware so far
+        if (vendor == "QEMU") { return core::add(QEMU); }
+        if (vendor == "Oracle Corporation") { return core::add(VMWARE); }
+
+        debug("CVENDOR: ", "unknown vendor = ", vendor);
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if the chassis type is valid (it's very often invalid in VMs)
+     * @category Linux
+     */
+    [[nodiscard]] static bool chassis_type() {
+#if (!LINUX)
+        return false;
+#else
+        const char* chassis = "/sys/devices/virtual/dmi/id/chassis_type";
+
+        if (util::exists(chassis)) {
+            return (stoi(util::read_file(chassis)) == 1);
+        } else {
+            debug("CTYPE: ", "file doesn't exist");
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if /.dockerenv or /.dockerinit file is present
+     * @category Linux
+     */
+    [[nodiscard]] static bool dockerenv() {
+#if (!LINUX)
+        return false;
+#else
+        if (util::exists("/.dockerenv") || util::exists("/.dockerinit")) {
+            return core::add(DOCKER);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if dmidecode output matches a VM brand
+     * @category Linux
+     */
+    [[nodiscard]] static bool dmidecode() {
+#if (!LINUX)
+        return false;
+#else
+        if (!util::is_admin()) {
+            debug("DMIDECODE: ", "precondition return called (root = ", util::is_admin(), ")");
+            return false;
+        }
+
+        if (!(util::exists("/bin/dmidecode") || util::exists("/usr/bin/dmidecode"))) {
+            debug("DMIDECODE: ", "binary doesn't exist");
+            return false;
+        }
+
+        const std::unique_ptr<std::string> result = util::sys_result("dmidecode -t system | grep 'Manufacturer|Product' | grep -c \"QEMU|VirtualBox|KVM\"");
+
+        if (*result == "" || result == nullptr) {
+            debug("DMIDECODE: ", "invalid output");
+            return false;
+        } else if (*result == "QEMU") {
+            return core::add(QEMU);
+        } else if (*result == "VirtualBox") {
+            return core::add(VBOX);
+        } else if (*result == "KVM") {
+            return core::add(KVM);
+        } else if (std::atoi(result->c_str()) >= 1) {
+            return true;
+        } else {
+            debug("DMIDECODE: ", "output = ", *result);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if dmesg output matches a VM brand
+     * @category Linux
+     */
+    [[nodiscard]] static bool dmesg() {
+#if (!LINUX || CPP <= 11)
+        return false;
+#else
+        if (!util::is_admin()) {
+            return false;
+        }
+
+        if (!util::exists("/bin/dmesg") && !util::exists("/usr/bin/dmesg")) {
+            debug("DMESG: ", "binary doesn't exist");
+            return false;
+        }
+
+        const std::unique_ptr<std::string> result = util::sys_result("dmesg | grep -i hypervisor | grep -c \"KVM|QEMU\"");
+
+        if (*result == "" || result == nullptr) {
+            return false;
+        } else if (*result == "KVM") {
+            return core::add(KVM);
+        } else if (*result == "QEMU") {
+            return core::add(QEMU);
+        } else if (std::atoi(result->c_str())) {
+            return true;
+        } else {
+            debug("DMESG: ", "output = ", *result);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if /sys/class/hwmon/ directory is present. If not, likely a VM
+     * @category Linux
+     */
+    [[nodiscard]] static bool hwmon() {
+#if (!LINUX)
+        return false;
+#else
+        return (!util::exists("/sys/class/hwmon/"));
+#endif
+    }
+
+
+    /**
+     * @brief Check if the 5th byte after sidt is null
+     * @author Matteo Malvica
+     * @link https://www.matteomalvica.com/blog/2018/12/05/detecting-vmware-on-64-bit-systems/
+     * @category x86
+     */
+    [[nodiscard]] static bool sidt5() {
+#if (!x86 || !LINUX || GCC)
+        return false;
+#else
+        u8 values[10];
+        std::memset(values, 0, 10);
+
+        fflush(stdout);
+        __asm__ __volatile__("sidt %0" : "=m"(values));
+
+#ifdef __VMAWARE_DEBUG__
+        u32 result = 0;
+
+        for (u8 i = 0; i < 10; i++) {
+            result <<= 8;
+            result |= values[i];
+        }
+
+        debug("SIDT5: ", "values = 0x", std::hex, std::setw(16), std::setfill('0'), result);
+#endif
+
+        return (values[5] == 0x00);
+#endif
+    }
+
+
+    /**
+     * @brief Check if the mouse coordinates have changed after 5 seconds
+     * @note Some VMs are automatic without a human due to mass malware scanning being a thing
+     * @note Disabled by default due to performance reasons
+     * @category Windows
+     */
+    [[nodiscard]] static bool cursor_check() {
+#if (!MSVC)
+        return false;
+#else
+        POINT pos1, pos2;
+        GetCursorPos(&pos1);
+
+        debug("CURSOR: pos1.x = ", pos1.x);
+        debug("CURSOR: pos1.y = ", pos1.y);
+
+        Sleep(5000);
+        GetCursorPos(&pos2);
+
+        debug("CURSOR: pos1.x = ", pos1.x);
+        debug("CURSOR: pos1.y = ", pos1.y);
+        debug("CURSOR: pos2.x = ", pos2.x);
+        debug("CURSOR: pos2.y = ", pos2.y);
+
+        return ((pos1.x == pos2.x) && (pos1.y == pos2.y));
+#endif
+    }
+
+
+    /**
+     * @brief Find for registries of VMware tools
+     * @category Windows
+     */
+    [[nodiscard]] static bool vmware_registry() {
+#if (!MSVC)
+        return false;
+#else
+        HKEY hKey;
+        // Use wide string literal
+        bool result = (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\VMware, Inc.\\VMware Tools", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS);
+
+        debug("VMWARE_REG: result = ", result);
+
+        if (result == true) {
+            return core::add(VMWARE);
+        }
+
+        return result;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VBox RdrDN
+     * @category Windows
+     */
+    [[nodiscard]] static bool vbox_registry() {
+#if (!MSVC)
+        return false;
+#else
+        HANDLE handle = CreateFile(_T("\\\\.\\VBoxMiniRdrDN"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+        if (handle != INVALID_HANDLE_VALUE) {
+            CloseHandle(handle);
+            return core::add(VBOX);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief checks for default usernames, often a sign of a VM
+     * @category Windows
+     */
+    [[nodiscard]] static bool user_check() {
+#if (!MSVC)
+        return false;
+#else
+        TCHAR user[UNLEN + 1]{};
+        DWORD user_len = UNLEN + 1;
+        GetUserName(user, &user_len);
+
+        //TODO Ansi: debug("USER: ", "output = ", user);
+
+        if (0 == _tcscmp(user, _T("vmware"))) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VM-specific DLLs
+     * @category Windows
+     */
+    [[nodiscard]] static bool DLL_check() {
+#if (!MSVC)
+        return false;
+#else
+        const char* real_dlls[] = {
+            "kernel32.dll",
+            "networkexplorer.dll",
+            "NlsData0000.dll",
+        };
+
+        const char* false_dlls[] = {
+            "NetProjW.dll",
+            "Ghofr.dll",
+            "fg122.dll",
+        };
+
+        // Check for real DLLs
+        for (const char* dll : real_dlls) {
+            if (GetModuleHandleA(dll) == nullptr) {
+                debug("DLL: ", "LIB_INST detected true for real dll = ", dll);
+                return true; // Detected a missing real DLL
+            }
+        }
+
+        // Check for false DLLs
+        for (const char* dll : false_dlls) {
+            if (GetModuleHandleA(dll) != nullptr) {
+                debug("DLL: ", "LIB_INST detected true for false dll = ", dll);
+                return true; // Detected a loaded false DLL
+            }
+        }
+
+        return false; // No DLLs detected
+#endif
+    }
+
+
+
+    /**
+     * @brief Check for VM-specific registry values
+     * @category Windows
+     */
+    [[nodiscard]] static bool registry_key() {
+#if (!MSVC)
+        return false;
+#else
+        u8 score = 0;
+
+        auto key = [&score](const char* p_brand, const char* regkey_s) -> void {
+            HKEY regkey;
+            LONG ret;
+
+            if (util::is_wow64()) {
+                wchar_t wRegKey[MAX_PATH];
+                MultiByteToWideChar(CP_ACP, 0, regkey_s, -1, wRegKey, MAX_PATH);
+
+                ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wRegKey, 0, KEY_READ | KEY_WOW64_64KEY, &regkey);
+            } else {
+                wchar_t wRegKey[MAX_PATH];
+                MultiByteToWideChar(CP_ACP, 0, regkey_s, -1, wRegKey, MAX_PATH);
+
+                ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wRegKey, 0, KEY_READ, &regkey);
+            }
+
+            if (ret == ERROR_SUCCESS) {
+                RegCloseKey(regkey);
+                score++;
+
+                if (std::string(p_brand) != "") {
+                    debug("REGISTRY: ", "detected = ", p_brand);
+                    core::add(p_brand);
+                }
+            }
+            };
+
+        // general
+        key("", "HKLM\\Software\\Classes\\Folder\\shell\\sandbox");
+
+        // hyper-v
+        key(HYPERV, "HKLM\\SOFTWARE\\Microsoft\\Hyper-V");
+        key(HYPERV, "HKLM\\SOFTWARE\\Microsoft\\VirtualMachine");
+        key(HYPERV, "HKLM\\SOFTWARE\\Microsoft\\Virtual Machine\\Guest\\Parameters");
+        key(HYPERV, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmicheartbeat");
+        key(HYPERV, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmicvss");
+        key(HYPERV, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmicshutdown");
+        key(HYPERV, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmicexchange");
+
+        // parallels
+        key(PARALLELS, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_1AB8*");
+
+        // sandboxie
+        key(SANDBOXIE, "HKLM\\SYSTEM\\CurrentControlSet\\Services\\SbieDrv");
+        key(SANDBOXIE, "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Sandboxie");
+
+        // virtualbox
+        key(VBOX, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_80EE*");
+        key(VBOX, "HKLM\\HARDWARE\\ACPI\\DSDT\\VBOX__");
+        key(VBOX, "HKLM\\HARDWARE\\ACPI\\FADT\\VBOX__");
+        key(VBOX, "HKLM\\HARDWARE\\ACPI\\RSDT\\VBOX__");
+        key(VBOX, "HKLM\\SOFTWARE\\Oracle\\VirtualBox Guest Additions");
+        key(VBOX, "HKLM\\SYSTEM\\ControlSet001\\Services\\VBoxGuest");
+        key(VBOX, "HKLM\\SYSTEM\\ControlSet001\\Services\\VBoxMouse");
+        key(VBOX, "HKLM\\SYSTEM\\ControlSet001\\Services\\VBoxService");
+        key(VBOX, "HKLM\\SYSTEM\\ControlSet001\\Services\\VBoxSF");
+        key(VBOX, "HKLM\\SYSTEM\\ControlSet001\\Services\\VBoxVideo");
+
+        // virtualpc
+        key(VPC, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_5333*");
+        key(VPC, "HKLM\\SYSTEM\\ControlSet001\\Services\\vpcbus");
+        key(VPC, "HKLM\\SYSTEM\\ControlSet001\\Services\\vpc-s3");
+        key(VPC, "HKLM\\SYSTEM\\ControlSet001\\Services\\vpcuhub");
+        key(VPC, "HKLM\\SYSTEM\\ControlSet001\\Services\\msvmmouf");
+
+        // vmware
+        key(VMWARE, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_15AD*");
+        key(VMWARE, "HKCU\\SOFTWARE\\VMware, Inc.\\VMware Tools");
+        key(VMWARE, "HKLM\\SOFTWARE\\VMware, Inc.\\VMware Tools");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmdebug");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmmouse");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\VMTools");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\VMMEMCTL");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmware");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmci");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmx86");
+        key(VMWARE, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\IDE\\CdRomNECVMWar_VMware_IDE_CD*");
+        key(VMWARE, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\IDE\\CdRomNECVMWar_VMware_SATA_CD*");
+        key(VMWARE, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\IDE\\DiskVMware_Virtual_IDE_Hard_Drive*");
+        key(VMWARE, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\IDE\\DiskVMware_Virtual_SATA_Hard_Drive*");
+
+        // wine
+        key(WINE, "HKCU\\SOFTWARE\\Wine");
+        key(WINE, "HKLM\\SOFTWARE\\Wine");
+
+        // xen
+        key(XEN, "HKLM\\HARDWARE\\ACPI\\DSDT\\xen");
+        key(XEN, "HKLM\\HARDWARE\\ACPI\\FADT\\xen");
+        key(XEN, "HKLM\\HARDWARE\\ACPI\\RSDT\\xen");
+        key(XEN, "HKLM\\SYSTEM\\ControlSet001\\Services\\xenevtchn");
+        key(XEN, "HKLM\\SYSTEM\\ControlSet001\\Services\\xennet");
+        key(XEN, "HKLM\\SYSTEM\\ControlSet001\\Services\\xennet6");
+        key(XEN, "HKLM\\SYSTEM\\ControlSet001\\Services\\xensvc");
+        key(XEN, "HKLM\\SYSTEM\\ControlSet001\\Services\\xenvdb");
+
+        debug("REGISTRY: ", "score = ", static_cast<u32>(score));
+
+        return (score >= 1);
+#endif
+    }
+
+
+    /**
+     * @brief Check if CWSandbox-specific file exists
+     * @category Windows
+     */
+    [[nodiscard]] static bool cwsandbox_check() {
+#if (!MSVC)
+        return false;
+#else
+        if (util::exists(_T("C:\\analysis"))) {
+            return core::add(CWSANDBOX);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Find for VMware and VBox specific files
+     * @category Windows
+     */
+    [[nodiscard]] static bool vm_files() {
+#if (!MSVC)
+        return false;
+#else
+        // points
+        u8 vbox = 0;
+        u8 vmware = 0;
+
+        constexpr std::array<const TCHAR*, 26> files = {{
+                // VMware
+                _T("C:\\windows\\System32\\Drivers\\Vmmouse.sys"),
+                _T("C:\\windows\\System32\\Drivers\\vm3dgl.dll"),
+                _T("C:\\windows\\System32\\Drivers\\vmdum.dll"),
+                _T("C:\\windows\\System32\\Drivers\\VmGuestLibJava.dll"),
+                _T("C:\\windows\\System32\\Drivers\\vm3dver.dll"),
+                _T("C:\\windows\\System32\\Drivers\\vmtray.dll"),
+                _T("C:\\windows\\System32\\Drivers\\VMToolsHook.dll"),
+                _T("C:\\windows\\System32\\Drivers\\vmGuestLib.dll"),
+                _T("C:\\windows\\System32\\Drivers\\vmhgfs.dll"),
+
+                // VBox
+                _T("C:\\windows\\System32\\Drivers\\VBoxMouse.sys"),
+                _T("C:\\windows\\System32\\Drivers\\VBoxGuest.sys"),
+                _T("C:\\windows\\System32\\Drivers\\VBoxSF.sys"),
+                _T("C:\\windows\\System32\\Drivers\\VBoxVideo.sys"),
+                _T("C:\\windows\\System32\\vboxoglpackspu.dll"),
+                _T("C:\\windows\\System32\\vboxoglpassthroughspu.dll"),
+                _T("C:\\windows\\System32\\vboxservice.exe"),
+                _T("C:\\windows\\System32\\vboxoglcrutil.dll"),
+                _T("C:\\windows\\System32\\vboxdisp.dll"),
+                _T("C:\\windows\\System32\\vboxhook.dll"),
+                _T("C:\\windows\\System32\\vboxmrxnp.dll"),
+                _T("C:\\windows\\System32\\vboxogl.dll"),
+                _T("C:\\windows\\System32\\vboxtray.exe"),
+                _T("C:\\windows\\System32\\VBoxControl.exe"),
+                _T("C:\\windows\\System32\\vboxoglerrorspu.dll"),
+                _T("C:\\windows\\System32\\vboxoglfeedbackspu.dll"),
+                _T("c:\\windows\\system32\\vboxoglarrayspu.dll")
+            }};
+
+        for (const auto file : files) {
+            if (util::exists(file)) {
+                const auto regex = tregex(file, std::regex::icase);
+
+                if (std::regex_search(_T("vbox"), regex)) {
+                    //TODO Ansi: debug("VM_FILES: found vbox file = ", file);
+                    vbox++;
+                } else {
+                    //TODO Ansi: debug("VM_FILES: found vmware file = ", file);
+                    vmware++;
+                }
+            }
+        }
+
+        debug("VM_FILES: vmware score: ", static_cast<u32>(vmware));
+        debug("VM_FILES: vbox score: ", static_cast<u32>(vbox));
+
+        if (vbox > vmware) {
+            return core::add(VBOX);
+        } else if (vbox < vmware) {
+            return core::add(VMWARE);
+        } else if (
+            vbox > 0 &&
+            vmware > 0 &&
+            vbox == vmware
+            ) {
+            return true;
+        }
+
+        // general VM file, not sure which brand it belongs to though
+        if (util::exists("C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\StartUp\\agent.pyw")) {
+            return true;
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if the sysctl for the hwmodel does not contain the "Mac" string
+     * @author MacRansom ransomware
+     * @category MacOS
+     */
+    [[nodiscard]] static bool hwmodel() {
+#if (!APPLE)
+        return false;
+#else
+        auto result = util::sys_result("sysctl -n hw.model");
+
+        std::smatch match;
+
+        if (result == nullptr) {
+            debug("HWMODEL: ", "null result received");
+            return false;
+        }
+
+        debug("HWMODEL: ", "output = ", *result);
+
+        // if string contains "Mac" anywhere in the string, assume it's baremetal
+        if (std::regex_search(*result, match, std::regex("Mac"))) {
+            return false;
+        }
+
+        // not sure about the other VMs, more could potentially be added
+        if (std::regex_search(*result, match, std::regex("VMware"))) {
+            return core::add(VMWARE);
+        }
+
+        // assumed true since it doesn't contain "Mac" string
+        return true;
+#endif
+    }
+
+
+    /**
+     * @brief Check if disk size is under or equal to 50GB
+     * @category Linux (for now)
+     */
+    [[nodiscard]] static bool disk_size() {
+#if (!LINUX)
+        return false;
+#else
+        const u32 size = util::get_disk_size();
+
+        debug("DISK_SIZE: size = ", size);
+
+        return (size <= 60); // in GB
+#endif
+    }
+
+
+    /**
+     * @brief Check for default RAM and DISK sizes set by VirtualBox
+     * @note        RAM     DISK
+     * WINDOWS 11:  4096MB, 80GB
+     * WINDOWS 10:  2048MB, 50GB
+     * ARCH, OPENSUSE, REDHAD, GENTOO, FEDORA, DEBIAN: 1024MB, 8GB
+     * UBUNTU:      1028MB, 10GB
+     * ORACLE:      1024MB, 12GB
+     * OTHER LINUX: 512MB,  8GB
+
+     * @todo: check if it still applies to host systems with larger RAM and disk size than what I have
+     * @category Linux, Windows
+     */
+    [[nodiscard]] static bool vbox_default_specs() {
+#if (APPLE)
+        return false;
+#else
+        const u32 disk = util::get_disk_size();
+        const u64 ram = util::get_physical_ram_size();
+
+        debug("VBOX_DEFAULT: disk = ", disk);
+        debug("VBOX_DEFAULT: ram = ", ram);
+
+        if ((disk > 80) || (ram > 4)) {
+            debug("VBOX_DEFAULT: returned false due to lack of precondition spec comparisons");
+            return false;
+        }
+
+#if (LINUX)
+        auto get_distro = []() -> std::string {
+            std::ifstream osReleaseFile("/etc/os-release");
+            std::string line;
+
+            while (std::getline(osReleaseFile, line)) {
+                if (line.find("ID=") != std::string::npos) {
+                    const std::size_t start = line.find('"');
+                    const std::size_t end = line.rfind('"');
+                    if (start != std::string::npos && end != std::string::npos && start < end) {
+                        return line.substr(start + 1, end - start - 1);
+                    }
+                }
+            }
+
+            return "unknown";
+        };
+
+        const std::string distro = get_distro();
+
+        debug("VBOX_DEFAULT: linux, detected distro: ", distro);
+
+        // yoda notation ftw
+        if ("unknown" == distro) {
+            return false;
+        }
+
+        if (
+            "arch" == distro ||
+            "opensuse" == distro ||
+            "redhat" == distro ||
+            "gentoo" == distro ||
+            "fedora" == distro ||
+            "debian" == distro
+        ) {
+            return ((8 == disk) && (1 == ram));
+        }
+
+        if ("ubuntu" == distro) {
+            return ((10 == disk) && (1 == ram));
+        }
+
+        if ("ol" == distro) { // ol = oracle
+            return ((12 == disk) && (1 == ram));
+        }
+#elif (MSVC)
+        const u8 version = util::get_windows_version();
+
+        if (version == 0) {
+            return false;
+        }
+
+        // less than windows 10
+        if (version < 10) {
+            debug("VBOX_DEFAULT: less than windows 10 detected");
+            return false;
+        }
+
+        // windows 10
+        if (10 == version) {
+            debug("VBOX_DEFAULT: windows 10 detected");
+            return ((50 == disk) && (2 == ram));
+        }
+
+        // windows 11
+        if (11 == version) {
+            debug("VBOX_DEFAULT: windows 11 detected");
+            return ((80 == disk) && (4 == ram));
+        }
+#endif
+#endif
+        return false;
+    }
+
+
+    /**
+     * @brief Check for VirtualBox network provider string
+     * @category Windows
+     */
+    [[nodiscard]] static bool vbox_network_share() {
+#if (!MSVC)
+        return false;
+#else
+        u32 pnsize = 0x1000;
+        TCHAR* provider = new TCHAR[pnsize];
+
+        u32 retv = WNetGetProviderName(WNNC_NET_RDR2SAMPLE, provider, reinterpret_cast<LPDWORD>(&pnsize));
+
+        if (retv == NO_ERROR) {
+            bool result = (lstrcmpi(provider, _T("VirtualBox Shared Folders")) == 0);
+            delete[] provider;
+            return result;
+        }
+
+        delete[] provider;
+        return false;
+#endif
+    }
+
+
+/* GPL */     // @brief Check if the computer name (not username to be clear) is VM-specific
+/* GPL */     // @category Windows
+/* GPL */     // @author InviZzzible project
+/* GPL */     // @copyright GPL-3.0
+/* GPL */     [[nodiscard]] static bool computer_name_match() {
+/* GPL */ #if (!MSVC)
+/* GPL */         return false;
+/* GPL */ #else
+/* GPL */         auto out_length = MAX_PATH;
+/* GPL */         std::vector<u8> comp_name(static_cast<u32>(out_length), 0);
+/* GPL */         GetComputerNameA((LPSTR)comp_name.data(), (LPDWORD)&out_length);
+/* GPL */ 
+/* GPL */         auto compare = [&](const std::string& s) -> bool {
+/* GPL */             return (std::strcmp((LPCSTR)comp_name.data(), s.c_str()) == 0);
+/* GPL */             };
+/* GPL */ 
+/* GPL */         debug("COMPUTER_NAME: fetched = ", (LPCSTR)comp_name.data());
+/* GPL */ 
+/* GPL */         if (compare("InsideTm") || compare("TU-4NH09SMCG1HC")) { // anubis
+/* GPL */             debug("COMPUTER_NAME: detected Anubis");
+/* GPL */             return core::add(ANUBIS);
+/* GPL */         }
+/* GPL */ 
+/* GPL */         if (compare("klone_x64-pc") || compare("tequilaboomboom")) { // general
+/* GPL */             debug("COMPUTER_NAME: detected general (VM but unknown)");
+/* GPL */             return true;
+/* GPL */         }
+/* GPL */ 
+/* GPL */         return false;
+/* GPL */ #endif
+/* GPL */     }
+/* GPL */ 
+/* GPL */ 
+/* GPL */     // @brief Check wine_get_unix_file_name file for Wine
+/* GPL */     // @author pafish project
+/* GPL */     // @link https://github.com/a0rtega/pafish/blob/master/pafish/wine.c
+/* GPL */     // @category Windows
+/* GPL */     // @copyright GPL-3.0
+/* GPL */     [[nodiscard]] static bool wine() {
+/* GPL */ #if (!MSVC)
+/* GPL */         return false;
+/* GPL */ #else
+/* GPL */         HMODULE k32;
+/* GPL */         k32 = GetModuleHandle(TEXT("kernel32.dll"));
+/* GPL */ 
+/* GPL */         if (k32 != NULL) {
+/* GPL */             if (GetProcAddress(k32, "wine_get_unix_file_name") != NULL) {
+/* GPL */                 return core::add(WINE);
+/* GPL */             }
+/* GPL */         }
+/* GPL */ 
+/* GPL */         return false;
+/* GPL */ #endif
+/* GPL */     }
+/* GPL */ 
+/* GPL */ 
+/* GPL */     // @brief Check if hostname is specific
+/* GPL */     // @author InviZzzible project
+/* GPL */     // @category Windows
+/* GPL */     // @copyright GPL-3.0
+/* GPL */     [[nodiscard]] static bool hostname_match() {
+/* GPL */ #if (!MSVC)
+/* GPL */         return false;
+/* GPL */ #else
+/* GPL */         auto out_length = MAX_PATH;
+/* GPL */         std::vector<u8> dns_host_name(static_cast<u32>(out_length), 0);
+/* GPL */         GetComputerNameExA(ComputerNameDnsHostname, (LPSTR)dns_host_name.data(), (LPDWORD)&out_length);
+/* GPL */ 
+/* GPL */         debug("HOSTNAME: ", (LPCSTR)dns_host_name.data());
+/* GPL */ 
+/* GPL */         return (!lstrcmpiA((LPCSTR)dns_host_name.data(), "SystemIT"));
+/* GPL */ #endif
+/* GPL */     }
+/* GPL */ 
+/* GPL */ 
+/* GPL */     // @brief Check if memory space is far too low for a physical machine
+/* GPL */     // @author Al-Khaser project
+/* GPL */     // @category x86?
+/* GPL */     // @copyright GPL-3.0
+/* GPL */     [[nodiscard]] static bool low_memory_space() {
+/* GPL */         constexpr u64 min_ram_1gb = (1024LL * (1024LL * (1024LL * 1LL)));
+/* GPL */         const u64 ram = util::get_memory_space();
+/* GPL */ 
+/* GPL */         debug("MEMORY: ram size (GB) = ", ram);
+/* GPL */         debug("MEMORY: minimum ram size (GB) = ", min_ram_1gb);
+/* GPL */ 
+/* GPL */         return (ram < min_ram_1gb);
+/* GPL */     }
+/* GPL */ 
+/* GPL */ 
+/* GPL */     // @brief Check for the window class for VirtualBox
+/* GPL */     // @category Windows
+/* GPL */     // @author Al-Khaser Project
+/* GPL */     // @copyright GPL-3.0
+/* GPL */     [[nodiscard]] static bool vbox_window_class() {
+/* GPL */ #if (!MSVC)
+/* GPL */         return false;
+/* GPL */ #else
+/* GPL */         HWND hClass = FindWindow(_T("VBoxTrayToolWndClass"), NULL);
+/* GPL */         HWND hWindow = FindWindow(NULL, _T("VBoxTrayToolWnd"));
+/* GPL */ 
+/* GPL */         if (hClass || hWindow) {
+/* GPL */             return core::add(VBOX);
+/* GPL */         }
+/* GPL */ 
+/* GPL */         return false;
+/* GPL */ #endif
+/* GPL */     }
+/* GPL */ 
+/* GPL */ 
+/* GPL */     // @brief Check for loaded DLLs in the process
+/* GPL */     // @category Windows
+/* GPL */     // @author LordNoteworthy
+/* GPL */     // @note modified code from Al-Khaser project
+/* GPL */     // @link https://github.com/LordNoteworthy/al-khaser/blob/c68fbd7ba0ba46315e819b490a2c782b80262fcd/al-khaser/Anti%20VM/Generic.cpp
+/* GPL */     [[nodiscard]] static bool loaded_dlls() {
+/* GPL */ #if (!MSVC)
+/* GPL */         return false;
+/* GPL */ #else
+/* GPL */         HMODULE hDll;
+/* GPL */
+/* GPL */         std::unordered_map<std::string, const char*> dllMap = {
+/* GPL */             { "sbiedll.dll",   SANDBOXIE },  // Sandboxie
+/* GPL */             { "pstorec.dll",   CWSANDBOX },  // CWSandbox
+/* GPL */             { "vmcheck.dll",   VPC },        // VirtualPC
+/* GPL */             { "cmdvrt32.dll",  COMODO },     // Comodo
+/* GPL */             { "cmdvrt64.dll",  COMODO },     // Comodo
+/* GPL */             { "dbghelp.dll",   NULL_BRAND }, // WindBG
+/* GPL */             { "avghookx.dll",  NULL_BRAND }, // AVG
+/* GPL */             { "avghooka.dll",  NULL_BRAND }, // AVG
+/* GPL */             { "snxhk.dll",     NULL_BRAND }, // Avast
+/* GPL */             { "api_log.dll",   NULL_BRAND }, // iDefense Lab
+/* GPL */             { "dir_watch.dll", NULL_BRAND }, // iDefense Lab
+/* GPL */             { "pstorec.dll",   NULL_BRAND }, // SunBelt CWSandbox
+/* GPL */             { "vmcheck.dll",   NULL_BRAND }, // Virtual PC
+/* GPL */             { "wpespy.dll",    NULL_BRAND }  // WPE Pro
+/* GPL */         };
+/* GPL */
+/* GPL */         for (const auto& key : dllMap) {
+/* GPL */             hDll = GetModuleHandleA(key.first.c_str());
+/* GPL */ 
+/* GPL */             if (hDll != NULL) {
+/* GPL */                 auto it = dllMap.find(key.first.c_str());
+/* GPL */                 if (it != dllMap.end()) {
+/* GPL */                     return core::add(it->second); 
+/* GPL */                 }
+/* GPL */             }
+/* GPL */         }
+/* GPL */
+/* GPL */           return false;
+/* GPL */ #endif
+/* GPL */     }
+/* GPL */ 
+/* GPL */ 
+/* GPL */     // @brief Check for KVM-specific registry strings
+/* GPL */     // @category Windows
+/* GPL */     // @note idea is from Al-Khaser, slightly modified code
+/* GPL */     // @author LordNoteWorthy
+/* GPL */     // @link https://github.com/LordNoteworthy/al-khaser/blob/0f31a3866bafdfa703d2ed1ee1a242ab31bf5ef0/al-khaser/AntiVM/KVM.cpp
+/* GPL */     [[nodiscard]] static bool kvm_registry() {
+/* GPL */ #if (!MSVC)
+/* GPL */         return false;
+/* GPL */ #else
+/* GPL */         auto registry_exists = [](const TCHAR* key) -> bool {
+/* GPL */             HKEY keyHandle;
+/* GPL */ 
+/* GPL */             if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_QUERY_VALUE, &keyHandle) == ERROR_SUCCESS) {
+/* GPL */                 RegCloseKey(keyHandle);
+/* GPL */                 return true;
+/* GPL */             }
+/* GPL */ 
+/* GPL */             return false;
+/* GPL */             };
+/* GPL */ 
+/* GPL */         constexpr std::array<const TCHAR*, 7> keys = {{
+/* GPL */             _T("SYSTEM\\ControlSet001\\Services\\vioscsi"),
+/* GPL */             _T("SYSTEM\\ControlSet001\\Services\\viostor"),
+/* GPL */             _T("SYSTEM\\ControlSet001\\Services\\VirtIO-FS Service"),
+/* GPL */             _T("SYSTEM\\ControlSet001\\Services\\VirtioSerial"),
+/* GPL */             _T("SYSTEM\\ControlSet001\\Services\\BALLOON"),
+/* GPL */             _T("SYSTEM\\ControlSet001\\Services\\BalloonService"),
+/* GPL */             _T("SYSTEM\\ControlSet001\\Services\\netkvm"),
+/* GPL */         }};
+/* GPL */ 
+/* GPL */         for (const auto& key : keys) {
+/* GPL */             if (registry_exists(key)) {
+/* GPL */                 return core::add(KVM);
+/* GPL */             }
+/* GPL */         }
+/* GPL */ 
+/* GPL */         return false;
+/* GPL */ #endif
+/* GPL */     }
+/* GPL */ 
+/* GPL */ 
+/* GPL */     // @brief Check for KVM-specific .sys files in system driver directory
+/* GPL */     // @category Windows
+/* GPL */     // @note idea is from Al-Khaser, slightly modified code
+/* GPL */     // @author LordNoteWorthy
+/* GPL */     // @link https://github.com/LordNoteworthy/al-khaser/blob/0f31a3866bafdfa703d2ed1ee1a242ab31bf5ef0/al-khaser/AntiVM/KVM.cpp
+/* GPL */     [[nodiscard]] static bool kvm_drivers() {
+/* GPL */ #if (!MSVC)
+/* GPL */         return false;
+/* GPL */ #else
+/* GPL */         constexpr std::array<const TCHAR*, 10> keys = { {
+/* GPL */             _T("System32\\drivers\\balloon.sys"),
+/* GPL */             _T("System32\\drivers\\netkvm.sys"),
+/* GPL */             _T("System32\\drivers\\pvpanic.sys"),
+/* GPL */             _T("System32\\drivers\\viofs.sys"),
+/* GPL */             _T("System32\\drivers\\viogpudo.sys"),
+/* GPL */             _T("System32\\drivers\\vioinput.sys"),
+/* GPL */             _T("System32\\drivers\\viorng.sys"),
+/* GPL */             _T("System32\\drivers\\vioscsi.sys"),
+/* GPL */             _T("System32\\drivers\\vioser.sys"),
+/* GPL */             _T("System32\\drivers\\viostor.sys")
+/* GPL */         } };
+/* GPL */ 
+/* GPL */         TCHAR szWinDir[MAX_PATH] = _T("");
+/* GPL */         TCHAR szPath[MAX_PATH] = _T("");
+/* GPL */         PVOID OldValue = NULL;
+/* GPL */ 
+/* GPL */         if (GetWindowsDirectory(szWinDir, MAX_PATH) == 0) {
+/* GPL */             return false;
+/* GPL */         }
+/* GPL */ 
+/* GPL */         if (util::is_wow64()) {
+/* GPL */             Wow64DisableWow64FsRedirection(&OldValue);
+/* GPL */         }
+/* GPL */ 
+/* GPL */         bool is_vm = false;
+/* GPL */ 
+/* GPL */         for (const auto& key : keys) {
+/* GPL */             PathCombine(szPath, szWinDir, key);
+/* GPL */             if (util::exists(szPath)) {
+/* GPL */                 is_vm = true;
+/* GPL */                 break;
+/* GPL */             }
+/* GPL */         }
+/* GPL */ 
+/* GPL */         if (util::is_wow64()) {
+/* GPL */             Wow64RevertWow64FsRedirection(&OldValue);
+/* GPL */         }
+/* GPL */ 
+/* GPL */         return is_vm;
+/* GPL */ #endif
+/* GPL */     }
+/* GPL */ 
+/* GPL */ 
+/* GPL */     // @brief Check for KVM directory "Virtio-Win"
+/* GPL */     // @category Windows
+/* GPL */     // @author LordNoteWorthy
+/* GPL */     // @note from Al-Khaser project
+/* GPL */     // @link https://github.com/LordNoteworthy/al-khaser/blob/0f31a3866bafdfa703d2ed1ee1a242ab31bf5ef0/al-khaser/AntiVM/KVM.cpp
+/* GPL */     [[nodiscard]] static bool kvm_directories() {
+/* GPL */ #if (!MSVC)
+/* GPL */         return false;
+/* GPL */ #else
+/* GPL */         TCHAR szProgramFile[MAX_PATH];
+/* GPL */         TCHAR szPath[MAX_PATH] = _T("");
+/* GPL */         TCHAR szTarget[MAX_PATH] = _T("Virtio-Win\\");
+/* GPL */ 
+/* GPL */         if (util::is_wow64()) {
+/* GPL */             ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile));
+/* GPL */         } else {
+/* GPL */             SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE);
+/* GPL */         }
+/* GPL */ 
+/* GPL */         PathCombine(szPath, szProgramFile, szTarget);
+/* GPL */         return util::exists(szPath);
+/* GPL */ #endif
+/* GPL */     }
+/* GPL */ 
+/* GPL */     
+/* GPL */     // @brief Check if audio device is present
+/* GPL */     // @category Windows
+/* GPL */     // @author CheckPointSW (InviZzzible project)
+/* GPL */     // @link https://github.com/CheckPointSW/InviZzzible/blob/master/SandboxEvasion/helper.cpp
+/* GPL */     // @copyright GPL-3.0
+/* GPL */     [[nodiscard]] static bool check_audio() {
+/* GPL */ #if (!MSVC)
+/* GPL */         return false;
+/* GPL */ #else
+/* GPL */         PCWSTR wszfilterName = L"audio_device_random_name";
+/* GPL */ 
+/* GPL */         if (FAILED(CoInitialize(NULL)))
+/* GPL */             return false;
+/* GPL */ 
+/* GPL */         IGraphBuilder* pGraph = nullptr;
+/* GPL */         if (FAILED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph)))
+/* GPL */             return false;
+/* GPL */ 
+/* GPL */         // First anti-emulation check: If AddFilter is called with NULL as a first argument it should return the E_POINTER error code. 
+/* GPL */         // Some emulators may implement unknown COM interfaces in a generic way, so they will probably fail here.
+/* GPL */         if (E_POINTER != pGraph->AddFilter(NULL, wszfilterName))
+/* GPL */             return true;
+/* GPL */ 
+/* GPL */         // Initializes a simple Audio Renderer, error code is not checked, 
+/* GPL */         // but pBaseFilter will be set to NULL upon failure and the code will eventually fail later.
+/* GPL */         IBaseFilter* pBaseFilter = nullptr;
+/* GPL */ 
+/* GPL */         HRESULT hr = CoCreateInstance(CLSID_AudioRender, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pBaseFilter);
+/* GPL */         if (FAILED(hr)) {
+/* GPL */             return false;
+/* GPL */         }
+/* GPL */ 
+/* GPL */         // Adds the previously created Audio Renderer to the Filter Graph, no error checks
+/* GPL */         pGraph->AddFilter(pBaseFilter, wszfilterName);
+/* GPL */ 
+/* GPL */         // Tries to find the filter that was just added; in case of any previously not checked error (or wrong emulation) 
+/* GPL */         // this function won't find the filter and the sandbox/emulator will be successfully detected.
+/* GPL */         IBaseFilter* pBaseFilter2 = nullptr;
+/* GPL */         pGraph->FindFilterByName(wszfilterName, &pBaseFilter2);
+/* GPL */         if (nullptr == pBaseFilter2)
+/* GPL */             return true;
+/* GPL */ 
+/* GPL */         // Checks if info.achName is equal to the previously added filterName, if not - poor API emulation
+/* GPL */         FILTER_INFO info = { 0 };
+/* GPL */         pBaseFilter2->QueryFilterInfo(&info);
+/* GPL */         if (0 != wcscmp(info.achName, wszfilterName))
+/* GPL */             return false;
+/* GPL */ 
+/* GPL */         // Checks if the API sets a proper IReferenceClock pointer
+/* GPL */         IReferenceClock* pClock = nullptr;
+/* GPL */         if (0 != pBaseFilter2->GetSyncSource(&pClock))
+/* GPL */             return false;
+/* GPL */         if (0 != pClock)
+/* GPL */             return false;
+/* GPL */ 
+/* GPL */         // Checks if CLSID is different from 0
+/* GPL */         CLSID clsID = { 0 };
+/* GPL */         pBaseFilter2->GetClassID(&clsID);
+/* GPL */         if (clsID.Data1 == 0)
+/* GPL */             return true;
+/* GPL */ 
+/* GPL */         if (nullptr == pBaseFilter2)
+/* GPL */             return true;
+/* GPL */ 
+/* GPL */         // Just checks if the call was successful
+/* GPL */         IEnumPins* pEnum = nullptr;
+/* GPL */         if (0 != pBaseFilter2->EnumPins(&pEnum))
+/* GPL */             return true;
+/* GPL */ 
+/* GPL */         // The reference count returned by AddRef has to be higher than 0
+/* GPL */         if (0 == pBaseFilter2->AddRef())
+/* GPL */             return true;
+/* GPL */ 
+/* GPL */         return false;
+/* GPL */ #endif
+/* GPL */     }
+/* GPL */ 
+/* GPL */ 
+/* GPL */     // @brief Check for QEMU-specific blacklisted directories
+/* GPL */     // @author LordNoteworthy
+/* GPL */     // @link https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/AntiVM/Qemu.cpp
+/* GPL */     // @category Windows
+/* GPL */     // @note from al-khaser project
+/* GPL */     // @copyright GPL-3.0
+/* GPL */     [[nodiscard]] static bool qemu_dir() {
+/* GPL */ #if (!MSVC)
+/* GPL */         return false;
+/* GPL */ #else
+/* GPL */         TCHAR szProgramFile[MAX_PATH];
+/* GPL */         TCHAR szPath[MAX_PATH] = _T("");
+/* GPL */ 
+/* GPL */         const TCHAR* szDirectories[] = {
+/* GPL */             _T("qemu-ga"),	// QEMU guest agent.
+/* GPL */             _T("SPICE Guest Tools"), // SPICE guest tools.
+/* GPL */         };
+/* GPL */ 
+/* GPL */         WORD iLength = sizeof(szDirectories) / sizeof(szDirectories[0]);
+/* GPL */         for (int i = 0; i < iLength; i++) {
+/* GPL */             TCHAR msg[256] = _T("");
+/* GPL */ 
+/* GPL */             if (util::is_wow64())
+/* GPL */                 ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile));
+/* GPL */             else
+/* GPL */                 SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE);
+/* GPL */ 
+/* GPL */             PathCombine(szPath, szProgramFile, szDirectories[i]);
+/* GPL */ 
+/* GPL */             if (util::exists(szPath))
+/* GPL */                 return core::add(QEMU);
+/* GPL */         }
+/* GPL */ 
+/* GPL */         return false;
+/* GPL */ #endif
+/* GPL */     }
+/* GPL */ 
+/* GPL */ 
+/* GPL */     // @brief Check for the presence of a mouse device
+/* GPL */     // @category Windows
+/* GPL */     // @author a0rtega
+/* GPL */     // @link https://github.com/a0rtega/pafish/blob/master/pafish/rtt.c
+/* GPL */     // @note from pafish project
+/* GPL */     // @copyright GPL
+/* GPL */     [[nodiscard]] static bool mouse_device() {
+/* GPL */ #if (!MSVC)
+/* GPL */         return false;
+/* GPL */ #else
+/* GPL */         int res;
+/* GPL */         res = GetSystemMetrics(SM_MOUSEPRESENT);
+/* GPL */         return (res == 0);
+/* GPL */ #endif
+/* GPL */     }
+
+
+    /**
+     * @brief Check for any VM processes that are active
+     * @category Windows
+     */
+    [[nodiscard]] static bool vm_processes() {
+#if (!MSVC)
+        return false;
+#else
+        auto check_proc = [](const TCHAR* proc) -> bool {
+            DWORD processes[1024], bytesReturned;
+
+            // Retrieve the list of process identifiers
+            if (!EnumProcesses(processes, sizeof(processes), &bytesReturned))
+                return false;
+
+            // Calculate how many process identifiers were returned
+            DWORD numProcesses = bytesReturned / sizeof(DWORD);
+
+            for (DWORD i = 0; i < numProcesses; ++i) {
+                // Open the process
+                const HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processes[i]);
+                if (process != nullptr) {
+                    // Get the process name
+                    TCHAR processName[MAX_PATH];
+                    if (GetModuleBaseName(process, nullptr, processName, sizeof(processName) / sizeof(TCHAR))) {
+                        // Check if the process name matches the desired executable
+                        if (_tcscmp(processName, proc) == 0) {
+                            CloseHandle(process);
+                            return true;
+                        }
+                    }
+                    CloseHandle(process);
+                }
+            }
+
+            return false;
+            };
+
+        if (check_proc(_T("joeboxserver.exe")) || check_proc(_T("joeboxcontrol.exe"))) {
+            return core::add(JOEBOX);
+        }
+
+        if (check_proc(_T("prl_cc.exe")) || check_proc(_T("prl_tools.exe"))) {
+            return core::add(PARALLELS);
+        }
+
+        if (check_proc(_T("vboxservice.exe")) || check_proc(_T("vboxtray.exe"))) {
+            return core::add(VBOX);
+        }
+
+        if (check_proc(_T("vmsrvc.exe")) || check_proc(_T("vmusrvc.exe"))) {
+            return core::add(VPC);
+        }
+        /*
+                removed due to potential false positives
+
+                if (
+                    check_proc(_T("vmtoolsd.exe")) ||
+                    check_proc(_T("vmwaretrat.exe")) ||
+                    check_proc(_T("vmacthlp.exe")) ||
+                    check_proc(_T("vmwaretray.exe")) ||
+                    check_proc(_T("vmwareuser.exe")) ||
+                    check_proc(_T("vmware.exe")) ||
+                    check_proc(_T("vmount2.exe"))
+                ) {
+                    return core::add(VMWARE);
+                }
+        */
+
+        if (check_proc(_T("xenservice.exe")) || check_proc(_T("xsvc_depriv.exe"))) {
+            return core::add(XEN);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for default VM username and hostname for linux
+     * @category Linux
+     */
+    [[nodiscard]] static bool linux_user_host() {
+#if (!LINUX)
+        return false;
+#else
+        if (util::is_admin()) {
+            return false;
+        }
+
+        const char* username = std::getenv("USER");
+        const char* hostname = std::getenv("HOSTNAME");
+
+        debug("LINUX_USER_HOST: user = ", username);
+        debug("LINUX_USER_HOST: host = ", hostname);
+
+        return (
+            (strcmp(username, "liveuser") == 0) &&
+            (strcmp(hostname, "localhost-live") == 0)
+            );
+#endif
+    }
+
+
+    /**
+     * @brief Check for Gamarue ransomware technique which compares VM-specific Window product IDs
+     * @category Windows
+     */
+    [[nodiscard]] static bool gamarue() {
+#if (!MSVC) 
+        return false;
+#else
+        HKEY hOpen;
+        char* szBuff;
+        int iBuffSize;
+        LONG nRes;
+
+        szBuff = (char*)calloc(512, sizeof(char));
+
+        const HANDLE hMod = GetModuleHandleA("SbieDll.dll"); // Sandboxie
+        if (hMod != 0) {
+            free(szBuff);
+            return core::add(SANDBOXIE);
+        }
+
+        /* this gave a false positive
+        hMod = GetModuleHandleA("dbghelp.dll"); // ThreatExpert
+        if (hMod != 0) {
+            free(szBuff);
+            return core::add(THREATEXPERT);
+        }
+        */
+
+        nRes = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", 0L, KEY_QUERY_VALUE, &hOpen);
+        if (nRes == ERROR_SUCCESS) {
+            iBuffSize = sizeof(szBuff);
+            nRes = RegQueryValueExA(hOpen, "ProductId", NULL, NULL, (unsigned char*)szBuff, reinterpret_cast<LPDWORD>(&iBuffSize));
+            if (nRes == ERROR_SUCCESS) {
+                // Check if szBuff is not NULL before using strcmp
+                if (szBuff == NULL) {
+                    RegCloseKey(hOpen);
+                    return false;
+                }
+
+                if (strcmp(szBuff, "55274-640-2673064-23950") == 0) { // joebox
+                    free(szBuff);
+                    return core::add(JOEBOX);
+                } else if (strcmp(szBuff, "76487-644-3177037-23510") == 0) { // CW Sandbox
+                    free(szBuff);
+                    return core::add(CWSANDBOX);
+                } else if (strcmp(szBuff, "76487-337-8429955-22614") == 0) { // anubis
+                    free(szBuff);
+                    return core::add(ANUBIS);
+                } else {
+                    free(szBuff);
+                    return false;
+                }
+            }
+            RegCloseKey(hOpen);
+        }
+        // Set szBuff to NULL after freeing to avoid double free issues
+        free(szBuff);
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if the CPU manufacturer ID matches that of a VM brand with leaf 0x40000000
+     * @category x86
+     */
+    [[nodiscard]] static bool vmid_0x4() {
+#if (!x86)
+        return false;
+#else
+        if (!core::cpuid_supported) {
+            return false;
+        }
+
+        return cpu::vmid_template(cpu::leaf::hypervisor, "VMID_0x4: ");
+#endif
+    }
+
+
+    /**
+     * @brief Check for any indication of Parallels VM through BIOS data
+     * @link https://stackoverflow.com/questions/1370586/detect-if-windows-is-running-from-within-parallels
+     * @category Windows
+     */
+    [[nodiscard]] static bool parallels() {
+#if (!MSVC)
+        return false;
+#else
+        std::unique_ptr<util::sys_info> info = util::make_unique<util::sys_info>();
+
+#ifdef __VMAWARE_DEBUG__
+        debug("Manufacturer: ", info->get_manufacturer());
+        debug("Product Name: ", info->get_productname());
+        debug("Serial No: ", info->get_serialnumber());
+        debug("UUID: ", info->get_uuid());
+        debug("Version: ", info->get_version());
+
+        if (!info->get_family().empty()) {
+            debug("Product family: ", info->get_family());
+        }
+
+        if (!info->get_sku().empty()) {
+            debug("SKU/Configuration: ", info->get_sku());
+        }
+#endif
+
+        auto compare = [](const std::string& str) -> bool {
+            std::regex pattern("Parallels", std::regex_constants::icase);
+            return std::regex_match(str, pattern);
+            };
+
+        if (
+            compare(info->get_manufacturer()) ||
+            compare(info->get_productname()) ||
+            compare(info->get_family())
+            ) {
+            return core::add(PARALLELS);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief check through alternative RDTSC technique with VMEXIT
+     * @category x86
+     */
+    [[nodiscard]]
+#if (LINUX)
+    // this is added so no sanitizers can potentially cause unwanted delays while measuring rdtsc in a debug compilation
+    __attribute__((no_sanitize("address", "leak", "thread", "undefined")))
+#endif
+    static bool rdtsc_vmexit() {
+#if (!x86)
+        return false;
+#else
+        u64 tsc1 = 0;
+        u64 tsc2 = 0;
+        u64 avg = 0;
+        i32 reg[4] = {};
+
+        for (std::size_t i = 0; i < 10; i++) {
+            tsc1 = __rdtsc();
+            cpu::cpuid(reg, 0);
+            tsc2 = __rdtsc();
+            avg += (tsc2 - tsc1);
+        }
+
+        avg /= 10;
+
+        return (avg >= 1500 || avg == 0);
+#endif
+    }
+
+
+    /**
+     * @brief Match for QEMU CPU brands with "QEMU Virtual CPU" string
+     * @category x86
+     */
+    [[nodiscard]] static bool cpu_brand_qemu() {
+#if (!x86)
+        return false;
+#else
+        if (!core::cpuid_supported) {
+            return false;
+        }
+
+        std::string brand = cpu::get_brand();
+
+        std::regex qemu_pattern("QEMU Virtual CPU", std::regex_constants::icase);
+
+        if (std::regex_match(brand, qemu_pattern)) {
+            return core::add(QEMU);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for various Bochs-related emulation oversights through CPU checks
+     * @category x86
+     * @note Discovered by Peter Ferrie, Senior Principal Researcher, Symantec Advanced Threat Research peter_ferrie@symantec.com
+     */
+    [[nodiscard]] static bool bochs_cpu() {
+#if (!x86)
+        return false;z
+#else
+        if (!core::cpuid_supported) {
+            return false;
+        }
+
+        const bool intel = cpu::is_intel();
+        const bool amd = cpu::is_amd();
+
+        // if neither amd or intel, return false
+        if (!(intel || amd)) {
+            debug("BOCHS_CPU: neither AMD or Intel detected, returned false");
+            return false;
+        }
+
+        const std::string brand = cpu::get_brand();
+
+        if (intel) {
+            // technique 1: not a valid brand 
+            if (brand == "              Intel(R) Pentium(R) 4 CPU        ") {
+                debug("BOCHS_CPU: technique 1 found");
+                return core::add(BOCHS);
+            }
+        } else if (amd) {
+            // technique 2: "processor" should have a capital P
+            if (brand == "AMD Athlon(tm) processor") {
+                debug("BOCHS_CPU: technique 2 found");
+                return core::add(BOCHS);
+            }
+
+            // technique 3: Check for absence of AMD easter egg for K7 and K8 CPUs
+            constexpr u32 AMD_EASTER_EGG = 0x8fffffff; // this is the CPUID leaf of the AMD easter egg
+
+            if (!cpu::is_leaf_supported(AMD_EASTER_EGG)) {
+                return false;
+            }
+
+            u32 unused, eax = 0;
+            cpu::cpuid(eax, unused, unused, unused, 1);
+
+            auto is_k7 = [](const u32 eax) -> bool {
+                const u32 family = (eax >> 8) & 0xF;
+                const u32 model = (eax >> 4) & 0xF;
+                const u32 extended_family = (eax >> 20) & 0xFF;
+
+                if (family == 6 && extended_family == 0) {
+                    if (model == 1 || model == 2 || model == 3 || model == 4) {
+                        return true;
+                    }
+                }
+
+                return false;
+            };
+
+            auto is_k8 = [](const u32 eax) -> bool {
+                const u32 family = (eax >> 8) & 0xF;
+                const u32 extended_family = (eax >> 20) & 0xFF;
+
+                if (family == 0xF) {
+                    if (extended_family == 0x00 || extended_family == 0x01) {
+                        return true;
+                    }
+                }
+
+                return false;
+            };
+
+            if (!(is_k7(eax) || is_k8(eax))) {
+                return false;
+            }
+
+            u32 ecx_bochs = 0;
+            cpu::cpuid(unused, unused, ecx_bochs, unused, AMD_EASTER_EGG);
+
+            if (ecx_bochs == 0) {
+                return true;
+            }
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check through the motherboard and match for VirtualPC-specific string
+     * @category Windows
+     */
+    [[nodiscard]] static bool vpc_board() {
+#if (!MSVC)
+        return false;
+#else
+        const bool is_vm = util::motherboard_string("Microsoft Corporation");
+
+        if (is_vm) {
+            return core::add(VPC);
+        }
+
+        return false;
+#endif
+    }
+
+
+
+    /**
+     * @brief Check if the BIOS serial is valid (null = VM)
+     * @category Windows
+     */
+    [[nodiscard]] static bool bios_serial() {
+#if (!MSVC)
+        return false;
+#else
+        std::unique_ptr<util::sys_info> info = util::make_unique<util::sys_info>();
+
+        const std::string str = info->get_serialnumber();
+        const std::size_t nl_pos = str.find('\n');
+
+        if (nl_pos == std::string::npos) {
+            return false;
+        }
+
+        debug("BIOS_SERIAL: ", str);
+
+        const std::string extract = str.substr(nl_pos + 1);
+
+        const bool all_digits = std::all_of(extract.cbegin(), extract.cend(), [](const char c) {
+            return std::isdigit(c);
+            });
+
+        if (all_digits) {
+            if (extract == "0") {
+                return true;
+            }
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VirtualBox-specific string for shared folder ID
+     * @category Windows
+     * @note slightly modified code from original
+     * @author @waleedassar
+     * @link https://pastebin.com/xhFABpPL
+     */
+    [[nodiscard]] static bool vbox_shared_folders() {
+#if (!MSVC)
+        return false;
+#else
+        DWORD pnsize = 0;  // Initialize to 0 to query the required size
+        wchar_t* provider = nullptr;
+
+        // Query the required size
+        DWORD retv = WNetGetProviderNameW(WNNC_NET_RDR2SAMPLE, nullptr, &pnsize);
+
+        if (retv == ERROR_MORE_DATA) {
+            // Allocate a buffer of the required size
+            provider = static_cast<wchar_t*>(LocalAlloc(LMEM_ZEROINIT, pnsize));
+
+            if (provider != nullptr) {
+                // Retrieve the actual data
+                retv = WNetGetProviderNameW(WNNC_NET_RDR2SAMPLE, provider, &pnsize);
+            }
+        }
+
+        if (retv == NO_ERROR && provider != nullptr) {
+            if (lstrcmpiW(provider, L"VirtualBox Shared Folders") == 0) {
+                LocalFree(provider);
+                return core::add(VBOX);
+            }
+        }
+
+        // Clean up the allocated buffer
+        LocalFree(provider);
+
+        return false;
+
+#endif
+    }
+
+
+    /**
+     * @brief Check MSSMBIOS registry for VM-specific strings
+     * @category Windows
+     * @note slightly modified from original code
+     * @author @waleedassar
+     * @link https://pastebin.com/fPY4MiYq
+     */
+    [[nodiscard]] static bool mssmbios() {
+#if (!MSVC)
+        return false;
+#else
+        const std::string p = util::SMBIOS_string();
+
+        if (p.empty()) {
+            debug("MSSMBIOS: empty, returned false");
+            return false;
+        }
+
+#ifdef __VMAWARE_DEBUG__
+        debug("MSSMBIOS: string = ", p);
+#endif
+
+        bool is_vm = false;
+
+        const bool x1 = (p == "INNOTEK GMBH");
+        const bool x2 = (p == "VIRTUALBOX");
+        const bool x3 = (p == "SUN MICROSYSTEMS");
+        const bool x4 = (p == "VBOXVER");
+        const bool x5 = (p == "VIRTUAL MACHINE");
+
+        if (x1 || x2 || x3 || x4 || x5) {
+            is_vm = true;
+        }
+
+        if (is_vm) {
+            if (x5) {
+                return true; // Hyper-V and VirtualBox both have the same BIOS string with "VIRTUAL MACHINE"
+            }
+
+            return core::add(VBOX);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if memory is too low for MacOS system
+     * @category MacOS
+     * @link https://evasions.checkpoint.com/techniques/macos.html
+     */
+    [[nodiscard]] static bool hw_memsize() {
+#if (!APPLE)
+        return false;
+#else
+        std::unique_ptr<std::string> result = util::sys_result("sysctl -n hw.memsize");
+        const std::string ram = *result;
+
+        if (ram == "0") {
+            return false;
+        }
+
+        debug("MAC_MEMSIZE: ", "ram size = ", ram);
+
+        for (const char c : ram) {
+            if (!std::isdigit(c)) {
+                debug("MAC_MEMSIZE: ", "found non-digit character, returned false");
+                return false;
+            }
+        }
+
+        const u64 ram_u64 = std::stoull(ram);
+
+        debug("MAC_MEMSIZE: ", "ram size in u64 = ", ram_u64);
+
+        constexpr u64 limit = 4000000000; // 4GB 
+
+        return (ram_u64 <= limit);
+#endif
+    }
+
+
+    /**
+     * @brief Check MacOS' IO kit registry for VM-specific strings
+     * @category MacOS
+     * @link https://evasions.checkpoint.com/techniques/macos.html
+     */
+    [[nodiscard]] static bool io_kit() {
+#if (!APPLE)
+        return false;
+#else
+        // board_ptr and manufacturer_ptr empty
+        std::unique_ptr<std::string> platform_ptr = util::sys_result("ioreg -rd1 -c IOPlatformExpertDevice");
+        std::unique_ptr<std::string> board_ptr = util::sys_result("ioreg -rd1 -c board-id");
+        std::unique_ptr<std::string> manufacturer_ptr = util::sys_result("ioreg -rd1 -c manufacturer");
+
+        const std::string platform = *platform_ptr;
+        const std::string board = *board_ptr;
+        const std::string manufacturer = *manufacturer_ptr;
+
+        auto check_platform = [&]() -> bool {
+            debug("IO_KIT: ", "platform = ", platform);
+
+            if (platform.empty()) {
+                return false;
+            }
+
+            for (const char c : platform) {
+                if (!std::isdigit(c)) {
+                    return false;
+                }
+            }
+
+            return (platform == "0");
+            };
+
+        auto check_board = [&]() -> bool {
+            debug("IO_KIT: ", "board = ", board);
+
+            if (board.empty()) {
+                return false;
+            }
+
+            if (util::find(board, "Mac")) {
+                return false;
+            }
+
+            if (util::find(board, "VirtualBox")) {
+                return core::add(VBOX);
+            }
+
+            if (util::find(board, "VMware")) {
+                return core::add(VMWARE);
+            }
+
+            return false;
+            };
+
+        auto check_manufacturer = [&]() -> bool {
+            debug("IO_KIT: ", "manufacturer = ", manufacturer);
+
+            if (manufacturer.empty()) {
+                return false;
+            }
+
+            if (util::find(manufacturer, "Apple")) {
+                return false;
+            }
+
+            if (util::find(manufacturer, "innotek")) {
+                return core::add(VBOX);
+            }
+
+            return false;
+            };
+
+        return (
+            check_platform() ||
+            check_board() ||
+            check_manufacturer()
+            );
+
+        return false;
+#endif            
+    }
+
+
+    /**
+     * @brief Check for VM-strings in ioreg commands for MacOS
+     * @category MacOS
+     * @link https://evasions.checkpoint.com/techniques/macos.html
+     */
+    [[nodiscard]] static bool ioreg_grep() {
+#if (!APPLE)
+        return false;
+#else
+        auto check_usb = []() -> bool {
+            std::unique_ptr<std::string> result = util::sys_result("ioreg -rd1 -c IOUSBHostDevice | grep \"USB Vendor Name\"");
+            const std::string usb = *result;
+
+            if (util::find(usb, "Apple")) {
+                return false;
+            }
+
+            if (util::find(usb, "VirtualBox")) {
+                return core::add(VBOX);
+            }
+
+            return false;
+            };
+
+        auto check_general = []() -> bool {
+            std::unique_ptr<std::string> sys_vbox = util::sys_result("ioreg -l | grep -i -c -e \"virtualbox\" -e \"oracle\"");
+
+            if (std::stoi(*sys_vbox) > 0) {
+                return core::add(VBOX);
+            }
+
+            std::unique_ptr<std::string> sys_vmware = util::sys_result("ioreg -l | grep -i -c -e \"vmware\"");
+
+            if (std::stoi(*sys_vmware) > 0) {
+                return core::add(VMWARE);
+            }
+
+            return false;
+            };
+
+        auto check_rom = []() -> bool {
+            std::unique_ptr<std::string> sys_rom = util::sys_result("system_profiler SPHardwareDataType | grep \"Boot ROM Version\"");
+            const std::string rom = *sys_rom;
+
+            if (util::find(rom, "VirtualBox")) {
+                return core::add(VBOX);
+            }
+
+            return false;
+        };
+
+        return (
+            check_usb() ||
+            check_general() ||
+            check_rom()
+        );
+#endif
+    }
+
+
+    /**
+     * @brief Check if System Integrity Protection is disabled (likely a VM if it is)
+     * @category MacOS
+     * @link https://evasions.checkpoint.com/techniques/macos.html
+     */
+    [[nodiscard]] static bool mac_sip() {
+#if (!APPLE)
+        return false;
+#else
+        std::unique_ptr<std::string> result = util::sys_result("csrutil status");
+        const std::string tmp = *result;
+
+        debug("MAC_SIP: ", "result = ", tmp);
+
+        return (util::find(tmp, "disabled") || (!util::find(tmp, "enabled")));
+#endif
+    }
+
+
+    /**
+     * @brief Check HKLM registries for specific VM strings
+     * @category Windows
+     */
+    [[nodiscard]] static bool hklm_registries() {
+#if (!MSVC)
+        return false;
+#else
+        u8 count = 0;
+
+        auto check_key = [&count](const char* p_brand, const char* subKey, const char* valueName, const char* comp_string) {
+            HKEY hKey;
+            DWORD dwType = REG_SZ;
+            char buffer[1024]{};
+            DWORD bufferSize = sizeof(buffer);
+
+            if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
+                if (RegQueryValueExA(hKey, valueName, NULL, &dwType, reinterpret_cast<LPBYTE>(buffer), &bufferSize) == ERROR_SUCCESS) {
+                    if (strcmp(buffer, comp_string) == 0) {
+                        core::add(p_brand);
+                        count++;
+                    }
+                } else {
+                    debug("Failed to query value for \"", subKey, "\"");
+                }
+
+                RegCloseKey(hKey);
+            } else {
+                debug("Failed to open registry key for \"", subKey, "\"");
+            }
+        };
+
+        check_key(BOCHS, "HARDWARE\\Description\\System", "SystemBiosVersion", "BOCHS");
+        check_key(BOCHS, "HARDWARE\\Description\\System", "VideoBiosVersion", "BOCHS");
+
+        check_key(ANUBIS, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductID", "76487-337-8429955-22614");
+        check_key(ANUBIS, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductID", "76487-337-8429955-22614");
+
+        check_key(CWSANDBOX, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductID", "76487-644-3177037-23510");
+        check_key(CWSANDBOX, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductID", "76487-644-3177037-23510");
+
+        check_key(JOEBOX, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductID", "55274-640-2673064-23950");
+        check_key(JOEBOX, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductID", "55274-640-2673064-23950");
+
+        check_key(PARALLELS, "HARDWARE\\Description\\System", "SystemBiosVersion", "PARALLELS");
+        check_key(PARALLELS, "HARDWARE\\Description\\System", "VideoBiosVersion", "PARALLELS");
+
+        check_key(QEMU, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "QEMU");
+        check_key(QEMU, "HARDWARE\\Description\\System", "SystemBiosVersion", "QEMU");
+        check_key(QEMU, "HARDWARE\\Description\\System", "VideoBiosVersion", "QEMU");
+        check_key(QEMU, "HARDWARE\\Description\\System\\BIOS", "SystemManufacturer", "QEMU");
+
+        check_key(VBOX, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VBOX");
+        check_key(VBOX, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VBOX");
+        check_key(VBOX, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 2\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VBOX");
+        check_key(VBOX, "HARDWARE\\Description\\System", "SystemBiosVersion", "VBOX");
+        check_key(VBOX, "HARDWARE\\Description\\System", "VideoBiosVersion", "VIRTUALBOX");
+        check_key(VBOX, "HARDWARE\\Description\\System\\BIOS", "SystemProductName", "VIRTUAL");
+        check_key(VBOX, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", "DeviceDesc", "VBOX");
+        check_key(VBOX, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", "FriendlyName", "VBOX");
+        check_key(VBOX, "SYSTEM\\ControlSet002\\Services\\Disk\\Enum", "DeviceDesc", "VBOX");
+        check_key(VBOX, "SYSTEM\\ControlSet002\\Services\\Disk\\Enum", "FriendlyName", "VBOX");
+        check_key(VBOX, "SYSTEM\\ControlSet003\\Services\\Disk\\Enum", "DeviceDesc", "VBOX");
+        check_key(VBOX, "SYSTEM\\ControlSet003\\Services\\Disk\\Enum", "FriendlyName", "VBOX");
+        check_key(VBOX, "SYSTEM\\CurrentControlSet\\Control\\SystemInformation", "SystemProductName", "VIRTUAL");
+        check_key(VBOX, "SYSTEM\\CurrentControlSet\\Control\\SystemInformation", "SystemProductName", "VIRTUALBOX");
+
+        check_key(VMWARE, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VMWARE");
+        check_key(VMWARE, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VMWARE");
+        check_key(VMWARE, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 2\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VMWARE");
+        check_key(VMWARE, "HARDWARE\\Description\\System", "SystemBiosVersion", "VMWARE");
+        check_key(VMWARE, "HARDWARE\\Description\\System", "SystemBiosVersion", "INTEL - 6040000");
+        check_key(VMWARE, "HARDWARE\\Description\\System", "VideoBiosVersion", "VMWARE");
+        check_key(VMWARE, "HARDWARE\\Description\\System\\BIOS", "SystemProductName", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", "0", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", "1", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", "DeviceDesc", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", "FriendlyName", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet002\\Services\\Disk\\Enum", "DeviceDesc", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet002\\Services\\Disk\\Enum", "FriendlyName", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet003\\Services\\Disk\\Enum", "DeviceDesc", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet003\\Services\\Disk\\Enum", "FriendlyName", "VMware");
+        //check_key(HKCR\Installer\Products 	ProductName 	vmware tools
+        //check_key(HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall 	DisplayName 	vmware tools
+        check_key(VMWARE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", "DisplayName", "vmware tools");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000", "CoInstallers32", "*vmx*");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000", "DriverDesc", "VMware*");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000", "InfSection", "vmx*");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000", "ProviderName", "VMware*");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000\\Settings", "Device Description", "VMware*");
+        check_key(VMWARE, "SYSTEM\\CurrentControlSet\\Control\\SystemInformation", "SystemProductName", "VMWARE");
+        check_key(VMWARE, "SYSTEM\\CurrentControlSet\\Control\\Video\\{GUID}\\Video", "Service", "vm3dmp");
+        check_key(VMWARE, "SYSTEM\\CurrentControlSet\\Control\\Video\\{GUID}\\Video", "Service", "vmx_svga");
+        check_key(VMWARE, "SYSTEM\\CurrentControlSet\\Control\\Video\\{GUID}\\0000", "Device Description", "VMware SVGA*");
+
+        check_key(XEN, "HARDWARE\\Description\\System\\BIOS", "SystemProductName", "Xen");
+
+        return (count > 0);
+#endif
+    }
+
+
+    /**
+     * @brief Check for "qemu-ga" process
+     * @category Linux
+     */
+    [[nodiscard]] static bool qemu_ga() {
+#if (!LINUX)
+        return false;
+#else
+        constexpr const char* process = "qemu-ga";
+
+        if (util::is_proc_running(process)) {
+            return core::add(QEMU);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for valid MSR value 0x40000000
+     * @category Windows
+     * @author LukeGoule
+     * @link https://github.com/LukeGoule/compact_vm_detector/tree/main
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool valid_msr() {
+    #if (!MSVC)
+            return false;  // Only valid on MSVC
+    #else
+            __try {
+                // Attempt to read the hypervisor MSR from Ring 3
+                __readmsr(0x40000000); // Reading MSR 0x40000000, which typically indicates hypervisor presence
+            }
+            __except (EXCEPTION_EXECUTE_HANDLER) {
+                // If an exception occurs, return false
+                return false;
+            }
+
+            // If we reached this point, the read was successful, so return true
+            return true;
+    #endif
+    }
+
+
+    /**
+     * @brief Check for QEMU processes
+     * @category Windows
+     */
+    [[nodiscard]] static bool qemu_processes() {
+#if (!MSVC)
+        return false;
+#else
+        constexpr std::array<const TCHAR*, 3> qemu_proc_strings = {{
+            _T("qemu-ga.exe"),
+            _T("vdagent.exe"),
+            _T("vdservice.exe")
+        }};
+
+        for (const auto str : qemu_proc_strings) {
+            if (util::is_proc_running(str)) {
+                return core::add(QEMU);
+            }
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VPC processes
+     * @category Windows
+     */
+    [[nodiscard]] static bool vpc_proc() {
+#if (!MSVC)
+        return false;
+#else
+        constexpr std::array<const TCHAR*, 2> vpc_proc_strings = {{
+            _T("VMSrvc.exe"),
+            _T("VMUSrvc.exe")
+        }};
+
+        for (const auto str : vpc_proc_strings) {
+            if (util::is_proc_running(str)) {
+                return core::add(VPC);
+            }
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for official VPC method
+     * @category Windows, x86
+     */
+    [[nodiscard]] static bool vpc_invalid() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        bool rc = false;
+
+        auto IsInsideVPC_exceptionFilter = [](PEXCEPTION_POINTERS ep) -> DWORD {
+            PCONTEXT ctx = ep->ContextRecord;
+
+            ctx->Ebx = static_cast<DWORD>(-1); // Not running VPC
+            ctx->Eip += 4; // skip past the "call VPC" opcodes
+            return static_cast<DWORD>(EXCEPTION_CONTINUE_EXECUTION);
+            // we can safely resume execution since we skipped faulty instruction
+            };
+
+        __try {
+            __asm {
+                push eax
+                push ebx
+                push ecx
+                push edx
+
+                mov ebx, 0h
+                mov eax, 01h
+
+                __emit 0Fh
+                __emit 3Fh
+                __emit 07h
+                __emit 0Bh
+
+                test ebx, ebx
+                setz[rc]
+
+                pop edx
+                pop ecx
+                pop ebx
+                pop eax
+            }
+        }
+        __except (IsInsideVPC_exceptionFilter(GetExceptionInformation())) {
+            rc = false;
+        }
+
+        return rc;
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for sidt instruction method
+     * @category Linux, Windows, x86
+     */
+    [[nodiscard]] static bool sidt() {
+        // gcc/g++ causes a stack smashing error at runtime for some reason
+        if (GCC) {
+            return false;
+        }
+
+        u8 idtr[10]{};
+        u32 idt_entry = 0;
+
+#if (MSVC)
+#   if (x86_32)
+        _asm sidt idtr
+#   elif (x86)
+#       pragma pack(1)
+        struct IDTR {
+            u16 limit;
+            u64 base;
+        };
+#       pragma pack()
+
+        IDTR idtrStruct;
+        __sidt(&idtrStruct);
+        std::memcpy(idtr, &idtrStruct, sizeof(IDTR));
+#   else
+        return false;
+#   endif
+
+        idt_entry = *reinterpret_cast<unsigned long*>(&idtr[2]);
+#elif (LINUX)
+        // false positive with root for some reason
+        if (util::is_admin()) {
+            return false;
+        }
+
+        struct IDTR {
+            u16 limit;
+            u32 base;
+        } __attribute__((packed));
+
+        IDTR idtr_struct;
+
+        __asm__ __volatile__(
+            "sidt %0"
+            : "=m" (idtr_struct)
+        );
+
+        std::ifstream mem("/dev/mem", std::ios::binary);
+        mem.seekg(idtr_struct.base + 8, std::ios::beg);
+        mem.read(reinterpret_cast<char*>(&idt_entry), sizeof(idt_entry));
+        mem.close();
+        UNUSED(idtr);
+#else
+        UNUSED(idtr);
+        UNUSED(idt_entry);
+        return false;
+#endif
+
+        if ((idt_entry >> 24) == 0xFF) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+    }
+
+
+    /**
+     * @brief Check for sgdt instruction method
+     * @category Windows, x86
+     */
+    [[nodiscard]] static bool sgdt() {
+#if (x86_32 && MSVC)
+        u8 gdtr[6]{};
+        u32 gdt = 0;
+
+        _asm sgdt gdtr
+        gdt = *((unsigned long*)&gdtr[2]);
+
+        return ((gdt >> 24) == 0xFF);
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for sldt instruction method
+     * @category Windows, x86
+     * @note code documentation paper in https://www.aldeid.com/wiki/X86-assembly/Instructions/sldt
+     */
+    [[nodiscard]] static bool sldt() {
+#if (x86_32 && MSVC)
+        unsigned char ldtr[5] = "\xef\xbe\xad\xde";
+        unsigned long ldt = 0;
+
+        __asm {
+            sldt word ptr ldtr  // 'word ptr' to indicate that we're working with a 16-bit value and avoid compiler warnings
+        }
+
+        ldt = *((unsigned long*)&ldtr[0]);
+
+        return (ldt != 0xdead0000);
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Offensive Security sidt method
+     * @category Windows, x86
+     * @author Danny Quist (chamuco@gmail.com)
+     * @author Val Smith (mvalsmith@metasploit.com)
+     * @note code documentation paper in /papers/www.offensivecomputing.net_vm.pdf
+     */
+    [[nodiscard]] static bool offsec_sidt() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        unsigned char m[6]{};
+        __asm sidt m;
+
+        return (m[5] > 0xD0);
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Offensive Security sgdt method
+     * @category Windows, x86
+     * @author Danny Quist (chamuco@gmail.com)
+     * @author Val Smith (mvalsmith@metasploit.com)
+     * @note code documentation paper in /papers/www.offensivecomputing.net_vm.pdf
+     */
+    [[nodiscard]] static bool offsec_sgdt() {
+#if (!MSVC || !x86 || GCC)
+        return false;
+#elif (x86_32)
+        unsigned char m[6]{};
+        __asm sgdt m;
+
+        return (m[5] > 0xD0);
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Offensive Security sldt method
+     * @category Windows, x86
+     * @author Danny Quist (chamuco@gmail.com)
+     * @author Val Smith (mvalsmith@metasploit.com)
+     * @note code documentation paper in /papers/www.offensivecomputing.net_vm.pdf
+     */
+    [[nodiscard]] static bool offsec_sldt() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        unsigned short m[6]{};
+        __asm sldt m;
+
+        return (m[0] != 0x00 && m[1] != 0x00);
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Hyper-V specific string in motherboard
+     * @category Windows
+     */
+    [[nodiscard]] static bool hyperv_board() {
+#if (!MSVC)
+        return false;
+#else
+        if (!wmi::initialize()) {
+            std::cerr << "Failed to initialize WMI.\n";
+            return false;
+        }
+
+        wmi_result results = wmi::execute(L"SELECT * FROM Win32_BaseBoard", { L"Manufacturer" });
+
+        for (const auto& res : results) {
+            if (res.type == wmi::result_type::String) {
+                if (_stricmp(res.strValue.c_str(), "Microsoft Corporation Virtual Machine") == 0) {
+                    return core::add(HYPERV);
+                }
+            }
+        }
+
+        return false; // No match found
+#endif
+    }
+
+
+    /**
+     * @brief Check for VPC and Parallels files
+     * @category Windows
+     */
+    [[nodiscard]] static bool vm_files_extra() {
+#if (!MSVC)
+        return false;
+#else
+        constexpr std::array<std::pair<const char*, const char*>, 9> files = {{
+            { VPC, "c:\\windows\\system32\\drivers\\vmsrvc.sys" },
+            { VPC, "c:\\windows\\system32\\drivers\\vpc-s3.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prleth.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prlfs.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prlmouse.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prlvideo.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prltime.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prl_pv32.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prl_paravirt_32.sys" }
+        }};
+
+        for (const auto& file_pair : files) {
+            if (util::exists(file_pair.second)) {
+                return core::add(file_pair.first);
+            }
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for sidt method with VPC's 0xE8XXXXXX range
+     * @category Windows, x86
+     * @note Idea from Tom Liston and Ed Skoudis' paper "On the Cutting Edge: Thwarting Virtual Machine Detection"
+     * @note Paper situated at /papers/ThwartingVMDetection_Liston_Skoudis.pdf
+     */
+    [[nodiscard]] static bool vpc_sidt() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        u8	idtr[6]{};
+        u32	idt = 0;
+
+        _asm sidt idtr
+        idt = *((unsigned long*)&idtr[2]);
+
+        if ((idt >> 24) == 0xE8) {
+            return core::add(VPC);
+        }
+
+        return false;
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VMware string in /proc/iomem
+     * @category Linux
+     * @note idea from ScoopyNG by Tobias Klein
+     */
+    [[nodiscard]] static bool vmware_iomem() {
+#if (!LINUX)
+        return false;
+#else
+        const std::string iomem_file = util::read_file("/proc/iomem");
+
+        if (util::find(iomem_file, "VMware")) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VMware string in /proc/ioports
+     * @category Windows
+     * @note idea from ScoopyNG by Tobias Klein
+     */
+    [[nodiscard]] static bool vmware_ioports() {
+#if (!LINUX)
+        return false;
+#else
+        const std::string ioports_file = util::read_file("/proc/ioports");
+
+        if (util::find(ioports_file, "VMware")) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VMware string in /proc/scsi/scsi
+     * @category Windows
+     * @note idea from ScoopyNG by Tobias Klein
+     */
+    [[nodiscard]] static bool vmware_scsi() {
+#if (!LINUX)
+        return false;
+#else
+        const std::string scsi_file = util::read_file("/proc/scsi/scsi");
+
+        if (util::find(scsi_file, "VMware")) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VMware-specific device name in dmesg output
+     * @category Windows
+     * @note idea from ScoopyNG by Tobias Klein
+     */
+    [[nodiscard]] static bool vmware_dmesg() {
+#if (!LINUX)
+        return false;
+#else
+        if (!util::is_admin()) {
+            return false;
+        }
+
+        auto dmesg_output = util::sys_result("dmesg");
+        const std::string dmesg = *dmesg_output;
+
+        if (dmesg.empty()) {
+            return false;
+        }
+
+        if (util::find(dmesg, "BusLogic BT-958")) {
+            return core::add(VMWARE);
+        }
+
+        if (util::find(dmesg, "pcnet32")) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check str assembly instruction method for VMware
+     * @note Alfredo Omella's (S21sec) STR technique
+     * @note paper describing this technique is located at /papers/www.s21sec.com_vmware-eng.pdf (2006)
+     * @category Windows
+     */
+        [[nodiscard]] static bool vmware_str() {
+#if (MSVC && x86_32)
+        unsigned short tr = 0;
+        __asm {
+            str ax
+            mov tr, ax
+        }
+        if ((tr & 0xFF) == 0x00 && ((tr >> 8) & 0xFF) == 0x40) {
+            return core::add(VMWARE);
+        }
+#endif
+        return false;
+    }
+
+
+    /**
+     * @brief Check for official VMware io port backdoor technique
+     * @category Windows, x86
+     * @note Code from ScoopyNG by Tobias Klein
+     * @note Technique founded by Ken Kato
+     * @copyright BSD clause 2
+     */
+    [[nodiscard]] static bool vmware_backdoor() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        u32 a = 0;
+        u32 b = 0;
+
+        constexpr std::array<i16, 2> ioports = { 'VX' , 'VY' };
+        i16 ioport;
+        bool is_vm = false;
+
+        for (u8 i = 0; i < ioports.size(); ++i) {
+            ioport = ioports[i];
+            for (u8 cmd = 0; cmd < 0x2c; ++cmd) {
+                __try {
+                    __asm {
+                        push eax
+                        push ebx
+                        push ecx
+                        push edx
+
+                        mov eax, 'VMXh'
+                        movzx ecx, cmd
+                        mov dx, ioport
+                        in eax, dx      // <- key point is here
+
+                        mov a, ebx
+                        mov b, ecx
+
+                        pop edx
+                        pop ecx
+                        pop ebx
+                        pop eax
+                    }
+
+                    is_vm = true;
+                    break;
+                }
+                __except (EXCEPTION_EXECUTE_HANDLER) {}
+            }
+        }
+
+        if (is_vm) {
+            switch (b) {
+                case 1:  return core::add(VMWARE_EXPRESS);
+                case 2:  return core::add(VMWARE_ESX);
+                case 3:  return core::add(VMWARE_GSX);
+                case 4:  return core::add(VMWARE_WORKSTATION);
+                default: return core::add(VMWARE);
+            }
+        }
+#endif
+        return false;
+    }
+
+
+    /**
+     * @brief Check for VMware memory using IO port backdoor
+     * @category Windows, x86
+     * @note Code from ScoopyNG by Tobias Klein
+     * @copyright BSD clause 2
+     */
+    [[nodiscard]] static bool vmware_port_memory() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        unsigned int a = 0;
+
+        __try {
+            __asm {
+                push eax
+                push ebx
+                push ecx
+                push edx
+
+                mov eax, 'VMXh'
+                mov ecx, 14h
+                mov dx, 'VX'
+                in eax, dx
+                mov a, eax
+
+                pop edx
+                pop ecx
+                pop ebx
+                pop eax
+            }
+        }
+        __except (EXCEPTION_EXECUTE_HANDLER) {}
+
+        if (a > 0) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for SMSW assembly instruction technique
+     * @category Windows, x86
+     * @author Danny Quist from Offensive Computing
+     */
+    [[nodiscard]] static bool smsw() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        unsigned int reax = 0;
+
+        __asm
+        {
+            mov eax, 0xCCCCCCCC;
+            smsw eax;
+            mov DWORD PTR[reax], eax;
+        }
+
+        return (
+            (((reax >> 24) & 0xFF) == 0xCC) &&
+            (((reax >> 16) & 0xFF) == 0xCC)
+        );
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for mutex strings of VM brands
+     * @category Windows, x86
+     * @note from VMDE project
+     * @author hfiref0x
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool mutex() {
+#if (!MSVC)
+        return false;
+#else
+        auto supMutexExist = [](const char* lpMutexName) -> bool {
+            DWORD dwError;
+            HANDLE hObject = NULL;
+            if (lpMutexName == NULL) {
+                return false;
+            }
+
+            SetLastError(0);
+            hObject = CreateMutexA(NULL, FALSE, lpMutexName);
+            dwError = GetLastError();
+
+            if (hObject) {
+                CloseHandle(hObject);
+            }
+
+            return (dwError == ERROR_ALREADY_EXISTS);
+        };
+
+        if (
+            supMutexExist("Sandboxie_SingleInstanceMutex_Control") ||
+            supMutexExist("SBIE_BOXED_ServiceInitComplete_Mutex1")
+        ) {
+            return core::add(SANDBOXIE);
+        }
+
+        if (supMutexExist("MicrosoftVirtualPC7UserServiceMakeSureWe'reTheOnlyOneMutex")) {
+            return core::add(VPC);
+        }
+
+        if (supMutexExist("Frz_State")) {
+            return true;
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if uptime is less than or equal to 2 minutes
+     * @category Windows, Linux
+     * @note https://stackoverflow.com/questions/30095439/how-do-i-get-system-up-time-in-milliseconds-in-c
+     */
+    [[nodiscard]] static bool uptime() {
+        constexpr u32 uptime_ms = 1000 * 60 * 2;
+        constexpr u32 uptime_s = 60 * 2;
+
+#if (MSVC)
+        UNUSED(uptime_s);
+        return (GetTickCount64() <= uptime_ms);
+#elif (LINUX)
+        UNUSED(uptime_ms);
+        struct sysinfo info;
+
+        if (sysinfo(&info) != 0) {
+            debug("UPTIME: sysinfo failed");
+            return false;
+        }
+
+        return (info.uptime < uptime_s);
+#elif (APPLE)
+        UNUSED(uptime_s);
+        std::chrono::milliseconds uptime(0u);
+
+        struct timeval ts;
+        std::size_t len = sizeof(ts);
+
+        int mib[2] = { CTL_KERN, KERN_BOOTTIME };
+
+        if (sysctl(mib, 2, &ts, &len, NULL, 0) != 0) {
+            return false;
+        }
+
+        uptime = std::chrono::milliseconds(
+            (static_cast<u64>(ts.tv_sec) * 1000ULL) +
+            (static_cast<u64>(ts.tv_usec) / 1000ULL)
+        );
+
+        return (uptime < uptime_ms);
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for odd CPU threads, usually a sign of modification through VM setting because 99% of CPUs have even numbers of threads
+     * @category All, x86
+     */
+    [[nodiscard]] static bool odd_cpu_threads() {
+#if (!x86)
+        return false;
+#else
+        const u32 threads = std::thread::hardware_concurrency();
+
+        struct cpu::stepping_struct steps = cpu::fetch_steppings();
+
+        debug("ODD_CPU_THREADS: model    = ", static_cast<u32>(steps.model));
+        debug("ODD_CPU_THREADS: family   = ", static_cast<u32>(steps.family));
+        debug("ODD_CPU_THREADS: extmodel = ", static_cast<u32>(steps.extmodel));
+
+        // check if the microarchitecture was made before 2006, which was around the time multi-core processors were implemented
+        auto old_microarchitecture = [&steps]() -> bool {
+            constexpr std::array<std::array<u8, 3>, 32> old_archs = {{
+                // 80486
+                {{ 0x4, 0x0, 0x1 }},
+                {{ 0x4, 0x0, 0x2 }},
+                {{ 0x4, 0x0, 0x3 }},
+                {{ 0x4, 0x0, 0x4 }},
+                {{ 0x4, 0x0, 0x5 }},
+                {{ 0x4, 0x0, 0x7 }},
+                {{ 0x4, 0x0, 0x8 }},
+                {{ 0x4, 0x0, 0x9 }},
+
+                // P5
+                {{ 0x5, 0x0, 0x1 }},
+                {{ 0x5, 0x0, 0x2 }},
+                {{ 0x5, 0x0, 0x4 }},
+                {{ 0x5, 0x0, 0x7 }},
+                {{ 0x5, 0x0, 0x8 }},
+
+                // P6
+                {{ 0x6, 0x0, 0x1 }},
+                {{ 0x6, 0x0, 0x3 }},
+                {{ 0x6, 0x0, 0x5 }},
+                {{ 0x6, 0x0, 0x6 }},
+                {{ 0x6, 0x0, 0x7 }},
+                {{ 0x6, 0x0, 0x8 }},
+                {{ 0x6, 0x0, 0xA }},
+                {{ 0x6, 0x0, 0xB }},
+
+                // Netburst
+                {{ 0xF, 0x0, 0x6 }},
+                {{ 0xF, 0x0, 0x4 }},
+                {{ 0xF, 0x0, 0x3 }},
+                {{ 0xF, 0x0, 0x2 }},
+                {{ 0xF, 0x0, 0x10 }},
+
+                {{ 0x6, 0x1, 0x5 }}, // Pentium M (Talopai)
+                {{ 0x6, 0x1, 0x6 }}, // Core (Client)
+                {{ 0x6, 0x0, 0x9 }}, // Pentium M
+                {{ 0x6, 0x0, 0xD }}, // Pentium M
+                {{ 0x6, 0x0, 0xE }}, // Modified Pentium M
+                {{ 0x6, 0x0, 0xF }}  // Core (Client)
+            }};
+
+            constexpr u8 FAMILY = 0;
+            constexpr u8 EXTMODEL = 1;
+            constexpr u8 MODEL = 2;
+
+            for (const auto& arch : old_archs) {
+                if (
+                    steps.family == arch.at(FAMILY) &&
+                    steps.extmodel == arch.at(EXTMODEL) &&
+                    steps.model == arch.at(MODEL)
+                    ) {
+                    return true;
+                }
+            }
+
+            return false;
+        };
+
+        // self-explanatory
+        if (!(cpu::is_intel() || cpu::is_amd())) {
+            return false;
+        }
+
+        // intel celeron CPUs are relatively modern, but they can contain a single or odd thread count
+        if (cpu::is_celeron(steps)) {
+            return false;
+        }
+
+        // CPUs before 2006 had no official multi-core processors
+        if (old_microarchitecture()) {
+            return false;
+        }
+
+        // is the count odd?
+        return (threads & 1);
+#endif
+    }
+
+
+    /**
+     * @brief Check for Intel CPU thread count database if it matches the system's thread count
+     * @category All, x86
+     * @link https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
+     */
+    [[nodiscard]] static bool intel_thread_mismatch() {
+#if (!x86)
+        return false;
+#else
+        if (!cpu::is_intel()) {
+            return false;
+        }
+
+        if (cpu::has_hyperthreading()) {
+            return false;
+        }
+
+        const cpu::model_struct model = cpu::get_model();
+
+        if (!model.found) {
+            return false;
+        }
+
+        if (!model.is_i_series) {
+            return false;
+        }
+
+        debug("INTEL_THREAD_MISMATCH: CPU model = ", model.string);
+
+        auto thread_database = util::make_unique<std::unordered_map<std::string, uint8_t>>();
+
+        auto push = [&thread_database](const char* brand_str, const u8 thread_count) -> void {
+            thread_database->emplace(brand_str, thread_count);
+        };
+
+        // i3 series
+        push("i3-1000G1", 4);
+        push("i3-1000G4", 4);
+        push("i3-1000NG4", 4);
+        push("i3-1005G1", 4);
+        push("i3-10100", 8);
+        push("i3-10100E", 8);
+        push("i3-10100F", 8);
+        push("i3-10100T", 8);
+        push("i3-10100TE", 8);
+        push("i3-10100Y", 4);
+        push("i3-10105", 8);
+        push("i3-10105F", 8);
+        push("i3-10105T", 8);
+        push("i3-10110U", 4);
+        push("i3-10110Y", 4);
+        push("i3-10300", 8);
+        push("i3-10300T", 8);
+        push("i3-10305", 8);
+        push("i3-10305T", 8);
+        push("i3-10320", 8);
+        push("i3-10325", 8);
+        push("i3-11100B", 8);
+        push("i3-11100HE", 8);
+        push("i3-1110G4", 4);
+        push("i3-1115G4E", 4);
+        push("i3-1115GRE", 4);
+        push("i3-1120G4", 8);
+        push("i3-12100", 8);
+        push("i3-12100F", 8);
+        push("i3-12100T", 8);
+        push("i3-1210U", 4);
+        push("i3-1215U", 4);
+        push("i3-1215UE", 4);
+        push("i3-1215UL", 4);
+        push("i3-12300", 8);
+        push("i3-12300T", 8);
+        push("i3-13100", 8);
+        push("i3-13100F", 8);
+        push("i3-13100T", 8);
+        push("i3-1315U", 4);
+        push("i3-1315UE", 4);
+        push("i3-14100", 8);
+        push("i3-14100F", 8);
+        push("i3-14100T", 8);
+        push("i3-2100", 4);
+        push("i3-2100T", 4);
+        push("i3-2102", 4);
+        push("i3-2105", 4);
+        push("i3-2120", 4);
+        push("i3-2120T", 4);
+        push("i3-2125", 4);
+        push("i3-2130", 4);
+        push("i3-2308M", 4);
+        push("i3-2310E", 4);
+        push("i3-2310M", 4);
+        push("i3-2312M", 4);
+        push("i3-2328M", 4);
+        push("i3-2330E", 4);
+        push("i3-2330M", 4);
+        push("i3-2332M", 4);
+        push("i3-2340UE", 4);
+        push("i3-2348M", 4);
+        push("i3-2350LM", 4);
+        push("i3-2350M", 4);
+        push("i3-2355M", 4);
+        push("i3-2357M", 4);
+        push("i3-2365M", 4);
+        push("i3-2367M", 4);
+        push("i3-2370LM", 4);
+        push("i3-2370M", 4);
+        push("i3-2375M", 4);
+        push("i3-2377M", 4);
+        push("i3-2390M", 4);
+        push("i3-2393M", 4);
+        push("i3-2394M", 4);
+        push("i3-2395M", 4);
+        push("i3-2397M", 4);
+        push("i3-3110M", 4);
+        push("i3-3115C", 4);
+        push("i3-3120M", 4);
+        push("i3-3120ME", 4);
+        push("i3-3130M", 4);
+        push("i3-3210", 4);
+        push("i3-3217U", 4);
+        push("i3-3217UE", 4);
+        push("i3-3220", 4);
+        push("i3-3220T", 4);
+        push("i3-3225", 4);
+        push("i3-3227U", 4);
+        push("i3-3229Y", 4);
+        push("i3-3240", 4);
+        push("i3-3240T", 4);
+        push("i3-3245", 4);
+        push("i3-3250", 4);
+        push("i3-3250T", 4);
+        push("i3-330E", 4);
+        push("i3-330M", 4);
+        push("i3-330UM", 4);
+        push("i3-350M", 4);
+        push("i3-370M", 4);
+        push("i3-380M", 4);
+        push("i3-380UM", 4);
+        push("i3-390M", 4);
+        push("i3-4000M", 4);
+        push("i3-4005U", 4);
+        push("i3-4010M", 4);
+        push("i3-4010U", 4);
+        push("i3-4010Y", 4);
+        push("i3-4012Y", 4);
+        push("i3-4020Y", 4);
+        push("i3-4025U", 4);
+        push("i3-4030U", 4);
+        push("i3-4030Y", 4);
+        push("i3-4100E", 4);
+        push("i3-4100M", 4);
+        push("i3-4100U", 4);
+        push("i3-4102E", 4);
+        push("i3-4110E", 4);
+        push("i3-4110M", 4);
+        push("i3-4112E", 4);
+        push("i3-4120U", 4);
+        push("i3-4130", 4);
+        push("i3-4130T", 4);
+        push("i3-4150", 4);
+        push("i3-4150T", 4);
+        push("i3-4158U", 4);
+        push("i3-4160", 4);
+        push("i3-4160T", 4);
+        push("i3-4170", 4);
+        push("i3-4170T", 4);
+        push("i3-4330", 4);
+        push("i3-4330T", 4);
+        push("i3-4330TE", 4);
+        push("i3-4340", 4);
+        push("i3-4340TE", 4);
+        push("i3-4350", 4);
+        push("i3-4350T", 4);
+        push("i3-4360", 4);
+        push("i3-4360T", 4);
+        push("i3-4370", 4);
+        push("i3-4370T", 4);
+        push("i3-5005U", 4);
+        push("i3-5010U", 4);
+        push("i3-5015U", 4);
+        push("i3-5020U", 4);
+        push("i3-5157U", 4);
+        push("i3-530", 4);
+        push("i3-540", 4);
+        push("i3-550", 4);
+        push("i3-560", 4);
+        push("i3-6006U", 4);
+        push("i3-6098P", 4);
+        push("i3-6100", 4);
+        push("i3-6100E", 4);
+        push("i3-6100H", 4);
+        push("i3-6100T", 4);
+        push("i3-6100TE", 4);
+        push("i3-6100U", 4);
+        push("i3-6102E", 4);
+        push("i3-6120T", 4);
+        push("i3-6157U", 4);
+        push("i3-6167U", 4);
+        push("i3-6300", 4);
+        push("i3-6300T", 4);
+        push("i3-6320", 4);
+        push("i3-6320T", 4);
+        push("i3-7007U", 4);
+        push("i3-7020U", 4);
+        push("i3-7100", 4);
+        push("i3-7100E", 4);
+        push("i3-7100H", 4);
+        push("i3-7100T", 4);
+        push("i3-7100U", 4);
+        push("i3-7101E", 4);
+        push("i3-7101TE", 4);
+        push("i3-7102E", 4);
+        push("i3-7110U", 4);
+        push("i3-7120", 4);
+        push("i3-7120T", 4);
+        push("i3-7130U", 4);
+        push("i3-7167U", 4);
+        push("i3-7300", 4);
+        push("i3-7300T", 4);
+        push("i3-7310T", 4);
+        push("i3-7310U", 4);
+        push("i3-7320", 4);
+        push("i3-7320T", 4);
+        push("i3-7340", 4);
+        push("i3-7350K", 4);
+        push("i3-8000", 4);
+        push("i3-8000T", 4);
+        push("i3-8020", 4);
+        push("i3-8020T", 4);
+        push("i3-8100", 4);
+        push("i3-8100B", 4);
+        push("i3-8100F", 4);
+        push("i3-8100H", 4);
+        push("i3-8100T", 4);
+        push("i3-8109U", 4);
+        push("i3-8120", 4);
+        push("i3-8120T", 4);
+        push("i3-8121U", 4);
+        push("i3-8130U", 4);
+        push("i3-8130U", 4);
+        push("i3-8140U", 4);
+        push("i3-8145U", 4);
+        push("i3-8145UE", 4);
+        push("i3-8300", 4);
+        push("i3-8300T", 4);
+        push("i3-8320", 4);
+        push("i3-8320T", 4);
+        push("i3-8350K", 4);
+        push("i3-9100", 4);
+        push("i3-9100E", 4);
+        push("i3-9100F", 4);
+        push("i3-9100HL", 4);
+        push("i3-9100T", 4);
+        push("i3-9100TE", 4);
+        push("i3-9300", 4);
+        push("i3-9300T", 4);
+        push("i3-9320", 4);
+        push("i3-9350K", 4);
+        push("i3-9350KF", 4);
+        push("i3-N300", 8);
+        push("i3-N305", 8);
+
+        // i5 series
+        push("i5-10200H", 8);
+        push("i5-10210U", 4);
+        push("i5-10210Y", 8);
+        push("i5-10300H", 8);
+        push("i5-1030G4", 8);
+        push("i5-1030G7", 8);
+        push("i5-1030NG7", 8);
+        push("i5-10310U", 4);
+        push("i5-10310Y", 8);
+        push("i5-1035G1", 8);
+        push("i5-1035G4", 8);
+        push("i5-1035G7", 8);
+        push("i5-1038NG7", 8);
+        push("i5-10400", 12);
+        push("i5-10400F", 12);
+        push("i5-10400H", 8);
+        push("i5-10400T", 12);
+        push("i5-10500", 12);
+        push("i5-10500E", 12);
+        push("i5-10500H", 12);
+        push("i5-10500T", 12);
+        push("i5-10500TE", 12);
+        push("i5-10505", 12);
+        push("i5-10600", 12);
+        push("i5-10600K", 12);
+        push("i5-10600KF", 12);
+        push("i5-10600T", 12);
+        push("i5-1115G4", 4);
+        push("i5-1125G4", 8);
+        push("i5-11260H", 12);
+        push("i5-11300H", 8);
+        push("i5-1130G7", 8);
+        push("i5-11320H", 8);
+        push("i5-1135G7", 8);
+        push("i5-11400", 12);
+        push("i5-11400F", 12);
+        push("i5-11400H", 12);
+        push("i5-11400T", 12);
+        push("i5-1140G7", 8);
+        push("i5-1145G7", 8);
+        push("i5-1145G7E", 8);
+        push("i5-1145GRE", 8);
+        push("i5-11500", 12);
+        push("i5-11500B", 12);
+        push("i5-11500H", 12);
+        push("i5-11500HE", 12);
+        push("i5-11500T", 12);
+        push("i5-1155G7", 8);
+        push("i5-11600", 12);
+        push("i5-11600K", 12);
+        push("i5-11600KF", 12);
+        push("i5-11600T", 12);
+        push("i5-1230U", 4);
+        push("i5-1235U", 4);
+        push("i5-12400", 12);
+        push("i5-12400F", 12);
+        push("i5-12400T", 12);
+        push("i5-1240P", 8);
+        push("i5-1240U", 4);
+        push("i5-1245U", 4);
+        push("i5-12490F", 12);
+        push("i5-12500", 12);
+        push("i5-12500H", 8);
+        push("i5-12500HL", 8);
+        push("i5-12500T", 12);
+        push("i5-1250P", 8);
+        push("i5-1250PE", 8);
+        push("i5-12600", 12);
+        push("i5-12600H", 8);
+        push("i5-12600HE", 8);
+        push("i5-12600HL", 8);
+        push("i5-12600HX", 8);
+        push("i5-12600K", 12);
+        push("i5-12600KF", 12);
+        push("i5-12600T", 12);
+        push("i5-13400", 12);
+        push("i5-13400F", 12);
+        push("i5-13400T", 12);
+        push("i5-1340P", 8);
+        push("i5-1340PE", 8);
+        push("i5-13490F", 12);
+        push("i5-13500", 12);
+        push("i5-13500H", 8);
+        push("i5-13500T", 12);
+        push("i5-13505H", 8);
+        push("i5-1350P", 8);
+        push("i5-1350PE", 8);
+        push("i5-13600", 12);
+        push("i5-13600H", 8);
+        push("i5-13600HE", 8);
+        push("i5-13600K", 12);
+        push("i5-13600K", 20);
+        push("i5-13600KF", 12);
+        push("i5-13600KF", 20);
+        push("i5-13600T", 12);
+        push("i5-2300", 4);
+        push("i5-2310", 4);
+        push("i5-2320", 4);
+        push("i5-2380P", 4);
+        push("i5-2390T", 4);
+        push("i5-2400", 4);
+        push("i5-2400S", 4);
+        push("i5-2405S", 4);
+        push("i5-2410M", 4);
+        push("i5-2415M", 4);
+        push("i5-2430M", 4);
+        push("i5-2435M", 4);
+        push("i5-2450M", 4);
+        push("i5-2450P", 4);
+        push("i5-2467M", 4);
+        push("i5-2475M", 4);
+        push("i5-2477M", 4);
+        push("i5-2487M", 4);
+        push("i5-2490M", 4);
+        push("i5-2497M", 4);
+        push("i5-2500", 4);
+        push("i5-2500K", 4);
+        push("i5-2500S", 4);
+        push("i5-2500T", 4);
+        push("i5-2510E", 4);
+        push("i5-2515E", 4);
+        push("i5-2520M", 4);
+        push("i5-2537M", 4);
+        push("i5-2540LM", 4);
+        push("i5-2540M", 4);
+        push("i5-2547M", 4);
+        push("i5-2550K", 4);
+        push("i5-2557M", 4);
+        push("i5-2560LM", 4);
+        push("i5-2560M", 4);
+        push("i5-2580M", 4);
+        push("i5-3210M", 4);
+        push("i5-3230M", 4);
+        push("i5-3317U", 4);
+        push("i5-3320M", 4);
+        push("i5-3330", 4);
+        push("i5-3330S", 4);
+        push("i5-3335S", 4);
+        push("i5-3337U", 4);
+        push("i5-3339Y", 4);
+        push("i5-3340", 4);
+        push("i5-3340M", 4);
+        push("i5-3340S", 4);
+        push("i5-3350P", 4);
+        push("i5-3360M", 4);
+        push("i5-3380M", 4);
+        push("i5-3427U", 4);
+        push("i5-3437U", 4);
+        push("i5-3439Y", 4);
+        push("i5-3450", 4);
+        push("i5-3450S", 4);
+        push("i5-3470", 4);
+        push("i5-3470S", 4);
+        push("i5-3470T", 4);
+        push("i5-3475S", 4);
+        push("i5-3550", 4);
+        push("i5-3550S", 4);
+        push("i5-3570", 4);
+        push("i5-3570K", 4);
+        push("i5-3570S", 4);
+        push("i5-3570T", 4);
+        push("i5-3610ME", 4);
+        push("i5-4200H", 4);
+        push("i5-4200M", 4);
+        push("i5-4200U", 4);
+        push("i5-4200Y", 4);
+        push("i5-4202Y", 4);
+        push("i5-4210H", 4);
+        push("i5-4210M", 4);
+        push("i5-4210U", 4);
+        push("i5-4210Y", 4);
+        push("i5-4220Y", 4);
+        push("i5-4250U", 4);
+        push("i5-4258U", 4);
+        push("i5-4260U", 4);
+        push("i5-4278U", 4);
+        push("i5-4288U", 4);
+        push("i5-4300M", 4);
+        push("i5-4300U", 4);
+        push("i5-4300Y", 4);
+        push("i5-4302Y", 4);
+        push("i5-4308U", 4);
+        push("i5-430M", 4);
+        push("i5-430UM", 4);
+        push("i5-4310M", 4);
+        push("i5-4310U", 4);
+        push("i5-4330M", 4);
+        push("i5-4340M", 4);
+        push("i5-4350U", 4);
+        push("i5-4360U", 4);
+        push("i5-4400E", 4);
+        push("i5-4402E", 4);
+        push("i5-4402EC", 4);
+        push("i5-4410E", 4);
+        push("i5-4422E", 4);
+        push("i5-4430", 4);
+        push("i5-4430S", 4);
+        push("i5-4440", 4);
+        push("i5-4440S", 4);
+        push("i5-4460", 4);
+        push("i5-4460S", 4);
+        push("i5-4460T", 4);
+        push("i5-4470", 4);
+        push("i5-450M", 4);
+        push("i5-4570", 4);
+        push("i5-4570R", 4);
+        push("i5-4570S", 4);
+        push("i5-4570T", 4);
+        push("i5-4570TE", 4);
+        push("i5-4590", 4);
+        push("i5-4590S", 4);
+        push("i5-4590T", 4);
+        push("i5-460M", 4);
+        push("i5-4670", 4);
+        push("i5-4670K", 4);
+        push("i5-4670R", 4);
+        push("i5-4670S", 4);
+        push("i5-4670T", 4);
+        push("i5-4690", 4);
+        push("i5-4690K", 4);
+        push("i5-4690S", 4);
+        push("i5-4690T", 4);
+        push("i5-470UM", 4);
+        push("i5-480M", 4);
+        push("i5-5200U", 4);
+        push("i5-520E", 4);
+        push("i5-520M", 4);
+        push("i5-520UM", 4);
+        push("i5-5250U", 4);
+        push("i5-5257U", 4);
+        push("i5-5287U", 4);
+        push("i5-5300U", 4);
+        push("i5-5350H", 4);
+        push("i5-5350U", 4);
+        push("i5-540M", 4);
+        push("i5-540UM", 4);
+        push("i5-5575R", 4);
+        push("i5-560M", 4);
+        push("i5-560UM", 4);
+        push("i5-5675C", 4);
+        push("i5-5675R", 4);
+        push("i5-580M", 4);
+        push("i5-6198DU", 4);
+        push("i5-6200U", 4);
+        push("i5-6260U", 4);
+        push("i5-6267U", 4);
+        push("i5-6287U", 4);
+        push("i5-6300HQ", 4);
+        push("i5-6300U", 4);
+        push("i5-6350HQ", 4);
+        push("i5-6360U", 4);
+        push("i5-6400", 4);
+        push("i5-6400T", 4);
+        push("i5-6402P", 4);
+        push("i5-6440EQ", 4);
+        push("i5-6440HQ", 4);
+        push("i5-6442EQ", 4);
+        push("i5-650", 4);
+        push("i5-6500", 4);
+        push("i5-6500T", 4);
+        push("i5-6500TE", 4);
+        push("i5-655K", 4);
+        push("i5-6585R", 4);
+        push("i5-660", 4);
+        push("i5-6600", 4);
+        push("i5-6600K", 4);
+        push("i5-6600T", 4);
+        push("i5-661", 4);
+        push("i5-6685R", 4);
+        push("i5-670", 4);
+        push("i5-680", 4);
+        push("i5-7200U", 4);
+        push("i5-7210U", 4);
+        push("i5-7260U", 4);
+        push("i5-7267U", 4);
+        push("i5-7287U", 4);
+        push("i5-7300HQ", 4);
+        push("i5-7300U", 4);
+        push("i5-7360U", 4);
+        push("i5-7400", 4);
+        push("i5-7400T", 4);
+        push("i5-7440EQ", 4);
+        push("i5-7440HQ", 4);
+        push("i5-7442EQ", 4);
+        push("i5-750", 4);
+        push("i5-7500", 4);
+        push("i5-7500T", 4);
+        push("i5-750S", 4);
+        push("i5-760", 4);
+        push("i5-7600", 4);
+        push("i5-7600K", 4);
+        push("i5-7600T", 4);
+        push("i5-7640X", 4);
+        push("i5-7Y54", 4);
+        push("i5-7Y57", 4);
+        push("i5-8200Y", 4);
+        push("i5-8210Y", 4);
+        push("i5-8250U", 8);
+        push("i5-8257U", 8);
+        push("i5-8259U", 8);
+        push("i5-8260U", 8);
+        push("i5-8265U", 8);
+        push("i5-8269U", 8);
+        push("i5-8279U", 8);
+        push("i5-8300H", 8);
+        push("i5-8305G", 8);
+        push("i5-8310Y", 4);
+        push("i5-8350U", 8);
+        push("i5-8365U", 8);
+        push("i5-8365UE", 8);
+        push("i5-8400", 6);
+        push("i5-8400B", 6);
+        push("i5-8400H", 8);
+        push("i5-8400T", 6);
+        push("i5-8420", 6);
+        push("i5-8420T", 6);
+        push("i5-8500", 6);
+        push("i5-8500B", 6);
+        push("i5-8500T", 6);
+        push("i5-8550", 6);
+        push("i5-8600", 6);
+        push("i5-8600K", 6);
+        push("i5-8600T", 6);
+        push("i5-8650", 6);
+        push("i5-9300H", 8);
+        push("i5-9300HF", 8);
+        push("i5-9400", 6);
+        push("i5-9400F", 6);
+        push("i5-9400H", 8);
+        push("i5-9400T", 6);
+        push("i5-9500", 6);
+        push("i5-9500E", 6);
+        push("i5-9500F", 6);
+        push("i5-9500T", 6);
+        push("i5-9500TE", 6);
+        push("i5-9600", 6);
+        push("i5-9600K", 6);
+        push("i5-9600KF", 6);
+        push("i5-9600T", 6);
+
+        // i7 series
+        push("i7-10510U", 8);
+        push("i7-10510Y", 8);
+        push("i7-1060G7", 8);
+        push("i7-10610U", 8);
+        push("i7-1065G7", 8);
+        push("i7-1068G7", 8);
+        push("i7-1068NG7", 8);
+        push("i7-10700", 16);
+        push("i7-10700E", 16);
+        push("i7-10700F", 16);
+        push("i7-10700K", 16);
+        push("i7-10700KF", 16);
+        push("i7-10700T", 16);
+        push("i7-10700TE", 16);
+        push("i7-10710U", 8);
+        push("i7-10750H", 12);
+        push("i7-10810U", 12);
+        push("i7-10850H", 12);
+        push("i7-10870H", 16);
+        push("i7-10875H", 16);
+        push("i7-11370H", 8);
+        push("i7-11375H", 8);
+        push("i7-11390H", 8);
+        push("i7-11600H", 12);
+        push("i7-1160G7", 8);
+        push("i7-1165G7", 8);
+        push("i7-11700", 16);
+        push("i7-11700B", 16);
+        push("i7-11700F", 16);
+        push("i7-11700K", 16);
+        push("i7-11700KF", 16);
+        push("i7-11700T", 16);
+        push("i7-11800H", 16);
+        push("i7-1180G7", 8);
+        push("i7-11850H", 16);
+        push("i7-11850HE", 16);
+        push("i7-1185G7", 8);
+        push("i7-1185G7E", 8);
+        push("i7-1185GRE", 8);
+        push("i7-1195G7", 8);
+        push("i7-1250U", 4);
+        push("i7-1255U", 4);
+        push("i7-1260P", 8);
+        push("i7-1260U", 4);
+        push("i7-1265U", 4);
+        push("i7-12700", 16);
+        push("i7-12700F", 16);
+        push("i7-12700KF", 16);
+        push("i7-12700T", 16);
+        push("i7-1270P", 8);
+        push("i7-1270PE", 8);
+        push("i7-1360P", 8);
+        push("i7-13700", 16);
+        push("i7-13700F", 16);
+        push("i7-13700K", 16);
+        push("i7-13700KF", 16);
+        push("i7-13700T", 16);
+        push("i7-13790F", 16);
+        push("i7-2535QM", 8);
+        push("i7-2570QM", 8);
+        push("i7-2600", 8);
+        push("i7-2600K", 8);
+        push("i7-2600S", 8);
+        push("i7-2610UE", 4);
+        push("i7-2617M", 4);
+        push("i7-2620M", 4);
+        push("i7-2627M", 4);
+        push("i7-2629M", 4);
+        push("i7-2630QM", 8);
+        push("i7-2635QM", 8);
+        push("i7-2637M", 4);
+        push("i7-2640M", 4);
+        push("i7-2649M", 4);
+        push("i7-2655LE", 4);
+        push("i7-2655QM", 8);
+        push("i7-2657M", 4);
+        push("i7-2660M", 4);
+        push("i7-2667M", 4);
+        push("i7-2669M", 4);
+        push("i7-2670QM", 8);
+        push("i7-2675QM", 8);
+        push("i7-2677M", 4);
+        push("i7-2685QM", 8);
+        push("i7-2689M", 4);
+        push("i7-2700K", 8);
+        push("i7-2710QE", 8);
+        push("i7-2715QE", 8);
+        push("i7-2720QM", 8);
+        push("i7-2740QM", 8);
+        push("i7-2760QM", 8);
+        push("i7-2820QM", 8);
+        push("i7-2840QM", 8);
+        push("i7-2860QM", 8);
+        push("i7-2920XM", 8);
+        push("i7-2960XM", 8);
+        push("i7-3517U", 4);
+        push("i7-3517UE", 4);
+        push("i7-3520M", 4);
+        push("i7-3537U", 4);
+        push("i7-3540M", 4);
+        push("i7-3555LE", 4);
+        push("i7-3610QE", 8);
+        push("i7-3610QM", 8);
+        push("i7-3612QE", 8);
+        push("i7-3612QM", 8);
+        push("i7-3615QE", 8);
+        push("i7-3615QM", 8);
+        push("i7-3630QM", 8);
+        push("i7-3632QM", 8);
+        push("i7-3635QM", 8);
+        push("i7-3667U", 4);
+        push("i7-3687U", 4);
+        push("i7-3689Y", 4);
+        push("i7-3720QM", 8);
+        push("i7-3740QM", 8);
+        push("i7-3770", 8);
+        push("i7-3770K", 8);
+        push("i7-3770S", 8);
+        push("i7-3770T", 8);
+        push("i7-3820", 8);
+        push("i7-3820QM", 8);
+        push("i7-3840QM", 8);
+        push("i7-3920XM", 8);
+        push("i7-3930K", 12);
+        push("i7-3940XM", 8);
+        push("i7-3960X", 12);
+        push("i7-3970X", 12);
+        push("i7-4500U", 4);
+        push("i7-4510U", 4);
+        push("i7-4550U", 4);
+        push("i7-4558U", 4);
+        push("i7-4578U", 4);
+        push("i7-4600M", 4);
+        push("i7-4600U", 4);
+        push("i7-4610M", 8);
+        push("i7-4610Y", 4);
+        push("i7-4650U", 4);
+        push("i7-4700EC", 8);
+        push("i7-4700EQ", 8);
+        push("i7-4700HQ", 8);
+        push("i7-4700MQ", 8);
+        push("i7-4701EQ", 8);
+        push("i7-4702EC", 8);
+        push("i7-4702HQ", 8);
+        push("i7-4702MQ", 8);
+        push("i7-4710HQ", 8);
+        push("i7-4710MQ", 8);
+        push("i7-4712HQ", 8);
+        push("i7-4712MQ", 8);
+        push("i7-4720HQ", 8);
+        push("i7-4722HQ", 8);
+        push("i7-4750HQ", 8);
+        push("i7-4760HQ", 8);
+        push("i7-4765T", 8);
+        push("i7-4770", 8);
+        push("i7-4770HQ", 8);
+        push("i7-4770K", 8);
+        push("i7-4770R", 8);
+        push("i7-4770S", 8);
+        push("i7-4770T", 8);
+        push("i7-4770TE", 8);
+        push("i7-4771", 8);
+        push("i7-4785T", 8);
+        push("i7-4790", 8);
+        push("i7-4790K", 8);
+        push("i7-4790S", 8);
+        push("i7-4790T", 8);
+        push("i7-4800MQ", 8);
+        push("i7-4810MQ", 8);
+        push("i7-4820K", 8);
+        push("i7-4850EQ", 8);
+        push("i7-4850HQ", 8);
+        push("i7-4860EQ", 8);
+        push("i7-4860HQ", 8);
+        push("i7-4870HQ", 8);
+        push("i7-4900MQ", 8);
+        push("i7-4910MQ", 8);
+        push("i7-4930K", 12);
+        push("i7-4930MX", 8);
+        push("i7-4940MX", 8);
+        push("i7-4950HQ", 8);
+        push("i7-4960HQ", 8);
+        push("i7-4960X", 12);
+        push("i7-4980HQ", 8);
+        push("i7-5500U", 4);
+        push("i7-5550U", 4);
+        push("i7-5557U", 4);
+        push("i7-5600U", 4);
+        push("i7-5650U", 4);
+        push("i7-5700EQ", 8);
+        push("i7-5700HQ", 8);
+        push("i7-5750HQ", 8);
+        push("i7-5775C", 8);
+        push("i7-5775R", 8);
+        push("i7-5820K", 12);
+        push("i7-5850EQ", 8);
+        push("i7-5850HQ", 8);
+        push("i7-5930K", 12);
+        push("i7-5950HQ", 8);
+        push("i7-5960X", 16);
+        push("i7-610E", 4);
+        push("i7-620LE", 4);
+        push("i7-620LM", 4);
+        push("i7-620M", 4);
+        push("i7-620UE", 4);
+        push("i7-620UM", 4);
+        push("i7-640LM", 4);
+        push("i7-640M", 4);
+        push("i7-640UM", 4);
+        push("i7-6498DU", 4);
+        push("i7-6500U", 4);
+        push("i7-6560U", 4);
+        push("i7-6567U", 4);
+        push("i7-6600U", 4);
+        push("i7-660LM", 4);
+        push("i7-660UE", 4);
+        push("i7-660UM", 4);
+        push("i7-6650U", 4);
+        push("i7-6660U", 4);
+        push("i7-6700", 8);
+        push("i7-6700HQ", 8);
+        push("i7-6700K", 8);
+        push("i7-6700T", 8);
+        push("i7-6700TE", 8);
+        push("i7-6770HQ", 8);
+        push("i7-6785R", 8);
+        push("i7-6800K", 12);
+        push("i7-680UM", 4);
+        push("i7-6820EQ", 8);
+        push("i7-6820HK", 8);
+        push("i7-6820HQ", 8);
+        push("i7-6822EQ", 8);
+        push("i7-6850K", 12);
+        push("i7-6870HQ", 8);
+        push("i7-6900K", 16);
+        push("i7-6920HQ", 8);
+        push("i7-6950X", 20);
+        push("i7-6970HQ", 8);
+        push("i7-720QM", 8);
+        push("i7-740QM", 8);
+        push("i7-7500U", 4);
+        push("i7-7510U", 4);
+        push("i7-7560U", 4);
+        push("i7-7567U", 4);
+        push("i7-7600U", 4);
+        push("i7-7660U", 4);
+        push("i7-7700", 8);
+        push("i7-7700HQ", 8);
+        push("i7-7700K", 8);
+        push("i7-7700T", 8);
+        push("i7-7740X", 8);
+        push("i7-7800X", 12);
+        push("i7-7820EQ", 8);
+        push("i7-7820HK", 8);
+        push("i7-7820HQ", 8);
+        push("i7-7820X", 16);
+        push("i7-7920HQ", 8);
+        push("i7-7Y75", 4);
+        push("i7-8086K", 12);
+        push("i7-820QM", 8);
+        push("i7-840QM", 8);
+        push("i7-8500Y", 4);
+        push("i7-8550U", 8);
+        push("i7-8557U", 8);
+        push("i7-8559U", 8);
+        push("i7-8565U", 8);
+        push("i7-8569U", 8);
+        push("i7-860", 8);
+        push("i7-860S", 8);
+        push("i7-8650U", 8);
+        push("i7-8665U", 8);
+        push("i7-8665UE", 8);
+        push("i7-8670", 12);
+        push("i7-8670T", 12);
+        push("i7-870", 8);
+        push("i7-8700", 12);
+        push("i7-8700B", 12);
+        push("i7-8700K", 12);
+        push("i7-8700T", 12);
+        push("i7-8705G", 8);
+        push("i7-8706G", 8);
+        push("i7-8709G", 8);
+        push("i7-870S", 8);
+        push("i7-8750H", 12);
+        push("i7-875K", 8);
+        push("i7-880", 8);
+        push("i7-8809G", 8);
+        push("i7-8850H", 12);
+        push("i7-920", 8);
+        push("i7-920XM", 8);
+        push("i7-930", 8);
+        push("i7-940", 8);
+        push("i7-940XM", 8);
+        push("i7-950", 8);
+        push("i7-960", 8);
+        push("i7-965", 8);
+        push("i7-970", 12);
+        push("i7-9700", 8);
+        push("i7-9700E", 8);
+        push("i7-9700F", 8);
+        push("i7-9700K", 8);
+        push("i7-9700KF", 8);
+        push("i7-9700T", 8);
+        push("i7-9700TE", 8);
+        push("i7-975", 8);
+        push("i7-9750H", 12);
+        push("i7-9750HF", 12);
+        push("i7-980", 12);
+        push("i7-9800X", 16);
+        push("i7-980X", 12);
+        push("i7-9850H", 12);
+        push("i7-9850HE", 12);
+        push("i7-9850HL", 12);
+        push("i7-990X", 12);
+
+        // i9 series
+        push("i9-10850K", 20);
+        push("i9-10885H", 16);
+        push("i9-10900", 20);
+        push("i9-10900E", 20);
+        push("i9-10900F ", 20);
+        push("i9-10900K", 20);
+        push("i9-10900KF", 20);
+        push("i9-10900T", 20);
+        push("i9-10900TE", 20);
+        push("i9-10900X", 20);
+        push("i9-10910", 20);
+        push("i9-10920X", 24);
+        push("i9-10940X", 28);
+        push("i9-10980HK", 16);
+        push("i9-10980XE", 36);
+        push("i9-11900", 16);
+        push("i9-11900F", 16);
+        push("i9-11900H", 16);
+        push("i9-11900K", 16);
+        push("i9-11900KB", 16);
+        push("i9-11900KF", 16);
+        push("i9-11900T", 16);
+        push("i9-11950H", 16);
+        push("i9-11980HK", 16);
+        push("i9-12900", 16);
+        push("i9-12900F", 16);
+        push("i9-12900K", 16);
+        push("i9-12900KF", 16);
+        push("i9-12900KS", 16);
+        push("i9-12900T", 16);
+        push("i9-13900", 16);
+        push("i9-13900E", 16);
+        push("i9-13900F", 16);
+        push("i9-13900HX", 16);
+        push("i9-13900K", 16);
+        push("i9-13900KF", 16);
+        push("i9-13900KS", 16);
+        push("i9-13900T", 16);
+        push("i9-13900TE", 16);
+        push("i9-13950HX", 16);
+        push("i9-13980HX", 16);
+        push("i9-14900", 16);
+        push("i9-14900F", 16);
+        push("i9-14900HX", 16);
+        push("i9-14900K", 16);
+        push("i9-14900KF", 16);
+        push("i9-14900KS", 16);
+        push("i9-14900T", 16);
+        push("i9-7900X", 20);
+        push("i9-7920X", 24);
+        push("i9-7940X", 28);
+        push("i9-7960X", 32);
+        push("i9-7980XE", 36);
+        push("i9-8950HK", 12);
+        push("i9-9820X", 20);
+        push("i9-9880H", 16);
+        push("i9-9900", 16);
+        push("i9-9900K", 16);
+        push("i9-9900KF", 16);
+        push("i9-9900KS", 16);
+        push("i9-9900T", 16);
+        push("i9-9900X", 20);
+        push("i9-9920X", 24);
+        push("i9-9940X", 28);
+        push("i9-9960X", 32);
+        push("i9-9980HK", 16);
+        push("i9-9980XE", 36);
+        push("i9-9990XE", 28);
+
+        // basically means "if there's 0 matches in the database, return false"
+        if (thread_database->count(model.string) == 0) {
+            return false;
+        }
+
+        const u8 threads = thread_database->at(model.string);
+
+        debug("INTEL_THREAD_MISMATCH: thread in database = ", static_cast<u32>(threads));
+
+        return (std::thread::hardware_concurrency() != threads);
+#endif
+    }
+
+
+    /**
+     * @brief Same as above, but for Xeon Intel CPUs
+     * @category All, x86
+     * @link https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
+     */
+    [[nodiscard]] static bool xeon_thread_mismatch() {
+#if (!x86)
+        return false;
+#else
+        if (!cpu::is_intel()) {
+            return false;
+        }
+
+        if (cpu::has_hyperthreading()) {
+            return false;
+        }
+
+        const cpu::model_struct model = cpu::get_model();
+
+        if (!model.found) {
+            return false;
+        }
+
+        if (!model.is_xeon) {
+            return false;
+        }
+
+        debug("XEON_THREAD_MISMATCH: CPU model = ", model.string);
+
+        auto xeon_thread_database = util::make_unique<std::unordered_map<std::string, uint8_t>>();
+
+        auto xeon_push = [&xeon_thread_database](const char* brand_str, const u8 thread_count) -> void {
+            xeon_thread_database->emplace(brand_str, thread_count);
+        };
+
+        // Xeon D
+        xeon_push("D-1518", 8);
+        xeon_push("D-1520", 8);
+        xeon_push("D-1521", 8);
+        xeon_push("D-1527", 8);
+        xeon_push("D-1528", 12);
+        xeon_push("D-1529", 8);
+        xeon_push("D-1531", 12);
+        xeon_push("D-1537", 16);
+        xeon_push("D-1539", 16);
+        xeon_push("D-1540", 16);
+        xeon_push("D-1541", 16);
+        xeon_push("D-1548", 16);
+        xeon_push("D-1557", 24);
+        xeon_push("D-1559", 24);
+        xeon_push("D-1567", 24);
+        xeon_push("D-1571", 32);
+        xeon_push("D-1577", 32);
+        xeon_push("D-1581", 32);
+        xeon_push("D-1587", 32);
+        xeon_push("D-1513N", 8);
+        xeon_push("D-1523N", 8);
+        xeon_push("D-1533N", 12);
+        xeon_push("D-1543N", 16);
+        xeon_push("D-1553N", 16);
+        xeon_push("D-1602", 4);
+        xeon_push("D-1612", 8);
+        xeon_push("D-1622", 8);
+        xeon_push("D-1627", 8);
+        xeon_push("D-1632", 16);
+        xeon_push("D-1637", 12);
+        xeon_push("D-1623N", 8);
+        xeon_push("D-1633N", 12);
+        xeon_push("D-1649N", 16);
+        xeon_push("D-1653N", 16);
+        xeon_push("D-2141I", 16);
+        xeon_push("D-2161I", 24);
+        xeon_push("D-2191", 36);
+        xeon_push("D-2123IT", 8);
+        xeon_push("D-2142IT", 16);
+        xeon_push("D-2143IT", 16);
+        xeon_push("D-2163IT", 24);
+        xeon_push("D-2173IT", 28);
+        xeon_push("D-2183IT", 32);
+        xeon_push("D-2145NT", 16);
+        xeon_push("D-2146NT", 16);
+        xeon_push("D-2166NT", 24);
+        xeon_push("D-2177NT", 28);
+        xeon_push("D-2187NT", 32);
+
+        // Xeon E
+        xeon_push("E-2104G", 4);
+        xeon_push("E-2124", 4);
+        xeon_push("E-2124G", 4);
+        xeon_push("E-2126G", 6);
+        xeon_push("E-2134", 8);
+        xeon_push("E-2136", 12);
+        xeon_push("E-2144G", 8);
+        xeon_push("E-2146G", 12);
+        xeon_push("E-2174G", 8);
+        xeon_push("E-2176G", 12);
+        xeon_push("E-2186G", 12);
+        xeon_push("E-2176M", 12);
+        xeon_push("E-2186M", 12);
+        xeon_push("E-2224", 4);
+        xeon_push("E-2224G", 4);
+        xeon_push("E-2226G", 6);
+        xeon_push("E-2234", 8);
+        xeon_push("E-2236", 12);
+        xeon_push("E-2244G", 8);
+        xeon_push("E-2246G", 12);
+        xeon_push("E-2274G", 8);
+        xeon_push("E-2276G", 12);
+        xeon_push("E-2278G", 16);
+        xeon_push("E-2286G", 12);
+        xeon_push("E-2288G", 16);
+        xeon_push("E-2276M", 12);
+        xeon_push("E-2286M", 16);
+
+        // Xeon W
+        xeon_push("W-2102", 4);
+        xeon_push("W-2104", 4);
+        xeon_push("W-2123", 8);
+        xeon_push("W-2125", 8);
+        xeon_push("W-2133", 12);
+        xeon_push("W-2135", 12);
+        xeon_push("W-2140B", 16);
+        xeon_push("W-2145", 16);
+        xeon_push("W-2150B", 20);
+        xeon_push("W-2155", 20);
+        xeon_push("W-2170B", 28);
+        xeon_push("W-2175", 28);
+        xeon_push("W-2191B", 36);
+        xeon_push("W-2195", 36);
+        xeon_push("W-3175X", 56);
+        xeon_push("W-3223", 16);
+        xeon_push("W-3225", 16);
+        xeon_push("W-3235", 24);
+        xeon_push("W-3245", 32);
+        xeon_push("W-3245M", 32);
+        xeon_push("W-3265", 48);
+        xeon_push("W-3265M", 48);
+        xeon_push("W-3275", 56);
+        xeon_push("W-3275M", 56);
+
+        if (xeon_thread_database->count(model.string) == 0) {
+            return false;
+        }
+
+        const u8 threads = xeon_thread_database->at(model.string);
+
+        debug("XEON_THREAD_MISMATCH: thread in database = ", static_cast<u32>(threads));
+
+        return (std::thread::hardware_concurrency() != threads);
+#endif
+    }
+
+
+    /**
+     * @brief Check for memory regions to detect VM-specific brands
+     * @category Windows
+     * @author Graham Sutherland
+     * @link https://labs.nettitude.com/blog/vm-detection-tricks-part-1-physical-memory-resource-maps/
+     */
+    [[nodiscard]] static bool nettitude_vm_memory() {
+#if (!MSVC)
+        return false;
+#else
+        typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;
+
+#pragma pack(push,4)
+        typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {
+            UCHAR Type;
+            UCHAR ShareDisposition;
+            USHORT Flags;
+            union {
+                struct {
+                    PHYSICAL_ADDRESS Start;
+                    ULONG Length;
+                } Generic;
+                struct {
+                    PHYSICAL_ADDRESS Start;
+                    ULONG Length;
+                } Port;
+                struct {
+#if defined(NT_PROCESSOR_GROUPS)
+                    USHORT Level;
+                    USHORT Group;
+#else
+                    ULONG Level;
+#endif
+                    ULONG Vector;
+                    KAFFINITY Affinity;
+                } Interrupt;
+                struct {
+                    union {
+                        struct {
+#if defined(NT_PROCESSOR_GROUPS)
+                            USHORT Group;
+#else
+                            USHORT Reserved;
+#endif
+                            USHORT MessageCount;
+                            ULONG Vector;
+                            KAFFINITY Affinity;
+                        } Raw;
+                        struct {
+#if defined(NT_PROCESSOR_GROUPS)
+                            USHORT Level;
+                            USHORT Group;
+#else
+                            ULONG Level;
+#endif
+                            ULONG Vector;
+                            KAFFINITY Affinity;
+                        } Translated;
+                    } DUMMYUNIONNAME;
+                } MessageInterrupt;
+                struct {
+                    PHYSICAL_ADDRESS Start;
+                    ULONG Length;
+                } Memory;
+                struct {
+                    ULONG Channel;
+                    ULONG Port;
+                    ULONG Reserved1;
+                } Dma;
+                struct {
+                    ULONG Channel;
+                    ULONG RequestLine;
+                    UCHAR TransferWidth;
+                    UCHAR Reserved1;
+                    UCHAR Reserved2;
+                    UCHAR Reserved3;
+                } DmaV3;
+                struct {
+                    ULONG Data[3];
+                } DevicePrivate;
+                struct {
+                    ULONG Start;
+                    ULONG Length;
+                    ULONG Reserved;
+                } BusNumber;
+                struct {
+                    ULONG DataSize;
+                    ULONG Reserved1;
+                    ULONG Reserved2;
+                } DeviceSpecificData;
+                struct {
+                    PHYSICAL_ADDRESS Start;
+                    ULONG Length40;
+                } Memory40;
+                struct {
+                    PHYSICAL_ADDRESS Start;
+                    ULONG Length48;
+                } Memory48;
+                struct {
+                    PHYSICAL_ADDRESS Start;
+                    ULONG Length64;
+                } Memory64;
+                struct {
+                    UCHAR Class;
+                    UCHAR Type;
+                    UCHAR Reserved1;
+                    UCHAR Reserved2;
+                    ULONG IdLowPart;
+                    ULONG IdHighPart;
+                } Connection;
+            } u;
+        } CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
+#pragma pack(pop,4)
+        typedef enum _INTERFACE_TYPE {
+            InterfaceTypeUndefined,
+            Internal,
+            Isa,
+            Eisa,
+            MicroChannel,
+            TurboChannel,
+            PCIBus,
+            VMEBus,
+            NuBus,
+            PCMCIABus,
+            CBus,
+            MPIBus,
+            MPSABus,
+            ProcessorInternal,
+            InternalPowerBus,
+            PNPISABus,
+            PNPBus,
+            Vmcs,
+            ACPIBus,
+            MaximumInterfaceType
+        } INTERFACE_TYPE, *PINTERFACE_TYPE;
+        typedef struct _CM_PARTIAL_RESOURCE_LIST {
+            USHORT                         Version;
+            USHORT                         Revision;
+            ULONG                          Count;
+            CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
+        } CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
+        typedef struct _CM_FULL_RESOURCE_DESCRIPTOR {
+            INTERFACE_TYPE           InterfaceType;
+            ULONG                    BusNumber;
+            CM_PARTIAL_RESOURCE_LIST PartialResourceList;
+        } *PCM_FULL_RESOURCE_DESCRIPTOR, CM_FULL_RESOURCE_DESCRIPTOR;
+        typedef struct _CM_RESOURCE_LIST {
+            ULONG                       Count;
+            CM_FULL_RESOURCE_DESCRIPTOR List[1];
+        } *PCM_RESOURCE_LIST, CM_RESOURCE_LIST;
+        struct memory_region {
+            ULONG64 size;
+            ULONG64 address;
+        };
+
+        /* registry keys for resource maps */
+#define VM_RESOURCE_CHECK_REGKEY_PHYSICAL 0
+#define VM_RESOURCE_CHECK_REGKEY_RESERVED 1
+#define VM_RESOURCE_CHECK_REGKEY_LOADER_RESERVED 2
+#define ResourceRegistryKeysLength 3
+
+        const struct map_key {
+            LPCTSTR KeyPath;
+            LPCTSTR ValueName;
+        } ResourceRegistryKeys[ResourceRegistryKeysLength] = {
+            {
+                _T("Hardware\\ResourceMap\\System Resources\\Physical Memory"),
+                _T(".Translated")
+            },
+            {
+                _T("Hardware\\ResourceMap\\System Resources\\Reserved"),
+                _T(".Translated")
+            },
+            {
+                _T("Hardware\\ResourceMap\\System Resources\\Loader Reserved"),
+                _T(".Raw")
+            }
+        };
+
+        /* parse a REG_RESOURCE_LIST value for memory descriptors */
+        auto parse_memory_map = [](
+            struct memory_region* regions,
+            struct map_key key
+        ) -> DWORD {
+            HKEY hKey = NULL;
+            LPCTSTR pszSubKey = key.KeyPath;
+            LPCTSTR pszValueName = key.ValueName;
+            LPBYTE lpData = NULL;
+            DWORD dwLength = 0, count = 0, type = 0;;
+            DWORD result;
+            if ((result = RegOpenKeyW(HKEY_LOCAL_MACHINE, reinterpret_cast<LPCWSTR>(pszSubKey), &hKey)) != ERROR_SUCCESS) {
+                debug("NETTITUDE_VM_MEMORY: Could not get reg key: ", result, " / ", GetLastError());
+                return 0;
+            }
+
+            if ((result = RegQueryValueExW(hKey, reinterpret_cast<LPCWSTR>(pszValueName), 0, &type, NULL, &dwLength)) != ERROR_SUCCESS) {
+                debug("NETTITUDE_VM_MEMORY: Could not query hardware key: ", result, " / ", GetLastError());
+                return 0;
+            }
+
+            lpData = (LPBYTE)malloc(dwLength);
+            RegQueryValueEx(hKey, pszValueName, 0, &type, lpData, &dwLength);
+            CM_RESOURCE_LIST* resource_list = (CM_RESOURCE_LIST*)lpData;
+            for (DWORD i = 0; i < resource_list->Count; i++)
+            {
+                for (DWORD j = 0; j < resource_list->List[0].PartialResourceList.Count; j++)
+                {
+                    if (resource_list->List[i].PartialResourceList.PartialDescriptors[j].Type == 3)
+                    {
+                        if (regions != NULL)
+                        {
+                            regions->address = resource_list->List[i].PartialResourceList.PartialDescriptors[j].u.Memory.Start.QuadPart;
+                            regions->size = resource_list->List[i].PartialResourceList.PartialDescriptors[j].u.Memory.Length;
+                            regions++;
+                        }
+                        count++;
+                    }
+                }
+            }
+            return count;
+        };
+
+#define VM_RESOURCE_CHECK_ERROR -1
+#define VM_RESOURCE_CHECK_NO_VM 0
+#define VM_RESOURCE_CHECK_HYPERV 1
+#define VM_RESOURCE_CHECK_VBOX 2
+#define VM_RESOURCE_CHECK_UNKNOWN_PLATFORM 99
+
+        auto vm_resource_check = [](
+            struct memory_region* phys, int phys_count,
+            struct memory_region* reserved, int reserved_count,
+            struct memory_region* loader_reserved, int loader_reserved_count
+        ) -> int {
+                const ULONG64 VBOX_PHYS_LO = 0x0000000000001000ULL;
+                const ULONG64 VBOX_PHYS_HI = 0x000000000009f000ULL;
+                const ULONG64 HYPERV_PHYS_LO = 0x0000000000001000ULL;
+                const ULONG64 HYPERV_PHYS_HI = 0x00000000000a0000ULL;
+
+                const ULONG64 RESERVED_ADDR_LOW = 0x0000000000001000ULL;
+                const ULONG64 LOADER_RESERVED_ADDR_LOW = 0x0000000000000000ULL;
+                if (phys_count <= 0 || reserved_count <= 0 || loader_reserved_count <= 0) {
+                    return VM_RESOURCE_CHECK_ERROR;
+                }
+
+                if (phys == NULL || reserved == NULL || loader_reserved == NULL) {
+                    return VM_RESOURCE_CHECK_ERROR;
+                }
+
+                /* find the reserved address range starting
+                RESERVED_ADDR_LOW, and record its end address */
+                ULONG64 lowestReservedAddrRangeEnd = 0;
+                for (int i = 0; i < reserved_count; i++) {
+                    if (reserved[i].address == RESERVED_ADDR_LOW) {
+                        lowestReservedAddrRangeEnd = reserved[i].address + reserved[i].size;
+                        break;
+                    }
+                }
+
+                if (lowestReservedAddrRangeEnd == 0) {
+                    /* every system tested had a range starting at RESERVED_ADDR_LOW */
+                    /* this is an outlier. error. */
+                    return VM_RESOURCE_CHECK_ERROR;
+                }
+
+                /* find the loader reserved address range starting
+                LOADER_RESERVED_ADDR_LOW, and record its end address */
+                ULONG64 lowestLoaderReservedAddrRangeEnd = 0;
+                for (int i = 0; i < loader_reserved_count; i++) {
+                    if (loader_reserved[i].address == LOADER_RESERVED_ADDR_LOW) {
+                        lowestLoaderReservedAddrRangeEnd = loader_reserved[i].address + loader_reserved[i].size;
+                        break;
+                    }
+                }
+
+                if (lowestLoaderReservedAddrRangeEnd == 0) {
+                    /* every system tested had a range starting at LOADER_RESERVED_ADDR_LOW */
+                    /* this is an outlier. error. */
+                    return VM_RESOURCE_CHECK_ERROR;
+                }
+
+                /* check if the end addresses are equal. if not, we haven't detected a VM */
+                if (lowestReservedAddrRangeEnd != lowestLoaderReservedAddrRangeEnd) {
+                    return VM_RESOURCE_CHECK_NO_VM;
+                }
+
+                /* now find the type of VM by its known physical memory range */
+                for (int i = 0; i < phys_count; i++) {
+                    if (phys[i].address == HYPERV_PHYS_LO && (phys[i].address + phys[i].size) == HYPERV_PHYS_HI) {
+                        /* hyper-v */
+                        return VM_RESOURCE_CHECK_HYPERV;
+                    }
+
+                    if (phys[i].address == VBOX_PHYS_LO && (phys[i].address + phys[i].size) == VBOX_PHYS_HI) {
+                        /* vbox */
+                        return VM_RESOURCE_CHECK_VBOX;
+                    }
+                }
+                /* pretty sure it's a VM, but we don't know what type */
+                return VM_RESOURCE_CHECK_UNKNOWN_PLATFORM;
+            };
+
+        DWORD count;
+
+        struct memory_region* regions[ResourceRegistryKeysLength]{};
+        int region_counts[ResourceRegistryKeysLength]{};
+
+        for (int i = 0; i < ResourceRegistryKeysLength; i++) {
+            debug(
+                "NETTITUDE_VM_MEMORY: Reading data from ",
+                ResourceRegistryKeys[i].KeyPath,
+                "\\",
+                ResourceRegistryKeys[i].ValueName
+            );
+
+            count = parse_memory_map(NULL, ResourceRegistryKeys[i]);
+
+            if (count == 0) {
+                debug("NETTITUDE_VM_MEMORY: Could not find memory region, returning 0.");
+                return 0;
+            }
+
+            regions[i] = (struct memory_region*)malloc(sizeof(struct memory_region) * count);
+
+            if (regions[i] == NULL) {
+                debug("NETTITUDE_VM_MEMORY: Memory allocation failed for regions[i].");
+                return 0;
+            }
+
+            count = parse_memory_map(regions[i], ResourceRegistryKeys[i]);
+
+            if (count <= 0) {
+                debug("NETTITUDE_VM_MEMORY: No regions parsed, freeing allocated memory.");
+                free(regions[i]);  
+                regions[i] = NULL;
+                continue;
+            }
+
+            region_counts[i] = count;
+            for (DWORD r = 0; r < count; r++) {
+                debug(
+                    "NETTITUDE_VM_MEMORY: --> Memory region found: ",
+                    regions[i][r].address,
+                    " - ",
+                    regions[i][r].address + regions[i][r].size
+                );
+            }
+        }
+
+        int check_result = vm_resource_check(
+            regions[VM_RESOURCE_CHECK_REGKEY_PHYSICAL],
+            region_counts[VM_RESOURCE_CHECK_REGKEY_PHYSICAL],
+            regions[VM_RESOURCE_CHECK_REGKEY_RESERVED],
+            region_counts[VM_RESOURCE_CHECK_REGKEY_RESERVED],
+            regions[VM_RESOURCE_CHECK_REGKEY_LOADER_RESERVED],
+            region_counts[VM_RESOURCE_CHECK_REGKEY_LOADER_RESERVED]
+        );
+
+        switch (check_result) {
+            // error
+            case VM_RESOURCE_CHECK_ERROR:
+                debug("NETTITUDE_VM_MEMORY: unknown error, returned false");
+                return false;
+                break;
+
+            // no VM
+            case VM_RESOURCE_CHECK_NO_VM:
+                debug("NETTITUDE_VM_MEMORY: no VM detected");
+                return false;
+                break;
+
+            // Hyper-V
+            case VM_RESOURCE_CHECK_HYPERV:
+                debug("NETTITUDE_VM_MEMORY: Hyper-V detected");
+                return core::add(HYPERV);
+                break;
+
+            // VirtualBox
+            case VM_RESOURCE_CHECK_VBOX:
+                debug("NETTITUDE_VM_MEMORY: Vbox detected");
+                return core::add(VBOX);
+                break;
+
+            // Unknown brand, but likely VM
+            case VM_RESOURCE_CHECK_UNKNOWN_PLATFORM:
+                debug("NETTITUDE_VM_MEMORY: unknown brand, but likely VM (returned true)");
+                return true;
+                break;
+
+            default:
+                debug("NETTITUDE_VM_MEMORY: returned false as default case");
+                return false;
+                break;
+        }
+#endif
+    }
+
+
+    /**
+     * @brief Check for CPUID technique by checking whether all the bits equate to more than 4000 (not sure how this works if i'm honest)
+     * @category x86
+     * @author 一半人生
+     * @link https://unprotect.it/snippet/vmcpuid/195/
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool cpuid_bitset() {
+#if (!x86)
+        return false;
+#else
+        if (util::hyper_x()) {
+            return false;
+        }
+
+        /// See: Feature Information Returned in the ECX Register
+        union CpuFeaturesEcx {
+            u32 all;
+            struct {
+                u32 sse3 : 1;       //!< [0] Streaming SIMD Extensions 3 (SSE3)
+                u32 pclmulqdq : 1;  //!< [1] PCLMULQDQ
+                u32 dtes64 : 1;     //!< [2] 64-bit DS Area
+                u32 monitor : 1;    //!< [3] MONITOR/WAIT
+                u32 ds_cpl : 1;     //!< [4] CPL qualified Debug Store
+                u32 vmx : 1;        //!< [5] Virtual Machine Technology
+                u32 smx : 1;        //!< [6] Safer Mode Extensions
+                u32 est : 1;        //!< [7] Enhanced Intel Speedstep Technology
+                u32 tm2 : 1;        //!< [8] Thermal monitor 2
+                u32 ssse3 : 1;      //!< [9] Supplemental Streaming SIMD Extensions 3
+                u32 cid : 1;        //!< [10] L1 context ID
+                u32 sdbg : 1;       //!< [11] IA32_DEBUG_INTERFACE MSR
+                u32 fma : 1;        //!< [12] FMA extensions using YMM state
+                u32 cx16 : 1;       //!< [13] CMPXCHG16B
+                u32 xtpr : 1;       //!< [14] xTPR Update Control
+                u32 pdcm : 1;       //!< [15] Performance/Debug capability MSR
+                u32 reserved : 1;   //!< [16] Reserved
+                u32 pcid : 1;       //!< [17] Process-context identifiers
+                u32 dca : 1;        //!< [18] prefetch from a memory mapped device
+                u32 sse4_1 : 1;     //!< [19] SSE4.1
+                u32 sse4_2 : 1;     //!< [20] SSE4.2
+                u32 x2_apic : 1;    //!< [21] x2APIC feature
+                u32 movbe : 1;      //!< [22] MOVBE instruction
+                u32 popcnt : 1;     //!< [23] POPCNT instruction
+                u32 reserved3 : 1;  //!< [24] one-shot operation using a TSC deadline
+                u32 aes : 1;        //!< [25] AESNI instruction
+                u32 xsave : 1;      //!< [26] XSAVE/XRSTOR feature
+                u32 osxsave : 1;    //!< [27] enable XSETBV/XGETBV instructions
+                u32 avx : 1;        //!< [28] AVX instruction extensions
+                u32 f16c : 1;       //!< [29] 16-bit floating-point conversion
+                u32 rdrand : 1;     //!< [30] RDRAND instruction
+                u32 not_used : 1;   //!< [31] Always 0 (a.k.a. HypervisorPresent)
+            } fields;
+        };
+
+        i32 cpu_info[4] = {};
+        cpu::cpuid(cpu_info, 0x40000001);
+        i32 vid = 0;
+        vid = (i32)cpu_info[0];
+
+        if (vid >= 4000) {
+            return true;
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for cuckoo directory using crt and WIN API directory functions
+     * @category Windows
+     * @author 一半人生
+     * @link https://unprotect.it/snippet/checking-specific-folder-name/196/
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool cuckoo_dir() {
+#if (!MSVC)
+        return false;
+#else
+        // win api
+        auto IsDirectory2 = [](std::string& strDirName) -> bool {
+            const auto iCode = CreateDirectoryA(strDirName.c_str(), NULL);
+
+            if (ERROR_ALREADY_EXISTS == GetLastError()) {
+                return true;
+            }
+
+            if (iCode) {
+                RemoveDirectoryA(strDirName.c_str());
+            }
+
+            return false;
+        };
+
+        // win api
+        auto IsDirectory1 = [](std::string& strDirName) -> bool {
+            const HANDLE hFile = CreateFileA(
+                strDirName.c_str(),
+                GENERIC_READ,
+                0,
+                NULL,
+                OPEN_EXISTING,
+                FILE_FLAG_BACKUP_SEMANTICS,
+                NULL
+            );
+
+            if (!hFile || (INVALID_HANDLE_VALUE == hFile)) {
+                return false;
+            }
+
+            CloseHandle(hFile);
+
+            return true;
+        };
+
+        // crt
+        auto IsDirectory = [](std::string& strDirName) -> bool {
+            if (0 == _access(strDirName.c_str(), 0)) {
+                return true;
+            }
+
+            return false;
+        };
+
+        std::string strDirName = "C:\\Cuckoo";
+
+        if (
+            IsDirectory(strDirName) ||
+            IsDirectory1(strDirName) ||
+            IsDirectory2(strDirName)
+        ) {
+            return core::add(CUCKOO);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Cuckoo specific piping mechanism
+     * @category Windows
+     * @author Thomas Roccia (fr0gger)
+     * @link https://unprotect.it/snippet/checking-specific-folder-name/196/
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool cuckoo_pipe() {
+#if (!LINUX)
+        return false;
+#else
+        int fd = open("\\\\.\\pipe\\cuckoo", O_RDONLY);
+        bool is_cuckoo = false;
+
+        if (fd >= 0) {
+            is_cuckoo = true;
+        }
+
+        close(fd);
+
+        if (is_cuckoo) {
+            return core::add(CUCKOO);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for default Azure hostname format regex (Azure uses Hyper-V as their base VM brand)
+     * @category Windows, Linux
+     */
+    [[nodiscard]] static bool hyperv_hostname() {
+#if (!(MSVC || LINUX))
+        return false;
+#else
+        std::string hostname = util::get_hostname();
+
+        // most Hyper-V hostnames under Azure have the hostname format of fv-azXXX-XXX where the X is a digit
+        std::regex pattern("fv-az\\d+-\\d+");
+
+        if (std::regex_match(hostname, pattern)) {
+            return core::add(AZURE_HYPERV);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for commonly set hostnames by certain VM brands
+     * @category Windows, Linux
+     * @note Idea from Thomas Roccia (fr0gger)
+     * @link https://unprotect.it/technique/detecting-hostname-username/
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool general_hostname() {
+#if (!(MSVC || LINUX))
+        return false;
+#else
+        std::string hostname = util::get_hostname();
+
+        auto cmp = [&](const char* str2) -> bool {
+            return (hostname == str2);
+        };
+
+        if (
+            cmp("Sandbox") ||
+            cmp("Maltest") ||
+            cmp("Malware") ||
+            cmp("malsand") ||
+            cmp("ClonePC")
+        ) {
+            return true;
+        }
+
+        if (cmp("Cuckoo")) {
+            return core::add(CUCKOO);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for pre-set screen resolutions commonly found in VMs
+     * @category Windows
+     * @note Idea from Thomas Roccia (fr0gger)
+     * @link https://unprotect.it/technique/checking-screen-resolution/
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool screen_resolution() {
+#if (!MSVC)
+        return false;
+#else
+        RECT desktop;
+        const HWND hDesktop = GetDesktopWindow();
+        GetWindowRect(hDesktop, &desktop);
+        const i32 horiz = desktop.right;
+        const i32 verti = desktop.bottom;
+
+        debug("SCREEN_RESOLUTION: horizontal = ", horiz, ", vertical = ", verti);
+
+        if (
+            (horiz == 1024 && verti == 768) ||
+            (horiz == 800 && verti == 600) ||
+            (horiz == 640 && verti == 480)
+        ) {
+            return true;
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if bogus device string would be accepted
+     * @category Windows
+     * @author Huntress Research Team
+     * @link https://unprotect.it/technique/buildcommdcbandtimeouta/
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool device_string() {
+#if (!MSVC)
+        return false;
+#else
+        DCB dcb = { 0 };
+        COMMTIMEOUTS timeouts = { 0 };
+
+        if (BuildCommDCBAndTimeoutsA("jhl46745fghb", &dcb, &timeouts)) {
+            return true;
+        } else {
+            debug("DEVICE_STRING: BuildCommDCBAndTimeouts failed");
+            return false;
+        }
+#endif
+    }
+
+
+    /**
+     * @brief Check for the presence of BlueStacks-specific folders
+     * @category ARM, Linux
+     */
+    [[nodiscard]] static bool bluestacks() {
+#if (!(ARM && LINUX))
+        return false;
+#else
+        if (
+            util::exists("/mnt/windows/BstSharedFolder") ||
+            util::exists("/sdcard/windows/BstSharedFolder")
+        ) {
+            return core::add(BLUESTACKS);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for signatures in leaf 0x40000001 in CPUID
+     * @link https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/shared/hvgdk_mini/hv_hypervisor_interface.htm
+     * @link https://github.com/ionescu007/SimpleVisor/blob/master/shvvp.c
+     * @category x86
+     */
+    [[nodiscard]] static bool cpuid_signature() {
+#if (!x86)
+        return false;
+#else
+        if (util::hyper_x()) {
+            return false;
+        }
+
+        u32 eax, unused = 0;
+        cpu::cpuid(eax, unused, unused, unused, 0x40000001);
+        UNUSED(unused);
+
+        constexpr u32 hyperv = 0x31237648; // "Hv#1"
+        constexpr u32 nanovisor = 0x766E6258; // "Xbnv" 
+        constexpr u32 simplevisor = 0x00766853; // " vhS"
+
+        debug("CPUID_SIGNATURE: eax = ", eax);
+
+        switch (eax) {
+            case hyperv: return core::add(HYPERV);
+            case nanovisor: return core::add(NANOVISOR);
+            case simplevisor: return core::add(SIMPLEVISOR);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Hyper-V CPUID bitmask range for reserved values
+     * @link https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/feature-discovery
+     * @category x86
+     */
+    [[nodiscard]] static bool hyperv_bitmask() {
+#if (!x86)
+        return false;
+#else
+        if (util::hyper_x()) {
+            return false;
+        }
+
+        enum registers : u8 {
+            EAX = 1,
+            EBX,
+            ECX,
+            EDX
+        };
+
+        auto fetch_register = [](const registers register_id, const u32 leaf) -> u32 {
+            u32 eax, ebx, ecx, edx = 0;
+            cpu::cpuid(eax, ebx, ecx, edx, leaf);
+
+            switch (register_id) {
+                case EAX: return eax;
+                case EBX: return ebx;
+                case ECX: return ecx;
+                case EDX: return edx;
+            }
+
+            return 0;
+        };
+
+        const u32 max_leaf = fetch_register(EAX, 0x40000000);
+
+        debug("HYPERV_BITMASK: max leaf = ", std::hex, max_leaf);
+
+        if (max_leaf < 0x4000000A) {
+            return false; // returned false because we want the most feature leafs as possible for Hyper-V
+        }
+
+/* this is just an ascii tool to check if all the arrows (^) are aligned correctly based on bit position, think of it as a ruler. (ignore this btw)
+||||||||||||||||||||||9876543210
+|||||||||||||||||||||10 
+||||||||||||||||||||11 
+|||||||||||||||||||12 
+||||||||||||||||||13 
+|||||||||||||||||14 
+||||||||||||||||15 
+|||||||||||||||16 
+||||||||||||||17 
+|||||||||||||18 
+||||||||||||19 
+|||||||||||20 
+||||||||||21 
+|||||||||22 
+||||||||23 
+|||||||24 
+||||||25 
+|||||26 
+||||27 
+|||28 
+||29 
+|30 
+31 
+*/
+
+        auto leaf_01 = [&]() -> bool {
+            u32 eax, ebx, ecx, edx = 0;
+            cpu::cpuid(eax, ebx, ecx, edx, 0x40000001);
+
+            debug("01 eax = ", std::bitset<32>(eax));
+            debug("01 ebx = ", std::bitset<32>(ebx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("01 ecx = ", std::bitset<32>(ecx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("01 edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+
+            return (
+                (eax != 0) &&
+                (ebx == 0) &&
+                (ecx == 0) &&
+                (edx == 0)
+            );
+        };
+
+        auto leaf_03 = [&]() -> bool {
+            const u32 ecx = fetch_register(ECX, 0x40000003);
+            const u32 edx = fetch_register(EDX, 0x40000003);
+
+            debug("03 ecx = ", std::bitset<32>(ecx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^    ^^^^^");
+            debug("03 edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^ ^^ ^     ^                ");
+
+            if (ecx == 0 || edx == 0) {
+                return false;
+            } else {
+                return (
+                    ((ecx & 0b11111) == 0) &&
+                    ((ecx >> 9) == 0) &&
+                    ((edx & (1 << 16)) == 0) &&
+                    ((edx & (1 << 22)) == 0) &&
+                    (((edx >> 24) & 0b11) == 0) &&
+                    ((edx >> 27) == 0)
+                );
+            }
+        };
+
+        auto leaf_04 = [&]() -> bool {
+            const u32 eax = fetch_register(EAX, 0x40000004);
+            const u32 ecx = fetch_register(ECX, 0x40000004);
+            const u32 edx = fetch_register(EDX, 0x40000004);
+
+            debug("04 eax = ", std::bitset<32>(eax));
+            debug("         ^^^^^^^^^^^^^  ^       ^        ");
+            debug("04 ecx = ", std::bitset<32>(ecx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^       ");
+            debug("04 edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+
+            if (
+                eax == 0 ||
+                ecx == 0 ||
+                edx != 0   // edx is supposed to be null
+            ) {
+                return false;
+            } else {
+                return (
+                    ((eax & (1 << 8)) == 0) &&
+                    ((eax & (1 << 16)) == 0) &&
+                    ((eax >> 19) == 0) &&
+                    ((ecx >> 7) == 0) &&
+                    (edx == 0)
+                );
+            }
+        };
+
+        auto leaf_05 = [&]() -> bool {
+            const u32 edx = fetch_register(EDX, 0x40000005);
+            debug("05 edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            return (edx == 0);
+        };
+
+        auto leaf_06 = [&]() -> bool {
+            u32 eax, ebx, ecx, edx = 0;
+            cpu::cpuid(eax, ebx, ecx, edx, 0x40000006);
+
+            debug("06 eax = ", std::bitset<32>(eax));
+            debug("         ^^^^^^^         ^               ");
+            debug("06 ebx = ", std::bitset<32>(ebx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("06 ecx = ", std::bitset<32>(ecx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("06 edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+
+            if (
+                eax == 0 ||
+                ebx != 0 ||
+                ecx != 0 ||
+                edx != 0   // edx is supposed to be null
+            ) {
+                return false;
+            } else {
+                return (
+                    ((eax & (1 << 15)) == 0) &&
+                    ((eax >> 25) == 0) &&
+                    (ebx == 0) &&
+                    (ecx == 0) &&
+                    (edx == 0)
+                );
+            }
+        };
+
+        auto leaf_09 = [&]() -> bool {
+            u32 eax, ebx, ecx, edx = 0;
+            cpu::cpuid(eax, ebx, ecx, edx, 0x40000009);
+
+            debug("09 eax = ", std::bitset<32>(eax));
+            debug("         ^^^^^^^^^^^^^^^^^^^ ^^^^^   ^ ^^");
+            debug("09 ebx = ", std::bitset<32>(ebx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("09 ecx = ", std::bitset<32>(ecx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("09 edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^^^^^^^^^^ ^ ^^^^^^^^^^ ^^^^");
+
+            if (
+                eax == 0 ||
+                ebx != 0 ||
+                ecx != 0 ||
+                edx == 0
+            ) {
+                return false;
+            } else {
+                return (
+                    ((eax & 0b11) == 0) &&
+                    ((eax & (1 << 3)) == 0) &&
+                    (((eax >> 7) & 0b11111) == 0) &&
+                    ((eax >> 13) == 0) &&
+                    (ebx == 0) &&
+                    (ecx == 0) &&
+                    ((edx & 0b1111) == 0) &&
+                    (((edx >> 5) & 0b1111111111) == 0) &&
+                    ((edx & (1 << 16)) == 0) &&
+                    ((edx >> 18) == 0)
+                );
+            }
+        };
+
+        auto leaf_0A = [&]() -> bool {
+            u32 eax, ebx, ecx, edx = 0;
+            cpu::cpuid(eax, ebx, ecx, edx, 0x40000009);
+
+            debug("0A eax = ", std::bitset<32>(eax));
+            debug("         ^^^^^^^^^^^    ^                ");
+            debug("0A eax = ", std::bitset<32>(ebx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ");
+            debug("0A ecx = ", std::bitset<32>(ecx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("0A edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+
+            // ebx is left out on purpose due to how likely it can result the overall result to be a false negative
+            if (
+                eax == 0 ||
+                ecx != 0 ||
+                edx != 0
+            ) {
+                return false;
+            } else {
+                return (
+                    ((eax & (1 << 16)) == 0) &&
+                    ((eax >> 21) == 0) &&
+                    ((ebx >> 30) == 0) &&
+                    (ecx == 0) &&
+                    (edx == 0)
+                );
+            }
+        };
+
+        debug("01: ", leaf_01());
+        debug("03: ", leaf_03());
+        debug("04: ", leaf_04());
+        debug("05: ", leaf_05());
+        debug("06: ", leaf_06());
+        debug("09: ", leaf_09());
+        debug("0A: ", leaf_0A());
+
+        if (
+            leaf_01() &&
+            leaf_03() &&
+            leaf_04() &&
+            leaf_05() &&
+            leaf_06() &&
+            leaf_09() &&
+            leaf_0A()
+        ) {
+            return core::add(HYPERV);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for KVM CPUID bitmask range for reserved values
+     * @category x86
+     */
+    [[nodiscard]] static bool kvm_bitmask() {
+#if (!x86)
+        return false;
+#else
+        u32 eax, ebx, ecx, edx = 0;
+        cpu::cpuid(eax, ebx, ecx, edx, 0x40000000);
+
+        // KVM brand and max leaf check
+        if (!(
+            (eax == 0x40000001) &&
+            (ebx == 0x4b4d564b) &&
+            (ecx == 0x564b4d56) &&
+            (edx == 0x4d)
+        )) {
+            return false;
+        }
+
+        cpu::cpuid(eax, ebx, ecx, edx, 0x40000001);
+
+        if (
+            (eax & (1 << 8)) &&
+            (((eax >> 13) & 0b1111111111) == 0) &&
+            ((eax >> 24) == 0)
+        ) {
+            return core::add(KVM);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Intel KGT (Trusty branch) hypervisor signature in CPUID
+     * @link https://github.com/intel/ikgt-core/blob/7dfd4d1614d788ec43b02602cce7a272ef8d5931/vmm/vmexit/vmexit_cpuid.c
+     * @category x86
+     */
+    [[nodiscard]] static bool intel_kgt_signature() {
+#if (!x86)
+        return false;
+#else
+        u32 unused, ecx, edx = 0;
+        cpu::cpuid(unused, unused, ecx, edx, 3);
+
+        if (
+            // ecx should be "EVMM" and edx is "INTC".
+            // Not sure if it's little endian or big endian, so i'm comparing both
+            ((ecx == 0x4D4D5645) && (edx == 0x43544E49)) ||
+            ((ecx == 0x45564D4D) && (edx == 0x494E5443))
+        ) {
+            return core::add(INTEL_KGT);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VMware DMI strings in BIOS serial number
+     * @link https://knowledge.broadcom.com/external/article?legacyId=1009458
+     * @category Windows
+     */
+    [[nodiscard]] static bool vmware_dmi() {
+#if (!MSVC)
+        return false;
+#else
+        std::unique_ptr<util::sys_info> info = util::make_unique<util::sys_info>();
+
+        const std::string str = info->get_serialnumber();
+
+        if (util::find(str, "VMware-")) {
+            return core::add(VMWARE);
+        }
+
+        if (util::find(str, "VMW")) {
+            return core::add(VMWARE_FUSION);
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for presence of Hyper-V in the Windows Event Logs
+     * @author Requiem (https://github.com/NotRequiem)
+     * @category Windows
+     */
+    [[nodiscard]] static bool hyperv_event_logs() {
+#if (!MSVC)
+        return false;
+#else
+        // Define the log name and search strings
+        std::wstring logName = L"Microsoft-Windows-Kernel-PnP/Configuration"; // Example: "System", "Application", "Security", or a custom path. In this case, we use Microsoft-Windows-Kernel-PnP/Configuration as a Hyper-V VM artifact
+        std::vector<std::wstring> searchStrings = { L"Virtual_Machine", L"VMBUS" };
+
+        bool found = util::query_event_logs(logName, searchStrings);
+
+        if (found) {
+            return core::add(HYPERV);
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for presence of QEMU in the /sys/devices/virtual/dmi/id directory
+     * @category Linux
+     */
+    [[nodiscard]] static bool qemu_virtual_dmi() {
+#if (!LINUX)
+        return false;
+#else
+        const char* sys_vendor = "/sys/devices/virtual/dmi/id/sys_vendor";
+        const char* modalias = "/sys/devices/virtual/dmi/id/modalias";
+
+        if (
+            util::exists(sys_vendor) &&
+            util::exists(modalias)
+        ) {
+            const std::string sys_vendor_str = util::read_file(sys_vendor);
+            const std::string modalias_str = util::read_file(modalias);
+
+            return (
+                util::find(sys_vendor_str, "QEMU") &&
+                util::find(modalias_str, "QEMU")
+            );
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for presence of QEMU in the /sys/kernel/debug/usb/devices directory
+     * @category Linux
+     */
+    [[nodiscard]] static bool qemu_USB() {
+#if (!LINUX)
+        return false;
+#else
+        if (!util::is_admin()) {
+            return false;
+        }
+
+        const char* usb_path = "/sys/kernel/debug/usb/devices";
+
+        if (util::exists(usb_path)) {
+            const std::string usb_path_str = util::read_file(usb_path);
+            return (util::find(usb_path_str, "QEMU"));
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for presence of any files in /sys/hypervisor directory
+     * @category Linux
+     */
+    [[nodiscard]] static bool hypervisor_dir() {
+#if (!LINUX)
+        return false;
+#else
+        DIR* dir = opendir("/sys/hypervisor");
+
+        if (dir == nullptr) {
+            return false;
+        }
+
+        struct dirent* entry;
+        int count = 0;
+
+        while ((entry = readdir(dir)) != nullptr) {
+            if (
+                (entry->d_name[0] == '.' && entry->d_name[1] == '\0') || 
+                (entry->d_name[1] == '.' && entry->d_name[2] == '\0')
+            ) {
+                continue;
+            }
+
+            count++;
+            break;
+        }
+
+        closedir(dir);
+
+        bool type = false;
+
+        if (util::exists("/sys/hypervisor/type")) {
+            type = true;
+        }
+
+        if (type) {
+            const std::string content = util::read_file("/sys/hypervisor/type");
+            if (util::find(content, "xen")) {
+                return core::add(XEN);
+            }
+        }
+
+        // check if there's a few files in that directory
+        return ((count != 0) && type);
+#endif
+    } 
+
+
+    /**
+     * @brief Check for the "UML" string in the CPU brand
+     * @note idea from https://github.com/ShellCode33/VM-Detection/blob/master/vmdetect/linux.go
+     * @category Linux
+     */
+    [[nodiscard]] static bool uml_cpu() {
+#if (!LINUX)
+        return false;
+#else
+        // method 1, get the CPU brand model
+        const std::string brand = cpu::get_brand();
+
+        if (brand == "UML") {
+            return core::add(UML);
+        }
+
+        // method 2, match for the "User Mode Linux" string in /proc/cpuinfo
+        const char* file = "/proc/cpuinfo";
+
+        if (util::exists(file)) {
+            const std::string file_content = util::read_file(file);
+
+            if (util::find(file_content, "User Mode Linux")) {
+                return core::add(UML);
+            }
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for any indications of hypervisors in the kernel message logs
+     * @note idea from https://github.com/ShellCode33/VM-Detection/blob/master/vmdetect/linux.go
+     * @category Linux
+     */
+    [[nodiscard]] static bool kmsg() {
+#if (!LINUX)
+        return false;
+#else
+        if (!util::is_admin()) {
+            return false;
+        }
+
+        // Open /dev/kmsg
+        int fd = open("/dev/kmsg", O_RDONLY | O_NONBLOCK);
+        if (fd < 0) {
+            debug("KMSG: Failed to open /dev/kmsg");
+            return 1;
+        }
+
+        char buffer[1024];
+        std::stringstream ss;
+
+        while (true) {
+            ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
+
+            if (bytes_read > 0) {
+                buffer[bytes_read] = '\0';
+                ss << buffer;
+            } else if (bytes_read == 0) {
+                usleep(100000); // Sleep for 100 milliseconds
+            } else {
+                if (errno == EAGAIN) {
+                    usleep(100000); // Sleep for 100 milliseconds
+                } else {
+                    debug("KMSG: Error reading /dev/kmsg");
+                    break;
+                }
+            }
+
+            if (bytes_read < 0) {
+                break;
+            }
+        }
+
+        close(fd);
+
+        const std::string content = ss.str();
+
+        if (content.empty()) {
+            return false;
+        }
+
+        return (util::find(content, "Hypervisor detected"));
+#endif
+    } 
+
+
+    /**
+     * @brief Check for a Xen VM process
+     * @note idea from https://github.com/ShellCode33/VM-Detection/blob/master/vmdetect/linux.go
+     * @category Linux
+     */
+    [[nodiscard]] static bool vm_procs() {
+#if (!LINUX)
+        return false;
+#else
+        if (util::exists("/proc/xen")) {
+            return core::add(XEN);
+        }
+
+        if (util::exists("/proc/vz")) {
+            return core::add(OPENVZ);
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for a VBox kernel module
+     * @note idea from https://github.com/ShellCode33/VM-Detection/blob/master/vmdetect/linux.go
+     * @category Linux
+     */
+    [[nodiscard]] static bool vbox_module() {
+#if (!LINUX)
+        return false;
+#else
+        const char* file = "/proc/modules";
+
+        if (!util::exists(file)) {
+            return false;
+        }
+
+        const std::string content = util::read_file(file);
+
+        if (util::find(content, "vboxguest")) {
+            return core::add(VBOX);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for potential VM info in /proc/sysinfo
+     * @note idea from https://github.com/ShellCode33/VM-Detection/blob/master/vmdetect/linux.go
+     * @category Linux
+     */
+    [[nodiscard]] static bool sysinfo_proc() {
+#if (!LINUX)
+        return false;
+#else
+        const char* file = "/proc/sysinfo";
+
+        if (!util::exists(file)) {
+            return false;
+        }
+
+        const std::string content = util::read_file(file);
+
+        if (util::find(content, "VM00")) {
+            return true;
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for specific files in /proc/device-tree directory
+     * @note idea from https://github.com/ShellCode33/VM-Detection/blob/master/vmdetect/linux.go
+     * @category Linux
+     */
+    [[nodiscard]] static bool device_tree() {
+#if (!LINUX)
+        return false;
+#else
+        if (util::exists("/proc/device-tree/fw-cfg")) {
+            return core::add(QEMU);
+        }
+
+        return (util::exists("/proc/device-tree/hypervisor/compatible"));
+#endif
+    } 
+
+
+    /**
+     * @brief Check for string matches of VM brands in the linux DMI
+     * @category Linux
+     */
+    [[nodiscard]] static bool dmi_scan() {
+#if (!LINUX)
+        return false;
+#else
+        /*
+        cat: /sys/class/dmi/id/board_serial: Permission denied
+        cat: /sys/class/dmi/id/chassis_serial: Permission denied
+        cat: /sys/class/dmi/id/product_serial: Permission denied
+        cat: /sys/class/dmi/id/product_uuid: Permission denied
+        */
+
+        constexpr std::array<const char*, 7> dmi_array {
+            "/sys/class/dmi/id/bios_vendor",
+            "/sys/class/dmi/id/board_name",
+            "/sys/class/dmi/id/board_vendor",
+            "/sys/class/dmi/id/chassis_asset_tag",
+            "/sys/class/dmi/id/product_family",
+            "/sys/class/dmi/id/product_sku",
+            "/sys/class/dmi/id/sys_vendor"
+        };
+
+        constexpr std::array<std::pair<const char*, const char*>, 15> vm_table {{
+            { "kvm", KVM },
+            { "openstack", OPENSTACK },
+            { "kubevirt", KUBEVIRT },
+            { "amazon ec2", AWS_NITRO },
+            { "qemu", QEMU },
+            { "vmware", VMWARE },
+            { "innotek gmbh", VBOX },
+            { "virtualbox", VBOX },
+            { "oracle corporation", VBOX },
+            //{ "xen", XEN },
+            { "bochs", BOCHS },
+            { "parallels", PARALLELS },
+            { "bhyve", BHYVE },
+            { "hyper-v", HYPERV },
+            { "apple virtualization", APPLE_VZ },
+            { "google compute engine", GCE }
+        }};
+
+        auto to_lower = [](std::string &str) {
+            for (auto& c : str) {
+                if (c == ' ') {
+                    continue;
+                }
+
+                c = static_cast<char>(tolower(c));
+            }
+        };
+
+        for (const auto &vm_string : vm_table) {
+            for (const auto file : dmi_array) {
+                if (!util::exists(file)) {
+                    continue;
+                }
+
+                std::string content = util::read_file(file);
+
+                to_lower(content);
+
+                if (std::regex_search(content, std::regex(vm_string.first))) {
+                    debug("DMI_SCAN: content = ", content);
+                    if (std::strcmp(vm_string.second, AWS_NITRO) == 0) {
+                        if (smbios_vm_bit()) {
+                            return core::add(AWS_NITRO);
+                        }
+                    } else {
+                        return core::add(vm_string.second);
+                    }
+                }
+            }
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for the VM bit in the SMBIOS data
+     * @note idea from https://github.com/systemd/systemd/blob/main/src/basic/virt.c
+     * @category Linux
+     */
+    [[nodiscard]] static bool smbios_vm_bit() {
+#if (!LINUX)
+        return false;
+#else
+        if (!util::is_admin()) {
+            return false;
+        }
+
+        const char* file = "/sys/firmware/dmi/entries/0-0/raw";
+
+        if (!util::exists(file)) {
+            return false;
+        }
+
+        const std::vector<u8> content = util::read_file_binary(file);
+
+        if (content.size() < 20 || content.at(1) < 20) {
+            debug("SMBIOS_VM_BIT: ", "only read ", content.size(), " bytes, expected 20");
+            return false;
+        }
+
+        debug("SMBIOS_VM_BIT: ", "content.at(19) = ", static_cast<int>(content.at(19)));
+
+        return (content.at(19) & (1 << 4));
+#endif
+    } 
+
+
+    /**
+     * @brief Check for podman file in /run/
+     * @note idea from https://github.com/systemd/systemd/blob/main/src/basic/virt.c
+     * @category Linux
+     */
+    [[nodiscard]] static bool podman_file() {
+#if (!LINUX)
+        return false;
+#else
+        if (util::exists("/run/.containerenv")) {
+            return core::add(PODMAN);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for WSL or microsoft indications in /proc/ subdirectories
+     * @note idea from https://github.com/systemd/systemd/blob/main/src/basic/virt.c
+     * @category Linux
+     */
+    [[nodiscard]] static bool wsl_proc_subdir() {
+#if (!LINUX)
+        return false;
+#else
+        const char* osrelease = "/proc/sys/kernel/osrelease";
+        const char* version = "/proc/version";
+
+        if (
+            util::exists(osrelease) &&
+            util::exists(version)
+        ) {
+            const std::string osrelease_content = util::read_file(osrelease);
+            const std::string version_content = util::read_file(version);
+
+            if (
+                (util::find(osrelease_content, "WSL") || util::find(osrelease_content, "Microsoft")) &&
+                (util::find(version, "WSL") || util::find(version, "Microsoft"))
+            ) {
+                return core::add(WSL);
+            }
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Use wmic to get the GPU/videocontrollers chip type.
+     * @category Windows
+     * @author utoshu
+     */
+    [[nodiscard]] static bool gpu_chiptype() {
+#if (!MSVC)
+        return false;
+#else
+        if (!wmi::initialize()) {
+            std::cerr << "Failed to initialize WMI.\n";
+            return false;
+        }
+
+        wmi_result results = wmi::execute(L"SELECT * FROM Win32_VideoController", { L"VideoProcessor" });
+
+        std::string result = "";
+        for (const auto& res : results) {
+            if (res.type == wmi::result_type::String) {
+                result += res.strValue + "\n"; // Collect video processor names
+            }
+        }
+
+        std::transform(result.begin(), result.end(), result.begin(), 
+            [](unsigned char c) { 
+                return static_cast<char>(::tolower(c));
+            }
+        );
+
+        if (util::find(result, "vmware")) {
+            return core::add(VMWARE);
+        }
+
+        if (util::find(result, "virtualbox")) {
+            return core::add(VBOX);
+        }
+
+        if (util::find(result, "hyper-v")) {
+            return core::add(HYPERV);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VM-specific names for drivers
+     * @category Windows
+     * @author Requiem (https://github.com/NotRequiem)
+     */
+    [[nodiscard]] static bool driver_names() {
+#if (!MSVC)
+        return false;
+#else
+        const int maxDrivers = 1024;
+        std::vector<LPVOID> drivers(maxDrivers);
+        DWORD cbNeeded;
+
+        if (!EnumDeviceDrivers(drivers.data(), maxDrivers * sizeof(LPVOID), &cbNeeded)) {
+            debug("Failed to enumerate device drivers");
+            return false;
+        }
+
+        int count = cbNeeded / sizeof(LPVOID);
+        char driverName[MAX_PATH];
+
+        for (int i = 0; i < count; ++i) {
+            if (GetDeviceDriverBaseNameA(drivers[i], driverName, sizeof(driverName))) {
+                if (
+                    strcmp(driverName, "VBoxGuest") == 0 ||
+                    strcmp(driverName, "VBoxMouse") == 0 ||
+                    strcmp(driverName, "VBoxSF") == 0
+                ) {
+                    return core::add(VBOX);
+                }
+            } else {
+                debug("Failed to retrieve driver name");
+                return false;
+            }
+        }
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for the VirtualBox IDT base address
+     * @category Windows
+     * @author Requiem (https://github.com/NotRequiem)
+     */
+    [[nodiscard]] static bool vbox_idt() {
+#if (!MSVC || !x86) 
+        return false;
+#else
+        u16 idt_limit;
+        u64 idt_base;
+
+        struct { uint16_t limit; uint64_t base; } idtr;
+        __sidt(&idtr);
+        idt_limit = idtr.limit;
+        idt_base = idtr.base;
+
+        constexpr u64 known_hyperv_exclusion = 0xfffff80000001000;
+
+        if ((idt_base & 0xFFFF000000000000) == 0xFFFF000000000000 && idt_base != known_hyperv_exclusion) {
+            return core::add(VBOX);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for HDD serial number
+     * @category Windows
+     * @author Requiem (https://github.com/NotRequiem)
+     */
+    [[nodiscard]] static bool hdd_serial_number() {
+#if (!MSVC) 
+        return false;
+#else
+        if (!wmi::initialize()) {
+            debug("HDD serial number: Failed to initialize WMI");
+            return false;
+        }
+
+        const char* targetSerial = "VBbd5bbffd-59166c24";
+
+        wmi_result results = wmi::execute(L"SELECT SerialNumber FROM Win32_DiskDrive", { L"SerialNumber" });
+
+        for (const auto& res : results) {
+            if (res.type == wmi::result_type::String) {
+                if (_stricmp(res.strValue.c_str(), targetSerial) == 0) {
+                    return core::add(VBOX);
+                }
+            }
+        }
+
+        return false;
+#endif
+    };
+
+
+    /**
+     * @brief Check for physical connection ports
+     * @category Windows
+     * @author @unusual-aspect (https://github.com/unusual-aspect)
+     */
+    [[nodiscard]] static bool port_connectors() {
+#if (!MSVC) 
+        return false;
+#else
+        if (!wmi::initialize()) {
+            return false;
+        }
+
+        wmi_result results = wmi::execute(L"SELECT * FROM Win32_PortConnector", { L"Caption" });
+
+        return results.empty();
+#endif
+    };
+
+
+    /**
+     * @brief Check for QEMU keyword in HDD model
+     * @category Windows
+     */
+    [[nodiscard]] static bool qemu_hdd() {
+#if (!MSVC) 
+        return false;
+#else
+        if (!wmi::initialize()) {
+            return false;
+        }
+
+        wmi_result results = wmi::execute(L"SELECT Model FROM Win32_DiskDrive", { L"Model" });
+
+        for (const auto& res : results) {
+            if (res.type == wmi::result_type::String) {
+                debug("QEMU_HDD: model = ", res.strValue);
+                if (util::find(res.strValue, "QEMU")) {
+                    return core::add(QEMU);
+                }
+            }
+        }
+
+        return false;
+#endif
+    };
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    struct core {
+        MSVC_DISABLE_WARNING(PADDING)
+        struct technique {
+            u8 points = 0;                // this is the certainty score between 0 and 100
+            std::function<bool()> run;    // this is the technique function itself
+            bool is_spoofable = false;    // this is to indicate that the technique can be very easily spoofed (not guaranteed)
+        };
+
+        struct custom_technique {
+            u8 points;
+            u16 id;
+            std::function<bool()> run;
+        };
+        MSVC_ENABLE_WARNING(PADDING)
+
+        static const std::map<enum_flags, technique> technique_table;
+
+        static std::vector<custom_technique> custom_table;
+
+        static bool cpuid_supported;
+
+        // VM scoreboard table specifically for VM::brand()
+        static std::map<const char*, brand_score_t> brand_scoreboard;
+
+        // directly return when adding a brand to the scoreboard for a more succint expression
+#if (MSVC)
+        __declspec(noalias)
+#elif (LINUX)
+        [[gnu::const]]
+#endif
+        static inline bool add(const char* p_brand, const char* extra_brand = "") noexcept {
+            core::brand_scoreboard.at(p_brand)++;
+            if (std::strcmp(extra_brand, "") != 0) {
+                core::brand_scoreboard.at(p_brand)++;
+            }
+            return true;
+        }
+
+        // assert if the flag is enabled, far better expression than typing std::bitset member functions
+#if (LINUX && __has_cpp_attribute(gnu::pure))
+        [[gnu::pure]]
+#endif
+        [[nodiscard]] static inline bool is_disabled(const flagset& flags, const u8 flag_bit) noexcept {
+            return (!flags.test(flag_bit));
+        }
+
+        // same as above but for checking enabled flags
+#if (LINUX && __has_cpp_attribute(gnu::pure))
+        [[gnu::pure]]
+#endif
+        [[nodiscard]] static inline bool is_enabled(const flagset& flags, const u8 flag_bit) noexcept {
+            return (flags.test(flag_bit));
+        }
+
+        [[nodiscard]] static bool is_technique_set(const flagset& flags) {
+            for (std::size_t i = technique_begin; i < technique_end; i++) {
+                if (flags.test(i)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        [[nodiscard]] static bool is_setting_flag_set(const flagset& flags) {
+            for (std::size_t i = non_technique_begin; i < non_technique_end; i++) {
+                if (flags.test(i)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        // manage the flag to handle edgecases
+        static void flag_sanitizer(flagset& flags) {
+            if (flags.count() == 0) {
+                flags |= DEFAULT;
+                return;
+            }
+
+            if (flags == DEFAULT) {
+                return;
+            }
+
+            // check if any technique flag is set, which is the "correct" way
+            if (core::is_technique_set(flags)) {
+                return;
+            }
+
+            if (!core::is_setting_flag_set(flags)) {
+                throw std::invalid_argument("Invalid flag option for function parameter found, either leave it empty or add the VM::DEFAULT flag");
+            }
+
+            // at this stage, only settings technique flags are asserted to be set
+            if (
+                flags.test(NO_MEMO) ||
+                flags.test(HIGH_THRESHOLD) ||
+                flags.test(SPOOFABLE) ||
+                flags.test(NULL_ARG) ||
+                flags.test(MULTIPLE)
+            ) {
+                flags |= DEFAULT;
+            } else {
+                throw std::invalid_argument("Invalid flag option found, aborting");
+            }
+        }
+
+        // run every VM detection mechanism in the technique table
+        static u16 run_all(const flagset& flags, const bool shortcut = false) {
+            u16 points = 0;
+
+            const bool memo_enabled = core::is_disabled(flags, NO_MEMO);
+
+            const u16 threshold_points = (core::is_enabled(flags, HIGH_THRESHOLD) ? high_threshold_score : 200);
+
+            // loop through technique table, where all the techniques are stored
+            for (const auto& tmp : technique_table) {
+                const enum_flags technique_macro = tmp.first;
+                const technique technique_data = tmp.second;
+
+                // check if the technique is disabled
+                if (core::is_disabled(flags, technique_macro)) {
+                    continue;
+                }
+
+                // check if it's spoofable, and whether it's enabled
+                if (
+                    technique_data.is_spoofable && 
+                    core::is_disabled(flags, SPOOFABLE)
+                ) {
+                    continue;
+                }
+
+                // check if the technique is cached already
+                if (memo_enabled && memo::is_cached(technique_macro)) {
+                    const memo::data_t data = memo::cache_fetch(technique_macro);
+
+                    if (data.result) {
+                        points += data.points;
+                    }
+
+                    continue;
+                }
+
+                // run the technique
+                const bool result = technique_data.run();
+
+                // accumulate the points if technique detected a VM
+                if (result) {
+                    points += technique_data.points;
+
+                    // this is specific to VM::detected_count() which returns 
+                    // the number of techniques that returned a positive
+                    detected_count_num++;
+                }
+                
+                // for things like VM::detect() and VM::percentage(),
+                // a score of 200+ is guaranteed to be a VM, so
+                // there's no point in running the rest of the techniques
+                if (shortcut && points >= threshold_points) {
+                    return points;
+                }
+
+                // store the current technique result to the cache
+                if (memo_enabled) {
+                    memo::cache_store(technique_macro, result, technique_data.points);
+                }
+            }
+
+            // for custom VM techniques, won't be used most of the time
+            if (!custom_table.empty()) {
+                for (const auto& technique : custom_table) {
+                    if (memo_enabled && memo::is_cached(technique.id)) {
+                        const memo::data_t data = memo::cache_fetch(technique.id);
+
+                        if (data.result) {
+                            points += data.points;
+                        }
+
+                        continue;
+                    }
+
+                    const bool result = technique.run();
+
+                    if (result) {
+                        points += technique.points;
+                        detected_count_num++;
+                    }
+
+                    if (memo_enabled) {
+                        memo::cache_store(
+                            technique.id,
+                            result, 
+                            technique.points
+                        );
+                    }
+                }
+            }
+
+            return points;
+        }
+
+
+        /**
+         * basically what this entire template fuckery does is manage the
+         * variadic arguments being given through the arg_handler function,
+         * which could either be a std::bitset<N>, a uint8_t, or a combination
+         * of both of them. This will handle both argument types and implement
+         * them depending on what their types are. If it's a std::bitset<N>,
+         * do the |= operation on flag_collector. If it's a uint8_t, simply 
+         * .set() that into the flag_collector. That's the gist of it.
+         *
+         * Also I won't even deny, the majority of this section was 90% generated
+         * by chatgpt. Can't be arsed with this C++ templatisation shit.
+         * Like is it really my fault that I have a hard time understanging C++'s 
+         * god awful metaprogramming designs? And don't even get me started on SNIFAE. 
+         * 
+         * You don't need an IQ of 3 digits to realise how dogshit this language
+         * is, when you end up in situations where there's a few correct solutions
+         * to a problem, but with a billion ways you can do the same thing but in 
+         * the "wrong" way. I genuinely can't wait for Carbon to come out.
+         */
+    private:
+        static flagset flag_collector;
+
+        static void flagset_manager(const flagset& flags) {
+            flag_collector |= flags;
+        }
+
+        static void flag_manager(const enum_flags flag) {
+            if (
+                (flag == INVALID) ||
+                (flag > enum_size)
+            ) {
+                throw std::invalid_argument("Non-flag or invalid flag provided for VM::detect(), aborting");
+            }
+
+            flag_collector.set(flag);
+        }
+
+        // Define a base class for different types
+        struct TestHandler {
+            virtual void handle(const flagset& flags) {
+                flagset_manager(flags);
+            }
+
+            virtual void handle(const enum_flags flag) {
+                flag_manager(flag);
+            }
+        };
+
+        // Define derived classes for specific type implementations
+        struct TestBitsetHandler : public TestHandler {
+            void handle(const flagset& flags) override {
+                flagset_manager(flags);
+            }
+        };
+
+        struct TestUint8Handler : public TestHandler {
+            void handle(const enum_flags flag) override {
+                flag_manager(flag);
+            }
+        };
+
+        // Define a function to dispatch handling based on type
+        template <typename T>
+        static void dispatch(const T& value, TestHandler& handler) {
+            handler.handle(value);
+        }
+
+        // Base case for the recursive handling
+        static void handleArgs() {
+            // Base case: Do nothing
+        }
+
+        // Base case for the recursive handling
+        static void handle_disabled_args() {
+            // Base case: Do nothing
+        }
+
+        // Helper function to check if a given argument is of a specific type
+        template <typename T, typename U>
+        static bool isType(U&&) {
+            return std::is_same<T, typename std::decay<U>::type>::value;
+        }
+
+        // Recursive case to handle each argument based on its type
+        template <typename First, typename... Rest>
+        static void handleArgs(First&& first, Rest&&... rest) {
+            TestBitsetHandler bitsetHandler;
+            TestUint8Handler uint8Handler;
+
+            if (isType<flagset>(first)) {
+                dispatch(first, bitsetHandler);
+            } else if (isType<enum_flags>(first)) {
+                dispatch(first, uint8Handler);
+            } else {
+                const std::string msg =
+                    "Arguments must either be a std::bitset<" +
+                    std::to_string(static_cast<u32>(enum_size + 1)) +
+                    "> such as VM::DEFAULT, or a flag such as VM::RDTSC for example";
+
+                throw std::invalid_argument(msg);
+            }
+
+            // Recursively handle the rest of the arguments
+            handleArgs(std::forward<Rest>(rest)...);
+        }
+
+        // Recursive case to handle each argument based on its type
+        template <typename First, typename... Rest>
+        static void handle_disabled_args(First&& first, Rest&&... rest) {
+            TestUint8Handler uint8Handler;
+
+            if (isType<flagset>(first)) {
+                throw std::invalid_argument("Arguments must not contain VM::DEFAULT or VM::ALL, only technique flags are accepted (view the documentation for a full list)");
+            } else if (isType<enum_flags>(first)) {
+                dispatch(first, uint8Handler);
+            } else {
+                throw std::invalid_argument("Arguments must be a technique flag, aborting");
+            }
+
+            // Recursively handle the rest of the arguments
+            handle_disabled_args(std::forward<Rest>(rest)...);
+        }
+
+        template <typename... Args>
+        static constexpr bool is_empty() {
+            return (sizeof...(Args) == 0);
+        }
+
+#if (CPP >= 17)
+#define VMAWARE_CONSTEXPR constexpr
+#else
+#define VMAWARE_CONSTEXPR
+#endif
+
+    public:
+        // fetch the flags, could be an enum value OR a std::bitset.
+        // This will then generate a different std::bitset as the 
+        // return value by enabling the bits based on the argument.
+        template <typename... Args>
+        static flagset arg_handler(Args&&... args) {
+            if VMAWARE_CONSTEXPR (is_empty<Args...>()) {
+                return DEFAULT;
+            }
+
+            flag_collector.reset();
+            global_flags.reset();
+
+            // set the bits in the flag, can take in 
+            // either an enum value or a std::bitset
+            handleArgs(std::forward<Args>(args)...);
+
+            // handle edgecases
+            core::flag_sanitizer(flag_collector);
+
+            global_flags = flag_collector;
+
+            return flag_collector;
+        }
+
+        // same as above but for VM::disable which only accepts technique flags
+        template <typename... Args>
+        static flagset disabled_arg_handler(Args&&... args) {
+            flag_collector.reset();
+
+            if VMAWARE_CONSTEXPR (is_empty<Args...>()) {
+                throw std::invalid_argument("VM::DISABLE() must contain a flag");
+            }
+
+            handle_disabled_args(std::forward<Args>(args)...);
+
+            // check if a settings flag is set, which is not valid
+            if (core::is_setting_flag_set(flag_collector)) {
+                throw std::invalid_argument("VM::DISABLE() must not contain a settings flag, they are disabled by default anyway");
+            }
+
+            return flag_collector;
+        }
+    };
+
+
+public: // START OF PUBLIC FUNCTIONS
+
+    /**
+     * @brief Check for a specific technique based on flag argument
+     * @param u8 (flags from VM wrapper)
+     * @return bool
+     * @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmcheck
+     */
+    static bool check(
+        const enum_flags flag_bit, 
+        const enum_flags memo_arg = NULL_ARG
+        // clang doesn't support std::source_location for some reason
+#if (CPP >= 20 && !CLANG)
+        , const std::source_location& loc = std::source_location::current()
+#endif
+    ) {
+        // lambda to manage exceptions
+        auto throw_error = [&](const char* text) -> void {
+            std::stringstream ss;
+#if (CPP >= 20 && !CLANG)
+            ss << ", error in " << loc.function_name() << " at " << loc.file_name() << ":" << loc.line() << ")";
+#endif
+            ss << ". Consult the documentation's flag handler for VM::check()";
+            throw std::invalid_argument(std::string(text) + ss.str());
+        };
+
+        // check if flag is out of range
+        if (flag_bit > enum_size) {
+            throw_error("Flag argument must be a valid");
+        }
+
+        // check if the bit is a settings flag, which shouldn't be allowed
+        if (
+            (flag_bit == NO_MEMO) ||
+            (flag_bit == HIGH_THRESHOLD) ||
+            (flag_bit == SPOOFABLE) ||
+            (flag_bit == MULTIPLE)
+        ) {
+            throw_error("Flag argument must be a technique flag and not a settings flag");
+        }
+
+        if (
+            (memo_arg != NO_MEMO) && 
+            (memo_arg != NULL_ARG)
+        ) {
+            throw_error("Flag argument for memoization must be either VM::NO_MEMO or left empty");
+        }
+
+        const bool is_memoized = (memo_arg != NO_MEMO);
+
+#if (CPP >= 23)
+        [[assume(flag_bit < technique_end)]];
+#endif
+
+        // if the technique is already cached, return the cached value instead
+        if (memo::is_cached(flag_bit) && is_memoized) {
+            const memo::data_t data = memo::cache_fetch(flag_bit);
+            return data.result;
+        }
+
+        // check if the flag even exists
+        auto it = core::technique_table.find(flag_bit);
+        if (it == core::technique_table.end()) {
+            throw_error("Flag is not known");
+        }
+
+        // initialise and run the technique
+        const core::technique& pair = it->second;
+        const bool result = pair.run();
+
+        if (result) {
+            detected_count_num++;
+        }
+
+#ifdef __VMAWARE_DEBUG__
+        total_points += pair.points;
+#endif
+
+        // store the technique result in the cache table
+        if (is_memoized) {
+            memo::cache_store(flag_bit, result, pair.points);
+        }
+
+        return result;
+    }
+
+
+    /**
+     * @brief Fetch the VM brand
+     * @param any flag combination in VM structure or nothing (VM::MULTIPLE can be added)
+     * @return std::string
+     * @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmbrand
+     */
+    template <typename ...Args>
+    static std::string brand(Args ...args) {
+        flagset flags = core::arg_handler(args...);
+
+        // is the multiple setting flag enabled? (meaning multiple 
+        // brand strings will be outputted if there's a conflict)
+        const bool is_multiple = core::is_enabled(flags, MULTIPLE);
+
+        // are all the techiques already run? if not, run them 
+        // to fetch the necessary info to determine the brand
+        if (!memo::all_present() || core::is_enabled(flags, NO_MEMO)) {
+            core::run_all(flags);
+        }
+
+        // check if the result is already cached and return that instead
+        if (core::is_disabled(flags, NO_MEMO)) {
+            if (is_multiple) {
+                if (memo::multi_brand::is_cached()) {
+                    core_debug("VM::brand(): returned multi brand from cache");
+                    return memo::multi_brand::fetch();
+                }
+            } else {
+                if (memo::brand::is_cached()) {
+                    core_debug("VM::brand(): returned brand from cache");
+                    return memo::brand::fetch();
+                }
+            }
+        }
+
+        // goofy ass C++11 and C++14 linker error workaround, 
+        // and yes, this does look indeed stupid.
+#if (CPP <= 14)
+        constexpr const char* TMP_QEMU = "QEMU";
+        constexpr const char* TMP_KVM = "KVM";
+        constexpr const char* TMP_QEMU_KVM = "QEMU+KVM";
+        constexpr const char* TMP_KVM_HYPERV = "KVM Hyper-V Enlightenment";
+        constexpr const char* TMP_QEMU_KVM_HYPERV = "QEMU+KVM Hyper-V Enlightenment";
+
+        constexpr const char* TMP_VMWARE = "VMware";
+        constexpr const char* TMP_EXPRESS = "VMware Express";
+        constexpr const char* TMP_ESX = "VMware ESX";
+        constexpr const char* TMP_GSX = "VMware GSX";
+        constexpr const char* TMP_WORKSTATION = "VMware Workstation";
+        constexpr const char* TMP_FUSION = "VMware Fusion";
+
+        constexpr const char* TMP_VPC = "Virtual PC";
+        constexpr const char* TMP_HYPERV = "Microsoft Hyper-V";
+        constexpr const char* TMP_HYPERV_VPC = "Microsoft Virtual PC/Hyper-V";
+        constexpr const char* TMP_AZURE = "Microsoft Azure Hyper-V";
+        constexpr const char* TMP_NANOVISOR = "Xbox NanoVisor (Hyper-V)";
+        constexpr const char* TMP_HYPERV_ARTIFACT = "Hyper-V artifact (not an actual VM)";
+#else
+        constexpr const char* TMP_QEMU = QEMU;
+        constexpr const char* TMP_KVM = KVM;
+        constexpr const char* TMP_QEMU_KVM = QEMU_KVM;
+        constexpr const char* TMP_KVM_HYPERV = KVM_HYPERV;
+        constexpr const char* TMP_QEMU_KVM_HYPERV = QEMU_KVM_HYPERV;
+
+        constexpr const char* TMP_VMWARE = VMWARE;
+        constexpr const char* TMP_EXPRESS = VMWARE_EXPRESS;
+        constexpr const char* TMP_ESX = VMWARE_ESX;
+        constexpr const char* TMP_GSX = VMWARE_GSX;
+        constexpr const char* TMP_WORKSTATION = VMWARE_WORKSTATION;
+        constexpr const char* TMP_FUSION = VMWARE_FUSION;
+
+        constexpr const char* TMP_VPC = VPC;
+        constexpr const char* TMP_HYPERV = HYPERV;
+        constexpr const char* TMP_HYPERV_VPC = HYPERV_VPC;
+        constexpr const char* TMP_AZURE = AZURE_HYPERV;
+        constexpr const char* TMP_NANOVISOR = NANOVISOR;
+        constexpr const char* TMP_HYPERV_ARTIFACT = HYPERV_ARTIFACT;
+#endif
+
+        // this is where all the RELEVANT brands are stored.
+        // The ones with no points will be filtered out.
+        std::map<const char*, brand_score_t> brands;
+
+        // add the relevant brands with at least 1 point
+        for (const auto &element : core::brand_scoreboard) {
+            if (element.second > 0) {
+                brands.insert(std::make_pair(element.first, element.second));
+            }
+        }
+
+        // if all brands had a point of 0, return 
+        // "Unknown" (no relevant brands were found)
+        if (brands.empty()) {
+            return "Unknown";
+        }
+
+        // if there's only a single brand, return it. 
+        // This will skip the rest of the function
+        // where it will process and merge certain
+        // brands 
+        if (brands.size() == 1) {
+            return brands.begin()->first;
+        }
+        
+        // remove Hyper-V artifacts if found with other 
+        // brands, because that's not a VM. It's added 
+        // only for the sake of information cuz of the 
+        // fucky wucky Hyper-V problem (see Hyper-X)
+        if (brands.size() > 1) {
+            if (brands.find(TMP_HYPERV_ARTIFACT) != brands.end()) {
+                brands.erase(TMP_HYPERV_ARTIFACT);
+            }
+        }
+
+        // merge 2 brands, and make a single brand out of it.
+        auto merger = [&](const char* a, const char* b, const char* result) -> void {
+            if (
+                (brands.count(a) > 0) &&
+                (brands.count(b) > 0)
+            ) {
+                brands.erase(a);
+                brands.erase(b);
+                brands.emplace(std::make_pair(result, 2));
+            }
+        };
+
+        // same as above, but for 3
+        auto triple_merger = [&](const char* a, const char* b, const char* c, const char* result) -> void {
+            if (
+                (brands.count(a) > 0) &&
+                (brands.count(b) > 0) &&
+                (brands.count(c) > 0)
+            ) {
+                brands.erase(a);
+                brands.erase(b);
+                brands.erase(c);
+                brands.emplace(std::make_pair(result, 2));
+            }
+        };
+
+        // some edgecase handling for Hyper-V and VirtualPC since
+        // they're very similar, and they're both from Microsoft (ew)
+        if ((brands.count(TMP_HYPERV) > brands.count(TMP_VPC))) {
+            brands.erase(TMP_VPC);
+        } else if (brands.count(TMP_HYPERV) < brands.count(TMP_VPC)) {
+            brands.erase(TMP_HYPERV);
+        } else if (
+            (brands.count(TMP_HYPERV) == brands.count(TMP_VPC)) &&
+            ((brands.count(TMP_HYPERV) > 0) && (brands.count(TMP_VPC) > 0))
+        ) {
+            merger(TMP_VPC, TMP_HYPERV, TMP_HYPERV_VPC);
+        }
+
+
+        // this is the section where brand post-processing will be done. 
+        // The reason why this part is necessary is because it will
+        // output a more accurate picture on the VM brand. For example, 
+        // Azure's cloud is based on Hyper-V, but Hyper-V may have 
+        // a higher score due to the prevalence of it in a practical 
+        // setting, which will put Azure to the side. This is stupid 
+        // because there should be an indication that Azure is involved
+        // since it's a better idea to let the end-user know that the
+        // brand is "Azure Hyper-V" instead of just "Hyper-V". So what
+        // this section does is "merge" the brands together to form
+        // a more accurate idea of the brand(s) involved.
+
+
+        merger(TMP_AZURE, TMP_HYPERV,     TMP_AZURE);
+        merger(TMP_AZURE, TMP_VPC,        TMP_AZURE);
+        merger(TMP_AZURE, TMP_HYPERV_VPC, TMP_AZURE);
+
+        merger(TMP_NANOVISOR, TMP_HYPERV,     TMP_NANOVISOR);
+        merger(TMP_NANOVISOR, TMP_VPC,        TMP_NANOVISOR);
+        merger(TMP_NANOVISOR, TMP_HYPERV_VPC, TMP_NANOVISOR);
+        
+        merger(TMP_QEMU,     TMP_KVM,        TMP_QEMU_KVM);
+        merger(TMP_KVM,      TMP_HYPERV,     TMP_KVM_HYPERV);
+        merger(TMP_QEMU,     TMP_HYPERV,     TMP_QEMU_KVM_HYPERV);
+        merger(TMP_QEMU_KVM, TMP_HYPERV,     TMP_QEMU_KVM_HYPERV);
+        merger(TMP_KVM,      TMP_KVM_HYPERV, TMP_KVM_HYPERV);
+        merger(TMP_QEMU,     TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
+        merger(TMP_QEMU_KVM, TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
+
+        triple_merger(TMP_QEMU, TMP_KVM, TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
+
+        merger(TMP_VMWARE, TMP_FUSION,      TMP_FUSION);
+        merger(TMP_VMWARE, TMP_EXPRESS,     TMP_EXPRESS);
+        merger(TMP_VMWARE, TMP_ESX,         TMP_ESX);
+        merger(TMP_VMWARE, TMP_GSX,         TMP_GSX);
+        merger(TMP_VMWARE, TMP_WORKSTATION, TMP_WORKSTATION);
+
+        // the brand element, which stores the NAME (const char*) and the SCORE (u8)
+        using brand_element_t = std::pair<const char*, brand_score_t>;
+
+        // sort the "brands" map so that the brands with the
+        // highest score appears first in descending order
+        auto sorter = [&]() -> std::vector<brand_element_t> {
+            std::vector<brand_element_t> vec(brands.begin(), brands.end());
+
+            std::sort(vec.begin(), vec.end(), [](
+                const brand_element_t &a,
+                const brand_element_t &b
+            ) {
+                return a.second < b.second;
+            });
+
+            return vec;
+        };
+
+        std::vector<brand_element_t> vec = sorter();
+        std::string ret_str = "Unknown";
+
+        // if the multiple setting flag is NOT set, return the
+        // brand with the highest score. Else, return a std::string
+        // of the brand message (i.e. "VirtualBox or VMware").
+        // See VM::MULTIPLE flag in docs for more information.
+        if (!is_multiple) {
+            ret_str = vec.front().first;
+        } else {
+            std::stringstream ss;
+            std::size_t i = 1;
+
+            ss << vec.front().first;
+            for (; i < vec.size(); i++) {
+                ss << " or ";
+                ss << vec.at(i).first;
+            }
+            ret_str = ss.str();
+        }
+
+        // cache the result if memoization is enabled
+        if (core::is_disabled(flags, NO_MEMO)) {
+            if (is_multiple) {
+                core_debug("VM::brand(): cached multiple brand string");
+                memo::multi_brand::store(ret_str);
+            } else {
+                core_debug("VM::brand(): cached brand string");
+                memo::brand::store(ret_str);
+            }
+        }
+
+        // debug stuff to see the brand scoreboard, ignore this
+#ifdef __VMAWARE_DEBUG__
+        for (const auto p : brands) {
+            core_debug("scoreboard: ", (int)p.second, " : ", p.first);
+        }
+#endif
+
+        return ret_str;
+    }
+
+
+    /**
+     * @brief Detect if running inside a VM
+     * @param any flag combination in VM structure or nothing
+     * @return bool
+     * @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmdetect
+     */
+    template <typename ...Args>
+    static bool detect(Args ...args) {
+        // fetch all the flags in a std::bitset
+        flagset flags = core::arg_handler(args...);
+
+        // run all the techniques based on the 
+        // flags above, and get a total score
+        const u16 points = core::run_all(flags, SHORTCUT);
+
+#if (CPP >= 23)
+        [[assume(points < maximum_points)]];
+#endif
+
+        u16 threshold = 150;
+
+        // if high threshold is set, the points 
+        // will be 300. If not, leave it as 150.
+        if (core::is_enabled(flags, HIGH_THRESHOLD)) {
+            threshold = high_threshold_score;
+        }
+
+        return (points >= threshold);
+    }
+
+
+    /**
+     * @brief Get the percentage of how likely it's a VM
+     * @param any flag combination in VM structure or nothing
+     * @return std::uint8_t
+     * @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmpercentage
+     */
+    template <typename ...Args>
+    static u8 percentage(Args ...args) {
+        // fetch all the flags in a std::bitset
+        const flagset flags = core::arg_handler(args...);
+
+        // run all the techniques based on the 
+        // flags above, and get a total score
+        const u16 points = core::run_all(flags, SHORTCUT);
+
+#if (CPP >= 23)
+        [[assume(points < maximum_points)]];
+#endif
+
+        u8 percent = 0;
+        u16 threshold = 150;
+
+        // set to 300 if high threshold is enabled
+        if (core::is_enabled(flags, HIGH_THRESHOLD)) {
+            threshold = high_threshold_score;
+        }
+
+        // the percentage will be set to 99%, because a score 
+        // of 100 is not entirely robust. 150 is more robust
+        // in my opinion, which is why you need a score of
+        // above 150 to get to 100% 
+        if (points >= threshold) {
+            percent = 100;
+        } else if (points >= 100) {
+            percent = 99;
+        } else {
+            percent = static_cast<u8>(points);
+        }
+
+        return percent;
+    }
+
+
+    /**
+     * @brief Add a custom technique to the VM detection technique collection
+     * @param either a function pointer, lambda function, or std::function<bool()>
+     * @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmaddcustom
+     * @return void
+     */
+    static void add_custom(
+        const std::uint8_t percent,
+        std::function<bool()> detection_func
+        // clang doesn't support std::source_location for some reason
+#if (CPP >= 20 && !CLANG)
+        , const std::source_location& loc = std::source_location::current()
+#endif
+    ) {
+        // lambda to throw the error
+        auto throw_error = [&](const char* text) -> void {
+            std::stringstream ss;
+#if (CPP >= 20 && !CLANG)
+            ss << ", error in " << loc.function_name() << " at " << loc.file_name() << ":" << loc.line() << ")";
+#endif
+            ss << ". Consult the documentation's parameters for VM::add_custom()";
+            throw std::invalid_argument(std::string(text) + ss.str());
+        };
+
+        if (percent > 100) {
+            throw_error("Percentage parameter must be between 0 and 100");
+        }
+
+#if (CPP >= 23)
+        [[assume(percent > 0 && percent <= 100)]];
+#endif
+
+        static u16 id = 0;
+        id++;
+
+        // generate the custom technique struct
+        core::custom_technique query{
+            percent,
+            // this fucking sucks
+            static_cast<u16>(static_cast<int>(base_technique_count) + static_cast<int>(id)),
+            detection_func
+        };
+
+        technique_count++;
+
+        // push it to the custome_table vector
+        core::custom_table.emplace_back(query);
+    }
+
+
+    /**
+     * @brief disable the provided technique flags so they are not counted to the overall result
+     * @param technique flag(s) only
+     * @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmdetect
+     * @return flagset
+     */
+    template <typename ...Args>
+    static flagset DISABLE(Args ...args) {
+        // basically core::arg_handler but in reverse,
+        // it'll clear the bits of the provided flags
+        flagset flags = core::disabled_arg_handler(args...);
+
+        flags.flip();
+        flags.set(NO_MEMO, 0);
+        flags.set(HIGH_THRESHOLD, 0);
+        flags.set(SPOOFABLE, 0);
+        flags.set(MULTIPLE, 0);
+
+        return flags;
+    }
+
+
+    /**
+     * @brief This will convert the technique flag into a string, which will correspond to the technique name
+     * @param single technique flag in VM structure
+     * @warning ⚠️ FOR DEVELOPMENT USAGE ONLY, NOT MEANT FOR PUBLIC USE FOR NOW ⚠️
+     */
+    [[nodiscard]] static std::string flag_to_string(const enum_flags flag) {
+        switch (flag) {
+            case VMID: return "VMID";
+            case CPU_BRAND: return "CPU_BRAND";
+            case HYPERVISOR_BIT: return "HYPERVISOR_BIT";
+            case HYPERVISOR_STR: return "HYPERVISOR_STR";
+            case RDTSC: return "RDTSC";
+            case THREADCOUNT: return "THREADCOUNT";
+            case MAC: return "MAC";
+            case TEMPERATURE: return "TEMPERATURE";
+            case SYSTEMD: return "SYSTEMD";
+            case CVENDOR: return "CVENDOR";
+            case CTYPE: return "CTYPE";
+            case DOCKERENV: return "DOCKERENV";
+            case DMIDECODE: return "DMIDECODE";
+            case DMESG: return "DMESG";
+            case HWMON: return "HWMON";
+            case SIDT5: return "SIDT5";
+            case CURSOR: return "CURSOR";
+            case VMWARE_REG: return "VMWARE_REG";
+            case VBOX_REG: return "VBOX_REG";
+            case USER: return "USER";
+            case DLL: return "DLL";
+            case REGISTRY: return "REGISTRY";
+            case CWSANDBOX_VM: return "CWSANDBOX_VM";
+            case VM_FILES: return "VM_FILES";
+            case HWMODEL: return "HWMODEL";
+            case DISK_SIZE: return "DISK_SIZE";
+            case VBOX_DEFAULT: return "VBOX_DEFAULT";
+            case VBOX_NETWORK: return "VBOX_NETWORK";
+/* GPL */   case COMPUTER_NAME: return "COMPUTER_NAME";
+/* GPL */   case WINE_CHECK: return "WINE_CHECK";
+/* GPL */   case HOSTNAME: return "HOSTNAME";
+/* GPL */   case MEMORY: return "MEMORY";
+/* GPL */   case VBOX_WINDOW_CLASS: return "VBOX_WINDOW_CLASS";
+/* GPL */   case LOADED_DLLS: return "LOADED_DLLS";
+/* GPL */   case KVM_REG: return "KVM_REG";
+/* GPL */   case KVM_DRIVERS: return "KVM_DRIVERS";
+/* GPL */   case KVM_DIRS: return "KVM_DIRS";
+/* GPL */   case AUDIO: return "AUDIO";
+/* GPL */   case QEMU_DIR: return "QEMU_DIR";
+/* GPL */   case MOUSE_DEVICE: return "MOUSE_DEVICE";
+            case VM_PROCESSES: return "VM_PROCESSES";
+            case LINUX_USER_HOST: return "LINUX_USER_HOST";
+            case GAMARUE: return "GAMARUE";
+            case VMID_0X4: return "VMID_0X4";
+            case PARALLELS_VM: return "PARALLELS_VM";
+            case RDTSC_VMEXIT: return "RDTSC_VMEXIT";
+            case QEMU_BRAND: return "QEMU_BRAND";
+            case BOCHS_CPU: return "BOCHS_CPU";
+            case VPC_BOARD: return "VPC_BOARD";
+            case HYPERV_WMI: return "HYPERV_WMI";
+            case HYPERV_REG: return "HYPERV_REG";
+            case BIOS_SERIAL: return "BIOS_SERIAL";
+            case VBOX_FOLDERS: return "VBOX_FOLDERS";
+            case MSSMBIOS: return "MSSMBIOS";
+            case MAC_MEMSIZE: return "MAC_MEMSIZE";
+            case MAC_IOKIT: return "MAC_IOKIT";
+            case IOREG_GREP: return "IOREG_GREP";
+            case MAC_SIP: return "MAC_SIP";
+            case HKLM_REGISTRIES: return "HKLM_REGISTRIES";
+            case QEMU_GA: return "QEMU_GA";
+            case VALID_MSR: return "VALID_MSR";
+            case QEMU_PROC: return "QEMU_PROC";
+            case VPC_PROC: return "VPC_PROC";
+            case VPC_INVALID: return "VPC_INVALID";
+            case SIDT: return "SIDT";
+            case SGDT: return "SGDT";
+            case SLDT: return "SLDT";
+            case OFFSEC_SIDT: return "OFFSEC_SIDT";
+            case OFFSEC_SGDT: return "OFFSEC_SGDT";
+            case OFFSEC_SLDT: return "OFFSEC_SLDT";
+            case HYPERV_BOARD: return "HYPERV_BOARD";
+            case VM_FILES_EXTRA: return "VM_FILES_EXTRA";
+            case VPC_SIDT: return "VPC_SIDT";
+            case VMWARE_IOMEM: return "VMWARE_IOMEM";
+            case VMWARE_IOPORTS: return "VMWARE_IOPORTS";
+            case VMWARE_SCSI: return "VMWARE_SCSI";
+            case VMWARE_DMESG: return "VMWARE_DMESG";
+            case VMWARE_STR: return "VMWARE_STR";
+            case VMWARE_BACKDOOR: return "VMWARE_BACKDOOR";
+            case VMWARE_PORT_MEM: return "VMWARE_PORT_MEM";
+            case SMSW: return "SMSW";
+            case MUTEX: return "MUTEX";
+            case UPTIME: return "UPTIME";
+            case ODD_CPU_THREADS: return "ODD_CPU_THREADS";
+            case INTEL_THREAD_MISMATCH: return "INTEL_THREAD_MISMATCH";
+            case XEON_THREAD_MISMATCH: return "XEON_THREAD_MISMATCH";
+            case NETTITUDE_VM_MEMORY: return "NETTITUDE_VM_MEMORY";
+            case CPUID_BITSET: return "CPUID_BITSET";
+            case CUCKOO_DIR: return "CUCKOO_DIR";
+            case CUCKOO_PIPE: return "CUCKOO_PIPE";
+            case HYPERV_HOSTNAME: return "HYPERV_HOSTNAME";
+            case GENERAL_HOSTNAME: return "GENERAL_HOSTNAME";
+            case SCREEN_RESOLUTION: return "SCREEN_RESOLUTION";
+            case DEVICE_STRING: return "DEVICE_STRING";
+            case BLUESTACKS_FOLDERS: return "BLUESTACKS_FOLDERS";
+            case CPUID_SIGNATURE: return "CPUID_SIGNATURE";
+            case HYPERV_BITMASK: return "HYPERV_BITMASK";
+            case KVM_BITMASK: return "KVM_BITMASK";
+            case KGT_SIGNATURE: return "KGT_SIGNATURE";
+            case VMWARE_DMI: return "VMWARE_DMI";
+            case EVENT_LOGS: return "EVENT_LOGS";
+            case QEMU_VIRTUAL_DMI: return "QEMU_VIRTUAL_DMI";
+            case QEMU_USB: return "QEMU_USB";
+            case HYPERVISOR_DIR: return "HYPERVISOR_DIR";
+            case UML_CPU: return "UML_CPU";
+            case KMSG: return "KMSG";
+            case VM_PROCS: return "VM_PROCS";
+            case VBOX_MODULE: return "VBOX_MODULE";
+            case SYSINFO_PROC: return "SYSINFO_PROC";
+            case DEVICE_TREE: return "DEVICE_TREE";
+            case DMI_SCAN: return "DMI_SCAN";
+            case SMBIOS_VM_BIT: return "SMBIOS_VM_BIT";
+            case PODMAN_FILE: return "PODMAN_FILE";
+            case WSL_PROC: return "WSL_PROC";
+            case GPU_CHIPTYPE: return "GPU_CHIPTYPE";
+            default: return "Unknown flag";
+        }
+    }
+
+
+    /**
+     * @brief return a vector of detected brand strings
+     * @param any flag combination in VM structure or nothing
+     * @warning ⚠️ FOR DEVELOPMENT USAGE ONLY, NOT MEANT FOR PUBLIC USE FOR NOW ⚠️
+     */
+    template <typename ...Args>
+    static std::map<const char*, brand_score_t> brand_map(Args ...args) {
+        flagset flags = core::arg_handler(args...);
+
+        // are all the techiques already run? if not, run all of them to get the necessary info to fetch the brand
+        if (!memo::all_present() || core::is_enabled(flags, NO_MEMO)) {
+            core::run_all(flags);
+        }
+
+        return core::brand_scoreboard;
+    }
+
+
+    /**
+     * @brief Change the certainty score of a technique
+     * @param technique flag, then the new percentage score to overwite
+     * @return void
+     * @warning ⚠️ FOR DEVELOPMENT USAGE ONLY, NOT MEANT FOR PUBLIC USE FOR NOW ⚠️
+     */
+    static void modify_score(
+        const enum_flags flag,
+        const u8 percent
+        // clang doesn't support std::source_location for some reason
+#if (CPP >= 20 && !CLANG)
+        , const std::source_location& loc = std::source_location::current()
+#endif
+    ) {
+        // lambda to throw the error
+        auto throw_error = [&](const char* text) -> void {
+            std::stringstream ss;
+#if (CPP >= 20 && !CLANG)
+            ss << ", error in " << loc.function_name() << " at " << loc.file_name() << ":" << loc.line() << ")";
+#endif
+            ss << ". Consult the documentation's parameters for VM::modify_score()";
+            throw std::invalid_argument(std::string(text) + ss.str());
+        };
+
+        if (percent > 100) {
+            throw_error("Percentage parameter must be between 0 and 100");
+        }
+
+#if (CPP >= 23)
+        [[assume(percent <= 100)]];
+#endif
+
+        // check if the flag provided is a setting flag, which isn't valid.
+        if (static_cast<u8>(flag) >= technique_end) {
+            throw_error("The flag is not a technique flag");
+        }
+
+        // replica type alias of the technique table
+        using table_t = std::map<enum_flags, core::technique>;
+
+        auto modify = [](table_t &table, const enum_flags flag, const u8 percent) -> void {
+            core::technique &tmp = table.at(flag);
+            table[flag] = { percent, tmp.run, tmp.is_spoofable };
+        };
+
+        modify(const_cast<table_t&>(core::technique_table), flag, percent);
+    }
+
+
+    /**
+     * @brief Fetch the total number of detected techniques
+     * @param any flag combination in VM structure or nothing
+     * @return std::uint8_t
+     */
+    template <typename ...Args>
+    static u8 detected_count(Args ...args) {
+        flagset flags = core::arg_handler(args...);
+
+        // run all the techniques, which will set the detected_count variable 
+        core::run_all(flags);
+
+        return detected_count_num;
+    }
+
+
+    /**
+     * @brief Fetch the total number of detected techniques
+     * @param any flag combination in VM structure or nothing
+     * @return std::uint8_t
+     */
+    template <typename ...Args>
+    static std::string type(Args ...args) {
+        flagset flags = core::arg_handler(args...);
+
+        const std::string brand_str = brand(flags);
+
+        // if multiple brands were found, return unknown
+        if (util::find(brand_str, " or ")) {
+            return "Unknown";
+        }
+
+        const std::map<std::string, const char*> type_table {
+            // type 1
+            { XEN, "Hypervisor (type 1)" },
+            { VMWARE_ESX, "Hypervisor (type 1)" },
+            { ACRN, "Hypervisor (type 1)" },
+            { QNX, "Hypervisor (type 1)" },
+            { HYPERV, "Hypervisor (type 1)" },
+            { AZURE_HYPERV, "Hypervisor (type 1)" },
+            { NANOVISOR, "Hypervisor (type 1)" },
+            { KVM, "Hypervisor (type 1)" },
+            { BHYVE, "Hypervisor (type 1)" },
+            { KVM_HYPERV, "Hypervisor (type 1)" },
+            { QEMU_KVM_HYPERV, "Hypervisor (type 1)" },
+            { QEMU_KVM, "Hypervisor (type 1)" },
+            { INTEL_HAXM, "Hypervisor (type 1)" },
+            { INTEL_KGT, "Hypervisor (type 1)" },
+            { SIMPLEVISOR, "Hypervisor (type 1)" },
+            { GCE, "Hypervisor (type 1)" },
+            { OPENSTACK, "Hypervisor (type 1)" },
+            { KUBEVIRT, "Hypervisor (type 1)" },
+            { POWERVM, "Hypervisor (type 1)" },
+            { AWS_NITRO, "Hypervisor (type 1)" },
+
+            // type 2
+            { VBOX, "Hypervisor (type 2)" },
+            { VMWARE, "Hypervisor (type 2)" },
+            { VMWARE_EXPRESS, "Hypervisor (type 2)" },
+            { VMWARE_GSX, "Hypervisor (type 2)" },
+            { VMWARE_WORKSTATION, "Hypervisor (type 2)" },
+            { VMWARE_FUSION, "Hypervisor (type 2)" },
+            { PARALLELS, "Hypervisor (type 2)" },
+            { VPC, "Hypervisor (type 2)" },
+            { NVMM, "Hypervisor (type 2)" },
+            { BSD_VMM, "Hypervisor (type 2)" },
+
+            // sandbox
+            { CUCKOO, "Sandbox" },
+            { SANDBOXIE, "Sandbox" },
+            { HYBRID, "Sandbox" },
+            { CWSANDBOX, "Sandbox" },
+            { JOEBOX, "Sandbox" },
+            { ANUBIS, "Sandbox" },
+            { COMODO, "Sandbox" },
+            { THREATEXPERT, "Sandbox" },
+
+            // misc
+            { BOCHS, "Emulator" },
+            { BLUESTACKS, "Emulator" },
+            { MSXTA, "Emulator" },
+            { QEMU, "Emulator/Hypervisor (type 2)" },
+            { JAILHOUSE, "Partitioning Hypervisor" },
+            { UNISYS, "Partitioning Hypervisor" },
+            { DOCKER, "Container" },
+            { PODMAN, "Container" },
+            { OPENVZ, "Container" },
+            { HYPERV_VPC, "Hypervisor (either type 1 or 2)" },
+            { LMHS, "Hypervisor (unknown type)" },
+            { WINE, "Compatibility layer" },
+            { APPLE_VZ, "Unknown" },
+            { HYPERV_ARTIFACT, "Unknown" },
+            { UML, "Paravirtualised/Hypervisor (type 2)" },
+            { WSL, "Hybrid Hyper-V (type 1 and 2)" }, // debatable tbh
+            { APPLE_ROSETTA, "Binary Translation Layer/Emulator" },
+        };
+
+        auto it = type_table.find(brand_str.c_str());
+
+        if (it != type_table.end()) {
+            return it->second;
+        }
+
+        return "Unknown";
+    }
+
+
+    /**
+     * @brief Fetch the conclusion message based on the brand and percentage
+     * @param any flag combination in VM structure or nothing
+     * @return std::string
+     */
+    template <typename ...Args>
+    static std::string conclusion(Args ...args) {
+        flagset flags = core::arg_handler(args...);
+
+        const std::string brand_tmp = brand(flags);
+        const u8 percent_tmp = percentage(flags);
+
+        constexpr const char* baremetal = "Running in baremetal";
+        constexpr const char* very_unlikely = "Very unlikely a VM";
+        constexpr const char* unlikely = "Unlikely a VM";
+
+        const std::string potentially = "Potentially";
+        const std::string might = "Might be";
+        const std::string likely = "Likely";
+        const std::string very_likely = "Very likely";
+        const std::string inside_vm = "Running inside";
+
+        auto make_conclusion = [&](const std::string &category) -> std::string {
+            std::string article = "";   
+
+            if (brand_tmp == "Unknown") {
+                article = " an ";
+            } else {
+                article = " a ";
+            }
+
+            return (category + article + brand_tmp + " VM"); 
+        };
+
+        if      (percent_tmp == 0)   { return baremetal; } 
+        else if (percent_tmp <= 20)  { return very_unlikely; } 
+        else if (percent_tmp <= 35)  { return unlikely; } 
+        else if (percent_tmp < 50)   { return make_conclusion(potentially); } 
+        else if (percent_tmp <= 62)  { return make_conclusion(might); } 
+        else if (percent_tmp <= 75)  { return make_conclusion(likely); } 
+        else if (percent_tmp < 100)  { return make_conclusion(very_likely); } 
+        else                         { return make_conclusion(inside_vm); }
+    }
+
+    #pragma pack(push, 1)
+    struct vmaware {
+        std::string brand;
+        std::string type;
+        std::string conclusion;
+        bool is_vm;
+        u8 percentage;
+        u8 detected_count;
+        u16 technique_count;
+
+        template <typename ...Args>
+        vmaware(Args ...args) {
+            flagset flags = core::arg_handler(args...);
+
+            brand = VM::brand(flags);
+            type = VM::type(flags);
+            conclusion = VM::conclusion(flags);
+            is_vm = VM::detect(flags);
+            percentage = VM::percentage(flags);
+            detected_count = VM::detected_count(flags);
+            technique_count = VM::technique_count;
+        }
+    };
+    #pragma pack(pop)
+
+
+    static u16 technique_count; // get total number of techniques
+    static std::vector<u8> technique_vector;
+#ifdef __VMAWARE_DEBUG__
+    static u16 total_points;
+#endif
+};
+
+MSVC_ENABLE_WARNING(ASSIGNMENT_OPERATOR NO_INLINE_FUNC SPECTRE)
+
+
+// ============= EXTERNAL DEFINITIONS =============
+// These are added here due to warnings related to C++17 inline variables for C++ standards that are under 17.
+// It's easier to just group them together rather than having C++17<= preprocessors with inline stuff
+
+
+// scoreboard list of brands, if a VM detection technique detects a brand, that will be incremented here as a single point.
+std::map<const char*, VM::brand_score_t> VM::core::brand_scoreboard{
+    { VM::VBOX, 0 },
+    { VM::VMWARE, 0 },
+    { VM::VMWARE_EXPRESS, 0 },
+    { VM::VMWARE_ESX, 0 },
+    { VM::VMWARE_GSX, 0 },
+    { VM::VMWARE_WORKSTATION, 0 },
+    { VM::VMWARE_FUSION, 0 },
+    { VM::BHYVE, 0 },
+    { VM::KVM, 0 },
+    { VM::QEMU, 0 },
+    { VM::QEMU_KVM, 0 },
+    { VM::KVM_HYPERV, 0 },
+    { VM::QEMU_KVM_HYPERV, 0 },
+    { VM::HYPERV, 0 },
+    { VM::HYPERV_VPC, 0 },
+    { VM::MSXTA, 0 },
+    { VM::PARALLELS, 0 },
+    { VM::XEN, 0 },
+    { VM::ACRN, 0 },
+    { VM::QNX, 0 },
+    { VM::HYBRID, 0 },
+    { VM::SANDBOXIE, 0 },
+    { VM::DOCKER, 0 },
+    { VM::WINE, 0 },
+    { VM::APPLE_ROSETTA, 0 },
+    { VM::VPC, 0 },
+    { VM::ANUBIS, 0 },
+    { VM::JOEBOX, 0 },
+    { VM::THREATEXPERT, 0 },
+    { VM::CWSANDBOX, 0 },
+    { VM::COMODO, 0 },
+    { VM::BOCHS, 0 },
+    { VM::NVMM, 0 },
+    { VM::BSD_VMM, 0 },
+    { VM::INTEL_HAXM, 0 },
+    { VM::UNISYS, 0 },
+    { VM::LMHS, 0 },
+    { VM::CUCKOO, 0 },
+    { VM::BLUESTACKS, 0 },
+    { VM::JAILHOUSE, 0 },
+    { VM::APPLE_VZ, 0 },
+    { VM::INTEL_KGT, 0 },
+    { VM::AZURE_HYPERV, 0 },
+    { VM::NANOVISOR, 0 },
+    { VM::SIMPLEVISOR, 0 },
+    { VM::HYPERV_ARTIFACT, 0 },
+    { VM::UML, 0 },
+    { VM::POWERVM, 0 },
+    { VM::GCE, 0 },
+    { VM::OPENSTACK, 0 },
+    { VM::KUBEVIRT, 0 },
+    { VM::AWS_NITRO, 0 },
+    { VM::PODMAN, 0 },
+    { VM::WSL, 0 },
+    { VM::OPENVZ, 0 },
+    { VM::NULL_BRAND, 0 }
+};
+
+
+// initial definitions for cache items because ISO C++ forbids in-class initializations
+std::map<VM::u16, VM::memo::data_t> VM::memo::cache_table;
+VM::flagset VM::memo::cache_keys = 0;
+std::string VM::memo::brand::brand_cache = "";
+std::string VM::memo::multi_brand::brand_cache = "";
+std::string VM::memo::cpu_brand::brand_cache = "";
+VM::hyperx_state VM::memo::hyperx::state = VM::hyperx_state::UNKNOWN;
+bool VM::memo::hyperx::cached = false;
+#if (MSVC)
+IWbemLocator* VM::wmi::pLoc = nullptr;
+IWbemServices* VM::wmi::pSvc = nullptr;
+bool VM::memo::wmi::cached = false;
+bool VM::memo::wmi::status = false;
+#endif
+
+#ifdef __VMAWARE_DEBUG__
+VM::u16 VM::total_points = 0;
+#endif
+
+// these are basically the base values for the core::arg_handler function.
+// It's like a bucket that will collect all the bits enabled. If for example 
+// VM::detect(VM::HIGH_THRESHOLD) is passed, the HIGH_THRESHOLD bit will be 
+// collected in this flagset (std::bitset) variable, and eventually be the 
+// return value for actual end-user functions like VM::detect() to rely 
+// and work on. VM::global_flags is just a copy of the flags but visible 
+// globally throughout the whole VM struct, as the name implies.
+VM::flagset VM::core::flag_collector;
+VM::flagset VM::global_flags;
+
+
+VM::u8 VM::detected_count_num = 0;
+
+
+// default flags 
+VM::flagset VM::DEFAULT = []() noexcept -> flagset {
+    flagset tmp;
+
+    // set all bits to 1
+    tmp.set();
+
+    // disable all non-default techniques
+    tmp.flip(CURSOR);
+    tmp.flip(RDTSC);
+    tmp.flip(RDTSC_VMEXIT);
+    tmp.flip(VMWARE_DMESG);
+
+    // disable all the settings flags
+    tmp.flip(NO_MEMO);
+    tmp.flip(HIGH_THRESHOLD);
+    tmp.flip(SPOOFABLE);
+    tmp.flip(MULTIPLE);
+
+    return tmp;
+}();
+
+
+// flag to enable every technique
+VM::flagset VM::ALL = []() noexcept -> flagset {
+    flagset tmp;
+
+    // set all bits to 1
+    tmp.set();
+
+    // disable all the settings technique flags (except SPOOFABLE)
+    tmp.flip(NO_MEMO);
+    tmp.flip(HIGH_THRESHOLD);
+    tmp.flip(MULTIPLE);
+
+    return tmp;
+}();
+
+
+std::vector<VM::u8> VM::technique_vector = []() -> std::vector<VM::u8> {
+    std::vector<VM::u8> tmp{};
+
+    // all the techniques have a macro value starting from 0 to ~90, hence why it's a classic loop
+    for (u8 i = VM::technique_begin; i < VM::technique_end; i++) {
+        tmp.push_back(i);
+    }
+
+    return tmp;
+}();
+
+
+// this value is incremented each time VM::add_custom is called
+VM::u16 VM::technique_count = base_technique_count;
+
+
+// check if cpuid is supported
+bool VM::core::cpuid_supported = []() -> bool {
+#if (x86)
+#if (MSVC)
+    int32_t info[4];
+    __cpuid(info, 0);
+    return (info[0] > 0);
+#elif (LINUX)
+    u32 ext = 0;
+    return (__get_cpuid_max(ext, nullptr) > 0);
+#else
+    return false;
+#endif
+#else
+    return false;
+#endif
+}();
+
+
+// this is initialised as empty, because this is where custom techniques can be added at runtime 
+std::vector<VM::core::custom_technique> VM::core::custom_table = {
+
+};
+
+// the 0~100 points are debatable, but I think it's fine how it is. Feel free to disagree.
+const std::map<VM::enum_flags, VM::core::technique> VM::core::technique_table = {
+    // FORMAT: { VM::<ID>, { certainty%, function pointer, is spoofable? } },
+
+    { VM::VMID, { 100, VM::vmid, false } },
+    { VM::CPU_BRAND, { 50, VM::cpu_brand, false } },
+    { VM::HYPERVISOR_BIT, { 100, VM::hypervisor_bit , false}} , 
+    { VM::HYPERVISOR_STR, { 45, VM::hypervisor_str, false } },
+    { VM::RDTSC, { 10, VM::rdtsc_check, false } },
+    { VM::THREADCOUNT, { 35, VM::thread_count, false } },
+    { VM::MAC, { 60, VM::mac_address_check, true } },
+    { VM::TEMPERATURE, { 15, VM::temperature, false } },
+    { VM::SYSTEMD, { 70, VM::systemd_virt, false } },
+    { VM::CVENDOR, { 65, VM::chassis_vendor, false } },
+    { VM::CTYPE, { 10, VM::chassis_type, false } },
+    { VM::DOCKERENV, { 15, VM::dockerenv, true } },
+    { VM::DMIDECODE, { 55, VM::dmidecode, false } },
+    { VM::DMESG, { 55, VM::dmesg, false } },
+    { VM::HWMON, { 75, VM::hwmon, true } },
+    { VM::SIDT5, { 45, VM::sidt5, false } },
+    { VM::CURSOR, { 5, VM::cursor_check, true } },
+    { VM::VMWARE_REG, { 65, VM::vmware_registry, true } },
+    { VM::VBOX_REG, { 65, VM::vbox_registry, true } },
+    { VM::USER, { 35, VM::user_check, true } },
+    { VM::DLL, { 50, VM::DLL_check, true } },
+    { VM::REGISTRY, { 75, VM::registry_key, true } },
+    { VM::CWSANDBOX_VM, { 10, VM::cwsandbox_check, true } },
+    { VM::VM_FILES, { 60, VM::vm_files, true } },
+    { VM::HWMODEL, { 75, VM::hwmodel, true } },
+    { VM::DISK_SIZE, { 60, VM::disk_size, false } },
+    { VM::VBOX_DEFAULT, { 55, VM::vbox_default_specs, false } },
+    { VM::VBOX_NETWORK, { 70, VM::vbox_network_share, false } },
+/* GPL */ { VM::COMPUTER_NAME, { 15, VM::computer_name_match, true } },
+/* GPL */ { VM::WINE_CHECK, { 85, VM::wine, false } },
+/* GPL */ { VM::HOSTNAME, { 25, VM::hostname_match, true } },
+/* GPL */ { VM::MEMORY, { 35, VM::low_memory_space, false } },
+/* GPL */ { VM::VBOX_WINDOW_CLASS, { 10, VM::vbox_window_class, false } },
+/* GPL */ { VM::LOADED_DLLS, { 75, VM::loaded_dlls, true } },
+/* GPL */ { VM::KVM_REG, { 75, VM::kvm_registry, true } },
+/* GPL */ { VM::KVM_DRIVERS, { 55, VM::kvm_drivers, true } },
+/* GPL */ { VM::KVM_DIRS, { 55, VM::kvm_directories, true } },
+/* GPL */ { VM::AUDIO, { 35, VM::check_audio, false } },
+/* GPL */ { VM::QEMU_DIR, { 45, VM::qemu_dir, true } },
+/* GPL */ { VM::MOUSE_DEVICE, { 20, VM::mouse_device, true } },
+    { VM::VM_PROCESSES, { 30, VM::vm_processes, true } },
+    { VM::LINUX_USER_HOST, { 25, VM::linux_user_host, true } },
+    { VM::GAMARUE, { 40, VM::gamarue, true } },
+    { VM::VMID_0X4, { 90, VM::vmid_0x4, false } },
+    { VM::PARALLELS_VM, { 50, VM::parallels, false } },
+    { VM::RDTSC_VMEXIT, { 15, VM::rdtsc_vmexit, false } },
+    { VM::QEMU_BRAND, { 100, VM::cpu_brand_qemu, false } },
+    { VM::BOCHS_CPU, { 95, VM::bochs_cpu, false } },
+    { VM::VPC_BOARD, { 20, VM::vpc_board, false } },
+    { VM::BIOS_SERIAL, { 60, VM::bios_serial, false } },
+    { VM::VBOX_FOLDERS, { 45, VM::vbox_shared_folders, false } },
+    { VM::MSSMBIOS, { 75, VM::mssmbios, false } },
+    { VM::MAC_MEMSIZE, { 30, VM::hw_memsize, true } },
+    { VM::MAC_IOKIT, { 80, VM::io_kit, true } },
+    { VM::IOREG_GREP, { 75, VM::ioreg_grep, true } },
+    { VM::MAC_SIP, { 85, VM::mac_sip, true } },
+    { VM::HKLM_REGISTRIES, { 70, VM::hklm_registries, true } },
+    { VM::QEMU_GA, { 20, VM::qemu_ga, true } },
+    { VM::VALID_MSR, { 35, VM::valid_msr, false } },
+    { VM::QEMU_PROC, { 30, VM::qemu_processes, true } },
+    { VM::VPC_PROC, { 30, VM::vpc_proc, true } },
+    { VM::VPC_INVALID, { 75, VM::vpc_invalid, false } },
+    { VM::SIDT, { 30, VM::sidt, false } },
+    { VM::SGDT, { 30, VM::sgdt, false } },
+    { VM::SLDT, { 15, VM::sldt, false } },
+    { VM::OFFSEC_SIDT, { 60, VM::offsec_sidt, false } },
+    { VM::OFFSEC_SGDT, { 60, VM::offsec_sgdt, false } },
+    { VM::OFFSEC_SLDT, { 20, VM::offsec_sldt, false } },
+    { VM::VPC_SIDT, { 15, VM::vpc_sidt, false } },
+    { VM::HYPERV_BOARD, { 45, VM::hyperv_board, false } },
+    { VM::VM_FILES_EXTRA, { 70, VM::vm_files_extra, true } },
+    { VM::VMWARE_IOMEM, { 65, VM::vmware_iomem, false } },
+    { VM::VMWARE_IOPORTS, { 70, VM::vmware_ioports, false } },
+    { VM::VMWARE_SCSI, { 40, VM::vmware_scsi, false } },
+    { VM::VMWARE_DMESG, { 65, VM::vmware_dmesg, false } },
+    { VM::VMWARE_STR, { 35, VM::vmware_str, false } },
+    { VM::VMWARE_BACKDOOR, { 100, VM::vmware_backdoor, false } },
+    { VM::VMWARE_PORT_MEM, { 85, VM::vmware_port_memory, false } },
+    { VM::SMSW, { 30, VM::smsw, false } },
+    { VM::MUTEX, { 85, VM::mutex, false } },
+    { VM::UPTIME, { 10, VM::uptime, true } },
+    { VM::ODD_CPU_THREADS, { 80, VM::odd_cpu_threads, false } },
+    { VM::INTEL_THREAD_MISMATCH, { 60, VM::intel_thread_mismatch, false } },
+    { VM::XEON_THREAD_MISMATCH, { 85, VM::xeon_thread_mismatch, false } },
+    { VM::NETTITUDE_VM_MEMORY, { 75, VM::nettitude_vm_memory, false } },
+    { VM::CPUID_BITSET, { 20, VM::cpuid_bitset, false } },
+    { VM::CUCKOO_DIR, { 15, VM::cuckoo_dir, true } },
+    { VM::CUCKOO_PIPE, { 20, VM::cuckoo_pipe, true } },
+    { VM::HYPERV_HOSTNAME, { 50, VM::hyperv_hostname, true } },
+    { VM::GENERAL_HOSTNAME, { 20, VM::general_hostname, true } },
+    { VM::SCREEN_RESOLUTION, { 30, VM::screen_resolution, false } },
+    { VM::DEVICE_STRING, { 25, VM::device_string, false } },
+    { VM::BLUESTACKS_FOLDERS, { 15, VM::bluestacks, true } },
+    { VM::CPUID_SIGNATURE, { 95, VM::cpuid_signature, false } },
+    { VM::HYPERV_BITMASK, { 20, VM::hyperv_bitmask, false } },
+    { VM::KVM_BITMASK, { 40, VM::kvm_bitmask, false } },
+    { VM::KGT_SIGNATURE, { 80, VM::intel_kgt_signature, false } },
+    { VM::VMWARE_DMI, { 30, VM::vmware_dmi, false } },
+    { VM::EVENT_LOGS, { 30, VM::hyperv_event_logs, true } },
+    { VM::QEMU_VIRTUAL_DMI, { 40, VM::qemu_virtual_dmi, false } },
+    { VM::QEMU_USB, { 20, VM::qemu_USB, false } },
+    { VM::HYPERVISOR_DIR, { 20, VM::hypervisor_dir, false } },
+    { VM::UML_CPU, { 80, VM::uml_cpu, false } },
+    { VM::KMSG, { 10, VM::kmsg, true } },
+    { VM::VM_PROCS, { 20, VM::vm_procs, true } },
+    { VM::VBOX_MODULE, { 15, VM::vbox_module, false } },
+    { VM::SYSINFO_PROC, { 15, VM::sysinfo_proc, false } },
+    { VM::DEVICE_TREE, { 20, VM::device_tree, false } },
+    { VM::DMI_SCAN, { 50, VM::dmi_scan, false } },
+    { VM::SMBIOS_VM_BIT, { 50, VM::smbios_vm_bit, false } },
+    { VM::PODMAN_FILE, { 15, VM::podman_file, true } },
+    { VM::WSL_PROC, { 30, VM::wsl_proc_subdir, false } },
+    { VM::GPU_CHIPTYPE, { 100, VM::gpu_chiptype, false } },
+    { VM::DRIVER_NAMES, { 30, VM::driver_names, false } },
+    { VM::VBOX_IDT, { 80, VM::vbox_idt, false } },
+    { VM::HDD_SERIAL, { 95, VM::hdd_serial_number, false } },
+    { VM::PORT_CONNECTORS, { 50, VM::port_connectors, false } },
+    { VM::QEMU_HDD, { 60, VM::qemu_hdd, false } }
+};
\ No newline at end of file
diff --git a/VMAware/src/vmaware_MIT.hpp b/VMAware/src/vmaware_MIT.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f50899151e5e1d183bbc1a212e887deb83d89947
--- /dev/null
+++ b/VMAware/src/vmaware_MIT.hpp
@@ -0,0 +1,9662 @@
+/**
+ * ██╗   ██╗███╗   ███╗ █████╗ ██╗    ██╗ █████╗ ██████╗ ███████╗
+ * ██║   ██║████╗ ████║██╔══██╗██║    ██║██╔══██╗██╔══██╗██╔════╝
+ * ██║   ██║██╔████╔██║███████║██║ █╗ ██║███████║██████╔╝█████╗
+ * ╚██╗ ██╔╝██║╚██╔╝██║██╔══██║██║███╗██║██╔══██║██╔══██╗██╔══╝
+ *  ╚████╔╝ ██║ ╚═╝ ██║██║  ██║╚███╔███╔╝██║  ██║██║  ██║███████╗
+ *   ╚═══╝  ╚═╝     ╚═╝╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝ 1.9 (October 2024)
+ *
+ *  C++ VM detection library
+ *
+ *  - Made by: kernelwernel (https://github.com/kernelwernel)
+ *  - Co-maintained by: Requiem (https://github.com/NotRequiem)
+ *  - Contributed by:
+ *      - Alex (https://github.com/greenozon)
+ *      - Marek Knápek (https://github.com/MarekKnapek)
+ *      - Vladyslav Miachkov (https://github.com/fameowner99)
+ *      - Alan Tse (https://github.com/alandtse)
+ *      - Georgii Gennadev (https://github.com/D00Movenok)
+ *      - utoshu (https://github.com/utoshu)
+ *  - Repository: https://github.com/kernelwernel/VMAware
+ *  - Docs: https://github.com/kernelwernel/VMAware/docs/documentation.md
+ *  - Full credits: https://github.com/kernelwernel/VMAware#credits-and-contributors-%EF%B8%8F
+ *  - License: MIT
+ * 
+ *                               MIT License
+ *  
+ *  Copyright (c) 2024 kernelwernel
+ *  
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to deal
+ *  in the Software without restriction, including without limitation the rights
+ *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *  copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *  
+ *  The above copyright notice and this permission notice shall be included in all
+ *  copies or substantial portions of the Software.
+ *  
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ *  SOFTWARE.
+ *
+ *
+ * ================================ SECTIONS ==================================
+ * - enums for publicly accessible techniques  => line 347
+ * - struct for internal cpu operations        => line 599
+ * - struct for internal memoization           => line 1038
+ * - struct for internal utility functions     => line 1378
+ * - struct for internal core components       => line 8142
+ * - start of internal VM detection techniques => line 2601
+ * - start of public VM detection functions    => line 8526
+ * - start of externally defined variables     => line 9380
+ *
+ *
+ * ================================ EXAMPLE ==================================
+ * #include "vmaware.hpp"
+ * #include <iostream>
+ *
+ * int main() {
+ *     if (VM::detect()) {
+ *         std::cout << "Virtual machine detected!" << std::endl;
+ *         std::cout << "VM name: " << VM::brand() << std::endl;
+ *     } else {
+ *         std::cout << "Running in baremetal" << std::endl;
+ *     }
+ *
+ *     std::cout << "VM certainty: " << (int)VM::percentage() << "%" << std::endl;
+ * }
+ */
+
+#pragma once
+
+#if (defined(_MSC_VER) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__))
+#define MSVC 1
+#define LINUX 0
+#define APPLE 0
+#elif (defined(__linux__))
+#define MSVC 0
+#define LINUX 1
+#define APPLE 0
+#elif (defined(__APPLE__) || defined(__APPLE_CPP__) || defined(__MACH__) || defined(__DARWIN))
+#define MSVC 0
+#define LINUX 0
+#define APPLE 1
+#else
+#define MSVC 0
+#define LINUX 0
+#define APPLE 0
+#endif
+
+ // shorter and succinct macros
+#if __cplusplus > 202100L
+#define CPP 23
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using post-C++23, set back to C++23 standard")
+#endif
+#elif __cplusplus == 202100L
+#define CPP 23
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using C++23")
+#endif
+#elif __cplusplus == 202002L
+#define CPP 20
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using C++20")
+#endif
+#elif __cplusplus == 201703L
+#define CPP 17
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using C++17")
+#endif
+#elif __cplusplus == 201402L
+#define CPP 14
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using C++14")
+#endif
+#elif __cplusplus == 201103L
+#define CPP 11
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using C++11")
+#endif
+#elif __cplusplus < 201103L
+#define CPP 1
+#ifdef __VMAWARE_DEBUG__
+#pragma message("using pre-C++11")
+#endif
+#else
+#define CPP 0
+#ifdef __VMAWARE_DEBUG__
+#pragma message("Unknown C++ standard")
+#endif
+#endif
+
+#if (CPP < 11 && !MSVC)
+#error "VMAware only supports C++11 or above, set your compiler flag to '-std=c++20' for gcc/clang, or '/std:c++20' for MSVC"
+#endif
+
+// unused for now, maybe in the future idk
+#if (WINVER == 0x0501) // Windows XP, (0x0701 for Windows 7)
+#define WIN_XP 1
+#else 
+#define WIN_XP 0
+#endif
+
+#if (defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64))
+#define x86 1
+#else
+#define x86 0
+#endif
+#if (defined(_M_IX86))
+#define x86_32 1
+#else
+#define x86_32 0
+#endif
+#if (defined(__arm__) || defined(__ARM_LINUX_COMPILER__) || defined(__aarch64__) || defined(_M_ARM64))
+#define ARM 1
+#else
+#define ARM 0
+#endif
+
+#if defined(__clang__)
+#define GCC 0
+#define CLANG 1
+#elif defined(__GNUC__)
+#define GCC 1
+#define CLANG 0
+#else
+#define GCC 0
+#define CLANG 0
+#endif
+
+#if !(defined(MSVC) || defined(LINUX) || defined(APPLE))
+#warning "Unknown OS detected, tests will be severely limited"
+#endif
+
+#if (CPP >= 23)
+#include <limits>
+#endif
+#if (CPP >= 20)
+#include <bit>
+#include <ranges>
+#include <source_location>
+#endif
+#if (CPP >= 17)
+#include <filesystem>
+#endif
+#ifdef __VMAWARE_DEBUG__
+#include <iomanip>
+#include <ios>
+#endif
+
+#if (MSVC)
+#pragma warning(disable : 4244)
+#include <functional>
+#pragma warning(default : 4244)
+
+#pragma warning(push, 0) // disable the windows SDK errors temporarily
+#else
+#include <functional>
+#endif
+
+#include <functional>
+#include <cstring>
+#include <string>
+#include <fstream>
+#include <regex>
+#include <thread>
+#include <cstdint>
+#include <map>
+#include <unordered_map>
+#include <array>
+#include <algorithm>
+#include <iostream>
+#include <cassert>
+#include <cmath>
+#include <sstream>
+#include <bitset>
+#include <type_traits>
+
+
+#if (MSVC)
+#include <windows.h>
+#include <intrin.h>
+#include <tchar.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <Iphlpapi.h>
+#include <Assert.h>
+#include <excpt.h>
+#include <winternl.h>
+#include <winnetwk.h>
+#include <winuser.h>
+#include <psapi.h>
+#include <comdef.h>
+#include <Wbemidl.h>
+#include <shlwapi.h>
+#include <shlobj_core.h>
+#include <strmif.h>
+#include <dshow.h>
+#include <stdio.h>
+#include <io.h>
+#include <winspool.h>
+#include <wtypes.h>
+#include <winevt.h>
+
+#if (!WIN_XP)
+#include <versionhelpers.h>
+#endif
+
+#pragma comment(lib, "wbemuuid.lib")
+#pragma comment(lib, "iphlpapi.lib")
+#pragma comment(lib, "Shlwapi.lib")
+#pragma comment(lib, "MPR")
+#pragma comment(lib, "advapi32.lib")
+#pragma comment(lib, "kernel32.lib")
+#pragma comment(lib, "shell32.lib")
+#pragma comment(lib, "strmiids.lib")
+#pragma comment(lib, "uuid.lib")
+#pragma comment(lib, "ntdll.lib")
+#pragma comment(lib, "wevtapi.lib")
+
+
+#ifdef _UNICODE
+#define tregex std::wregex
+#else
+#define tregex std::regex
+#endif
+
+#elif (LINUX)
+#if (x86)
+#include <cpuid.h>
+#include <x86intrin.h>
+#include <immintrin.h>
+#endif
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/ioctl.h>
+#include <sys/syscall.h>
+#include <sys/sysinfo.h>
+#include <net/if.h> 
+#include <netinet/in.h>
+#include <unistd.h>
+#include <string.h>
+#include <dirent.h>
+#include <memory>
+#include <cctype>
+#include <fcntl.h>
+#include <limits.h>
+#elif (APPLE)
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <chrono>
+#endif
+
+#if (!MSVC)
+#define TCHAR char
+#endif
+
+#if (MSVC)
+#pragma warning(pop) // enable all warnings
+#endif
+
+// macro shortcut to disable MSVC warnings
+#if (MSVC)
+#define MSVC_DISABLE_WARNING(...) __pragma(warning(disable : __VA_ARGS__))
+#define MSVC_ENABLE_WARNING(...) __pragma(warning(default : __VA_ARGS__))
+#else
+#define MSVC_DISABLE_WARNING(...)
+#define MSVC_ENABLE_WARNING(...)
+#endif
+
+// MSVC-specific errors
+#define SPECTRE 5045
+#define ASSIGNMENT_OPERATOR 4626
+#define NO_INLINE_FUNC 4514
+#define PADDING 4820
+#define FS_HANDLE 4733
+
+MSVC_DISABLE_WARNING(ASSIGNMENT_OPERATOR NO_INLINE_FUNC SPECTRE)
+
+#ifdef __VMAWARE_DEBUG__
+#define debug(...) VM::util::debug_msg(__VA_ARGS__)
+#define core_debug(...) VM::util::core_debug_msg(__VA_ARGS__)
+#else
+#define debug(...)
+#define core_debug(...)
+#endif
+
+struct VM {
+private:
+    using u8  = std::uint8_t;
+    using u16 = std::uint16_t;
+    using u32 = std::uint32_t;
+    using u64 = std::uint64_t;
+    using i8  = std::int8_t;
+    using i16 = std::int16_t;
+    using i32 = std::int32_t;
+    using i64 = std::int64_t;
+
+public:
+    enum enum_flags : u8 {
+        VMID = 0,
+        CPU_BRAND,
+        HYPERVISOR_BIT,
+        HYPERVISOR_STR,
+        RDTSC,
+        THREADCOUNT,
+        MAC,
+        TEMPERATURE,
+        SYSTEMD,
+        CVENDOR,
+        CTYPE,
+        DOCKERENV,
+        DMIDECODE,
+        DMESG,
+        HWMON,
+        SIDT5,
+        CURSOR,
+        VMWARE_REG,
+        VBOX_REG,
+        USER,
+        DLL,
+        REGISTRY,
+        CWSANDBOX_VM,
+        VM_FILES,
+        HWMODEL,
+        DISK_SIZE,
+        VBOX_DEFAULT,
+        VBOX_NETWORK,
+        VM_PROCESSES,
+        LINUX_USER_HOST,
+        GAMARUE,
+        VMID_0X4,
+        PARALLELS_VM,
+        RDTSC_VMEXIT,
+        QEMU_BRAND,
+        BOCHS_CPU,
+        VPC_BOARD,
+        HYPERV_WMI,
+        HYPERV_REG,
+        BIOS_SERIAL,
+        VBOX_FOLDERS,
+        MSSMBIOS,
+        MAC_MEMSIZE,
+        MAC_IOKIT,
+        IOREG_GREP,
+        MAC_SIP,
+        HKLM_REGISTRIES,
+        QEMU_GA,
+        VALID_MSR,
+        QEMU_PROC,
+        VPC_PROC,
+        VPC_INVALID,
+        SIDT,
+        SGDT,
+        SLDT,
+        OFFSEC_SIDT,
+        OFFSEC_SGDT,
+        OFFSEC_SLDT,
+        HYPERV_BOARD,
+        VM_FILES_EXTRA,
+        VPC_SIDT,
+        VMWARE_IOMEM,
+        VMWARE_IOPORTS,
+        VMWARE_SCSI,
+        VMWARE_DMESG,
+        VMWARE_STR,
+        VMWARE_BACKDOOR,
+        VMWARE_PORT_MEM,
+        SMSW,
+        MUTEX,
+        UPTIME,
+        ODD_CPU_THREADS,
+        INTEL_THREAD_MISMATCH,
+        XEON_THREAD_MISMATCH,
+        NETTITUDE_VM_MEMORY,
+        CPUID_BITSET,
+        CUCKOO_DIR,
+        CUCKOO_PIPE,
+        HYPERV_HOSTNAME,
+        GENERAL_HOSTNAME,
+        SCREEN_RESOLUTION,
+        DEVICE_STRING,
+        BLUESTACKS_FOLDERS,
+        CPUID_SIGNATURE,
+        HYPERV_BITMASK,
+        KVM_BITMASK,
+        KGT_SIGNATURE,
+        VMWARE_DMI,
+        EVENT_LOGS,
+        QEMU_VIRTUAL_DMI,
+        QEMU_USB,
+        HYPERVISOR_DIR,
+        UML_CPU,
+        KMSG,
+        VM_PROCS,
+        VBOX_MODULE,
+        SYSINFO_PROC,
+        DEVICE_TREE,
+        DMI_SCAN,
+        SMBIOS_VM_BIT,
+        PODMAN_FILE,
+        WSL_PROC,
+        GPU_CHIPTYPE,
+
+        // start of settings technique flags (THE ORDERING IS VERY SPECIFIC HERE AND MIGHT BREAK SOMETHING IF RE-ORDERED)
+        NO_MEMO,
+        HIGH_THRESHOLD,
+        NULL_ARG, // does nothing, just a placeholder flag mainly for the CLI
+        SPOOFABLE,
+        MULTIPLE
+    };
+
+private:
+    static constexpr u8 enum_size = MULTIPLE; // get enum size through value of last element
+    static constexpr u8 non_technique_count = MULTIPLE - NO_MEMO + 1; // get number of settings technique flags like VM::NO_MEMO for example
+    static constexpr u8 INVALID = 255; // explicit invalid technique macro
+    static constexpr u16 base_technique_count = NO_MEMO; // original technique count, constant on purpose
+    static constexpr u16 maximum_points = 4765; // theoretical total points if all VM detections returned true (which is practically impossible)
+    static constexpr u16 high_threshold_score = 300; // new threshold score from 100 to 350 if VM::HIGH_THRESHOLD flag is enabled
+    static constexpr bool SHORTCUT = true; // macro for whether VM::core::run_all() should take a shortcut by skipping the rest of the techniques if the threshold score is already met
+
+
+    // intended for loop indexes
+    static constexpr u8 enum_begin = 0;
+    static constexpr u8 enum_end = enum_size + 1;
+    static constexpr u8 technique_begin = enum_begin;
+    static constexpr u8 technique_end = NO_MEMO;
+    static constexpr u8 non_technique_begin = NO_MEMO;
+    static constexpr u8 non_technique_end = enum_end;
+
+    // this is specifically meant for VM::detected_count() to 
+    // get the total number of techniques that detected a VM
+    static u8 detected_count_num; 
+
+private:
+
+#if (MSVC)
+    using brand_score_t = i32;
+#else
+    using brand_score_t = u8;
+#endif
+
+    // for the flag bitset structure
+    using flagset = std::bitset<enum_size + 1>;
+
+public:
+    // this will allow the enum to be used in the public interface as "VM::TECHNIQUE"
+    enum enum_flags tmp_ignore_this = NO_MEMO;
+
+    // constructor shit ignore this
+    VM() = delete;
+    VM(const VM&) = delete;
+    VM(VM&&) = delete;
+
+    static flagset DEFAULT; // default bitset that will be run if no parameters are specified
+    static flagset ALL; // same as default, but with cursor check included
+
+private:
+
+    /**
+     * Official aliases for VM brands. This is added to avoid accidental typos
+     * which could really fuck up the result. Also, no errors/warnings are
+     * issued if the string is invalid in case of a typo. For example:
+     * scoreboard[VBOX]++;
+     * is much better and safer against typos than:
+     * scoreboard["VirtualBox"]++;
+     * Hopefully this makes sense.
+     *
+     * TL;DR I have wonky fingers :(
+     */
+    static constexpr const char* VBOX = "VirtualBox";
+    static constexpr const char* VMWARE = "VMware";
+    static constexpr const char* VMWARE_EXPRESS = "VMware Express";
+    static constexpr const char* VMWARE_ESX = "VMware ESX";
+    static constexpr const char* VMWARE_GSX = "VMware GSX";
+    static constexpr const char* VMWARE_WORKSTATION = "VMware Workstation";
+    static constexpr const char* VMWARE_FUSION = "VMware Fusion";
+    static constexpr const char* BHYVE = "bhyve";
+    static constexpr const char* KVM = "KVM";
+    static constexpr const char* QEMU = "QEMU";
+    static constexpr const char* QEMU_KVM = "QEMU+KVM";
+    static constexpr const char* KVM_HYPERV = "KVM Hyper-V Enlightenment";
+    static constexpr const char* QEMU_KVM_HYPERV = "QEMU+KVM Hyper-V Enlightenment";
+    static constexpr const char* HYPERV = "Microsoft Hyper-V";
+    static constexpr const char* HYPERV_VPC = "Microsoft Virtual PC/Hyper-V";
+    static constexpr const char* MSXTA = "Microsoft x86-to-ARM";
+    static constexpr const char* PARALLELS = "Parallels";
+    static constexpr const char* XEN = "Xen HVM";
+    static constexpr const char* ACRN = "ACRN";
+    static constexpr const char* QNX = "QNX hypervisor";
+    static constexpr const char* HYBRID = "Hybrid Analysis";
+    static constexpr const char* SANDBOXIE = "Sandboxie";
+    static constexpr const char* DOCKER = "Docker";
+    static constexpr const char* WINE = "Wine";
+    static constexpr const char* APPLE_ROSETTA = "Apple Rosetta 2";
+    static constexpr const char* VPC = "Virtual PC";
+    static constexpr const char* ANUBIS = "Anubis";
+    static constexpr const char* JOEBOX = "JoeBox";
+    static constexpr const char* THREATEXPERT = "ThreatExpert";
+    static constexpr const char* CWSANDBOX = "CWSandbox";
+    static constexpr const char* COMODO = "Comodo";
+    static constexpr const char* BOCHS = "Bochs";
+    static constexpr const char* NVMM = "NetBSD NVMM";
+    static constexpr const char* BSD_VMM = "OpenBSD VMM";
+    static constexpr const char* INTEL_HAXM = "Intel HAXM";
+    static constexpr const char* UNISYS = "Unisys s-Par";
+    static constexpr const char* LMHS = "Lockheed Martin LMHS"; // yes, you read that right. The library can now detect VMs running on US military fighter jets, apparently.
+    static constexpr const char* CUCKOO = "Cuckoo";
+    static constexpr const char* BLUESTACKS = "BlueStacks";
+    static constexpr const char* JAILHOUSE = "Jailhouse";
+    static constexpr const char* APPLE_VZ = "Apple VZ";
+    static constexpr const char* INTEL_KGT = "Intel KGT (Trusty)";
+    static constexpr const char* AZURE_HYPERV = "Microsoft Azure Hyper-V";
+    static constexpr const char* NANOVISOR = "Xbox NanoVisor (Hyper-V)";
+    static constexpr const char* SIMPLEVISOR = "SimpleVisor";
+    static constexpr const char* HYPERV_ARTIFACT = "Hyper-V artifact (not an actual VM)";
+    static constexpr const char* UML = "User-mode Linux";
+    static constexpr const char* POWERVM = "IBM PowerVM";
+    static constexpr const char* GCE = "Google Compute Engine (KVM)";
+    static constexpr const char* OPENSTACK = "OpenStack (KVM)";
+    static constexpr const char* KUBEVIRT = "KubeVirt (KVM)";
+    static constexpr const char* AWS_NITRO = "AWS Nitro System EC2 (KVM-based)";
+    static constexpr const char* PODMAN = "Podman";
+    static constexpr const char* WSL = "WSL";
+    static constexpr const char* OPENVZ = "OpenVZ";
+    static constexpr const char* NULL_BRAND = "Unknown";
+
+
+
+    static flagset global_flags; // for certain techniques where the flags MUST be accessible
+
+    // macro for bypassing unused parameter/variable warnings
+    #define UNUSED(x) ((void)(x))
+
+// likely and unlikely macros
+#if (LINUX)
+#   define VMAWARE_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#   define VMAWARE_LIKELY(x)   __builtin_expect(!!(x), 1)
+#else
+#   define VMAWARE_UNLIKELY
+#   define VMAWARE_LIKELY
+#endif
+
+    // specifically for util::hyper_x() and memo::hyperv
+    enum class hyperx_state : u8 {
+        HYPERV_REAL_VM = 1,
+        HYPERV_ARTIFACT_VM,
+        UNKNOWN
+    };
+
+    // various cpu operation stuff
+    struct cpu {
+        // cpuid leaf values
+        struct leaf {
+            static constexpr u32
+                func_ext = 0x80000000,
+                proc_ext = 0x80000001,
+                brand1 = 0x80000002,
+                brand2 = 0x80000003,
+                brand3 = 0x80000004,
+                hypervisor = 0x40000000,
+                amd_easter_egg = 0x8fffffff;
+        };
+
+        // cross-platform wrapper function for linux and MSVC cpuid
+        static void cpuid
+        (
+            u32& a, u32& b, u32& c, u32& d,
+            const u32 a_leaf,
+            const u32 c_leaf = 0xFF  // dummy value if not set manually
+        ) {
+#if (x86)
+            // may be unmodified for older 32-bit processors, clearing just in case
+            b = 0;
+            c = 0;
+#if (MSVC)
+            int32_t x[4]{};
+            __cpuidex((int32_t*)x, static_cast<int>(a_leaf), static_cast<int>(c_leaf));
+            a = static_cast<u32>(x[0]);
+            b = static_cast<u32>(x[1]);
+            c = static_cast<u32>(x[2]);
+            d = static_cast<u32>(x[3]);
+#elif (LINUX)
+            __cpuid_count(a_leaf, c_leaf, a, b, c, d);
+#endif
+#else
+            return;
+#endif
+        };
+
+        // same as above but for array type parameters (MSVC specific)
+        static void cpuid
+        (
+            int32_t x[4],
+            const u32 a_leaf,
+            const u32 c_leaf = 0xFF
+        ) {
+#if (x86)
+            // may be unmodified for older 32-bit processors, clearing just in case
+            x[1] = 0;
+            x[2] = 0;
+#if (MSVC)
+            __cpuidex((int32_t*)x, static_cast<int>(a_leaf), static_cast<int>(c_leaf));
+#elif (LINUX)
+            __cpuid_count(a_leaf, c_leaf, x[0], x[1], x[2], x[3]);
+#endif
+#else
+            return;
+#endif
+        };
+
+        // check for maximum function leaf
+        static bool is_leaf_supported(const u32 p_leaf) {
+            u32 eax, unused = 0;
+            cpu::cpuid(eax, unused, unused, unused, cpu::leaf::func_ext);
+
+            debug("CPUID function: highest leaf = ", eax);
+
+            return (p_leaf <= eax);
+        }
+
+        // check AMD
+        [[nodiscard]] static bool is_amd() {
+            constexpr u32 amd_ecx = 0x444d4163; // "cAMD"
+
+            u32 unused, ecx = 0;
+            cpuid(unused, unused, ecx, unused, 0);
+
+            return (ecx == amd_ecx);
+        }
+
+        // check Intel
+        [[nodiscard]] static bool is_intel() {
+            constexpr u32 intel_ecx1 = 0x6c65746e; // "ntel"
+            constexpr u32 intel_ecx2 = 0x6c65746f; // "otel", this is because some Intel CPUs have a rare manufacturer string of "GenuineIotel"
+
+            u32 unused, ecx = 0;
+            cpuid(unused, unused, ecx, unused, 0);
+
+            return ((ecx == intel_ecx1) || (ecx == intel_ecx2));
+        }
+
+        // check for POSSIBILITY of hyperthreading, I don't think there's a 
+        // full-proof method to detect if you're actually hyperthreading imo.
+        [[nodiscard]] static bool has_hyperthreading() {
+            u32 unused, ebx, edx;
+
+            cpuid(unused, ebx, unused, edx, 1);
+            UNUSED(unused);
+
+            bool htt_available = (edx & (1 << 28));
+
+            if (!htt_available) {
+                return false;
+            }
+
+            i32 logical_cores = ((ebx >> 16) & 0xFF);
+            i32 physical_cores = 0;
+
+#if (MSVC)
+            SYSTEM_INFO sysinfo;
+            GetSystemInfo(&sysinfo);
+            physical_cores = sysinfo.dwNumberOfProcessors;
+#elif (LINUX)
+            physical_cores = static_cast<i32>(sysconf(_SC_NPROCESSORS_CONF));
+#elif (APPLE)
+            sysctlbyname("hw.physicalcpu", &physical_cores, sizeof(physical_cores), NULL, 0);
+#else
+            return false;
+#endif
+
+            return (logical_cores > physical_cores);
+        }
+
+        // get the CPU product
+        [[nodiscard]] static std::string get_brand() {
+            if (memo::cpu_brand::is_cached()) {
+                return memo::cpu_brand::fetch();
+            }
+
+            if (!core::cpuid_supported) {
+                return "Unknown";
+            }
+
+#if (!x86)
+            return "Unknown";
+#else
+            if (!cpu::is_leaf_supported(cpu::leaf::brand3)) {
+                return "Unknown";
+            }
+
+            std::array<u32, 4> buffer{};
+            constexpr std::size_t buffer_size = sizeof(int32_t) * buffer.size();
+            std::array<char, 64> charbuffer{};
+
+            constexpr std::array<u32, 3> ids = {{
+                cpu::leaf::brand1,
+                cpu::leaf::brand2,
+                cpu::leaf::brand3
+            }};
+
+            std::string brand = "";
+
+            for (const u32& id : ids) {
+                cpu::cpuid(buffer.at(0), buffer.at(1), buffer.at(2), buffer.at(3), id);
+
+                std::memcpy(charbuffer.data(), buffer.data(), buffer_size);
+
+                const char* convert = charbuffer.data();
+                brand += convert;
+            }
+
+            debug("BRAND: ", "cpu brand = ", brand);
+
+            memo::cpu_brand::store(brand);
+
+            return brand;
+#endif
+        }
+
+
+        [[nodiscard]] static std::array<std::string, 2> cpu_manufacturer(const u32 p_leaf) {
+            auto cpuid_thingy = [](const u32 p_leaf, u32* regs, std::size_t start = 0, std::size_t end = 4) -> bool {
+                u32 x[4]{};
+                cpu::cpuid(x[0], x[1], x[2], x[3], p_leaf);
+
+                for (; start < end; start++) {
+                    *regs++ = x[start];
+                }
+
+                return true;
+            };
+
+            u32 sig_reg[3] = { 0 };
+
+            if (
+                (sig_reg[0] == 0) &&
+                (sig_reg[1] == 0) &&
+                (sig_reg[2] == 0)
+            ) {
+                return { "", "" };
+            }
+
+            if (!cpuid_thingy(p_leaf, sig_reg, 1)) {
+                return { "", "" };
+            }
+
+            auto strconvert = [](u64 n) -> std::string {
+                const std::string& str(reinterpret_cast<char*>(&n));
+                return str;
+            };
+
+            // the reason why there's 2 is because depending on the leaf, 
+            // the last 4 characters might be switched with the middle 
+            // characters for some fuckin reason, idk why this is even a thing
+            // so this function basically returns the same string but with 
+            // the 4~8 and 8~12 characters switched for one, and the other isn't.
+            std::stringstream ss;
+            std::stringstream ss2;
+
+            ss << strconvert(sig_reg[0]);
+            ss << strconvert(sig_reg[2]);
+            ss << strconvert(sig_reg[1]);
+
+            ss2 << strconvert(sig_reg[0]);
+            ss2 << strconvert(sig_reg[1]);
+            ss2 << strconvert(sig_reg[2]);
+
+            std::string brand_str = ss.str();
+            std::string brand_str2 = ss2.str();
+
+            const std::array<std::string, 2> result = { brand_str, brand_str2 };
+
+            return result;
+        }
+
+        struct stepping_struct {
+            u8 model;
+            u8 family;
+            u8 extmodel;
+        };
+
+        [[nodiscard]] static stepping_struct fetch_steppings() {
+            struct stepping_struct steps {};
+
+            u32 unused, eax = 0;
+            cpu::cpuid(eax, unused, unused, unused, 1);
+            UNUSED(unused);
+
+            steps.model = ((eax >> 4) & 0b1111);
+            steps.family = ((eax >> 8) & 0b1111);
+            steps.extmodel = ((eax >> 16) & 0b1111);
+
+            return steps;
+        }
+
+        // check if the CPU is an intel celeron
+        [[nodiscard]] static bool is_celeron(const stepping_struct steps) {
+            if (!cpu::is_intel()) {
+                return false;
+            }
+
+            constexpr u8 celeron_model = 0xA;
+            constexpr u8 celeron_family = 0x6;
+            constexpr u8 celeron_extmodel = 0x2;
+
+            return (
+                steps.model == celeron_model &&
+                steps.family == celeron_family &&
+                steps.extmodel == celeron_extmodel
+                );
+        }
+
+
+        struct model_struct {
+            bool found;
+            bool is_xeon;
+            bool is_i_series;
+            bool is_ryzen;
+            std::string string;
+        };
+
+        [[nodiscard]] static model_struct get_model() {
+            const std::string brand = get_brand();
+
+            constexpr const char* intel_i_series_regex = "i[0-9]-[A-Z0-9]{1,7}";
+            constexpr const char* intel_xeon_series_regex = "[DEW]-[A-Z0-9]{1,7}";
+            constexpr const char* amd_ryzen_regex = "^(PRO)?[A-Z0-9]{1,7}";
+
+            std::string match_str = "";
+
+            auto match = [&](const char* regex) -> bool {
+                std::regex pattern(regex);
+
+                auto words_begin = std::sregex_iterator(brand.begin(), brand.end(), pattern);
+                auto words_end = std::sregex_iterator();
+
+                for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
+                    std::smatch match = *i;
+                    match_str = match.str();
+                }
+
+                if (!match_str.empty()) {
+                    return true;
+                }
+
+                return false;
+                };
+
+            bool found = false;
+            bool is_xeon = false;
+            bool is_i_series = false;
+            bool is_ryzen = false;
+
+            if (cpu::is_intel()) {
+                if (match(intel_i_series_regex)) {
+                    found = true;
+                    is_i_series = true;
+                } else if (match(intel_xeon_series_regex)) {
+                    found = true;
+                    is_xeon = true;
+                }
+            }
+
+            if (cpu::is_amd()) {
+                if (match(amd_ryzen_regex)) {
+                    found = true;
+                    is_ryzen = true;
+                }
+            }
+
+            return model_struct{ found, is_xeon, is_i_series, is_ryzen, match_str };
+        };
+
+#if (CPP >= 17)
+        [[nodiscard]] static bool vmid_template(const u32 p_leaf, [[maybe_unused]] const char* technique_name) {
+#else 
+        [[nodiscard]] static bool vmid_template(const u32 p_leaf, const char* technique_name) {
+#endif
+#if (CPP >= 17)
+            constexpr std::string_view
+#else
+            const std::string
+#endif
+                bhyve = "bhyve bhyve ",
+                bhyve2 = "BHyVE BHyVE ",
+                kvm = "KVMKVMKVM\0\0\0",
+                kvm_hyperv = "Linux KVM Hv",
+                qemu = "TCGTCGTCGTCG",
+                hyperv = "Microsoft Hv",
+                xta = "MicrosoftXTA",
+                parallels = " prl hyperv ",
+                parallels2 = " lrpepyh  vr",
+                vmware = "VMwareVMware",
+                vbox = "VBoxVBoxVBox",
+                xen = "XenVMMXenVMM",
+                acrn = "ACRNACRNACRN",
+                qnx = " QNXQVMBSQG ",
+                qnx2 = "QXNQSBMV",
+                nvmm = "___ NVMM ___",
+                openbsd_vmm = "OpenBSDVMM58",
+                intel_haxm = "HAXMHAXMHAXM",
+                virtapple = "VirtualApple",
+                unisys = "UnisysSpar64",
+                lmhs = "SRESRESRESRE",
+                jailhouse = "Jailhouse\0\0\0",
+                apple_vz = "Apple VZ",
+                intel_kgt = "EVMMEVMMEVMM";
+
+            const std::array<std::string, 2> brand_strings = cpu_manufacturer(p_leaf);
+
+            debug(technique_name, brand_strings.at(0));
+            debug(technique_name, brand_strings.at(1));
+
+#if (CPP < 17)
+            // bypass compiler warning about unused parameter, ignore this
+            UNUSED(technique_name);
+#endif
+
+            for (const std::string &brand_str : brand_strings) {
+                if (brand_str == qemu) { return core::add(QEMU); }
+                if (brand_str == vmware) { return core::add(VMWARE); }
+                if (brand_str == vbox) { return core::add(VBOX); }
+                if (brand_str == bhyve) { return core::add(BHYVE); }
+                if (brand_str == bhyve2) { return core::add(BHYVE); }
+                if (brand_str == kvm) { return core::add(KVM); }
+                if (brand_str == kvm_hyperv) { return core::add(KVM_HYPERV); }
+                if (brand_str == xta) { return core::add(MSXTA); }
+                if (brand_str == parallels) { return core::add(PARALLELS); }
+                if (brand_str == parallels2) { return core::add(PARALLELS); }
+                if (brand_str == xen) { return core::add(XEN); }
+                if (brand_str == acrn) { return core::add(ACRN); }
+                if (brand_str == qnx) { return core::add(QNX); }
+                if (brand_str == virtapple) { return core::add(APPLE_ROSETTA); }
+                if (brand_str == nvmm) { return core::add(NVMM); }
+                if (brand_str == openbsd_vmm) { return core::add(BSD_VMM); }
+                if (brand_str == intel_haxm) { return core::add(INTEL_HAXM); }
+                if (brand_str == unisys) { return core::add(UNISYS); }
+                if (brand_str == lmhs) { return core::add(LMHS); }
+                if (brand_str == jailhouse) { return core::add(JAILHOUSE); }
+                if (brand_str == intel_kgt) { return core::add(INTEL_KGT); }
+
+                // both Hyper-V and VirtualPC have the same string value
+                if (brand_str == hyperv) {
+                    if (util::hyper_x()) {
+                        return false;
+                    }
+                    return core::add(HYPERV, VPC);
+                }
+
+                /**
+                 * this is added because there are inconsistent string
+                 * values for KVM's manufacturer ID. For example,
+                 * it gives me "KVMKMVMKV" when I run it under QEMU
+                 * but the Wikipedia article on CPUID says it's
+                 * "KVMKVMKVM\0\0\0", like wtf????
+                 */
+                if (util::find(brand_str, "KVM")) {
+                    return core::add(KVM);
+                }
+
+                /**
+                 * i'm honestly not sure about this one,
+                 * they're supposed to have 12 characters but
+                 * Wikipedia tells me it these brands have
+                 * less characters (both 8), so i'm just
+                 * going to scan for the entire string ig
+                 */
+#if (CPP >= 17)
+                const char* qnx_sample = qnx2.data();
+                const char* applevz_sample = apple_vz.data();
+#else
+                const char* qnx_sample = qnx2.c_str();
+                const char* applevz_sample = apple_vz.c_str();
+#endif
+
+                if (util::find(brand_str, qnx_sample)) {
+                    return core::add(QNX);
+                }
+
+                if (util::find(brand_str, applevz_sample)) {
+                    return core::add(APPLE_VZ);
+                }
+            }
+
+            return false;
+        }
+    };
+
+    // memoization
+    struct memo {
+    private:
+        using result_t = bool;
+        using points_t = u8;
+
+    public:
+        struct data_t {
+            result_t result;
+            points_t points;
+        };
+
+    private:
+        static std::map<u16, data_t> cache_table;
+        static flagset cache_keys;
+
+    public:
+        static void cache_store(const u16 technique_macro, const result_t result, const points_t points) {
+            cache_table[technique_macro] = { result, points };
+            cache_keys.set(technique_macro);
+        }
+
+        static bool is_cached(const u16 technique_macro) {
+            return cache_keys.test(technique_macro);
+        }
+
+        static data_t cache_fetch(const u16 technique_macro) {
+            return cache_table.at(technique_macro);
+        }
+
+        static std::vector<u16> cache_fetch_all() {
+            std::vector<u16> vec;
+
+            for (auto it = cache_table.cbegin(); it != cache_table.cend(); ++it) {
+                const data_t data = it->second;
+
+                if (data.result == true) {
+                    const u16 macro = it->first;
+                    vec.push_back(macro);
+                }
+            }
+
+            return vec;
+        }
+
+        // basically checks whether all the techniques were cached (with exception of techniques disabled by default)
+        static bool all_present() {
+            if (cache_table.size() == technique_count) {
+                return true;
+            } else if (cache_table.size() == static_cast<std::size_t>(technique_count) - 3) {
+                return (
+                    !cache_keys.test(CURSOR) &&
+                    !cache_keys.test(RDTSC_VMEXIT) &&
+                    !cache_keys.test(RDTSC) &&
+                    !cache_keys.test(VMWARE_DMESG)
+                );
+            }
+
+            return false;
+        }
+
+        struct brand {
+            static std::string brand_cache;
+
+            static std::string fetch() {
+                return brand_cache;
+            }
+
+            static void store(const std::string& p_brand) {
+                brand_cache = p_brand;
+            }
+
+            static bool is_cached() {
+                return (!brand_cache.empty());
+            }
+        };
+
+        struct multi_brand {
+            static std::string brand_cache;
+
+            static std::string fetch() {
+                return brand_cache;
+            }
+
+            static void store(const std::string& p_brand) {
+                brand_cache = p_brand;
+            }
+
+            static bool is_cached() {
+                return (!brand_cache.empty());
+            }
+        };
+
+        struct cpu_brand {
+            static std::string brand_cache;
+
+            static std::string fetch() {
+                return brand_cache;
+            }
+
+            static void store(const std::string& p_brand) {
+                brand_cache = p_brand;
+            }
+
+            static bool is_cached() {
+                return (!brand_cache.empty());
+            }
+        };
+
+        struct hyperx {
+            static hyperx_state state;
+            static bool cached;
+
+            static hyperx_state fetch() {
+                return state;
+            }
+
+            static void store(const hyperx_state p_state) {
+                state = p_state;
+                cached = true;
+            }
+
+            static bool is_cached() {
+                return cached;
+            }
+        };
+    };
+
+#if (MSVC)
+    struct wmi {
+        static IWbemLocator* pLoc;
+        static IWbemServices* pSvc;
+
+        enum class result_type {
+            String,
+            Integer,
+            Double,
+            None
+        };
+
+        struct result {
+            result_type type;
+            union {
+                std::string strValue;
+                int intValue;
+                double doubleValue;
+            };
+
+            result(const std::string& str) : type(result_type::String), strValue(str) {}
+
+            result(int integer) : type(result_type::Integer), intValue(integer) {}
+
+            result(double dbl) : type(result_type::Double), doubleValue(dbl) {}
+
+            result(const result& other) : type(other.type), strValue() {
+                if (type == result_type::String) {
+                    new (&strValue) std::string(other.strValue);
+                }
+                else if (type == result_type::Integer) {
+                    intValue = other.intValue;
+                }
+                else if (type == result_type::Double) {
+                    doubleValue = other.doubleValue;
+                }
+            }
+
+            result& operator=(const result& other) {
+                if (this != &other) {
+                    if (type == result_type::String) {
+                        strValue.~basic_string();
+                    }
+                    type = other.type;
+                    if (type == result_type::String) {
+                        new (&strValue) std::string(other.strValue);
+                    } else if (type == result_type::Integer) {
+                        intValue = other.intValue;
+                    } else if (type == result_type::Double) {
+                        doubleValue = other.doubleValue;
+                    }
+                }
+                return *this;
+            }
+
+            ~result() {
+                if (type == result_type::String) {
+                    strValue.~basic_string();
+                }
+            }
+        };
+
+        static bool initialize() {
+            if (pSvc != nullptr) {
+                return true;
+            }
+
+            HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
+            if (FAILED(hres)) {
+                debug("wmi: Failed to initialize COM library. Error code = ", hres);
+                return false;
+            }
+
+            hres = CoInitializeSecurity(
+                NULL,
+                -1,
+                NULL,
+                NULL,
+                RPC_C_AUTHN_LEVEL_DEFAULT,
+                RPC_C_IMP_LEVEL_IMPERSONATE,
+                NULL,
+                EOAC_NONE,
+                NULL
+            );
+
+            if (FAILED(hres)) {
+                CoUninitialize();
+                debug("wmi: Failed to initialize security. Error code = ", hres);
+                return false;
+            }
+
+            hres = CoCreateInstance(
+                CLSID_WbemLocator,
+                0,
+                CLSCTX_INPROC_SERVER,
+                IID_IWbemLocator,
+                (LPVOID*)&pLoc
+            );
+
+            if (FAILED(hres)) {
+                CoUninitialize();
+                debug("wmi: Failed to create IWbemLocator object. Error code = ", hres);
+                return false;
+            }
+
+            hres = pLoc->ConnectServer(
+                _bstr_t(L"ROOT\\CIMV2"),
+                NULL,
+                NULL,
+                0,
+                NULL,
+                0,
+                0,
+                &pSvc
+            );
+
+            if (FAILED(hres)) {
+                pLoc->Release();
+                CoUninitialize();
+                debug("wmi: Could not connect to WMI server. Error code = ", hres);
+                return false;
+            }
+
+            hres = CoSetProxyBlanket(
+                pSvc,
+                RPC_C_AUTHN_WINNT,
+                RPC_C_AUTHZ_NONE,
+                NULL,
+                RPC_C_AUTHN_LEVEL_CALL,
+                RPC_C_IMP_LEVEL_IMPERSONATE,
+                NULL,
+                EOAC_NONE
+            );
+
+            if (FAILED(hres)) {
+                pSvc->Release();
+                pLoc->Release();
+                CoUninitialize();
+                debug("wmi: Could not set proxy blanket. Error code = ", hres);
+                return false;
+            }
+
+            return true;
+        }
+
+        static std::vector<result> execute(const std::wstring& query, const std::vector<std::wstring>& properties) {
+            std::vector<result> results;
+
+            IEnumWbemClassObject* pEnumerator = NULL;
+            HRESULT hres = pSvc->ExecQuery(
+                _bstr_t(L"WQL"),
+                _bstr_t(query.c_str()),
+                WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
+                NULL,
+                &pEnumerator
+            );
+
+            if (FAILED(hres)) {
+                debug("wmi: ExecQuery failed. Error code = ", hres);
+                return results;
+            }
+
+            IWbemClassObject* pclsObj = NULL;
+            ULONG uReturn = 0;
+
+            while (pEnumerator) {
+                HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+
+                if (0 == uReturn || FAILED(hr)) {
+                    break;
+                }
+
+                for (const auto& prop : properties) {
+                    VARIANT vtProp;
+                    VariantInit(&vtProp);
+                    hr = pclsObj->Get(prop.c_str(), 0, &vtProp, 0, 0);
+
+                    if (SUCCEEDED(hr)) {
+                        if (vtProp.vt == VT_BSTR) {
+                            results.emplace_back(_com_util::ConvertBSTRToString(vtProp.bstrVal));
+                        }
+                        else if (vtProp.vt == VT_I4) {
+                            results.emplace_back(vtProp.intVal);
+                        }
+                        else if (vtProp.vt == VT_R8) {
+                            results.emplace_back(vtProp.dblVal);
+                        }
+                    }
+                    VariantClear(&vtProp);
+                }
+
+                pclsObj->Release();
+            }
+
+            pEnumerator->Release();
+            return results;
+        }
+
+        static void cleanup() {
+            if (pSvc) {
+                pSvc->Release();
+                pSvc = nullptr;
+            }
+            if (pLoc) {
+                pLoc->Release();
+                pLoc = nullptr;
+            }
+            CoUninitialize();
+        }
+    };
+#endif
+
+    // miscellaneous functionalities
+    struct util {
+#if (LINUX)
+        // fetch file data
+        [[nodiscard]] static std::string read_file(const char* file_path) {
+            if (!exists(file_path)) {
+                return "";
+            }
+
+            std::ifstream file{};
+            std::string data{};
+            file.open(file_path);
+
+            if (file.is_open()) {
+                file >> data;
+            }
+
+            file.close();
+            return data;
+        }
+#endif
+
+        // fetch the file but in binary form
+        [[nodiscard]] static std::vector<u8> read_file_binary(const char* file_path) {
+            std::ifstream file(file_path, std::ios::binary);
+    
+            if (!file) {
+                std::vector<u8> tmp{};
+                return tmp;
+            }
+
+            std::vector<u8> buffer((std::istreambuf_iterator<char>(file)),
+                                    std::istreambuf_iterator<char>());
+
+            file.close();
+
+            return buffer;
+        }
+
+        // check if file exists
+        [[nodiscard]] static bool exists(const char* path) {
+#if (MSVC)
+            return (GetFileAttributesA(path) != INVALID_FILE_ATTRIBUTES) || (GetLastError() != ERROR_FILE_NOT_FOUND);
+#else 
+#if (CPP >= 17)
+            return std::filesystem::exists(path);
+#elif (CPP >= 11)
+            struct stat buffer;
+            return (stat(path, &buffer) == 0);
+#endif
+#endif
+        }
+
+#if (MSVC) && (_UNICODE)
+        // handle TCHAR conversion
+        [[nodiscard]] static bool exists(const TCHAR* path) {
+            char c_szText[_MAX_PATH]{};
+            size_t convertedChars = 0;
+            wcstombs_s(&convertedChars, c_szText, path, _MAX_PATH);
+            return exists(c_szText);
+        }
+#endif
+
+        // wrapper for std::make_unique because it's not available for C++11
+        template<typename T, typename... Args>
+        [[nodiscard]] static std::unique_ptr<T> make_unique(Args&&... args) {
+#if (CPP < 14)
+            return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+#else
+            return std::make_unique<T>(std::forward<Args>(args)...);
+#endif
+        }
+
+        // self-explanatory
+        [[nodiscard]] static bool is_admin() noexcept {
+#if (LINUX || APPLE)
+            const uid_t uid = getuid();
+            const uid_t euid = geteuid();
+
+            return (
+                (uid != euid) ||
+                (euid == 0)
+            );
+#elif (MSVC)
+            BOOL is_admin = FALSE;
+            HANDLE hToken = NULL;
+            if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
+                DWORD dwSize = 0;
+                if (!GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwSize) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+                    PTOKEN_MANDATORY_LABEL pTIL = (PTOKEN_MANDATORY_LABEL)malloc(dwSize);
+                    if (pTIL != NULL) {
+                        if (GetTokenInformation(hToken, TokenIntegrityLevel, pTIL, dwSize, &dwSize)) {
+                            SID* pSID = (SID*)GetSidSubAuthority(pTIL->Label.Sid, (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1));
+                            DWORD dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid, (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1));
+
+                            if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID) {
+                                is_admin = TRUE;
+                            }
+
+                            UNUSED(pSID);
+                        }
+                        free(pTIL);
+                    }
+                }
+            }
+
+            CloseHandle(hToken); 
+
+            return is_admin;
+#endif
+        }
+
+        // scan for keyword in string
+        [[nodiscard]] static bool find(const std::string& base_str, const char* keyword) noexcept {
+            return (base_str.find(keyword) != std::string::npos);
+        };
+
+        // for debug output
+#ifdef __VMAWARE_DEBUG__
+#if (CPP < 17)
+        // Helper function to handle the recursion
+        static inline void print_to_stream(std::ostream&) noexcept {
+            // Base case: do nothing
+        }
+
+        template <typename T, typename... Args>
+        static void print_to_stream(std::ostream& os, T&& first, Args&&... args) noexcept {
+            os << std::forward<T>(first);
+            using expander = int[];
+            (void)expander {
+                0, (void(os << std::forward<Args>(args)), 0)...
+            };
+        }
+#endif
+
+        template <typename... Args>
+        static inline void debug_msg(Args... message) noexcept {
+#if (LINUX || APPLE)
+            constexpr const char* black_bg = "\x1B[48;2;0;0;0m";
+            constexpr const char* bold = "\033[1m";
+            constexpr const char* blue = "\x1B[38;2;00;59;193m";
+            constexpr const char* ansiexit = "\x1B[0m";
+
+            std::cout.setf(std::ios::fixed, std::ios::floatfield);
+            std::cout.setf(std::ios::showpoint);
+
+            std::cout << black_bg << bold << "[" << blue << "DEBUG" << ansiexit << bold << black_bg << "]" << ansiexit << " ";
+#else       
+            std::cout << "[DEBUG] ";
+#endif
+
+#if (CPP >= 17)
+            ((std::cout << message), ...);
+#else
+            print_to_stream(std::cout, message...);
+#endif
+
+            std::cout << std::dec << "\n";
+        }
+
+        template <typename... Args>
+        static inline void core_debug_msg(Args... message) noexcept {
+#if (LINUX || APPLE)
+            constexpr const char* black_bg = "\x1B[48;2;0;0;0m";
+            constexpr const char* bold = "\033[1m";
+            constexpr const char* blue = "\x1B[38;2;255;180;5m";
+            constexpr const char* ansiexit = "\x1B[0m";
+
+            std::cout.setf(std::ios::fixed, std::ios::floatfield);
+            std::cout.setf(std::ios::showpoint);
+
+            std::cout << black_bg << bold << "[" << blue << "CORE DEBUG" << ansiexit << bold << black_bg << "]" << ansiexit << " ";
+#else       
+            std::cout << "[CORE DEBUG] ";
+#endif
+
+#if (CPP >= 17)
+            ((std::cout << message), ...);
+#else
+            print_to_stream(std::cout, message...);
+#endif
+
+            std::cout << std::dec << "\n";
+        }
+#endif
+
+        // basically std::system but it runs in the background with std::string output
+        [[nodiscard]] static std::unique_ptr<std::string> sys_result(const TCHAR* cmd) {
+#if (CPP < 14)
+            std::unique_ptr<std::string> tmp(nullptr);
+            UNUSED(cmd);
+            return tmp;
+#else
+#if (LINUX || APPLE)
+#if (ARM)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wignored-attributes"
+#endif
+            std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
+
+#if (ARM)
+#pragma GCC diagnostic pop
+#endif
+
+            if (!pipe) {
+                return nullptr;
+            }
+
+            std::string result{};
+            std::array<char, 128> buffer{};
+
+            while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
+                result += buffer.data();
+            }
+
+            result.pop_back();
+
+            return util::make_unique<std::string>(result);
+#elif (MSVC)
+            // Set up the structures for creating the process
+            STARTUPINFO si = { 0 };
+            PROCESS_INFORMATION pi = { 0 };
+            si.cb = sizeof(si);
+
+            // Create a pipe to capture the command output
+            HANDLE hReadPipe, hWritePipe;
+            SECURITY_ATTRIBUTES sa;
+            sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+            sa.bInheritHandle = TRUE;
+            sa.lpSecurityDescriptor = NULL;
+
+            if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) {
+                debug("sys_result: ", "error creating pipe");
+
+                return nullptr;
+            }
+
+            // Set up the startup information with the write end of the pipe as the standard output
+            si.hStdError = hWritePipe;
+            si.hStdOutput = hWritePipe;
+            si.dwFlags |= STARTF_USESTDHANDLES;
+
+            // Create the process
+            if (!CreateProcess(NULL, const_cast<TCHAR*>(cmd), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
+                debug("sys_result: ", "error creating process");
+
+                CloseHandle(hReadPipe);
+                CloseHandle(hWritePipe);
+                return nullptr;
+            }
+
+            // Close the write end of the pipe as it's not needed in this process
+            CloseHandle(hWritePipe);
+
+            // Read the output from the pipe
+            char buffer[4096];
+            DWORD bytesRead;
+            std::string result;
+
+            while (ReadFile(hReadPipe, buffer, sizeof(buffer), &bytesRead, NULL) && bytesRead > 0) {
+                result.append(buffer, bytesRead);
+            }
+
+            // Close handles
+            CloseHandle(hReadPipe);
+            CloseHandle(pi.hProcess);
+            CloseHandle(pi.hThread);
+
+            // Return the result as a unique_ptr<string>
+            return util::make_unique<std::string>(result);
+#endif
+#endif
+        }
+
+        // get disk size in GB
+        [[nodiscard]] static u32 get_disk_size() {
+            u32 size = 0;
+            constexpr u64 GB = (static_cast<u64>(1024 * 1024) * 1024);
+
+#if (LINUX)
+            struct statvfs stat;
+
+            if (statvfs("/", &stat) != 0) {
+                debug("private util::get_disk_size( function: ", "failed to fetch disk size");
+                return false;
+            }
+
+            // in gigabytes
+            size = static_cast<u32>((stat.f_blocks * stat.f_frsize) / GB);
+#elif (MSVC)
+            ULARGE_INTEGER totalNumberOfBytes;
+
+            if (GetDiskFreeSpaceExW(
+                L"C:",                      // Drive or directory path (use wide character string)
+                nullptr,                    // Free bytes available to the caller (not needed for total size)
+                reinterpret_cast<PULARGE_INTEGER>(&totalNumberOfBytes),  // Total number of bytes on the disk
+                nullptr                     // Total number of free bytes on the disk (not needed for total size)
+            )) {
+                size = static_cast<u32>(totalNumberOfBytes.QuadPart) / GB;
+            } else {
+                debug("util::get_disk_size(: ", "failed to fetch size in GB");
+            }
+#endif
+
+            if (size == 0) {
+                return false;
+            }
+
+            // round to the nearest factor of 10
+            const u32 result = static_cast<u32>(std::round((size / 10.0) * 10));
+
+            debug("private util::get_disk_size( function: ", "disk size = ", result, "GB");
+
+            return result;
+        }
+
+        // get physical RAM size in GB
+        [[nodiscard]] static u64 get_physical_ram_size() {
+#if (LINUX)
+            if (!util::is_admin()) {
+                debug("private get_physical_ram_size function: ", "not root, returned 0");
+                return 0;
+            }
+
+            auto result = util::sys_result("dmidecode --type 19 | grep 'Size' | grep '[[:digit:]]*'");
+
+            if (result == nullptr) {
+                debug("private get_physical_ram_size function: ", "invalid system result from dmidecode, returned 0");
+                return 0;
+            }
+
+            const bool MB = (std::regex_search(*result, std::regex("MB")));
+            const bool GB = (std::regex_search(*result, std::regex("GB")));
+
+            if (!(MB || GB)) {
+                debug("private get_physical_ram_size function: ", "neither MB nor GB found, returned 0");
+                return 0;
+            }
+
+            std::string number_str;
+            bool in_number = false;
+
+            for (char c : *result) {
+                if (std::isdigit(c)) {
+                    number_str += c;
+                    in_number = true;
+                } else if (in_number) {
+                    break;
+                }
+            }
+
+            if (number_str.empty()) {
+                debug("private get_physical_ram_size_gb function: ", "string is empty, returned 0");
+                return 0;
+            }
+
+            u64 number = 0;
+
+            number = std::stoull(number_str);
+
+            if (MB == true) {
+                number = static_cast<u64>(std::round(number / 1024));
+            }
+
+            return number; // in GB
+#elif (MSVC)
+            if (!IsWindowsVistaOrGreater()) {
+                return 0;
+            }
+
+            ULONGLONG total_memory_kb = 0;
+
+            if (GetPhysicallyInstalledSystemMemory(&total_memory_kb) == ERROR_INVALID_DATA) {
+                return 0;
+            }
+
+            return (total_memory_kb / (static_cast<unsigned long long>(1024) * 1024)); // MB
+#else
+            return 0;
+#endif
+        }
+
+        // get available memory space
+        [[nodiscard]] static u64 get_memory_space() {
+#if (MSVC)
+            MEMORYSTATUSEX statex = { 0 };
+            statex.dwLength = sizeof(statex);
+            GlobalMemoryStatusEx(&statex); // calls NtQuerySystemInformation
+            return statex.ullTotalPhys;
+#elif (LINUX)
+            const i64 pages = sysconf(_SC_PHYS_PAGES);
+            const i64 page_size = sysconf(_SC_PAGE_SIZE);
+            return (pages * page_size);
+#elif (APPLE)
+            int32_t mib[2] = { CTL_HW, HW_MEMSIZE };
+            u32 namelen = sizeof(mib) / sizeof(mib[0]);
+            u64 size = 0;
+            std::size_t len = sizeof(size);
+
+            if (sysctl(mib, namelen, &size, &len, NULL, 0) < 0) {
+                return 0;
+            }
+
+            return size; // in bytes
+#endif
+        }
+
+
+        [[nodiscard]] static bool is_proc_running(const TCHAR* executable) {
+#if (MSVC)
+            DWORD processes[1024], bytesReturned;
+
+            if (!EnumProcesses(processes, sizeof(processes), &bytesReturned))
+                return false;
+
+            DWORD numProcesses = bytesReturned / sizeof(DWORD);
+
+            for (DWORD i = 0; i < numProcesses; ++i) {
+                const HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processes[i]);
+                if (process != nullptr) {
+                    TCHAR processName[MAX_PATH];
+                    if (GetModuleBaseName(process, nullptr, processName, sizeof(processName) / sizeof(TCHAR))) {
+                        if (!_tcsicmp(processName, executable)) {
+                            CloseHandle(process);
+                            return true;
+                        }
+                    }
+                    CloseHandle(process);
+                }
+            }
+
+            return false;
+#elif (LINUX)
+#if (CPP >= 17)
+            for (const auto& entry : std::filesystem::directory_iterator("/proc")) {
+                if (!(entry.is_directory())) {
+                    continue;
+                }
+
+                const std::string filename = entry.path().filename().string();
+#else
+            //DIR* dir = opendir("/proc/");
+            std::unique_ptr<DIR, decltype(&closedir)> dir(opendir("/proc"), closedir);
+            if (!dir) {
+                debug("util::is_proc_running: ", "failed to open /proc directory");
+                return false;
+            }
+
+            struct dirent* entry;
+            while ((entry = readdir(dir.get())) != nullptr) {
+                std::string filename(entry->d_name);
+                if (filename == "." || filename == "..") {
+                    continue;
+                }
+#endif
+                if (!(std::all_of(filename.begin(), filename.end(), ::isdigit))) {
+                    continue;
+                }
+
+                const std::string cmdline_file = "/proc/" + filename + "/cmdline";
+                std::ifstream cmdline(cmdline_file);
+                if (!(cmdline.is_open())) {
+                    continue;
+                }
+
+                std::string line;
+                std::getline(cmdline, line);
+                cmdline.close();
+
+                if (line.empty()) {
+                    continue;
+                }
+
+                //std::cout << "\n\nLINE = " << line << "\n";
+                if (line.find(executable) == std::string::npos) {
+                    //std::cout << "skipped\n";
+                    continue;
+                }
+
+                //std::cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nNOT SKIPPED\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
+
+                const std::size_t slash_index = line.find_last_of('/');
+
+                if (slash_index == std::string::npos) {
+                    continue;
+                }
+
+                line = line.substr(slash_index + 1);
+
+                const std::size_t space_index = line.find_first_of(' ');
+
+                if (space_index != std::string::npos) {
+                    line = line.substr(0, space_index);
+                }
+
+                if (line != executable) {
+                    continue;
+                }
+                //#if (CPP < 17)
+                //                closedir(dir);
+                //                free(dir);
+                //#endif
+                return true;
+            }
+
+            return false;
+#else
+            return false;
+#endif
+        }
+
+        [[nodiscard]] static std::string get_hostname() {
+#if (MSVC)
+            char ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
+            DWORD cbComputerName = sizeof(ComputerName);
+
+            if (GetComputerNameA(ComputerName, &cbComputerName)) {
+                return std::string(ComputerName);
+            }
+#elif (LINUX)
+            char hostname[HOST_NAME_MAX];
+
+            if (gethostname(hostname, sizeof(hostname)) == 0) {
+                return std::string(hostname);
+            }
+#endif
+
+            return std::string();
+        }
+
+
+        /**
+         * @brief Checks whether Hyper-V host artifacts are present instead of an actual Hyper-V VM
+         * @note Hyper-V has an obscure feature where if it's enabled in the host system, the CPU 
+         *       hardware values makes it look like the whole system is running inside Hyper-V, 
+         *       which isn't true. This makes it a challenge to determine whether the hardware 
+         *       values the library is collecting is either a real Hyper-V VM, or just the artifacts 
+         *       of what Hyper-V has left as a consequence of having it enabled in the host system. 
+         *       The reason why this is a problem is because the library might falsely conclude that 
+         *       your the host system is running in Hyper-V, which is a false positive. This is where 
+         *       the Hyper-X mechanism comes into play to distinguish between these two.
+         * @author idea by Requiem (https://github.com/NotRequiem)
+         * @returns boolean, true = Hyper-V artifact, false = Real Hyper-V VM
+         * @link graph to explain how this works: https://github.com/kernelwernel/VMAware/blob/main/assets/hyper-x/v4/Hyper-X_version_4.drawio.png
+         */
+        [[nodiscard]] static bool hyper_x() {
+#if (!MSVC)
+            return false;
+#else
+            if (memo::hyperx::is_cached()) {
+                core_debug("HYPER_X: returned from cache");
+                return (memo::hyperx::fetch() == hyperx_state::HYPERV_ARTIFACT_VM);
+            }
+
+
+            // SMBIOS check
+            auto is_smbios_hyperv = []() -> bool {
+                const std::string smbios = SMBIOS_string();
+                const bool result = (smbios == "VIRTUAL MACHINE");
+
+                if (result) {
+                    core_debug("HYPER_X: SMBIOS string = ", smbios);
+                    core_debug("HYPER_X: SMBIOS string returned true");
+                }
+
+                return result;
+            };
+
+
+            // motherboard check
+            auto is_motherboard_hyperv = []() -> bool {
+                const bool motherboard = motherboard_string("Microsoft Corporation");
+
+                if (motherboard) {
+                    core_debug("HYPER_X: motherboard string match = ", motherboard);
+                }
+
+                return motherboard;
+            };
+
+
+            // event log check (slow, so in last place)
+            auto is_event_log_hyperv = []() -> bool {
+                std::wstring logName = L"Microsoft-Windows-Kernel-PnP/Configuration";
+                std::vector<std::wstring> searchStrings = { L"Virtual_Machine", L"VMBUS" };
+                const bool result = (util::query_event_logs(logName, searchStrings));
+
+                if (result) {
+                    core_debug("HYPER_X: event log returned true");
+                }
+
+                return result;
+            };
+
+
+            // VMProtect method for Hyper-V artifact detection
+            auto is_root_partition = []() -> bool {
+                u32 ebx, unused = 0;
+                cpu::cpuid(unused, ebx, unused, unused, 0x40000003);
+                const bool result = (ebx & 1);
+
+                if (result) {
+                    core_debug("HYPER_X: root partition returned true");
+                }
+
+                return result;
+            };
+
+
+            // check if eax is either 11 or 12 after running VM::HYPERVISOR_STR technique
+            auto eax = []() -> u32 {
+                char out[sizeof(int32_t) * 4 + 1] = { 0 }; // e*x size + number of e*x registers + null terminator
+                cpu::cpuid((int*)out, cpu::leaf::hypervisor);
+
+                const u32 eax = static_cast<u32>(out[0]);
+
+                core_debug("HYPER_X: eax = ", eax);
+
+                return eax;
+            };
+
+            bool run_mechanism = false;
+
+            switch (eax()) {
+                case 11: run_mechanism = false; break; // real hyper-v vm
+                case 12: run_mechanism = true; break; // artifact hyper-v vm
+                default:
+                    // fallback in case eax fails
+                    if (is_root_partition()) {
+                        run_mechanism = true;
+                    }
+            }
+
+            enum hyperx_state state;
+
+            if (run_mechanism) {
+                const bool has_hyperv_indications = (
+                    is_smbios_hyperv() || 
+                    is_motherboard_hyperv() || 
+                    is_event_log_hyperv()
+                );
+
+                const bool eax_result = (eax() == 11 || eax() == 12);
+
+                const bool is_real_hyperv_vm = (eax_result && has_hyperv_indications);
+
+                if (is_real_hyperv_vm) {
+                    state = hyperx_state::HYPERV_REAL_VM;
+                } else {
+                    state = hyperx_state::HYPERV_ARTIFACT_VM;
+                }
+            } else if (eax() == 11) {
+                state = hyperx_state::HYPERV_REAL_VM;
+            } else {
+                core_debug("HYPER_X: none detected");
+                state = hyperx_state::UNKNOWN;
+            }
+
+            memo::hyperx::store(state);
+            core_debug("HYPER_X: cached");
+
+            // false means it's an artifact, which is what the 
+            // point of this whole function is supposed to do
+            switch (state) {
+                case hyperx_state::HYPERV_ARTIFACT_VM:
+                    core_debug("HYPER_X: added Hyper-V artifact VM");
+                    core::add(HYPERV_ARTIFACT);
+                    return true;
+
+                case hyperx_state::HYPERV_REAL_VM:
+                    core_debug("HYPER_X: added Hyper-V real VM");
+                    core::add(HYPERV);
+                    return false;
+
+                case hyperx_state::UNKNOWN:
+                    core_debug("HYPER_X: none detected");
+                    return false;
+
+                default: 
+                    return false;
+            }
+#endif
+        }
+
+#if (MSVC)
+        /**
+         * @link: https://codereview.stackexchange.com/questions/249034/systeminfo-a-c-class-to-retrieve-system-management-data-from-the-bios
+         * @author: arcomber
+         */
+        class sys_info {
+        private:
+#pragma pack(push) 
+#pragma pack(1)
+            /*
+            SMBIOS Structure header (System Management BIOS) spec:
+            https ://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.3.0.pdf
+            */
+            struct SMBIOSHEADER
+            {
+                uint8_t type;
+                uint8_t length;
+                uint16_t handle;
+            };
+
+            /*
+            Structure needed to get the SMBIOS table using GetSystemFirmwareTable API.
+            see https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemfirmwaretable
+            */
+            struct SMBIOSData {
+                uint8_t  Used20CallingMethod;
+                uint8_t  SMBIOSMajorVersion;
+                uint8_t  SMBIOSMinorVersion;
+                uint8_t  DmiRevision;
+                uint32_t  Length;
+                uint8_t  SMBIOSTableData[1];
+            };
+
+            // System Information (Type 1)
+            struct SYSTEMINFORMATION {
+                SMBIOSHEADER Header;
+                uint8_t Manufacturer;
+                uint8_t ProductName;
+                uint8_t Version;
+                uint8_t SerialNumber;
+                uint8_t UUID[16];
+                uint8_t WakeUpType;  // Identifies the event that caused the system to power up
+                uint8_t SKUNumber;   // identifies a particular computer configuration for sale
+                uint8_t Family;
+            };
+#pragma pack(pop) 
+
+            // helper to retrieve string at string offset. Optional null string description can be set.
+            const char* get_string_by_index(const char* str, int index, const char* null_string_text = "")
+            {
+                if (0 == index || 0 == *str) {
+                    return null_string_text;
+                }
+
+                while (--index) {
+                    str += strlen(str) + 1;
+                }
+                return str;
+            }
+
+            // retrieve the BIOS data block from the system
+            SMBIOSData* get_bios_data() {
+                SMBIOSData* bios_data = nullptr;
+
+                // GetSystemFirmwareTable with arg RSMB retrieves raw SMBIOS firmware table
+                // return value is either size of BIOS table or zero if function fails
+                DWORD bios_size = GetSystemFirmwareTable('RSMB', 0, NULL, 0);
+
+                if (bios_size > 0) {
+                    if (bios_data != nullptr) {
+                        bios_data = (SMBIOSData*)malloc(bios_size);
+
+                        // Retrieve the SMBIOS table
+                        DWORD bytes_retrieved = GetSystemFirmwareTable('RSMB', 0, bios_data, bios_size);
+
+                        if (bytes_retrieved != bios_size) {
+                            free(bios_data);
+                            bios_data = nullptr;
+                        }
+                    }
+                }
+
+                return bios_data;
+            }
+
+
+            // locates system information memory block in BIOS table
+            SYSTEMINFORMATION* find_system_information(SMBIOSData* bios_data) {
+                uint8_t* data = bios_data->SMBIOSTableData;
+
+                while (data < bios_data->SMBIOSTableData + bios_data->Length)
+                {
+                    uint8_t* next;
+                    SMBIOSHEADER* header = (SMBIOSHEADER*)data;
+
+                    if (header->length < 4)
+                        break;
+
+                    //Search for System Information structure with type 0x01 (see para 7.2)
+                    if (header->type == 0x01 && header->length >= 0x19)
+                    {
+                        return (SYSTEMINFORMATION*)header;
+                    }
+
+                    //skip over formatted area
+                    next = data + header->length;
+
+                    //skip over unformatted area of the structure (marker is 0000h)
+                    while (next < bios_data->SMBIOSTableData + bios_data->Length && (next[0] != 0 || next[1] != 0)) {
+                        next++;
+                    }
+                    next += 2;
+
+                    data = next;
+                }
+                return nullptr;
+            }
+
+        public:
+            // System information data retrieved on construction and string members populated
+            sys_info() {
+                SMBIOSData* bios_data = get_bios_data();
+
+                if (bios_data) {
+                    SYSTEMINFORMATION* sysinfo = find_system_information(bios_data);
+                    if (sysinfo) {
+                        const char* str = (const char*)sysinfo + sysinfo->Header.length;
+
+                        manufacturer_ = get_string_by_index(str, sysinfo->Manufacturer);
+                        productname_ = get_string_by_index(str, sysinfo->ProductName);
+                        serialnumber_ = get_string_by_index(str, sysinfo->SerialNumber);
+                        version_ = get_string_by_index(str, sysinfo->Version);
+
+                        // for v2.1 and later
+                        if (sysinfo->Header.length > 0x08)
+                        {
+                            static const int max_uuid_size{ 50 };
+                            char uuid[max_uuid_size] = {};
+                            _snprintf_s(uuid, max_uuid_size, static_cast<size_t>(max_uuid_size) - 1, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+                                sysinfo->UUID[0], sysinfo->UUID[1], sysinfo->UUID[2], sysinfo->UUID[3],
+                                sysinfo->UUID[4], sysinfo->UUID[5], sysinfo->UUID[6], sysinfo->UUID[7],
+                                sysinfo->UUID[8], sysinfo->UUID[9], sysinfo->UUID[10], sysinfo->UUID[11],
+                                sysinfo->UUID[12], sysinfo->UUID[13], sysinfo->UUID[14], sysinfo->UUID[15]);
+
+                            uuid_ = uuid;
+                        }
+
+                        if (sysinfo->Header.length > 0x19)
+                        {
+                            // supported in v 2.4 spec
+                            sku_ = get_string_by_index(str, sysinfo->SKUNumber);
+                            family_ = get_string_by_index(str, sysinfo->Family);
+                        }
+                    }
+                    free(bios_data);
+                }
+            }
+
+            // get product family
+            const std::string get_family() const {
+                return family_;
+            }
+
+            // get manufacturer - generally motherboard or system assembler name
+            const std::string get_manufacturer() const {
+                return manufacturer_;
+            }
+
+            // get product name
+            const std::string get_productname() const {
+                return productname_;
+            }
+
+            // get BIOS serial number
+            const std::string get_serialnumber() const {
+                return serialnumber_;
+            }
+
+            // get SKU / system configuration
+            const std::string get_sku() const {
+                return sku_;
+            }
+
+            // get a universally unique identifier for system
+            const std::string get_uuid() const {
+                return uuid_;
+            }
+
+            // get version of system information
+            const std::string get_version() const {
+                return version_;
+            }
+
+            sys_info(sys_info const&) = delete;
+            sys_info& operator=(sys_info const&) = delete;
+
+        private:
+            std::string family_;
+            std::string manufacturer_;
+            std::string productname_;
+            std::string serialnumber_;
+            std::string sku_;
+            std::string uuid_;
+            std::string version_;
+        };
+
+        [[nodiscard]] static bool is_wow64() {
+            BOOL isWow64 = FALSE;
+            BOOL tmp = IsWow64Process(GetCurrentProcess(), &isWow64);
+            return (tmp && isWow64);
+        }
+
+        // backup function in case the main get_windows_version function fails
+        [[nodiscard]] static u8 get_windows_version_backup() {
+            u8 ret = 0;
+            NTSTATUS(WINAPI * RtlGetVersion)(LPOSVERSIONINFOEXW) = nullptr;
+            OSVERSIONINFOEXW osInfo{};
+
+            const HMODULE ntdllModule = GetModuleHandleA("ntdll.dll");
+
+            if (ntdllModule == nullptr) {
+                return false;
+            }
+
+            *(FARPROC*)&RtlGetVersion = GetProcAddress(ntdllModule, "RtlGetVersion");
+
+            if (RtlGetVersion == nullptr) {
+                return false;
+            }
+
+            if (RtlGetVersion != nullptr) {
+                osInfo.dwOSVersionInfoSize = sizeof(osInfo);
+                RtlGetVersion(&osInfo);
+                ret = static_cast<u8>(osInfo.dwMajorVersion);
+            }
+
+            return ret;
+        }
+
+        // credits to @Requiem for the code, thanks man :)
+        [[nodiscard]] static u8 get_windows_version() {
+            typedef NTSTATUS(WINAPI* RtlGetVersionFunc)(PRTL_OSVERSIONINFOW);
+
+            const std::map<DWORD, u8> windowsVersions = {
+                { 6002, static_cast<u8>(6) }, // windows vista, technically no number but this function is just for great than operations anyway so it doesn't matter
+                { 7601, static_cast<u8>(7) },
+                { 9200, static_cast<u8>(8) },
+                { 9600, static_cast<u8>(8) },
+                { 10240, static_cast<u8>(10) },
+                { 10586, static_cast<u8>(10) },
+                { 14393, static_cast<u8>(10) },
+                { 15063, static_cast<u8>(10) },
+                { 16299, static_cast<u8>(10) },
+                { 17134, static_cast<u8>(10) },
+                { 17763, static_cast<u8>(10) },
+                { 18362, static_cast<u8>(10) },
+                { 18363, static_cast<u8>(10) },
+                { 19041, static_cast<u8>(10) },
+                { 19042, static_cast<u8>(10) },
+                { 19043, static_cast<u8>(10) },
+                { 19044, static_cast<u8>(10) },
+                { 19045, static_cast<u8>(10) },
+                { 22000, static_cast<u8>(11) },
+                { 22621, static_cast<u8>(11) },
+                { 22631, static_cast<u8>(11) }
+            };
+
+            const HMODULE ntdll = GetModuleHandleA("ntdll.dll");
+            if (!ntdll) {
+                return util::get_windows_version_backup();
+            }
+
+            RtlGetVersionFunc pRtlGetVersion = (RtlGetVersionFunc)GetProcAddress(ntdll, "RtlGetVersion");
+            if (!pRtlGetVersion) {
+                return util::get_windows_version_backup();
+            }
+
+            RTL_OSVERSIONINFOW osvi{};
+            osvi.dwOSVersionInfoSize = sizeof(osvi);
+
+            if (pRtlGetVersion(&osvi) != 0) {
+                return util::get_windows_version_backup();
+            }
+
+            u8 major_version = 0;
+
+            if (windowsVersions.find(osvi.dwBuildNumber) != windowsVersions.end()) {
+                major_version = windowsVersions.at(osvi.dwBuildNumber);
+            }
+
+            if (major_version == 0) {
+                return util::get_windows_version_backup();
+            }
+
+            return major_version;
+        }
+
+
+        [[nodiscard]] static std::string SMBIOS_string() {
+            HKEY hk = 0;
+            int ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\mssmbios\\data", 0, KEY_ALL_ACCESS, &hk);
+            if (ret != ERROR_SUCCESS) {
+                debug("SMBIOS_string(): ret = error");
+                return "";
+            }
+
+            unsigned long type = 0;
+            unsigned long length = 0;
+
+            ret = RegQueryValueExA(hk, "SMBiosData", 0, &type, 0, &length);
+
+            if (ret != ERROR_SUCCESS) {
+                RegCloseKey(hk);
+                debug("SMBIOS_string(): ret = error 2");
+                return "";
+            }
+
+            if (length == 0) {
+                RegCloseKey(hk);
+                debug("SMBIOS_string(): length = 0");
+                return "";
+            }
+
+            char* p = static_cast<char*>(LocalAlloc(LMEM_ZEROINIT, length));
+            if (p == nullptr) {
+                RegCloseKey(hk);
+                debug("SMBIOS_string(): p = nullptr");
+                return "";
+            }
+
+            ret = RegQueryValueExA(hk, "SMBiosData", 0, &type, reinterpret_cast<unsigned char*>(p), &length);
+
+            if (ret != ERROR_SUCCESS) {
+                LocalFree(p);
+                RegCloseKey(hk);
+                debug("SMBIOS_string(): ret = error 3");
+                return "";
+            }
+
+            auto ScanDataForString = [](const unsigned char* data, unsigned long data_length, const unsigned char* string2) -> const unsigned char* {
+                std::size_t string_length = strlen(reinterpret_cast<const char*>(string2));
+                for (std::size_t i = 0; i <= (data_length - string_length); i++) {
+                    if (strncmp(reinterpret_cast<const char*>(&data[i]), reinterpret_cast<const char*>(string2), string_length) == 0) {
+                        return &data[i];
+                    }
+                }
+                return nullptr;
+            };
+
+            auto AllToUpper = [](char* str, std::size_t len) {
+                for (std::size_t i = 0; i < len; ++i) {
+                    str[i] = static_cast<char>(std::toupper(static_cast<unsigned char>(str[i])));
+                }
+            };
+
+            AllToUpper(p, length);
+
+            auto cast = [](char* p) -> unsigned char* {
+                return reinterpret_cast<unsigned char*>(p);
+            };
+
+            const unsigned char* x1 = ScanDataForString(cast(p), length, reinterpret_cast<const unsigned char*>("INNOTEK GMBH"));
+            const unsigned char* x2 = ScanDataForString(cast(p), length, reinterpret_cast<const unsigned char*>("VIRTUALBOX"));
+            const unsigned char* x3 = ScanDataForString(cast(p), length, reinterpret_cast<const unsigned char*>("SUN MICROSYSTEMS"));
+            const unsigned char* x4 = ScanDataForString(cast(p), length, reinterpret_cast<const unsigned char*>("VBOXVER"));
+            const unsigned char* x5 = ScanDataForString(cast(p), length, reinterpret_cast<const unsigned char*>("VIRTUAL MACHINE"));
+
+            std::string result = "";
+            bool is_vm = false;
+
+            if (x1 || x2 || x3 || x4 || x5) {
+                is_vm = true;
+#ifdef __VMAWARE_DEBUG__
+                if (x1) { debug("SMBIOS: x1 = ", x1); result = std::string(reinterpret_cast<const char*>(x1)); }
+                if (x2) { debug("SMBIOS: x2 = ", x2); result = std::string(reinterpret_cast<const char*>(x2)); }
+                if (x3) { debug("SMBIOS: x3 = ", x3); result = std::string(reinterpret_cast<const char*>(x3)); }
+                if (x4) { debug("SMBIOS: x4 = ", x4); result = std::string(reinterpret_cast<const char*>(x4)); }
+                if (x5) { debug("SMBIOS: x5 = ", x5); result = std::string(reinterpret_cast<const char*>(x5)); }
+#endif
+            }
+
+            LocalFree(p);
+            RegCloseKey(hk);
+
+            if (is_vm) {
+                return result;
+            }
+
+            return "";
+        }
+
+
+        [[nodiscard]] static bool motherboard_string(const char* vm_string) {
+            if (!wmi::initialize()) {
+                std::cerr << "Failed to initialize WMI.\n";
+                return false;
+            }
+
+            std::vector<wmi::result> results =
+                wmi::execute(L"SELECT * FROM Win32_BaseBoard", { L"Manufacturer" });
+
+            for (const auto& res : results) {
+                if (res.type == wmi::result_type::String) {
+                    if (_stricmp(res.strValue.c_str(), vm_string) == 0) {
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+
+        /**
+         * @brief Retrieves the last error message from the Windows API. Useful for __VMAWARE_DEBUG__
+         * 
+         * @author Requiem (https://github.com/NotRequiem)
+         *
+         * @return A std::wstring containing the error message.
+         */
+        [[nodiscard]] static std::wstring GetLastErrorString() {
+            const DWORD error = GetLastError();
+            LPWSTR messageBuffer = nullptr;
+            size_t size = FormatMessageW(
+                FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+                nullptr, error, 0, (LPWSTR)&messageBuffer, 0, nullptr
+            );
+
+            std::wstring message(messageBuffer, size);
+            LocalFree(messageBuffer);
+            return message;
+        }
+
+
+        /**
+         * @brief Searches for specific strings within events in a Windows Event Log.
+         *
+         * @param logName The name or path of the event log to search (e.g., "System", "Application", "Security", or a custom path).
+         * @param searchStrings A vector of strings to search for within the event messages.
+         * @param flags Query flags that define the direction of the search; default is EvtQueryReverseDirection.
+         * @param timeout The maximum amount of time (in milliseconds) to wait for events; default is INFINITE.
+         * @param maxEvents The maximum number of events to process; default is 1000.
+         *
+         * @author Requiem (https://github.com/NotRequiem)
+         * 
+         * @return True if any of the search strings are found in the events; otherwise, false.
+         */
+        [[nodiscard]] static bool query_event_logs(const std::wstring& logName,
+            const std::vector<std::wstring>& searchStrings,
+            DWORD flags = EvtQueryReverseDirection,
+            DWORD timeout = INFINITE,
+            DWORD maxEvents = 1000) {
+
+            EVT_HANDLE hLog = EvtOpenLog(nullptr, logName.c_str(), EvtOpenChannelPath);
+            if (!hLog) {
+                std::wcerr << L"Failed to open event log: " << logName << L". Error: " << GetLastErrorString() << "\n";
+                return false;
+            }
+
+            EVT_HANDLE hResults = EvtQuery(nullptr, logName.c_str(), nullptr, flags);
+            if (!hResults) {
+                std::wcerr << L"Failed to query event log: " << logName << L". Error: " << GetLastErrorString() << "\n";
+                EvtClose(hLog);
+                return false;
+            }
+
+            EVT_HANDLE hEvent = nullptr;
+            DWORD bufferUsed = 0;
+            DWORD bufferSize = 0;
+            DWORD count = 0;
+            WCHAR* pBuffer = nullptr;
+
+            // Iterate over events up to the maximum number specified
+            for (DWORD eventCount = 0; eventCount < maxEvents; ++eventCount) {
+                if (!EvtNext(hResults, 1, &hEvent, timeout, 0, &count)) {
+                    if (GetLastError() == ERROR_NO_MORE_ITEMS) {
+                        break; // No more events to process
+                    }
+                    std::wcerr << L"EvtNext failed. Error: " << GetLastErrorString() << "\n";
+                    EvtClose(hResults);
+                    EvtClose(hLog);
+                    return false;
+                }
+
+                if (!EvtRender(nullptr, hEvent, EvtRenderEventXml, 0, nullptr, &bufferUsed, &count) &&
+                    GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+                    bufferSize = bufferUsed;
+                    pBuffer = new WCHAR[bufferSize];
+                    if (!pBuffer) {
+                        std::cerr <<"Memory allocation failed.\n";
+                        EvtClose(hResults);
+                        EvtClose(hLog);
+                        return false;
+                    }
+
+                    if (!EvtRender(nullptr, hEvent, EvtRenderEventXml, bufferSize, pBuffer, &bufferUsed, &count)) {
+                        std::wcerr << L"EvtRender failed. Error: " << GetLastErrorString() << "\n";
+                        delete[] pBuffer;
+                        EvtClose(hResults);
+                        EvtClose(hLog);
+                        return false;
+                    }
+                }
+                else {
+                    std::wcerr << L"EvtRender failed. Error: " << GetLastErrorString() << "\n";
+                    EvtClose(hResults);
+                    EvtClose(hLog);
+                    return false;
+                }
+
+                std::wstring eventMessage(pBuffer);
+                delete[] pBuffer;
+
+                // Check if any of the search strings are found in the event message, not in the event name
+                bool found = false;
+                for (const auto& searchString : searchStrings) {
+                    if (eventMessage.find(searchString) != std::wstring::npos) {
+                        found = true;
+                        break;
+                    }
+                }
+
+                if (found) {
+                    EvtClose(hResults);
+                    EvtClose(hLog);
+                    return true;
+                }
+
+                EvtClose(hEvent);
+            }
+
+            EvtClose(hResults);
+            EvtClose(hLog);
+
+            return false;
+        }
+#endif
+    };
+
+
+private: // START OF PRIVATE VM DETECTION TECHNIQUE DEFINITIONS
+    /**
+     * @brief Check CPUID output of manufacturer ID for known VMs/hypervisors at leaf 0
+     * @category x86
+     */
+    [[nodiscard]] static bool vmid() {
+#if (!x86)
+        return false;
+#else
+        if (!core::cpuid_supported) {
+            return false;
+        }
+
+        return cpu::vmid_template(0, "VMID: ");
+#endif
+    }
+
+
+    /**
+     * @brief Check if CPU brand model contains any VM-specific string snippets
+     * @category x86
+     */
+    [[nodiscard]] static bool cpu_brand() {
+#if (!x86)
+        return false;
+#else
+        if (!core::cpuid_supported) {
+            return false;
+        }
+
+        std::string brand = cpu::get_brand();
+
+        // TODO: might add more potential keywords, be aware that it could (theoretically) cause false positives
+        constexpr std::array<const char*, 16> vmkeywords {{
+            "qemu", "kvm", "virtual", "vm",
+            "vbox", "virtualbox", "vmm", "monitor",
+            "bhyve", "hyperv", "hypervisor", "hvisor",
+            "parallels", "vmware", "hvm", "qnx"
+        }};
+
+        u8 match_count = 0;
+
+        for (auto it = vmkeywords.cbegin(); it != vmkeywords.cend(); it++) {
+            const auto regex = std::regex(*it, std::regex::icase);
+            const bool match = std::regex_search(brand, regex);
+
+            if (match) {
+                debug("BRAND_KEYWORDS: ", "match = ", *it);
+                match_count++;
+            }
+        }
+
+        debug("BRAND_KEYWORDS: ", "matches: ", static_cast<u32>(match_count));
+
+        if (match_count > 0) {
+            const auto qemu_regex = std::regex("QEMU", std::regex::icase);
+            const bool qemu_match = std::regex_search(brand, qemu_regex);
+
+            if (qemu_match) {
+                return core::add(QEMU);
+            }
+        }
+
+        return (match_count >= 1);
+#endif
+    }
+
+
+    /**
+     * @brief Check if hypervisor feature bit in CPUID eax bit 31 is enabled (always false for physical CPUs)
+     * @category x86
+     */
+    [[nodiscard]] static bool hypervisor_bit() {
+#if (!x86)
+        return false;
+#else
+        if (!core::cpuid_supported) {
+            return false;
+        }
+
+        if (util::hyper_x()) {
+            return false;
+        }
+
+        u32 unused, ecx = 0;
+        cpu::cpuid(unused, unused, ecx, unused, 1);
+
+        return (ecx & (1 << 31));
+#endif
+    }
+
+
+    /**
+     * @brief Check for hypervisor brand string length (would be around 2 characters in a host machine)
+     * @category x86
+     */
+    [[nodiscard]] static bool hypervisor_str() {
+#if (!x86)
+        return false;
+#else
+        if (util::hyper_x()) {
+            return false;
+        }
+
+        char out[sizeof(int32_t) * 4 + 1] = { 0 }; // e*x size + number of e*x registers + null terminator
+        cpu::cpuid((int*)out, cpu::leaf::hypervisor);
+
+        debug("HYPERVISOR_STR: eax: ", static_cast<u32>(out[0]),
+            "\nebx: ", static_cast<u32>(out[1]),
+            "\necx: ", static_cast<u32>(out[2]),
+            "\nedx: ", static_cast<u32>(out[3])
+        );
+
+        return (std::strlen(out + 4) >= 4);
+#endif
+    }
+
+
+    /**
+     * @brief Benchmark RDTSC and evaluate its speed, usually it's very slow in VMs
+     * @category x86
+     */
+    [[nodiscard]]
+#if (LINUX)
+    // this is added so no sanitizers can potentially cause unwanted delays while measuring rdtsc in a debug compilation
+    __attribute__((no_sanitize("address", "leak", "thread", "undefined")))
+#endif
+        static bool rdtsc_check() {
+#if (!x86)
+        return false;
+#else
+#if (LINUX)
+        u32 a, b, c, d = 0;
+
+        // check if rdtsc is available
+        if (!__get_cpuid(cpu::leaf::proc_ext, &a, &b, &c, &d)) {
+            if (!(d & (1 << 27))) {
+                return false;
+            }
+        }
+
+        u64 s, acc = 0;
+        int32_t out[4];
+
+        for (std::size_t i = 0; i < 100; ++i) {
+            s = __rdtsc();
+            cpu::cpuid(out, 0, 0);
+            acc += __rdtsc() - s;
+        }
+
+        debug("RDTSC: ", "acc = ", acc);
+        debug("RDTSC: ", "acc/100 = ", acc / 100);
+
+        return (acc / 100 > 350);
+#elif (MSVC)
+#define LODWORD(_qw)    ((DWORD)(_qw))
+        u64 tsc1 = 0;
+        u64 tsc2 = 0;
+        u64 tsc3 = 0;
+        for (INT i = 0; i < 10; i++) {
+            tsc1 = __rdtsc();
+            GetProcessHeap();  // delay
+            tsc2 = __rdtsc();
+#pragma warning(push)
+#pragma warning(disable: 6387)
+            CloseHandle(0);
+#pragma warning(pop)
+            tsc3 = __rdtsc();
+            const bool condition = ((LODWORD(tsc3) - LODWORD(tsc2)) / (LODWORD(tsc2) - LODWORD(tsc1)) >= 10);
+            if (condition) {
+                return false;
+            }
+        }
+
+        return true;
+#else
+        return false;
+#endif
+#endif
+    }
+
+
+    /**
+     * @brief Check if there are only 1 or 2 threads, which is a common pattern in VMs with default settings (nowadays physical CPUs should have at least 4 threads for modern CPUs
+     * @category x86 (ARM might have very low thread counts, which si why it should be only for x86)
+     */
+    [[nodiscard]] static bool thread_count() {
+#if (x86)
+        debug("THREADCOUNT: ", "threads = ", std::thread::hardware_concurrency());
+
+        struct cpu::stepping_struct steps = cpu::fetch_steppings();
+
+        if (cpu::is_celeron(steps)) {
+            return false;
+        }
+
+        return (std::thread::hardware_concurrency() <= 2);
+#else 
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if mac address starts with certain VM designated values
+     * @category All systems (I think)
+     */
+    [[nodiscard]] static bool mac_address_check() {
+        // C-style array on purpose
+        u8 mac[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+#if (LINUX)
+        struct ifreq ifr;
+        struct ifconf ifc;
+        char buf[1024];
+        int32_t success = 0;
+
+        int32_t sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+
+        if (sock == -1) {
+            return false;
+        };
+
+        ifc.ifc_len = sizeof(buf);
+        ifc.ifc_buf = buf;
+
+        if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) {
+            return false;
+        }
+
+        struct ifreq* it = ifc.ifc_req;
+        const struct ifreq* end = it + (ifc.ifc_len / sizeof(struct ifreq));
+
+        for (; it != end; ++it) {
+            std::strcpy(ifr.ifr_name, it->ifr_name);
+
+            if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
+                return false;
+            }
+
+            if (!(ifr.ifr_flags & IFF_LOOPBACK)) {
+                if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
+                    success = 1;
+                    break;
+                }
+            }
+        }
+
+        if (success) {
+            std::memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
+        } else {
+            debug("MAC: ", "not successful");
+        }
+#elif (MSVC)
+        PIP_ADAPTER_INFO AdapterInfo;
+        DWORD dwBufLen = sizeof(IP_ADAPTER_INFO);
+
+        AdapterInfo = (IP_ADAPTER_INFO*)std::malloc(sizeof(IP_ADAPTER_INFO));
+
+        if (AdapterInfo == NULL) {
+            return false;
+        }
+
+        if (GetAdaptersInfo(AdapterInfo, &dwBufLen) == ERROR_BUFFER_OVERFLOW) {
+            std::free(AdapterInfo);
+            AdapterInfo = (IP_ADAPTER_INFO*)std::malloc(dwBufLen);
+            if (AdapterInfo == NULL) {
+                return false;
+            }
+        }
+
+        if (GetAdaptersInfo(AdapterInfo, &dwBufLen) == NO_ERROR) {
+            PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo;
+            for (std::size_t i = 0; i < 6; i++) {
+                mac[i] = pAdapterInfo->Address[i];
+            }
+        }
+
+        std::free(AdapterInfo);
+#else
+        return false;
+#endif
+
+#ifdef __VMAWARE_DEBUG__
+        std::stringstream ss;
+        ss << std::setw(2) << std::setfill('0') << std::hex
+            << static_cast<int32_t>(mac[0]) << ":"
+            << static_cast<int32_t>(mac[1]) << ":"
+            << static_cast<int32_t>(mac[2]) << ":XX:XX:XX";
+        // removed for privacy reasons, cuz only the first 3 bytes are needed
+        //<< static_cast<int32_t>(mac[3]) << ":"  
+        //<< static_cast<int32_t>(mac[4]) << ":"
+        //<< static_cast<int32_t>(mac[5]);
+        debug("MAC: ", ss.str());
+#endif
+
+        // better expression to fix code duplication
+        auto compare = [=](const u8 mac1, const u8 mac2, const u8 mac3) noexcept -> bool {
+            return (mac[0] == mac1 && mac[1] == mac2 && mac[2] == mac3);
+            };
+
+        if (compare(0x08, 0x00, 0x27)) {
+            return core::add(VBOX);
+        }
+
+        if (
+            (compare(0x00, 0x0C, 0x29)) ||
+            (compare(0x00, 0x1C, 0x14)) ||
+            (compare(0x00, 0x50, 0x56)) ||
+            (compare(0x00, 0x05, 0x69))
+            ) {
+            return core::add(VMWARE);
+        }
+
+        if (compare(0x00, 0x16, 0xE3)) {
+            return core::add(XEN);
+        }
+
+        if (compare(0x00, 0x1C, 0x42)) {
+            return core::add(PARALLELS);
+        }
+
+        /*
+        see https://github.com/kernelwernel/VMAware/issues/105
+
+        if (compare(0x0A, 0x00, 0x27)) {
+            return core::add(HYBRID);
+        }
+        */
+
+        return false;
+    }
+
+
+    /**
+     * @brief Check if thermal directory in linux is present, might not be present in VMs
+     * @category Linux
+     */
+    [[nodiscard]] static bool temperature() {
+#if (!LINUX)
+        return false;
+#else
+        return (!util::exists("/sys/class/thermal/thermal_zone0/"));
+#endif
+    }
+
+
+    /**
+     * @brief Check result from systemd-detect-virt tool
+     * @category Linux
+     */
+    [[nodiscard]] static bool systemd_virt() {
+#if (!LINUX)
+        return false;
+#else
+        if (!(util::exists("/usr/bin/systemd-detect-virt") || util::exists("/bin/systemd-detect-virt"))) {
+            debug("SYSTEMD: ", "binary doesn't exist");
+            return false;
+        }
+
+        const std::unique_ptr<std::string> result = util::sys_result("systemd-detect-virt");
+
+        if (result == nullptr) {
+            debug("SYSTEMD: ", "invalid stdout output from systemd-detect-virt");
+            return false;
+        }
+
+        debug("SYSTEMD: ", "output = ", *result);
+
+        return (*result != "none");
+#endif
+    }
+
+
+    /**
+     * @brief Check if the chassis vendor is a VM vendor
+     * @category Linux
+     */
+    [[nodiscard]] static bool chassis_vendor() {
+#if (!LINUX)
+        return false;
+#else
+        const char* vendor_file = "/sys/devices/virtual/dmi/id/chassis_vendor";
+
+        if (!util::exists(vendor_file)) {
+            debug("CVENDOR: ", "file doesn't exist");
+            return false;
+        }
+
+        const std::string vendor = util::read_file(vendor_file);
+
+        // TODO: More can definitely be added, I only tried QEMU and VMware so far
+        if (vendor == "QEMU") { return core::add(QEMU); }
+        if (vendor == "Oracle Corporation") { return core::add(VMWARE); }
+
+        debug("CVENDOR: ", "unknown vendor = ", vendor);
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if the chassis type is valid (it's very often invalid in VMs)
+     * @category Linux
+     */
+    [[nodiscard]] static bool chassis_type() {
+#if (!LINUX)
+        return false;
+#else
+        const char* chassis = "/sys/devices/virtual/dmi/id/chassis_type";
+
+        if (util::exists(chassis)) {
+            return (stoi(util::read_file(chassis)) == 1);
+        } else {
+            debug("CTYPE: ", "file doesn't exist");
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if /.dockerenv or /.dockerinit file is present
+     * @category Linux
+     */
+    [[nodiscard]] static bool dockerenv() {
+#if (!LINUX)
+        return false;
+#else
+        if (util::exists("/.dockerenv") || util::exists("/.dockerinit")) {
+            return core::add(DOCKER);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if dmidecode output matches a VM brand
+     * @category Linux
+     */
+    [[nodiscard]] static bool dmidecode() {
+#if (!LINUX)
+        return false;
+#else
+        if (!util::is_admin()) {
+            debug("DMIDECODE: ", "precondition return called (root = ", util::is_admin(), ")");
+            return false;
+        }
+
+        if (!(util::exists("/bin/dmidecode") || util::exists("/usr/bin/dmidecode"))) {
+            debug("DMIDECODE: ", "binary doesn't exist");
+            return false;
+        }
+
+        const std::unique_ptr<std::string> result = util::sys_result("dmidecode -t system | grep 'Manufacturer|Product' | grep -c \"QEMU|VirtualBox|KVM\"");
+
+        if (*result == "" || result == nullptr) {
+            debug("DMIDECODE: ", "invalid output");
+            return false;
+        } else if (*result == "QEMU") {
+            return core::add(QEMU);
+        } else if (*result == "VirtualBox") {
+            return core::add(VBOX);
+        } else if (*result == "KVM") {
+            return core::add(KVM);
+        } else if (std::atoi(result->c_str()) >= 1) {
+            return true;
+        } else {
+            debug("DMIDECODE: ", "output = ", *result);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if dmesg output matches a VM brand
+     * @category Linux
+     */
+    [[nodiscard]] static bool dmesg() {
+#if (!LINUX || CPP <= 11)
+        return false;
+#else
+        if (!util::is_admin()) {
+            return false;
+        }
+
+        if (!util::exists("/bin/dmesg") && !util::exists("/usr/bin/dmesg")) {
+            debug("DMESG: ", "binary doesn't exist");
+            return false;
+        }
+
+        const std::unique_ptr<std::string> result = util::sys_result("dmesg | grep -i hypervisor | grep -c \"KVM|QEMU\"");
+
+        if (*result == "" || result == nullptr) {
+            return false;
+        } else if (*result == "KVM") {
+            return core::add(KVM);
+        } else if (*result == "QEMU") {
+            return core::add(QEMU);
+        } else if (std::atoi(result->c_str())) {
+            return true;
+        } else {
+            debug("DMESG: ", "output = ", *result);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if /sys/class/hwmon/ directory is present. If not, likely a VM
+     * @category Linux
+     */
+    [[nodiscard]] static bool hwmon() {
+#if (!LINUX)
+        return false;
+#else
+        return (!util::exists("/sys/class/hwmon/"));
+#endif
+    }
+
+
+    /**
+     * @brief Check if the 5th byte after sidt is null
+     * @author Matteo Malvica
+     * @link https://www.matteomalvica.com/blog/2018/12/05/detecting-vmware-on-64-bit-systems/
+     * @category x86
+     */
+    [[nodiscard]] static bool sidt5() {
+#if (!x86 || !LINUX || GCC)
+        return false;
+#else
+        u8 values[10];
+        std::memset(values, 0, 10);
+
+        fflush(stdout);
+        __asm__ __volatile__("sidt %0" : "=m"(values));
+
+#ifdef __VMAWARE_DEBUG__
+        u32 result = 0;
+
+        for (u8 i = 0; i < 10; i++) {
+            result <<= 8;
+            result |= values[i];
+        }
+
+        debug("SIDT5: ", "values = 0x", std::hex, std::setw(16), std::setfill('0'), result);
+#endif
+
+        return (values[5] == 0x00);
+#endif
+    }
+
+
+    /**
+     * @brief Check if the mouse coordinates have changed after 5 seconds
+     * @note Some VMs are automatic without a human due to mass malware scanning being a thing
+     * @note Disabled by default due to performance reasons
+     * @category Windows
+     */
+    [[nodiscard]] static bool cursor_check() {
+#if (!MSVC)
+        return false;
+#else
+        POINT pos1, pos2;
+        GetCursorPos(&pos1);
+
+        debug("CURSOR: pos1.x = ", pos1.x);
+        debug("CURSOR: pos1.y = ", pos1.y);
+
+        Sleep(5000);
+        GetCursorPos(&pos2);
+
+        debug("CURSOR: pos1.x = ", pos1.x);
+        debug("CURSOR: pos1.y = ", pos1.y);
+        debug("CURSOR: pos2.x = ", pos2.x);
+        debug("CURSOR: pos2.y = ", pos2.y);
+
+        return ((pos1.x == pos2.x) && (pos1.y == pos2.y));
+#endif
+    }
+
+
+    /**
+     * @brief Find for registries of VMware tools
+     * @category Windows
+     */
+    [[nodiscard]] static bool vmware_registry() {
+#if (!MSVC)
+        return false;
+#else
+        HKEY hKey;
+        // Use wide string literal
+        bool result = (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\VMware, Inc.\\VMware Tools", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS);
+
+        debug("VMWARE_REG: result = ", result);
+
+        if (result == true) {
+            return core::add(VMWARE);
+        }
+
+        return result;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VBox RdrDN
+     * @category Windows
+     */
+    [[nodiscard]] static bool vbox_registry() {
+#if (!MSVC)
+        return false;
+#else
+        HANDLE handle = CreateFile(_T("\\\\.\\VBoxMiniRdrDN"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+        if (handle != INVALID_HANDLE_VALUE) {
+            CloseHandle(handle);
+            return core::add(VBOX);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief checks for default usernames, often a sign of a VM
+     * @category Windows
+     */
+    [[nodiscard]] static bool user_check() {
+#if (!MSVC)
+        return false;
+#else
+        TCHAR user[UNLEN + 1]{};
+        DWORD user_len = UNLEN + 1;
+        GetUserName(user, &user_len);
+
+        //TODO Ansi: debug("USER: ", "output = ", user);
+
+        if (0 == _tcscmp(user, _T("vmware"))) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VM-specific DLLs
+     * @category Windows
+     */
+    [[nodiscard]] static bool DLL_check() {
+#if (!MSVC)
+        return false;
+#else
+        const char* real_dlls[] = {
+            "kernel32.dll",
+            "networkexplorer.dll",
+            "NlsData0000.dll",
+        };
+
+        const char* false_dlls[] = {
+            "NetProjW.dll",
+            "Ghofr.dll",
+            "fg122.dll",
+        };
+
+        // Check for real DLLs
+        for (const char* dll : real_dlls) {
+            if (GetModuleHandleA(dll) == nullptr) {
+                debug("DLL: ", "LIB_INST detected true for real dll = ", dll);
+                return true; // Detected a missing real DLL
+            }
+        }
+
+        // Check for false DLLs
+        for (const char* dll : false_dlls) {
+            if (GetModuleHandleA(dll) != nullptr) {
+                debug("DLL: ", "LIB_INST detected true for false dll = ", dll);
+                return true; // Detected a loaded false DLL
+            }
+        }
+
+        return false; // No DLLs detected
+#endif
+    }
+
+
+
+    /**
+     * @brief Check for VM-specific registry values
+     * @category Windows
+     */
+    [[nodiscard]] static bool registry_key() {
+#if (!MSVC)
+        return false;
+#else
+        u8 score = 0;
+
+        auto key = [&score](const char* p_brand, const char* regkey_s) -> void {
+            HKEY regkey;
+            LONG ret;
+
+            if (util::is_wow64()) {
+                wchar_t wRegKey[MAX_PATH];
+                MultiByteToWideChar(CP_ACP, 0, regkey_s, -1, wRegKey, MAX_PATH);
+
+                ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wRegKey, 0, KEY_READ | KEY_WOW64_64KEY, &regkey);
+            } else {
+                wchar_t wRegKey[MAX_PATH];
+                MultiByteToWideChar(CP_ACP, 0, regkey_s, -1, wRegKey, MAX_PATH);
+
+                ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wRegKey, 0, KEY_READ, &regkey);
+            }
+
+            if (ret == ERROR_SUCCESS) {
+                RegCloseKey(regkey);
+                score++;
+
+                if (std::string(p_brand) != "") {
+                    debug("REGISTRY: ", "detected = ", p_brand);
+                    core::add(p_brand);
+                }
+            }
+            };
+
+        // general
+        key("", "HKLM\\Software\\Classes\\Folder\\shell\\sandbox");
+
+        // hyper-v
+        key(HYPERV, "HKLM\\SOFTWARE\\Microsoft\\Hyper-V");
+        key(HYPERV, "HKLM\\SOFTWARE\\Microsoft\\VirtualMachine");
+        key(HYPERV, "HKLM\\SOFTWARE\\Microsoft\\Virtual Machine\\Guest\\Parameters");
+        key(HYPERV, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmicheartbeat");
+        key(HYPERV, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmicvss");
+        key(HYPERV, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmicshutdown");
+        key(HYPERV, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmicexchange");
+
+        // parallels
+        key(PARALLELS, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_1AB8*");
+
+        // sandboxie
+        key(SANDBOXIE, "HKLM\\SYSTEM\\CurrentControlSet\\Services\\SbieDrv");
+        key(SANDBOXIE, "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Sandboxie");
+
+        // virtualbox
+        key(VBOX, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_80EE*");
+        key(VBOX, "HKLM\\HARDWARE\\ACPI\\DSDT\\VBOX__");
+        key(VBOX, "HKLM\\HARDWARE\\ACPI\\FADT\\VBOX__");
+        key(VBOX, "HKLM\\HARDWARE\\ACPI\\RSDT\\VBOX__");
+        key(VBOX, "HKLM\\SOFTWARE\\Oracle\\VirtualBox Guest Additions");
+        key(VBOX, "HKLM\\SYSTEM\\ControlSet001\\Services\\VBoxGuest");
+        key(VBOX, "HKLM\\SYSTEM\\ControlSet001\\Services\\VBoxMouse");
+        key(VBOX, "HKLM\\SYSTEM\\ControlSet001\\Services\\VBoxService");
+        key(VBOX, "HKLM\\SYSTEM\\ControlSet001\\Services\\VBoxSF");
+        key(VBOX, "HKLM\\SYSTEM\\ControlSet001\\Services\\VBoxVideo");
+
+        // virtualpc
+        key(VPC, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_5333*");
+        key(VPC, "HKLM\\SYSTEM\\ControlSet001\\Services\\vpcbus");
+        key(VPC, "HKLM\\SYSTEM\\ControlSet001\\Services\\vpc-s3");
+        key(VPC, "HKLM\\SYSTEM\\ControlSet001\\Services\\vpcuhub");
+        key(VPC, "HKLM\\SYSTEM\\ControlSet001\\Services\\msvmmouf");
+
+        // vmware
+        key(VMWARE, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_15AD*");
+        key(VMWARE, "HKCU\\SOFTWARE\\VMware, Inc.\\VMware Tools");
+        key(VMWARE, "HKLM\\SOFTWARE\\VMware, Inc.\\VMware Tools");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmdebug");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmmouse");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\VMTools");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\VMMEMCTL");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmware");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmci");
+        key(VMWARE, "HKLM\\SYSTEM\\ControlSet001\\Services\\vmx86");
+        key(VMWARE, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\IDE\\CdRomNECVMWar_VMware_IDE_CD*");
+        key(VMWARE, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\IDE\\CdRomNECVMWar_VMware_SATA_CD*");
+        key(VMWARE, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\IDE\\DiskVMware_Virtual_IDE_Hard_Drive*");
+        key(VMWARE, "HKLM\\SYSTEM\\CurrentControlSet\\Enum\\IDE\\DiskVMware_Virtual_SATA_Hard_Drive*");
+
+        // wine
+        key(WINE, "HKCU\\SOFTWARE\\Wine");
+        key(WINE, "HKLM\\SOFTWARE\\Wine");
+
+        // xen
+        key(XEN, "HKLM\\HARDWARE\\ACPI\\DSDT\\xen");
+        key(XEN, "HKLM\\HARDWARE\\ACPI\\FADT\\xen");
+        key(XEN, "HKLM\\HARDWARE\\ACPI\\RSDT\\xen");
+        key(XEN, "HKLM\\SYSTEM\\ControlSet001\\Services\\xenevtchn");
+        key(XEN, "HKLM\\SYSTEM\\ControlSet001\\Services\\xennet");
+        key(XEN, "HKLM\\SYSTEM\\ControlSet001\\Services\\xennet6");
+        key(XEN, "HKLM\\SYSTEM\\ControlSet001\\Services\\xensvc");
+        key(XEN, "HKLM\\SYSTEM\\ControlSet001\\Services\\xenvdb");
+
+        debug("REGISTRY: ", "score = ", static_cast<u32>(score));
+
+        return (score >= 1);
+#endif
+    }
+
+
+    /**
+     * @brief Check if CWSandbox-specific file exists
+     * @category Windows
+     */
+    [[nodiscard]] static bool cwsandbox_check() {
+#if (!MSVC)
+        return false;
+#else
+        if (util::exists(_T("C:\\analysis"))) {
+            return core::add(CWSANDBOX);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Find for VMware and VBox specific files
+     * @category Windows
+     */
+    [[nodiscard]] static bool vm_files() {
+#if (!MSVC)
+        return false;
+#else
+        // points
+        u8 vbox = 0;
+        u8 vmware = 0;
+
+        constexpr std::array<const TCHAR*, 26> files = {{
+                // VMware
+                _T("C:\\windows\\System32\\Drivers\\Vmmouse.sys"),
+                _T("C:\\windows\\System32\\Drivers\\vm3dgl.dll"),
+                _T("C:\\windows\\System32\\Drivers\\vmdum.dll"),
+                _T("C:\\windows\\System32\\Drivers\\VmGuestLibJava.dll"),
+                _T("C:\\windows\\System32\\Drivers\\vm3dver.dll"),
+                _T("C:\\windows\\System32\\Drivers\\vmtray.dll"),
+                _T("C:\\windows\\System32\\Drivers\\VMToolsHook.dll"),
+                _T("C:\\windows\\System32\\Drivers\\vmGuestLib.dll"),
+                _T("C:\\windows\\System32\\Drivers\\vmhgfs.dll"),
+
+                // VBox
+                _T("C:\\windows\\System32\\Drivers\\VBoxMouse.sys"),
+                _T("C:\\windows\\System32\\Drivers\\VBoxGuest.sys"),
+                _T("C:\\windows\\System32\\Drivers\\VBoxSF.sys"),
+                _T("C:\\windows\\System32\\Drivers\\VBoxVideo.sys"),
+                _T("C:\\windows\\System32\\vboxoglpackspu.dll"),
+                _T("C:\\windows\\System32\\vboxoglpassthroughspu.dll"),
+                _T("C:\\windows\\System32\\vboxservice.exe"),
+                _T("C:\\windows\\System32\\vboxoglcrutil.dll"),
+                _T("C:\\windows\\System32\\vboxdisp.dll"),
+                _T("C:\\windows\\System32\\vboxhook.dll"),
+                _T("C:\\windows\\System32\\vboxmrxnp.dll"),
+                _T("C:\\windows\\System32\\vboxogl.dll"),
+                _T("C:\\windows\\System32\\vboxtray.exe"),
+                _T("C:\\windows\\System32\\VBoxControl.exe"),
+                _T("C:\\windows\\System32\\vboxoglerrorspu.dll"),
+                _T("C:\\windows\\System32\\vboxoglfeedbackspu.dll"),
+                _T("c:\\windows\\system32\\vboxoglarrayspu.dll")
+            }};
+
+        for (const auto file : files) {
+            if (util::exists(file)) {
+                const auto regex = tregex(file, std::regex::icase);
+
+                if (std::regex_search(_T("vbox"), regex)) {
+                    //TODO Ansi: debug("VM_FILES: found vbox file = ", file);
+                    vbox++;
+                } else {
+                    //TODO Ansi: debug("VM_FILES: found vmware file = ", file);
+                    vmware++;
+                }
+            }
+        }
+
+        debug("VM_FILES: vmware score: ", static_cast<u32>(vmware));
+        debug("VM_FILES: vbox score: ", static_cast<u32>(vbox));
+
+        if (vbox > vmware) {
+            return core::add(VBOX);
+        } else if (vbox < vmware) {
+            return core::add(VMWARE);
+        } else if (
+            vbox > 0 &&
+            vmware > 0 &&
+            vbox == vmware
+            ) {
+            return true;
+        }
+
+        // general VM file, not sure which brand it belongs to though
+        if (util::exists("C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\StartUp\\agent.pyw")) {
+            return true;
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if the sysctl for the hwmodel does not contain the "Mac" string
+     * @author MacRansom ransomware
+     * @category MacOS
+     */
+    [[nodiscard]] static bool hwmodel() {
+#if (!APPLE)
+        return false;
+#else
+        auto result = util::sys_result("sysctl -n hw.model");
+
+        std::smatch match;
+
+        if (result == nullptr) {
+            debug("HWMODEL: ", "null result received");
+            return false;
+        }
+
+        debug("HWMODEL: ", "output = ", *result);
+
+        // if string contains "Mac" anywhere in the string, assume it's baremetal
+        if (std::regex_search(*result, match, std::regex("Mac"))) {
+            return false;
+        }
+
+        // not sure about the other VMs, more could potentially be added
+        if (std::regex_search(*result, match, std::regex("VMware"))) {
+            return core::add(VMWARE);
+        }
+
+        // assumed true since it doesn't contain "Mac" string
+        return true;
+#endif
+    }
+
+
+    /**
+     * @brief Check if disk size is under or equal to 50GB
+     * @category Linux (for now)
+     */
+    [[nodiscard]] static bool disk_size() {
+#if (!LINUX)
+        return false;
+#else
+        const u32 size = util::get_disk_size();
+
+        debug("DISK_SIZE: size = ", size);
+
+        return (size <= 60); // in GB
+#endif
+    }
+
+
+    /**
+     * @brief Check for default RAM and DISK sizes set by VirtualBox
+     * @note        RAM     DISK
+     * WINDOWS 11:  4096MB, 80GB
+     * WINDOWS 10:  2048MB, 50GB
+     * ARCH, OPENSUSE, REDHAD, GENTOO, FEDORA, DEBIAN: 1024MB, 8GB
+     * UBUNTU:      1028MB, 10GB
+     * ORACLE:      1024MB, 12GB
+     * OTHER LINUX: 512MB,  8GB
+
+     * @todo: check if it still applies to host systems with larger RAM and disk size than what I have
+     * @category Linux, Windows
+     */
+    [[nodiscard]] static bool vbox_default_specs() {
+#if (APPLE)
+        return false;
+#else
+        const u32 disk = util::get_disk_size();
+        const u64 ram = util::get_physical_ram_size();
+
+        debug("VBOX_DEFAULT: disk = ", disk);
+        debug("VBOX_DEFAULT: ram = ", ram);
+
+        if ((disk > 80) || (ram > 4)) {
+            debug("VBOX_DEFAULT: returned false due to lack of precondition spec comparisons");
+            return false;
+        }
+
+#if (LINUX)
+        auto get_distro = []() -> std::string {
+            std::ifstream osReleaseFile("/etc/os-release");
+            std::string line;
+
+            while (std::getline(osReleaseFile, line)) {
+                if (line.find("ID=") != std::string::npos) {
+                    const std::size_t start = line.find('"');
+                    const std::size_t end = line.rfind('"');
+                    if (start != std::string::npos && end != std::string::npos && start < end) {
+                        return line.substr(start + 1, end - start - 1);
+                    }
+                }
+            }
+
+            return "unknown";
+        };
+
+        const std::string distro = get_distro();
+
+        debug("VBOX_DEFAULT: linux, detected distro: ", distro);
+
+        // yoda notation ftw
+        if ("unknown" == distro) {
+            return false;
+        }
+
+        if (
+            "arch" == distro ||
+            "opensuse" == distro ||
+            "redhat" == distro ||
+            "gentoo" == distro ||
+            "fedora" == distro ||
+            "debian" == distro
+        ) {
+            return ((8 == disk) && (1 == ram));
+        }
+
+        if ("ubuntu" == distro) {
+            return ((10 == disk) && (1 == ram));
+        }
+
+        if ("ol" == distro) { // ol = oracle
+            return ((12 == disk) && (1 == ram));
+        }
+#elif (MSVC)
+        const u8 version = util::get_windows_version();
+
+        if (version == 0) {
+            return false;
+        }
+
+        // less than windows 10
+        if (version < 10) {
+            debug("VBOX_DEFAULT: less than windows 10 detected");
+            return false;
+        }
+
+        // windows 10
+        if (10 == version) {
+            debug("VBOX_DEFAULT: windows 10 detected");
+            return ((50 == disk) && (2 == ram));
+        }
+
+        // windows 11
+        if (11 == version) {
+            debug("VBOX_DEFAULT: windows 11 detected");
+            return ((80 == disk) && (4 == ram));
+        }
+#endif
+#endif
+        return false;
+    }
+
+
+    /**
+     * @brief Check for VirtualBox network provider string
+     * @category Windows
+     */
+    [[nodiscard]] static bool vbox_network_share() {
+#if (!MSVC)
+        return false;
+#else
+        u32 pnsize = 0x1000;
+        TCHAR* provider = new TCHAR[pnsize];
+
+        u32 retv = WNetGetProviderName(WNNC_NET_RDR2SAMPLE, provider, reinterpret_cast<LPDWORD>(&pnsize));
+
+        if (retv == NO_ERROR) {
+            bool result = (lstrcmpi(provider, _T("VirtualBox Shared Folders")) == 0);
+            delete[] provider;
+            return result;
+        }
+
+        delete[] provider;
+        return false;
+#endif
+    }
+
+
+
+
+    /**
+     * @brief Check for any VM processes that are active
+     * @category Windows
+     */
+    [[nodiscard]] static bool vm_processes() {
+#if (!MSVC)
+        return false;
+#else
+        auto check_proc = [](const TCHAR* proc) -> bool {
+            DWORD processes[1024], bytesReturned;
+
+            // Retrieve the list of process identifiers
+            if (!EnumProcesses(processes, sizeof(processes), &bytesReturned))
+                return false;
+
+            // Calculate how many process identifiers were returned
+            DWORD numProcesses = bytesReturned / sizeof(DWORD);
+
+            for (DWORD i = 0; i < numProcesses; ++i) {
+                // Open the process
+                const HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processes[i]);
+                if (process != nullptr) {
+                    // Get the process name
+                    TCHAR processName[MAX_PATH];
+                    if (GetModuleBaseName(process, nullptr, processName, sizeof(processName) / sizeof(TCHAR))) {
+                        // Check if the process name matches the desired executable
+                        if (_tcscmp(processName, proc) == 0) {
+                            CloseHandle(process);
+                            return true;
+                        }
+                    }
+                    CloseHandle(process);
+                }
+            }
+
+            return false;
+            };
+
+        if (check_proc(_T("joeboxserver.exe")) || check_proc(_T("joeboxcontrol.exe"))) {
+            return core::add(JOEBOX);
+        }
+
+        if (check_proc(_T("prl_cc.exe")) || check_proc(_T("prl_tools.exe"))) {
+            return core::add(PARALLELS);
+        }
+
+        if (check_proc(_T("vboxservice.exe")) || check_proc(_T("vboxtray.exe"))) {
+            return core::add(VBOX);
+        }
+
+        if (check_proc(_T("vmsrvc.exe")) || check_proc(_T("vmusrvc.exe"))) {
+            return core::add(VPC);
+        }
+        /*
+                removed due to potential false positives
+
+                if (
+                    check_proc(_T("vmtoolsd.exe")) ||
+                    check_proc(_T("vmwaretrat.exe")) ||
+                    check_proc(_T("vmacthlp.exe")) ||
+                    check_proc(_T("vmwaretray.exe")) ||
+                    check_proc(_T("vmwareuser.exe")) ||
+                    check_proc(_T("vmware.exe")) ||
+                    check_proc(_T("vmount2.exe"))
+                ) {
+                    return core::add(VMWARE);
+                }
+        */
+
+        if (check_proc(_T("xenservice.exe")) || check_proc(_T("xsvc_depriv.exe"))) {
+            return core::add(XEN);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for default VM username and hostname for linux
+     * @category Linux
+     */
+    [[nodiscard]] static bool linux_user_host() {
+#if (!LINUX)
+        return false;
+#else
+        if (util::is_admin()) {
+            return false;
+        }
+
+        const char* username = std::getenv("USER");
+        const char* hostname = std::getenv("HOSTNAME");
+
+        debug("LINUX_USER_HOST: user = ", username);
+        debug("LINUX_USER_HOST: host = ", hostname);
+
+        return (
+            (strcmp(username, "liveuser") == 0) &&
+            (strcmp(hostname, "localhost-live") == 0)
+            );
+#endif
+    }
+
+
+    /**
+     * @brief Check for Gamarue ransomware technique which compares VM-specific Window product IDs
+     * @category Windows
+     */
+    [[nodiscard]] static bool gamarue() {
+#if (!MSVC) 
+        return false;
+#else
+        HKEY hOpen;
+        char* szBuff;
+        int iBuffSize;
+        LONG nRes;
+
+        szBuff = (char*)calloc(512, sizeof(char));
+
+        const HANDLE hMod = GetModuleHandleA("SbieDll.dll"); // Sandboxie
+        if (hMod != 0) {
+            free(szBuff);
+            return core::add(SANDBOXIE);
+        }
+
+        /* this gave a false positive
+        hMod = GetModuleHandleA("dbghelp.dll"); // ThreatExpert
+        if (hMod != 0) {
+            free(szBuff);
+            return core::add(THREATEXPERT);
+        }
+        */
+
+        nRes = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", 0L, KEY_QUERY_VALUE, &hOpen);
+        if (nRes == ERROR_SUCCESS) {
+            iBuffSize = sizeof(szBuff);
+            nRes = RegQueryValueExA(hOpen, "ProductId", NULL, NULL, (unsigned char*)szBuff, reinterpret_cast<LPDWORD>(&iBuffSize));
+            if (nRes == ERROR_SUCCESS) {
+                // Check if szBuff is not NULL before using strcmp
+                if (szBuff == NULL) {
+                    RegCloseKey(hOpen);
+                    return false;
+                }
+
+                if (strcmp(szBuff, "55274-640-2673064-23950") == 0) { // joebox
+                    free(szBuff);
+                    return core::add(JOEBOX);
+                } else if (strcmp(szBuff, "76487-644-3177037-23510") == 0) { // CW Sandbox
+                    free(szBuff);
+                    return core::add(CWSANDBOX);
+                } else if (strcmp(szBuff, "76487-337-8429955-22614") == 0) { // anubis
+                    free(szBuff);
+                    return core::add(ANUBIS);
+                } else {
+                    free(szBuff);
+                    return false;
+                }
+            }
+            RegCloseKey(hOpen);
+        }
+        // Set szBuff to NULL after freeing to avoid double free issues
+        free(szBuff);
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if the CPU manufacturer ID matches that of a VM brand with leaf 0x40000000
+     * @category x86
+     */
+    [[nodiscard]] static bool vmid_0x4() {
+#if (!x86)
+        return false;
+#else
+        if (!core::cpuid_supported) {
+            return false;
+        }
+
+        return cpu::vmid_template(cpu::leaf::hypervisor, "VMID_0x4: ");
+#endif
+    }
+
+
+    /**
+     * @brief Check for any indication of Parallels VM through BIOS data
+     * @link https://stackoverflow.com/questions/1370586/detect-if-windows-is-running-from-within-parallels
+     * @category Windows
+     */
+    [[nodiscard]] static bool parallels() {
+#if (!MSVC)
+        return false;
+#else
+        std::unique_ptr<util::sys_info> info = util::make_unique<util::sys_info>();
+
+#ifdef __VMAWARE_DEBUG__
+        debug("Manufacturer: ", info->get_manufacturer());
+        debug("Product Name: ", info->get_productname());
+        debug("Serial No: ", info->get_serialnumber());
+        debug("UUID: ", info->get_uuid());
+        debug("Version: ", info->get_version());
+
+        if (!info->get_family().empty()) {
+            debug("Product family: ", info->get_family());
+        }
+
+        if (!info->get_sku().empty()) {
+            debug("SKU/Configuration: ", info->get_sku());
+        }
+#endif
+
+        auto compare = [](const std::string& str) -> bool {
+            std::regex pattern("Parallels", std::regex_constants::icase);
+            return std::regex_match(str, pattern);
+            };
+
+        if (
+            compare(info->get_manufacturer()) ||
+            compare(info->get_productname()) ||
+            compare(info->get_family())
+            ) {
+            return core::add(PARALLELS);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief check through alternative RDTSC technique with VMEXIT
+     * @category x86
+     */
+    [[nodiscard]]
+#if (LINUX)
+    // this is added so no sanitizers can potentially cause unwanted delays while measuring rdtsc in a debug compilation
+    __attribute__((no_sanitize("address", "leak", "thread", "undefined")))
+#endif
+    static bool rdtsc_vmexit() {
+#if (!x86)
+        return false;
+#else
+        u64 tsc1 = 0;
+        u64 tsc2 = 0;
+        u64 avg = 0;
+        i32 reg[4] = {};
+
+        for (std::size_t i = 0; i < 10; i++) {
+            tsc1 = __rdtsc();
+            cpu::cpuid(reg, 0);
+            tsc2 = __rdtsc();
+            avg += (tsc2 - tsc1);
+        }
+
+        avg /= 10;
+
+        return (avg >= 1500 || avg == 0);
+#endif
+    }
+
+
+    /**
+     * @brief Match for QEMU CPU brands with "QEMU Virtual CPU" string
+     * @category x86
+     */
+    [[nodiscard]] static bool cpu_brand_qemu() {
+#if (!x86)
+        return false;
+#else
+        if (!core::cpuid_supported) {
+            return false;
+        }
+
+        std::string brand = cpu::get_brand();
+
+        std::regex qemu_pattern("QEMU Virtual CPU", std::regex_constants::icase);
+
+        if (std::regex_match(brand, qemu_pattern)) {
+            return core::add(QEMU);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for various Bochs-related emulation oversights through CPU checks
+     * @category x86
+     * @note Discovered by Peter Ferrie, Senior Principal Researcher, Symantec Advanced Threat Research peter_ferrie@symantec.com
+     */
+    [[nodiscard]] static bool bochs_cpu() {
+#if (!x86)
+        return false;z
+#else
+        if (!core::cpuid_supported) {
+            return false;
+        }
+
+        const bool intel = cpu::is_intel();
+        const bool amd = cpu::is_amd();
+
+        // if neither amd or intel, return false
+        if (!(intel || amd)) {
+            debug("BOCHS_CPU: neither AMD or Intel detected, returned false");
+            return false;
+        }
+
+        const std::string brand = cpu::get_brand();
+
+        if (intel) {
+            // technique 1: not a valid brand 
+            if (brand == "              Intel(R) Pentium(R) 4 CPU        ") {
+                debug("BOCHS_CPU: technique 1 found");
+                return core::add(BOCHS);
+            }
+        } else if (amd) {
+            // technique 2: "processor" should have a capital P
+            if (brand == "AMD Athlon(tm) processor") {
+                debug("BOCHS_CPU: technique 2 found");
+                return core::add(BOCHS);
+            }
+
+            // technique 3: Check for absence of AMD easter egg for K7 and K8 CPUs
+            constexpr u32 AMD_EASTER_EGG = 0x8fffffff; // this is the CPUID leaf of the AMD easter egg
+
+            if (!cpu::is_leaf_supported(AMD_EASTER_EGG)) {
+                return false;
+            }
+
+            u32 unused, eax = 0;
+            cpu::cpuid(eax, unused, unused, unused, 1);
+
+            auto is_k7 = [](const u32 eax) -> bool {
+                const u32 family = (eax >> 8) & 0xF;
+                const u32 model = (eax >> 4) & 0xF;
+                const u32 extended_family = (eax >> 20) & 0xFF;
+
+                if (family == 6 && extended_family == 0) {
+                    if (model == 1 || model == 2 || model == 3 || model == 4) {
+                        return true;
+                    }
+                }
+
+                return false;
+            };
+
+            auto is_k8 = [](const u32 eax) -> bool {
+                const u32 family = (eax >> 8) & 0xF;
+                const u32 extended_family = (eax >> 20) & 0xFF;
+
+                if (family == 0xF) {
+                    if (extended_family == 0x00 || extended_family == 0x01) {
+                        return true;
+                    }
+                }
+
+                return false;
+            };
+
+            if (!(is_k7(eax) || is_k8(eax))) {
+                return false;
+            }
+
+            u32 ecx_bochs = 0;
+            cpu::cpuid(unused, unused, ecx_bochs, unused, AMD_EASTER_EGG);
+
+            if (ecx_bochs == 0) {
+                return true;
+            }
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check through the motherboard and match for VirtualPC-specific string
+     * @category Windows
+     */
+    [[nodiscard]] static bool vpc_board() {
+#if (!MSVC)
+        return false;
+#else
+        const bool is_vm = util::motherboard_string("Microsoft Corporation");
+
+        if (is_vm) {
+            return core::add(VPC);
+        }
+
+        return false;
+#endif
+    }
+
+
+
+    /**
+     * @brief Check if the BIOS serial is valid (null = VM)
+     * @category Windows
+     */
+    [[nodiscard]] static bool bios_serial() {
+#if (!MSVC)
+        return false;
+#else
+        std::unique_ptr<util::sys_info> info = util::make_unique<util::sys_info>();
+
+        const std::string str = info->get_serialnumber();
+        const std::size_t nl_pos = str.find('\n');
+
+        if (nl_pos == std::string::npos) {
+            return false;
+        }
+
+        debug("BIOS_SERIAL: ", str);
+
+        const std::string extract = str.substr(nl_pos + 1);
+
+        const bool all_digits = std::all_of(extract.cbegin(), extract.cend(), [](const char c) {
+            return std::isdigit(c);
+            });
+
+        if (all_digits) {
+            if (extract == "0") {
+                return true;
+            }
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VirtualBox-specific string for shared folder ID
+     * @category Windows
+     * @note slightly modified code from original
+     * @author @waleedassar
+     * @link https://pastebin.com/xhFABpPL
+     */
+    [[nodiscard]] static bool vbox_shared_folders() {
+#if (!MSVC)
+        return false;
+#else
+        DWORD pnsize = 0;  // Initialize to 0 to query the required size
+        wchar_t* provider = nullptr;
+
+        // Query the required size
+        DWORD retv = WNetGetProviderNameW(WNNC_NET_RDR2SAMPLE, nullptr, &pnsize);
+
+        if (retv == ERROR_MORE_DATA) {
+            // Allocate a buffer of the required size
+            provider = static_cast<wchar_t*>(LocalAlloc(LMEM_ZEROINIT, pnsize));
+
+            if (provider != nullptr) {
+                // Retrieve the actual data
+                retv = WNetGetProviderNameW(WNNC_NET_RDR2SAMPLE, provider, &pnsize);
+            }
+        }
+
+        if (retv == NO_ERROR && provider != nullptr) {
+            if (lstrcmpiW(provider, L"VirtualBox Shared Folders") == 0) {
+                LocalFree(provider);
+                return core::add(VBOX);
+            }
+        }
+
+        // Clean up the allocated buffer
+        LocalFree(provider);
+
+        return false;
+
+#endif
+    }
+
+
+    /**
+     * @brief Check MSSMBIOS registry for VM-specific strings
+     * @category Windows
+     * @note slightly modified from original code
+     * @author @waleedassar
+     * @link https://pastebin.com/fPY4MiYq
+     */
+    [[nodiscard]] static bool mssmbios() {
+#if (!MSVC)
+        return false;
+#else
+        const std::string p = util::SMBIOS_string();
+
+        if (p.empty()) {
+            debug("MSSMBIOS: empty, returned false");
+            return false;
+        }
+
+#ifdef __VMAWARE_DEBUG__
+        debug("MSSMBIOS: string = ", p);
+#endif
+
+        bool is_vm = false;
+
+        const bool x1 = (p == "INNOTEK GMBH");
+        const bool x2 = (p == "VIRTUALBOX");
+        const bool x3 = (p == "SUN MICROSYSTEMS");
+        const bool x4 = (p == "VBOXVER");
+        const bool x5 = (p == "VIRTUAL MACHINE");
+
+        if (x1 || x2 || x3 || x4 || x5) {
+            is_vm = true;
+        }
+
+        if (is_vm) {
+            if (x5) {
+                return true; // Hyper-V and VirtualBox both have the same BIOS string with "VIRTUAL MACHINE"
+            }
+
+            return core::add(VBOX);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if memory is too low for MacOS system
+     * @category MacOS
+     * @link https://evasions.checkpoint.com/techniques/macos.html
+     */
+    [[nodiscard]] static bool hw_memsize() {
+#if (!APPLE)
+        return false;
+#else
+        std::unique_ptr<std::string> result = util::sys_result("sysctl -n hw.memsize");
+        const std::string ram = *result;
+
+        if (ram == "0") {
+            return false;
+        }
+
+        debug("MAC_MEMSIZE: ", "ram size = ", ram);
+
+        for (const char c : ram) {
+            if (!std::isdigit(c)) {
+                debug("MAC_MEMSIZE: ", "found non-digit character, returned false");
+                return false;
+            }
+        }
+
+        const u64 ram_u64 = std::stoull(ram);
+
+        debug("MAC_MEMSIZE: ", "ram size in u64 = ", ram_u64);
+
+        constexpr u64 limit = 4000000000; // 4GB 
+
+        return (ram_u64 <= limit);
+#endif
+    }
+
+
+    /**
+     * @brief Check MacOS' IO kit registry for VM-specific strings
+     * @category MacOS
+     * @link https://evasions.checkpoint.com/techniques/macos.html
+     */
+    [[nodiscard]] static bool io_kit() {
+#if (!APPLE)
+        return false;
+#else
+        // board_ptr and manufacturer_ptr empty
+        std::unique_ptr<std::string> platform_ptr = util::sys_result("ioreg -rd1 -c IOPlatformExpertDevice");
+        std::unique_ptr<std::string> board_ptr = util::sys_result("ioreg -rd1 -c board-id");
+        std::unique_ptr<std::string> manufacturer_ptr = util::sys_result("ioreg -rd1 -c manufacturer");
+
+        const std::string platform = *platform_ptr;
+        const std::string board = *board_ptr;
+        const std::string manufacturer = *manufacturer_ptr;
+
+        auto check_platform = [&]() -> bool {
+            debug("IO_KIT: ", "platform = ", platform);
+
+            if (platform.empty()) {
+                return false;
+            }
+
+            for (const char c : platform) {
+                if (!std::isdigit(c)) {
+                    return false;
+                }
+            }
+
+            return (platform == "0");
+            };
+
+        auto check_board = [&]() -> bool {
+            debug("IO_KIT: ", "board = ", board);
+
+            if (board.empty()) {
+                return false;
+            }
+
+            if (util::find(board, "Mac")) {
+                return false;
+            }
+
+            if (util::find(board, "VirtualBox")) {
+                return core::add(VBOX);
+            }
+
+            if (util::find(board, "VMware")) {
+                return core::add(VMWARE);
+            }
+
+            return false;
+            };
+
+        auto check_manufacturer = [&]() -> bool {
+            debug("IO_KIT: ", "manufacturer = ", manufacturer);
+
+            if (manufacturer.empty()) {
+                return false;
+            }
+
+            if (util::find(manufacturer, "Apple")) {
+                return false;
+            }
+
+            if (util::find(manufacturer, "innotek")) {
+                return core::add(VBOX);
+            }
+
+            return false;
+            };
+
+        return (
+            check_platform() ||
+            check_board() ||
+            check_manufacturer()
+            );
+
+        return false;
+#endif            
+    }
+
+
+    /**
+     * @brief Check for VM-strings in ioreg commands for MacOS
+     * @category MacOS
+     * @link https://evasions.checkpoint.com/techniques/macos.html
+     */
+    [[nodiscard]] static bool ioreg_grep() {
+#if (!APPLE)
+        return false;
+#else
+        auto check_usb = []() -> bool {
+            std::unique_ptr<std::string> result = util::sys_result("ioreg -rd1 -c IOUSBHostDevice | grep \"USB Vendor Name\"");
+            const std::string usb = *result;
+
+            if (util::find(usb, "Apple")) {
+                return false;
+            }
+
+            if (util::find(usb, "VirtualBox")) {
+                return core::add(VBOX);
+            }
+
+            return false;
+            };
+
+        auto check_general = []() -> bool {
+            std::unique_ptr<std::string> sys_vbox = util::sys_result("ioreg -l | grep -i -c -e \"virtualbox\" -e \"oracle\"");
+
+            if (std::stoi(*sys_vbox) > 0) {
+                return core::add(VBOX);
+            }
+
+            std::unique_ptr<std::string> sys_vmware = util::sys_result("ioreg -l | grep -i -c -e \"vmware\"");
+
+            if (std::stoi(*sys_vmware) > 0) {
+                return core::add(VMWARE);
+            }
+
+            return false;
+            };
+
+        auto check_rom = []() -> bool {
+            std::unique_ptr<std::string> sys_rom = util::sys_result("system_profiler SPHardwareDataType | grep \"Boot ROM Version\"");
+            const std::string rom = *sys_rom;
+
+            if (util::find(rom, "VirtualBox")) {
+                return core::add(VBOX);
+            }
+
+            return false;
+        };
+
+        return (
+            check_usb() ||
+            check_general() ||
+            check_rom()
+        );
+#endif
+    }
+
+
+    /**
+     * @brief Check if System Integrity Protection is disabled (likely a VM if it is)
+     * @category MacOS
+     * @link https://evasions.checkpoint.com/techniques/macos.html
+     */
+    [[nodiscard]] static bool mac_sip() {
+#if (!APPLE)
+        return false;
+#else
+        std::unique_ptr<std::string> result = util::sys_result("csrutil status");
+        const std::string tmp = *result;
+
+        debug("MAC_SIP: ", "result = ", tmp);
+
+        return (util::find(tmp, "disabled") || (!util::find(tmp, "enabled")));
+#endif
+    }
+
+
+    /**
+     * @brief Check HKLM registries for specific VM strings
+     * @category Windows
+     */
+    [[nodiscard]] static bool hklm_registries() {
+#if (!MSVC)
+        return false;
+#else
+        u8 count = 0;
+
+        auto check_key = [&count](const char* p_brand, const char* subKey, const char* valueName, const char* comp_string) {
+            HKEY hKey;
+            DWORD dwType = REG_SZ;
+            char buffer[1024]{};
+            DWORD bufferSize = sizeof(buffer);
+
+            if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
+                if (RegQueryValueExA(hKey, valueName, NULL, &dwType, reinterpret_cast<LPBYTE>(buffer), &bufferSize) == ERROR_SUCCESS) {
+                    if (strcmp(buffer, comp_string) == 0) {
+                        core::add(p_brand);
+                        count++;
+                    }
+                } else {
+                    debug("Failed to query value for \"", subKey, "\"");
+                }
+
+                RegCloseKey(hKey);
+            } else {
+                debug("Failed to open registry key for \"", subKey, "\"");
+            }
+        };
+
+        check_key(BOCHS, "HARDWARE\\Description\\System", "SystemBiosVersion", "BOCHS");
+        check_key(BOCHS, "HARDWARE\\Description\\System", "VideoBiosVersion", "BOCHS");
+
+        check_key(ANUBIS, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductID", "76487-337-8429955-22614");
+        check_key(ANUBIS, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductID", "76487-337-8429955-22614");
+
+        check_key(CWSANDBOX, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductID", "76487-644-3177037-23510");
+        check_key(CWSANDBOX, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductID", "76487-644-3177037-23510");
+
+        check_key(JOEBOX, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductID", "55274-640-2673064-23950");
+        check_key(JOEBOX, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductID", "55274-640-2673064-23950");
+
+        check_key(PARALLELS, "HARDWARE\\Description\\System", "SystemBiosVersion", "PARALLELS");
+        check_key(PARALLELS, "HARDWARE\\Description\\System", "VideoBiosVersion", "PARALLELS");
+
+        check_key(QEMU, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "QEMU");
+        check_key(QEMU, "HARDWARE\\Description\\System", "SystemBiosVersion", "QEMU");
+        check_key(QEMU, "HARDWARE\\Description\\System", "VideoBiosVersion", "QEMU");
+        check_key(QEMU, "HARDWARE\\Description\\System\\BIOS", "SystemManufacturer", "QEMU");
+
+        check_key(VBOX, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VBOX");
+        check_key(VBOX, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VBOX");
+        check_key(VBOX, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 2\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VBOX");
+        check_key(VBOX, "HARDWARE\\Description\\System", "SystemBiosVersion", "VBOX");
+        check_key(VBOX, "HARDWARE\\Description\\System", "VideoBiosVersion", "VIRTUALBOX");
+        check_key(VBOX, "HARDWARE\\Description\\System\\BIOS", "SystemProductName", "VIRTUAL");
+        check_key(VBOX, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", "DeviceDesc", "VBOX");
+        check_key(VBOX, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", "FriendlyName", "VBOX");
+        check_key(VBOX, "SYSTEM\\ControlSet002\\Services\\Disk\\Enum", "DeviceDesc", "VBOX");
+        check_key(VBOX, "SYSTEM\\ControlSet002\\Services\\Disk\\Enum", "FriendlyName", "VBOX");
+        check_key(VBOX, "SYSTEM\\ControlSet003\\Services\\Disk\\Enum", "DeviceDesc", "VBOX");
+        check_key(VBOX, "SYSTEM\\ControlSet003\\Services\\Disk\\Enum", "FriendlyName", "VBOX");
+        check_key(VBOX, "SYSTEM\\CurrentControlSet\\Control\\SystemInformation", "SystemProductName", "VIRTUAL");
+        check_key(VBOX, "SYSTEM\\CurrentControlSet\\Control\\SystemInformation", "SystemProductName", "VIRTUALBOX");
+
+        check_key(VMWARE, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VMWARE");
+        check_key(VMWARE, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VMWARE");
+        check_key(VMWARE, "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 2\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", "Identifier", "VMWARE");
+        check_key(VMWARE, "HARDWARE\\Description\\System", "SystemBiosVersion", "VMWARE");
+        check_key(VMWARE, "HARDWARE\\Description\\System", "SystemBiosVersion", "INTEL - 6040000");
+        check_key(VMWARE, "HARDWARE\\Description\\System", "VideoBiosVersion", "VMWARE");
+        check_key(VMWARE, "HARDWARE\\Description\\System\\BIOS", "SystemProductName", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", "0", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", "1", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", "DeviceDesc", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", "FriendlyName", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet002\\Services\\Disk\\Enum", "DeviceDesc", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet002\\Services\\Disk\\Enum", "FriendlyName", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet003\\Services\\Disk\\Enum", "DeviceDesc", "VMware");
+        check_key(VMWARE, "SYSTEM\\ControlSet003\\Services\\Disk\\Enum", "FriendlyName", "VMware");
+        //check_key(HKCR\Installer\Products 	ProductName 	vmware tools
+        //check_key(HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall 	DisplayName 	vmware tools
+        check_key(VMWARE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", "DisplayName", "vmware tools");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000", "CoInstallers32", "*vmx*");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000", "DriverDesc", "VMware*");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000", "InfSection", "vmx*");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000", "ProviderName", "VMware*");
+        check_key(VMWARE, "SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000\\Settings", "Device Description", "VMware*");
+        check_key(VMWARE, "SYSTEM\\CurrentControlSet\\Control\\SystemInformation", "SystemProductName", "VMWARE");
+        check_key(VMWARE, "SYSTEM\\CurrentControlSet\\Control\\Video\\{GUID}\\Video", "Service", "vm3dmp");
+        check_key(VMWARE, "SYSTEM\\CurrentControlSet\\Control\\Video\\{GUID}\\Video", "Service", "vmx_svga");
+        check_key(VMWARE, "SYSTEM\\CurrentControlSet\\Control\\Video\\{GUID}\\0000", "Device Description", "VMware SVGA*");
+
+        check_key(XEN, "HARDWARE\\Description\\System\\BIOS", "SystemProductName", "Xen");
+
+        return (count > 0);
+#endif
+    }
+
+
+    /**
+     * @brief Check for "qemu-ga" process
+     * @category Linux
+     */
+    [[nodiscard]] static bool qemu_ga() {
+#if (!LINUX)
+        return false;
+#else
+        constexpr const char* process = "qemu-ga";
+
+        if (util::is_proc_running(process)) {
+            return core::add(QEMU);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for valid MSR value 0x40000000
+     * @category Windows
+     * @author LukeGoule
+     * @link https://github.com/LukeGoule/compact_vm_detector/tree/main
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool valid_msr() {
+    #if (!MSVC)
+            return false;  // Only valid on MSVC
+    #else
+            __try {
+                // Attempt to read the hypervisor MSR from Ring 3
+                __readmsr(0x40000000); // Reading MSR 0x40000000, which typically indicates hypervisor presence
+            }
+            __except (EXCEPTION_EXECUTE_HANDLER) {
+                // If an exception occurs, return false
+                return false;
+            }
+
+            // If we reached this point, the read was successful, so return true
+            return true;
+    #endif
+    }
+
+
+    /**
+     * @brief Check for QEMU processes
+     * @category Windows
+     */
+    [[nodiscard]] static bool qemu_processes() {
+#if (!MSVC)
+        return false;
+#else
+        constexpr std::array<const TCHAR*, 3> qemu_proc_strings = {{
+            _T("qemu-ga.exe"),
+            _T("vdagent.exe"),
+            _T("vdservice.exe")
+        }};
+
+        for (const auto str : qemu_proc_strings) {
+            if (util::is_proc_running(str)) {
+                return core::add(QEMU);
+            }
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VPC processes
+     * @category Windows
+     */
+    [[nodiscard]] static bool vpc_proc() {
+#if (!MSVC)
+        return false;
+#else
+        constexpr std::array<const TCHAR*, 2> vpc_proc_strings = {{
+            _T("VMSrvc.exe"),
+            _T("VMUSrvc.exe")
+        }};
+
+        for (const auto str : vpc_proc_strings) {
+            if (util::is_proc_running(str)) {
+                return core::add(VPC);
+            }
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for official VPC method
+     * @category Windows, x86
+     */
+    [[nodiscard]] static bool vpc_invalid() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        bool rc = false;
+
+        auto IsInsideVPC_exceptionFilter = [](PEXCEPTION_POINTERS ep) -> DWORD {
+            PCONTEXT ctx = ep->ContextRecord;
+
+            ctx->Ebx = static_cast<DWORD>(-1); // Not running VPC
+            ctx->Eip += 4; // skip past the "call VPC" opcodes
+            return static_cast<DWORD>(EXCEPTION_CONTINUE_EXECUTION);
+            // we can safely resume execution since we skipped faulty instruction
+            };
+
+        __try {
+            __asm {
+                push eax
+                push ebx
+                push ecx
+                push edx
+
+                mov ebx, 0h
+                mov eax, 01h
+
+                __emit 0Fh
+                __emit 3Fh
+                __emit 07h
+                __emit 0Bh
+
+                test ebx, ebx
+                setz[rc]
+
+                pop edx
+                pop ecx
+                pop ebx
+                pop eax
+            }
+        }
+        __except (IsInsideVPC_exceptionFilter(GetExceptionInformation())) {
+            rc = false;
+        }
+
+        return rc;
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for sidt instruction method
+     * @category Linux, Windows, x86
+     */
+    [[nodiscard]] static bool sidt() {
+        // gcc/g++ causes a stack smashing error at runtime for some reason
+        if (GCC) {
+            return false;
+        }
+
+        u8 idtr[10]{};
+        u32 idt_entry = 0;
+
+#if (MSVC)
+#   if (x86_32)
+        _asm sidt idtr
+#   elif (x86)
+#       pragma pack(1)
+        struct IDTR {
+            u16 limit;
+            u64 base;
+        };
+#       pragma pack()
+
+        IDTR idtrStruct;
+        __sidt(&idtrStruct);
+        std::memcpy(idtr, &idtrStruct, sizeof(IDTR));
+#   else
+        return false;
+#   endif
+
+        idt_entry = *reinterpret_cast<unsigned long*>(&idtr[2]);
+#elif (LINUX)
+        // false positive with root for some reason
+        if (util::is_admin()) {
+            return false;
+        }
+
+        struct IDTR {
+            u16 limit;
+            u32 base;
+        } __attribute__((packed));
+
+        IDTR idtr_struct;
+
+        __asm__ __volatile__(
+            "sidt %0"
+            : "=m" (idtr_struct)
+        );
+
+        std::ifstream mem("/dev/mem", std::ios::binary);
+        mem.seekg(idtr_struct.base + 8, std::ios::beg);
+        mem.read(reinterpret_cast<char*>(&idt_entry), sizeof(idt_entry));
+        mem.close();
+        UNUSED(idtr);
+#else
+        UNUSED(idtr);
+        UNUSED(idt_entry);
+        return false;
+#endif
+
+        if ((idt_entry >> 24) == 0xFF) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+    }
+
+
+    /**
+     * @brief Check for sgdt instruction method
+     * @category Windows, x86
+     */
+    [[nodiscard]] static bool sgdt() {
+#if (x86_32 && MSVC)
+        u8 gdtr[6]{};
+        u32 gdt = 0;
+
+        _asm sgdt gdtr
+        gdt = *((unsigned long*)&gdtr[2]);
+
+        return ((gdt >> 24) == 0xFF);
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for sldt instruction method
+     * @category Windows, x86
+     * @note code documentation paper in https://www.aldeid.com/wiki/X86-assembly/Instructions/sldt
+     */
+    [[nodiscard]] static bool sldt() {
+#if (x86_32 && MSVC)
+        unsigned char ldtr[5] = "\xef\xbe\xad\xde";
+        unsigned long ldt = 0;
+
+        __asm {
+            sldt word ptr ldtr  // 'word ptr' to indicate that we're working with a 16-bit value and avoid compiler warnings
+        }
+
+        ldt = *((unsigned long*)&ldtr[0]);
+
+        return (ldt != 0xdead0000);
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Offensive Security sidt method
+     * @category Windows, x86
+     * @author Danny Quist (chamuco@gmail.com)
+     * @author Val Smith (mvalsmith@metasploit.com)
+     * @note code documentation paper in /papers/www.offensivecomputing.net_vm.pdf
+     */
+    [[nodiscard]] static bool offsec_sidt() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        unsigned char m[6]{};
+        __asm sidt m;
+
+        return (m[5] > 0xD0);
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Offensive Security sgdt method
+     * @category Windows, x86
+     * @author Danny Quist (chamuco@gmail.com)
+     * @author Val Smith (mvalsmith@metasploit.com)
+     * @note code documentation paper in /papers/www.offensivecomputing.net_vm.pdf
+     */
+    [[nodiscard]] static bool offsec_sgdt() {
+#if (!MSVC || !x86 || GCC)
+        return false;
+#elif (x86_32)
+        unsigned char m[6]{};
+        __asm sgdt m;
+
+        return (m[5] > 0xD0);
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Offensive Security sldt method
+     * @category Windows, x86
+     * @author Danny Quist (chamuco@gmail.com)
+     * @author Val Smith (mvalsmith@metasploit.com)
+     * @note code documentation paper in /papers/www.offensivecomputing.net_vm.pdf
+     */
+    [[nodiscard]] static bool offsec_sldt() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        unsigned short m[6]{};
+        __asm sldt m;
+
+        return (m[0] != 0x00 && m[1] != 0x00);
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Hyper-V specific string in motherboard
+     * @category Windows
+     */
+    [[nodiscard]] static bool hyperv_board() {
+#if (!MSVC)
+        return false;
+#else
+        if (!wmi::initialize()) {
+            std::cerr << "Failed to initialize WMI.\n";
+            return false;
+        }
+
+        std::vector<wmi::result> results =
+            wmi::execute(L"SELECT * FROM Win32_BaseBoard", { L"Manufacturer" });
+
+        for (const auto& res : results) {
+            if (res.type == wmi::result_type::String) {
+                if (_stricmp(res.strValue.c_str(), "Microsoft Corporation Virtual Machine") == 0) {
+                    return core::add(HYPERV);
+                }
+            }
+        }
+
+        return false; // No match found
+#endif
+    }
+
+
+    /**
+     * @brief Check for VPC and Parallels files
+     * @category Windows
+     */
+    [[nodiscard]] static bool vm_files_extra() {
+#if (!MSVC)
+        return false;
+#else
+        constexpr std::array<std::pair<const char*, const char*>, 9> files = {{
+            { VPC, "c:\\windows\\system32\\drivers\\vmsrvc.sys" },
+            { VPC, "c:\\windows\\system32\\drivers\\vpc-s3.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prleth.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prlfs.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prlmouse.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prlvideo.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prltime.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prl_pv32.sys" },
+            { PARALLELS, "c:\\windows\\system32\\drivers\\prl_paravirt_32.sys" }
+        }};
+
+        for (const auto& file_pair : files) {
+            if (util::exists(file_pair.second)) {
+                return core::add(file_pair.first);
+            }
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for sidt method with VPC's 0xE8XXXXXX range
+     * @category Windows, x86
+     * @note Idea from Tom Liston and Ed Skoudis' paper "On the Cutting Edge: Thwarting Virtual Machine Detection"
+     * @note Paper situated at /papers/ThwartingVMDetection_Liston_Skoudis.pdf
+     */
+    [[nodiscard]] static bool vpc_sidt() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        u8	idtr[6]{};
+        u32	idt = 0;
+
+        _asm sidt idtr
+        idt = *((unsigned long*)&idtr[2]);
+
+        if ((idt >> 24) == 0xE8) {
+            return core::add(VPC);
+        }
+
+        return false;
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VMware string in /proc/iomem
+     * @category Linux
+     * @note idea from ScoopyNG by Tobias Klein
+     */
+    [[nodiscard]] static bool vmware_iomem() {
+#if (!LINUX)
+        return false;
+#else
+        const std::string iomem_file = util::read_file("/proc/iomem");
+
+        if (util::find(iomem_file, "VMware")) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VMware string in /proc/ioports
+     * @category Windows
+     * @note idea from ScoopyNG by Tobias Klein
+     */
+    [[nodiscard]] static bool vmware_ioports() {
+#if (!LINUX)
+        return false;
+#else
+        const std::string ioports_file = util::read_file("/proc/ioports");
+
+        if (util::find(ioports_file, "VMware")) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VMware string in /proc/scsi/scsi
+     * @category Windows
+     * @note idea from ScoopyNG by Tobias Klein
+     */
+    [[nodiscard]] static bool vmware_scsi() {
+#if (!LINUX)
+        return false;
+#else
+        const std::string scsi_file = util::read_file("/proc/scsi/scsi");
+
+        if (util::find(scsi_file, "VMware")) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VMware-specific device name in dmesg output
+     * @category Windows
+     * @note idea from ScoopyNG by Tobias Klein
+     */
+    [[nodiscard]] static bool vmware_dmesg() {
+#if (!LINUX)
+        return false;
+#else
+        if (!util::is_admin()) {
+            return false;
+        }
+
+        auto dmesg_output = util::sys_result("dmesg");
+        const std::string dmesg = *dmesg_output;
+
+        if (dmesg.empty()) {
+            return false;
+        }
+
+        if (util::find(dmesg, "BusLogic BT-958")) {
+            return core::add(VMWARE);
+        }
+
+        if (util::find(dmesg, "pcnet32")) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check str assembly instruction method for VMware
+     * @note Alfredo Omella's (S21sec) STR technique
+     * @note paper describing this technique is located at /papers/www.s21sec.com_vmware-eng.pdf (2006)
+     * @category Windows
+     */
+        [[nodiscard]] static bool vmware_str() {
+#if (MSVC && x86_32)
+        unsigned short tr = 0;
+        __asm {
+            str ax
+            mov tr, ax
+        }
+        if ((tr & 0xFF) == 0x00 && ((tr >> 8) & 0xFF) == 0x40) {
+            return core::add(VMWARE);
+        }
+#endif
+        return false;
+    }
+
+
+    /**
+     * @brief Check for official VMware io port backdoor technique
+     * @category Windows, x86
+     * @note Code from ScoopyNG by Tobias Klein
+     * @note Technique founded by Ken Kato
+     * @copyright BSD clause 2
+     */
+    [[nodiscard]] static bool vmware_backdoor() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        u32 a = 0;
+        u32 b = 0;
+
+        constexpr std::array<i16, 2> ioports = { 'VX' , 'VY' };
+        i16 ioport;
+        bool is_vm = false;
+
+        for (u8 i = 0; i < ioports.size(); ++i) {
+            ioport = ioports[i];
+            for (u8 cmd = 0; cmd < 0x2c; ++cmd) {
+                __try {
+                    __asm {
+                        push eax
+                        push ebx
+                        push ecx
+                        push edx
+
+                        mov eax, 'VMXh'
+                        movzx ecx, cmd
+                        mov dx, ioport
+                        in eax, dx      // <- key point is here
+
+                        mov a, ebx
+                        mov b, ecx
+
+                        pop edx
+                        pop ecx
+                        pop ebx
+                        pop eax
+                    }
+
+                    is_vm = true;
+                    break;
+                }
+                __except (EXCEPTION_EXECUTE_HANDLER) {}
+            }
+        }
+
+        if (is_vm) {
+            switch (b) {
+                case 1:  return core::add(VMWARE_EXPRESS);
+                case 2:  return core::add(VMWARE_ESX);
+                case 3:  return core::add(VMWARE_GSX);
+                case 4:  return core::add(VMWARE_WORKSTATION);
+                default: return core::add(VMWARE);
+            }
+        }
+#endif
+        return false;
+    }
+
+
+    /**
+     * @brief Check for VMware memory using IO port backdoor
+     * @category Windows, x86
+     * @note Code from ScoopyNG by Tobias Klein
+     * @copyright BSD clause 2
+     */
+    [[nodiscard]] static bool vmware_port_memory() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        unsigned int a = 0;
+
+        __try {
+            __asm {
+                push eax
+                push ebx
+                push ecx
+                push edx
+
+                mov eax, 'VMXh'
+                mov ecx, 14h
+                mov dx, 'VX'
+                in eax, dx
+                mov a, eax
+
+                pop edx
+                pop ecx
+                pop ebx
+                pop eax
+            }
+        }
+        __except (EXCEPTION_EXECUTE_HANDLER) {}
+
+        if (a > 0) {
+            return core::add(VMWARE);
+        }
+
+        return false;
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for SMSW assembly instruction technique
+     * @category Windows, x86
+     * @author Danny Quist from Offensive Computing
+     */
+    [[nodiscard]] static bool smsw() {
+#if (!MSVC || !x86)
+        return false;
+#elif (x86_32)
+        unsigned int reax = 0;
+
+        __asm
+        {
+            mov eax, 0xCCCCCCCC;
+            smsw eax;
+            mov DWORD PTR[reax], eax;
+        }
+
+        return (
+            (((reax >> 24) & 0xFF) == 0xCC) &&
+            (((reax >> 16) & 0xFF) == 0xCC)
+        );
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for mutex strings of VM brands
+     * @category Windows, x86
+     * @note from VMDE project
+     * @author hfiref0x
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool mutex() {
+#if (!MSVC)
+        return false;
+#else
+        auto supMutexExist = [](const char* lpMutexName) -> bool {
+            DWORD dwError;
+            HANDLE hObject = NULL;
+            if (lpMutexName == NULL) {
+                return false;
+            }
+
+            SetLastError(0);
+            hObject = CreateMutexA(NULL, FALSE, lpMutexName);
+            dwError = GetLastError();
+
+            if (hObject) {
+                CloseHandle(hObject);
+            }
+
+            return (dwError == ERROR_ALREADY_EXISTS);
+        };
+
+        if (
+            supMutexExist("Sandboxie_SingleInstanceMutex_Control") ||
+            supMutexExist("SBIE_BOXED_ServiceInitComplete_Mutex1")
+        ) {
+            return core::add(SANDBOXIE);
+        }
+
+        if (supMutexExist("MicrosoftVirtualPC7UserServiceMakeSureWe'reTheOnlyOneMutex")) {
+            return core::add(VPC);
+        }
+
+        if (supMutexExist("Frz_State")) {
+            return true;
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if uptime is less than or equal to 2 minutes
+     * @category Windows, Linux
+     * @note https://stackoverflow.com/questions/30095439/how-do-i-get-system-up-time-in-milliseconds-in-c
+     */
+    [[nodiscard]] static bool uptime() {
+        constexpr u32 uptime_ms = 1000 * 60 * 2;
+        constexpr u32 uptime_s = 60 * 2;
+
+#if (MSVC)
+        UNUSED(uptime_s);
+        return (GetTickCount64() <= uptime_ms);
+#elif (LINUX)
+        UNUSED(uptime_ms);
+        struct sysinfo info;
+
+        if (sysinfo(&info) != 0) {
+            debug("UPTIME: sysinfo failed");
+            return false;
+        }
+
+        return (info.uptime < uptime_s);
+#elif (APPLE)
+        UNUSED(uptime_s);
+        std::chrono::milliseconds uptime(0u);
+
+        struct timeval ts;
+        std::size_t len = sizeof(ts);
+
+        int mib[2] = { CTL_KERN, KERN_BOOTTIME };
+
+        if (sysctl(mib, 2, &ts, &len, NULL, 0) != 0) {
+            return false;
+        }
+
+        uptime = std::chrono::milliseconds(
+            (static_cast<u64>(ts.tv_sec) * 1000ULL) +
+            (static_cast<u64>(ts.tv_usec) / 1000ULL)
+        );
+
+        return (uptime < uptime_ms);
+#else
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for odd CPU threads, usually a sign of modification through VM setting because 99% of CPUs have even numbers of threads
+     * @category All, x86
+     */
+    [[nodiscard]] static bool odd_cpu_threads() {
+#if (!x86)
+        return false;
+#else
+        const u32 threads = std::thread::hardware_concurrency();
+
+        struct cpu::stepping_struct steps = cpu::fetch_steppings();
+
+        debug("ODD_CPU_THREADS: model    = ", static_cast<u32>(steps.model));
+        debug("ODD_CPU_THREADS: family   = ", static_cast<u32>(steps.family));
+        debug("ODD_CPU_THREADS: extmodel = ", static_cast<u32>(steps.extmodel));
+
+        // check if the microarchitecture was made before 2006, which was around the time multi-core processors were implemented
+        auto old_microarchitecture = [&steps]() -> bool {
+            constexpr std::array<std::array<u8, 3>, 32> old_archs = {{
+                // 80486
+                {{ 0x4, 0x0, 0x1 }},
+                {{ 0x4, 0x0, 0x2 }},
+                {{ 0x4, 0x0, 0x3 }},
+                {{ 0x4, 0x0, 0x4 }},
+                {{ 0x4, 0x0, 0x5 }},
+                {{ 0x4, 0x0, 0x7 }},
+                {{ 0x4, 0x0, 0x8 }},
+                {{ 0x4, 0x0, 0x9 }},
+
+                // P5
+                {{ 0x5, 0x0, 0x1 }},
+                {{ 0x5, 0x0, 0x2 }},
+                {{ 0x5, 0x0, 0x4 }},
+                {{ 0x5, 0x0, 0x7 }},
+                {{ 0x5, 0x0, 0x8 }},
+
+                // P6
+                {{ 0x6, 0x0, 0x1 }},
+                {{ 0x6, 0x0, 0x3 }},
+                {{ 0x6, 0x0, 0x5 }},
+                {{ 0x6, 0x0, 0x6 }},
+                {{ 0x6, 0x0, 0x7 }},
+                {{ 0x6, 0x0, 0x8 }},
+                {{ 0x6, 0x0, 0xA }},
+                {{ 0x6, 0x0, 0xB }},
+
+                // Netburst
+                {{ 0xF, 0x0, 0x6 }},
+                {{ 0xF, 0x0, 0x4 }},
+                {{ 0xF, 0x0, 0x3 }},
+                {{ 0xF, 0x0, 0x2 }},
+                {{ 0xF, 0x0, 0x10 }},
+
+                {{ 0x6, 0x1, 0x5 }}, // Pentium M (Talopai)
+                {{ 0x6, 0x1, 0x6 }}, // Core (Client)
+                {{ 0x6, 0x0, 0x9 }}, // Pentium M
+                {{ 0x6, 0x0, 0xD }}, // Pentium M
+                {{ 0x6, 0x0, 0xE }}, // Modified Pentium M
+                {{ 0x6, 0x0, 0xF }}  // Core (Client)
+            }};
+
+            constexpr u8 FAMILY = 0;
+            constexpr u8 EXTMODEL = 1;
+            constexpr u8 MODEL = 2;
+
+            for (const auto& arch : old_archs) {
+                if (
+                    steps.family == arch.at(FAMILY) &&
+                    steps.extmodel == arch.at(EXTMODEL) &&
+                    steps.model == arch.at(MODEL)
+                    ) {
+                    return true;
+                }
+            }
+
+            return false;
+        };
+
+        // self-explanatory
+        if (!(cpu::is_intel() || cpu::is_amd())) {
+            return false;
+        }
+
+        // intel celeron CPUs are relatively modern, but they can contain a single or odd thread count
+        if (cpu::is_celeron(steps)) {
+            return false;
+        }
+
+        // CPUs before 2006 had no official multi-core processors
+        if (old_microarchitecture()) {
+            return false;
+        }
+
+        // is the count odd?
+        return (threads & 1);
+#endif
+    }
+
+
+    /**
+     * @brief Check for Intel CPU thread count database if it matches the system's thread count
+     * @category All, x86
+     * @link https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
+     */
+    [[nodiscard]] static bool intel_thread_mismatch() {
+#if (!x86)
+        return false;
+#else
+        if (!cpu::is_intel()) {
+            return false;
+        }
+
+        if (cpu::has_hyperthreading()) {
+            return false;
+        }
+
+        const cpu::model_struct model = cpu::get_model();
+
+        if (!model.found) {
+            return false;
+        }
+
+        if (!model.is_i_series) {
+            return false;
+        }
+
+        debug("INTEL_THREAD_MISMATCH: CPU model = ", model.string);
+
+        auto thread_database = util::make_unique<std::unordered_map<std::string, uint8_t>>();
+
+        auto push = [&thread_database](const char* brand_str, const u8 thread_count) -> void {
+            thread_database->emplace(brand_str, thread_count);
+        };
+
+        // i3 series
+        push("i3-1000G1", 4);
+        push("i3-1000G4", 4);
+        push("i3-1000NG4", 4);
+        push("i3-1005G1", 4);
+        push("i3-10100", 8);
+        push("i3-10100E", 8);
+        push("i3-10100F", 8);
+        push("i3-10100T", 8);
+        push("i3-10100TE", 8);
+        push("i3-10100Y", 4);
+        push("i3-10105", 8);
+        push("i3-10105F", 8);
+        push("i3-10105T", 8);
+        push("i3-10110U", 4);
+        push("i3-10110Y", 4);
+        push("i3-10300", 8);
+        push("i3-10300T", 8);
+        push("i3-10305", 8);
+        push("i3-10305T", 8);
+        push("i3-10320", 8);
+        push("i3-10325", 8);
+        push("i3-11100B", 8);
+        push("i3-11100HE", 8);
+        push("i3-1110G4", 4);
+        push("i3-1115G4E", 4);
+        push("i3-1115GRE", 4);
+        push("i3-1120G4", 8);
+        push("i3-12100", 8);
+        push("i3-12100F", 8);
+        push("i3-12100T", 8);
+        push("i3-1210U", 4);
+        push("i3-1215U", 4);
+        push("i3-1215UE", 4);
+        push("i3-1215UL", 4);
+        push("i3-12300", 8);
+        push("i3-12300T", 8);
+        push("i3-13100", 8);
+        push("i3-13100F", 8);
+        push("i3-13100T", 8);
+        push("i3-1315U", 4);
+        push("i3-1315UE", 4);
+        push("i3-14100", 8);
+        push("i3-14100F", 8);
+        push("i3-14100T", 8);
+        push("i3-2100", 4);
+        push("i3-2100T", 4);
+        push("i3-2102", 4);
+        push("i3-2105", 4);
+        push("i3-2120", 4);
+        push("i3-2120T", 4);
+        push("i3-2125", 4);
+        push("i3-2130", 4);
+        push("i3-2308M", 4);
+        push("i3-2310E", 4);
+        push("i3-2310M", 4);
+        push("i3-2312M", 4);
+        push("i3-2328M", 4);
+        push("i3-2330E", 4);
+        push("i3-2330M", 4);
+        push("i3-2332M", 4);
+        push("i3-2340UE", 4);
+        push("i3-2348M", 4);
+        push("i3-2350LM", 4);
+        push("i3-2350M", 4);
+        push("i3-2355M", 4);
+        push("i3-2357M", 4);
+        push("i3-2365M", 4);
+        push("i3-2367M", 4);
+        push("i3-2370LM", 4);
+        push("i3-2370M", 4);
+        push("i3-2375M", 4);
+        push("i3-2377M", 4);
+        push("i3-2390M", 4);
+        push("i3-2393M", 4);
+        push("i3-2394M", 4);
+        push("i3-2395M", 4);
+        push("i3-2397M", 4);
+        push("i3-3110M", 4);
+        push("i3-3115C", 4);
+        push("i3-3120M", 4);
+        push("i3-3120ME", 4);
+        push("i3-3130M", 4);
+        push("i3-3210", 4);
+        push("i3-3217U", 4);
+        push("i3-3217UE", 4);
+        push("i3-3220", 4);
+        push("i3-3220T", 4);
+        push("i3-3225", 4);
+        push("i3-3227U", 4);
+        push("i3-3229Y", 4);
+        push("i3-3240", 4);
+        push("i3-3240T", 4);
+        push("i3-3245", 4);
+        push("i3-3250", 4);
+        push("i3-3250T", 4);
+        push("i3-330E", 4);
+        push("i3-330M", 4);
+        push("i3-330UM", 4);
+        push("i3-350M", 4);
+        push("i3-370M", 4);
+        push("i3-380M", 4);
+        push("i3-380UM", 4);
+        push("i3-390M", 4);
+        push("i3-4000M", 4);
+        push("i3-4005U", 4);
+        push("i3-4010M", 4);
+        push("i3-4010U", 4);
+        push("i3-4010Y", 4);
+        push("i3-4012Y", 4);
+        push("i3-4020Y", 4);
+        push("i3-4025U", 4);
+        push("i3-4030U", 4);
+        push("i3-4030Y", 4);
+        push("i3-4100E", 4);
+        push("i3-4100M", 4);
+        push("i3-4100U", 4);
+        push("i3-4102E", 4);
+        push("i3-4110E", 4);
+        push("i3-4110M", 4);
+        push("i3-4112E", 4);
+        push("i3-4120U", 4);
+        push("i3-4130", 4);
+        push("i3-4130T", 4);
+        push("i3-4150", 4);
+        push("i3-4150T", 4);
+        push("i3-4158U", 4);
+        push("i3-4160", 4);
+        push("i3-4160T", 4);
+        push("i3-4170", 4);
+        push("i3-4170T", 4);
+        push("i3-4330", 4);
+        push("i3-4330T", 4);
+        push("i3-4330TE", 4);
+        push("i3-4340", 4);
+        push("i3-4340TE", 4);
+        push("i3-4350", 4);
+        push("i3-4350T", 4);
+        push("i3-4360", 4);
+        push("i3-4360T", 4);
+        push("i3-4370", 4);
+        push("i3-4370T", 4);
+        push("i3-5005U", 4);
+        push("i3-5010U", 4);
+        push("i3-5015U", 4);
+        push("i3-5020U", 4);
+        push("i3-5157U", 4);
+        push("i3-530", 4);
+        push("i3-540", 4);
+        push("i3-550", 4);
+        push("i3-560", 4);
+        push("i3-6006U", 4);
+        push("i3-6098P", 4);
+        push("i3-6100", 4);
+        push("i3-6100E", 4);
+        push("i3-6100H", 4);
+        push("i3-6100T", 4);
+        push("i3-6100TE", 4);
+        push("i3-6100U", 4);
+        push("i3-6102E", 4);
+        push("i3-6120T", 4);
+        push("i3-6157U", 4);
+        push("i3-6167U", 4);
+        push("i3-6300", 4);
+        push("i3-6300T", 4);
+        push("i3-6320", 4);
+        push("i3-6320T", 4);
+        push("i3-7007U", 4);
+        push("i3-7020U", 4);
+        push("i3-7100", 4);
+        push("i3-7100E", 4);
+        push("i3-7100H", 4);
+        push("i3-7100T", 4);
+        push("i3-7100U", 4);
+        push("i3-7101E", 4);
+        push("i3-7101TE", 4);
+        push("i3-7102E", 4);
+        push("i3-7110U", 4);
+        push("i3-7120", 4);
+        push("i3-7120T", 4);
+        push("i3-7130U", 4);
+        push("i3-7167U", 4);
+        push("i3-7300", 4);
+        push("i3-7300T", 4);
+        push("i3-7310T", 4);
+        push("i3-7310U", 4);
+        push("i3-7320", 4);
+        push("i3-7320T", 4);
+        push("i3-7340", 4);
+        push("i3-7350K", 4);
+        push("i3-8000", 4);
+        push("i3-8000T", 4);
+        push("i3-8020", 4);
+        push("i3-8020T", 4);
+        push("i3-8100", 4);
+        push("i3-8100B", 4);
+        push("i3-8100F", 4);
+        push("i3-8100H", 4);
+        push("i3-8100T", 4);
+        push("i3-8109U", 4);
+        push("i3-8120", 4);
+        push("i3-8120T", 4);
+        push("i3-8121U", 4);
+        push("i3-8130U", 4);
+        push("i3-8130U", 4);
+        push("i3-8140U", 4);
+        push("i3-8145U", 4);
+        push("i3-8145UE", 4);
+        push("i3-8300", 4);
+        push("i3-8300T", 4);
+        push("i3-8320", 4);
+        push("i3-8320T", 4);
+        push("i3-8350K", 4);
+        push("i3-9100", 4);
+        push("i3-9100E", 4);
+        push("i3-9100F", 4);
+        push("i3-9100HL", 4);
+        push("i3-9100T", 4);
+        push("i3-9100TE", 4);
+        push("i3-9300", 4);
+        push("i3-9300T", 4);
+        push("i3-9320", 4);
+        push("i3-9350K", 4);
+        push("i3-9350KF", 4);
+        push("i3-N300", 8);
+        push("i3-N305", 8);
+
+        // i5 series
+        push("i5-10200H", 8);
+        push("i5-10210U", 4);
+        push("i5-10210Y", 8);
+        push("i5-10300H", 8);
+        push("i5-1030G4", 8);
+        push("i5-1030G7", 8);
+        push("i5-1030NG7", 8);
+        push("i5-10310U", 4);
+        push("i5-10310Y", 8);
+        push("i5-1035G1", 8);
+        push("i5-1035G4", 8);
+        push("i5-1035G7", 8);
+        push("i5-1038NG7", 8);
+        push("i5-10400", 12);
+        push("i5-10400F", 12);
+        push("i5-10400H", 8);
+        push("i5-10400T", 12);
+        push("i5-10500", 12);
+        push("i5-10500E", 12);
+        push("i5-10500H", 12);
+        push("i5-10500T", 12);
+        push("i5-10500TE", 12);
+        push("i5-10505", 12);
+        push("i5-10600", 12);
+        push("i5-10600K", 12);
+        push("i5-10600KF", 12);
+        push("i5-10600T", 12);
+        push("i5-1115G4", 4);
+        push("i5-1125G4", 8);
+        push("i5-11260H", 12);
+        push("i5-11300H", 8);
+        push("i5-1130G7", 8);
+        push("i5-11320H", 8);
+        push("i5-1135G7", 8);
+        push("i5-11400", 12);
+        push("i5-11400F", 12);
+        push("i5-11400H", 12);
+        push("i5-11400T", 12);
+        push("i5-1140G7", 8);
+        push("i5-1145G7", 8);
+        push("i5-1145G7E", 8);
+        push("i5-1145GRE", 8);
+        push("i5-11500", 12);
+        push("i5-11500B", 12);
+        push("i5-11500H", 12);
+        push("i5-11500HE", 12);
+        push("i5-11500T", 12);
+        push("i5-1155G7", 8);
+        push("i5-11600", 12);
+        push("i5-11600K", 12);
+        push("i5-11600KF", 12);
+        push("i5-11600T", 12);
+        push("i5-1230U", 4);
+        push("i5-1235U", 4);
+        push("i5-12400", 12);
+        push("i5-12400F", 12);
+        push("i5-12400T", 12);
+        push("i5-1240P", 8);
+        push("i5-1240U", 4);
+        push("i5-1245U", 4);
+        push("i5-12490F", 12);
+        push("i5-12500", 12);
+        push("i5-12500H", 8);
+        push("i5-12500HL", 8);
+        push("i5-12500T", 12);
+        push("i5-1250P", 8);
+        push("i5-1250PE", 8);
+        push("i5-12600", 12);
+        push("i5-12600H", 8);
+        push("i5-12600HE", 8);
+        push("i5-12600HL", 8);
+        push("i5-12600HX", 8);
+        push("i5-12600K", 12);
+        push("i5-12600KF", 12);
+        push("i5-12600T", 12);
+        push("i5-13400", 12);
+        push("i5-13400F", 12);
+        push("i5-13400T", 12);
+        push("i5-1340P", 8);
+        push("i5-1340PE", 8);
+        push("i5-13490F", 12);
+        push("i5-13500", 12);
+        push("i5-13500H", 8);
+        push("i5-13500T", 12);
+        push("i5-13505H", 8);
+        push("i5-1350P", 8);
+        push("i5-1350PE", 8);
+        push("i5-13600", 12);
+        push("i5-13600H", 8);
+        push("i5-13600HE", 8);
+        push("i5-13600K", 12);
+        push("i5-13600K", 20);
+        push("i5-13600KF", 12);
+        push("i5-13600KF", 20);
+        push("i5-13600T", 12);
+        push("i5-2300", 4);
+        push("i5-2310", 4);
+        push("i5-2320", 4);
+        push("i5-2380P", 4);
+        push("i5-2390T", 4);
+        push("i5-2400", 4);
+        push("i5-2400S", 4);
+        push("i5-2405S", 4);
+        push("i5-2410M", 4);
+        push("i5-2415M", 4);
+        push("i5-2430M", 4);
+        push("i5-2435M", 4);
+        push("i5-2450M", 4);
+        push("i5-2450P", 4);
+        push("i5-2467M", 4);
+        push("i5-2475M", 4);
+        push("i5-2477M", 4);
+        push("i5-2487M", 4);
+        push("i5-2490M", 4);
+        push("i5-2497M", 4);
+        push("i5-2500", 4);
+        push("i5-2500K", 4);
+        push("i5-2500S", 4);
+        push("i5-2500T", 4);
+        push("i5-2510E", 4);
+        push("i5-2515E", 4);
+        push("i5-2520M", 4);
+        push("i5-2537M", 4);
+        push("i5-2540LM", 4);
+        push("i5-2540M", 4);
+        push("i5-2547M", 4);
+        push("i5-2550K", 4);
+        push("i5-2557M", 4);
+        push("i5-2560LM", 4);
+        push("i5-2560M", 4);
+        push("i5-2580M", 4);
+        push("i5-3210M", 4);
+        push("i5-3230M", 4);
+        push("i5-3317U", 4);
+        push("i5-3320M", 4);
+        push("i5-3330", 4);
+        push("i5-3330S", 4);
+        push("i5-3335S", 4);
+        push("i5-3337U", 4);
+        push("i5-3339Y", 4);
+        push("i5-3340", 4);
+        push("i5-3340M", 4);
+        push("i5-3340S", 4);
+        push("i5-3350P", 4);
+        push("i5-3360M", 4);
+        push("i5-3380M", 4);
+        push("i5-3427U", 4);
+        push("i5-3437U", 4);
+        push("i5-3439Y", 4);
+        push("i5-3450", 4);
+        push("i5-3450S", 4);
+        push("i5-3470", 4);
+        push("i5-3470S", 4);
+        push("i5-3470T", 4);
+        push("i5-3475S", 4);
+        push("i5-3550", 4);
+        push("i5-3550S", 4);
+        push("i5-3570", 4);
+        push("i5-3570K", 4);
+        push("i5-3570S", 4);
+        push("i5-3570T", 4);
+        push("i5-3610ME", 4);
+        push("i5-4200H", 4);
+        push("i5-4200M", 4);
+        push("i5-4200U", 4);
+        push("i5-4200Y", 4);
+        push("i5-4202Y", 4);
+        push("i5-4210H", 4);
+        push("i5-4210M", 4);
+        push("i5-4210U", 4);
+        push("i5-4210Y", 4);
+        push("i5-4220Y", 4);
+        push("i5-4250U", 4);
+        push("i5-4258U", 4);
+        push("i5-4260U", 4);
+        push("i5-4278U", 4);
+        push("i5-4288U", 4);
+        push("i5-4300M", 4);
+        push("i5-4300U", 4);
+        push("i5-4300Y", 4);
+        push("i5-4302Y", 4);
+        push("i5-4308U", 4);
+        push("i5-430M", 4);
+        push("i5-430UM", 4);
+        push("i5-4310M", 4);
+        push("i5-4310U", 4);
+        push("i5-4330M", 4);
+        push("i5-4340M", 4);
+        push("i5-4350U", 4);
+        push("i5-4360U", 4);
+        push("i5-4400E", 4);
+        push("i5-4402E", 4);
+        push("i5-4402EC", 4);
+        push("i5-4410E", 4);
+        push("i5-4422E", 4);
+        push("i5-4430", 4);
+        push("i5-4430S", 4);
+        push("i5-4440", 4);
+        push("i5-4440S", 4);
+        push("i5-4460", 4);
+        push("i5-4460S", 4);
+        push("i5-4460T", 4);
+        push("i5-4470", 4);
+        push("i5-450M", 4);
+        push("i5-4570", 4);
+        push("i5-4570R", 4);
+        push("i5-4570S", 4);
+        push("i5-4570T", 4);
+        push("i5-4570TE", 4);
+        push("i5-4590", 4);
+        push("i5-4590S", 4);
+        push("i5-4590T", 4);
+        push("i5-460M", 4);
+        push("i5-4670", 4);
+        push("i5-4670K", 4);
+        push("i5-4670R", 4);
+        push("i5-4670S", 4);
+        push("i5-4670T", 4);
+        push("i5-4690", 4);
+        push("i5-4690K", 4);
+        push("i5-4690S", 4);
+        push("i5-4690T", 4);
+        push("i5-470UM", 4);
+        push("i5-480M", 4);
+        push("i5-5200U", 4);
+        push("i5-520E", 4);
+        push("i5-520M", 4);
+        push("i5-520UM", 4);
+        push("i5-5250U", 4);
+        push("i5-5257U", 4);
+        push("i5-5287U", 4);
+        push("i5-5300U", 4);
+        push("i5-5350H", 4);
+        push("i5-5350U", 4);
+        push("i5-540M", 4);
+        push("i5-540UM", 4);
+        push("i5-5575R", 4);
+        push("i5-560M", 4);
+        push("i5-560UM", 4);
+        push("i5-5675C", 4);
+        push("i5-5675R", 4);
+        push("i5-580M", 4);
+        push("i5-6198DU", 4);
+        push("i5-6200U", 4);
+        push("i5-6260U", 4);
+        push("i5-6267U", 4);
+        push("i5-6287U", 4);
+        push("i5-6300HQ", 4);
+        push("i5-6300U", 4);
+        push("i5-6350HQ", 4);
+        push("i5-6360U", 4);
+        push("i5-6400", 4);
+        push("i5-6400T", 4);
+        push("i5-6402P", 4);
+        push("i5-6440EQ", 4);
+        push("i5-6440HQ", 4);
+        push("i5-6442EQ", 4);
+        push("i5-650", 4);
+        push("i5-6500", 4);
+        push("i5-6500T", 4);
+        push("i5-6500TE", 4);
+        push("i5-655K", 4);
+        push("i5-6585R", 4);
+        push("i5-660", 4);
+        push("i5-6600", 4);
+        push("i5-6600K", 4);
+        push("i5-6600T", 4);
+        push("i5-661", 4);
+        push("i5-6685R", 4);
+        push("i5-670", 4);
+        push("i5-680", 4);
+        push("i5-7200U", 4);
+        push("i5-7210U", 4);
+        push("i5-7260U", 4);
+        push("i5-7267U", 4);
+        push("i5-7287U", 4);
+        push("i5-7300HQ", 4);
+        push("i5-7300U", 4);
+        push("i5-7360U", 4);
+        push("i5-7400", 4);
+        push("i5-7400T", 4);
+        push("i5-7440EQ", 4);
+        push("i5-7440HQ", 4);
+        push("i5-7442EQ", 4);
+        push("i5-750", 4);
+        push("i5-7500", 4);
+        push("i5-7500T", 4);
+        push("i5-750S", 4);
+        push("i5-760", 4);
+        push("i5-7600", 4);
+        push("i5-7600K", 4);
+        push("i5-7600T", 4);
+        push("i5-7640X", 4);
+        push("i5-7Y54", 4);
+        push("i5-7Y57", 4);
+        push("i5-8200Y", 4);
+        push("i5-8210Y", 4);
+        push("i5-8250U", 8);
+        push("i5-8257U", 8);
+        push("i5-8259U", 8);
+        push("i5-8260U", 8);
+        push("i5-8265U", 8);
+        push("i5-8269U", 8);
+        push("i5-8279U", 8);
+        push("i5-8300H", 8);
+        push("i5-8305G", 8);
+        push("i5-8310Y", 4);
+        push("i5-8350U", 8);
+        push("i5-8365U", 8);
+        push("i5-8365UE", 8);
+        push("i5-8400", 6);
+        push("i5-8400B", 6);
+        push("i5-8400H", 8);
+        push("i5-8400T", 6);
+        push("i5-8420", 6);
+        push("i5-8420T", 6);
+        push("i5-8500", 6);
+        push("i5-8500B", 6);
+        push("i5-8500T", 6);
+        push("i5-8550", 6);
+        push("i5-8600", 6);
+        push("i5-8600K", 6);
+        push("i5-8600T", 6);
+        push("i5-8650", 6);
+        push("i5-9300H", 8);
+        push("i5-9300HF", 8);
+        push("i5-9400", 6);
+        push("i5-9400F", 6);
+        push("i5-9400H", 8);
+        push("i5-9400T", 6);
+        push("i5-9500", 6);
+        push("i5-9500E", 6);
+        push("i5-9500F", 6);
+        push("i5-9500T", 6);
+        push("i5-9500TE", 6);
+        push("i5-9600", 6);
+        push("i5-9600K", 6);
+        push("i5-9600KF", 6);
+        push("i5-9600T", 6);
+
+        // i7 series
+        push("i7-10510U", 8);
+        push("i7-10510Y", 8);
+        push("i7-1060G7", 8);
+        push("i7-10610U", 8);
+        push("i7-1065G7", 8);
+        push("i7-1068G7", 8);
+        push("i7-1068NG7", 8);
+        push("i7-10700", 16);
+        push("i7-10700E", 16);
+        push("i7-10700F", 16);
+        push("i7-10700K", 16);
+        push("i7-10700KF", 16);
+        push("i7-10700T", 16);
+        push("i7-10700TE", 16);
+        push("i7-10710U", 8);
+        push("i7-10750H", 12);
+        push("i7-10810U", 12);
+        push("i7-10850H", 12);
+        push("i7-10870H", 16);
+        push("i7-10875H", 16);
+        push("i7-11370H", 8);
+        push("i7-11375H", 8);
+        push("i7-11390H", 8);
+        push("i7-11600H", 12);
+        push("i7-1160G7", 8);
+        push("i7-1165G7", 8);
+        push("i7-11700", 16);
+        push("i7-11700B", 16);
+        push("i7-11700F", 16);
+        push("i7-11700K", 16);
+        push("i7-11700KF", 16);
+        push("i7-11700T", 16);
+        push("i7-11800H", 16);
+        push("i7-1180G7", 8);
+        push("i7-11850H", 16);
+        push("i7-11850HE", 16);
+        push("i7-1185G7", 8);
+        push("i7-1185G7E", 8);
+        push("i7-1185GRE", 8);
+        push("i7-1195G7", 8);
+        push("i7-1250U", 4);
+        push("i7-1255U", 4);
+        push("i7-1260P", 8);
+        push("i7-1260U", 4);
+        push("i7-1265U", 4);
+        push("i7-12700", 16);
+        push("i7-12700F", 16);
+        push("i7-12700KF", 16);
+        push("i7-12700T", 16);
+        push("i7-1270P", 8);
+        push("i7-1270PE", 8);
+        push("i7-1360P", 8);
+        push("i7-13700", 16);
+        push("i7-13700F", 16);
+        push("i7-13700K", 16);
+        push("i7-13700KF", 16);
+        push("i7-13700T", 16);
+        push("i7-13790F", 16);
+        push("i7-2535QM", 8);
+        push("i7-2570QM", 8);
+        push("i7-2600", 8);
+        push("i7-2600K", 8);
+        push("i7-2600S", 8);
+        push("i7-2610UE", 4);
+        push("i7-2617M", 4);
+        push("i7-2620M", 4);
+        push("i7-2627M", 4);
+        push("i7-2629M", 4);
+        push("i7-2630QM", 8);
+        push("i7-2635QM", 8);
+        push("i7-2637M", 4);
+        push("i7-2640M", 4);
+        push("i7-2649M", 4);
+        push("i7-2655LE", 4);
+        push("i7-2655QM", 8);
+        push("i7-2657M", 4);
+        push("i7-2660M", 4);
+        push("i7-2667M", 4);
+        push("i7-2669M", 4);
+        push("i7-2670QM", 8);
+        push("i7-2675QM", 8);
+        push("i7-2677M", 4);
+        push("i7-2685QM", 8);
+        push("i7-2689M", 4);
+        push("i7-2700K", 8);
+        push("i7-2710QE", 8);
+        push("i7-2715QE", 8);
+        push("i7-2720QM", 8);
+        push("i7-2740QM", 8);
+        push("i7-2760QM", 8);
+        push("i7-2820QM", 8);
+        push("i7-2840QM", 8);
+        push("i7-2860QM", 8);
+        push("i7-2920XM", 8);
+        push("i7-2960XM", 8);
+        push("i7-3517U", 4);
+        push("i7-3517UE", 4);
+        push("i7-3520M", 4);
+        push("i7-3537U", 4);
+        push("i7-3540M", 4);
+        push("i7-3555LE", 4);
+        push("i7-3610QE", 8);
+        push("i7-3610QM", 8);
+        push("i7-3612QE", 8);
+        push("i7-3612QM", 8);
+        push("i7-3615QE", 8);
+        push("i7-3615QM", 8);
+        push("i7-3630QM", 8);
+        push("i7-3632QM", 8);
+        push("i7-3635QM", 8);
+        push("i7-3667U", 4);
+        push("i7-3687U", 4);
+        push("i7-3689Y", 4);
+        push("i7-3720QM", 8);
+        push("i7-3740QM", 8);
+        push("i7-3770", 8);
+        push("i7-3770K", 8);
+        push("i7-3770S", 8);
+        push("i7-3770T", 8);
+        push("i7-3820", 8);
+        push("i7-3820QM", 8);
+        push("i7-3840QM", 8);
+        push("i7-3920XM", 8);
+        push("i7-3930K", 12);
+        push("i7-3940XM", 8);
+        push("i7-3960X", 12);
+        push("i7-3970X", 12);
+        push("i7-4500U", 4);
+        push("i7-4510U", 4);
+        push("i7-4550U", 4);
+        push("i7-4558U", 4);
+        push("i7-4578U", 4);
+        push("i7-4600M", 4);
+        push("i7-4600U", 4);
+        push("i7-4610M", 8);
+        push("i7-4610Y", 4);
+        push("i7-4650U", 4);
+        push("i7-4700EC", 8);
+        push("i7-4700EQ", 8);
+        push("i7-4700HQ", 8);
+        push("i7-4700MQ", 8);
+        push("i7-4701EQ", 8);
+        push("i7-4702EC", 8);
+        push("i7-4702HQ", 8);
+        push("i7-4702MQ", 8);
+        push("i7-4710HQ", 8);
+        push("i7-4710MQ", 8);
+        push("i7-4712HQ", 8);
+        push("i7-4712MQ", 8);
+        push("i7-4720HQ", 8);
+        push("i7-4722HQ", 8);
+        push("i7-4750HQ", 8);
+        push("i7-4760HQ", 8);
+        push("i7-4765T", 8);
+        push("i7-4770", 8);
+        push("i7-4770HQ", 8);
+        push("i7-4770K", 8);
+        push("i7-4770R", 8);
+        push("i7-4770S", 8);
+        push("i7-4770T", 8);
+        push("i7-4770TE", 8);
+        push("i7-4771", 8);
+        push("i7-4785T", 8);
+        push("i7-4790", 8);
+        push("i7-4790K", 8);
+        push("i7-4790S", 8);
+        push("i7-4790T", 8);
+        push("i7-4800MQ", 8);
+        push("i7-4810MQ", 8);
+        push("i7-4820K", 8);
+        push("i7-4850EQ", 8);
+        push("i7-4850HQ", 8);
+        push("i7-4860EQ", 8);
+        push("i7-4860HQ", 8);
+        push("i7-4870HQ", 8);
+        push("i7-4900MQ", 8);
+        push("i7-4910MQ", 8);
+        push("i7-4930K", 12);
+        push("i7-4930MX", 8);
+        push("i7-4940MX", 8);
+        push("i7-4950HQ", 8);
+        push("i7-4960HQ", 8);
+        push("i7-4960X", 12);
+        push("i7-4980HQ", 8);
+        push("i7-5500U", 4);
+        push("i7-5550U", 4);
+        push("i7-5557U", 4);
+        push("i7-5600U", 4);
+        push("i7-5650U", 4);
+        push("i7-5700EQ", 8);
+        push("i7-5700HQ", 8);
+        push("i7-5750HQ", 8);
+        push("i7-5775C", 8);
+        push("i7-5775R", 8);
+        push("i7-5820K", 12);
+        push("i7-5850EQ", 8);
+        push("i7-5850HQ", 8);
+        push("i7-5930K", 12);
+        push("i7-5950HQ", 8);
+        push("i7-5960X", 16);
+        push("i7-610E", 4);
+        push("i7-620LE", 4);
+        push("i7-620LM", 4);
+        push("i7-620M", 4);
+        push("i7-620UE", 4);
+        push("i7-620UM", 4);
+        push("i7-640LM", 4);
+        push("i7-640M", 4);
+        push("i7-640UM", 4);
+        push("i7-6498DU", 4);
+        push("i7-6500U", 4);
+        push("i7-6560U", 4);
+        push("i7-6567U", 4);
+        push("i7-6600U", 4);
+        push("i7-660LM", 4);
+        push("i7-660UE", 4);
+        push("i7-660UM", 4);
+        push("i7-6650U", 4);
+        push("i7-6660U", 4);
+        push("i7-6700", 8);
+        push("i7-6700HQ", 8);
+        push("i7-6700K", 8);
+        push("i7-6700T", 8);
+        push("i7-6700TE", 8);
+        push("i7-6770HQ", 8);
+        push("i7-6785R", 8);
+        push("i7-6800K", 12);
+        push("i7-680UM", 4);
+        push("i7-6820EQ", 8);
+        push("i7-6820HK", 8);
+        push("i7-6820HQ", 8);
+        push("i7-6822EQ", 8);
+        push("i7-6850K", 12);
+        push("i7-6870HQ", 8);
+        push("i7-6900K", 16);
+        push("i7-6920HQ", 8);
+        push("i7-6950X", 20);
+        push("i7-6970HQ", 8);
+        push("i7-720QM", 8);
+        push("i7-740QM", 8);
+        push("i7-7500U", 4);
+        push("i7-7510U", 4);
+        push("i7-7560U", 4);
+        push("i7-7567U", 4);
+        push("i7-7600U", 4);
+        push("i7-7660U", 4);
+        push("i7-7700", 8);
+        push("i7-7700HQ", 8);
+        push("i7-7700K", 8);
+        push("i7-7700T", 8);
+        push("i7-7740X", 8);
+        push("i7-7800X", 12);
+        push("i7-7820EQ", 8);
+        push("i7-7820HK", 8);
+        push("i7-7820HQ", 8);
+        push("i7-7820X", 16);
+        push("i7-7920HQ", 8);
+        push("i7-7Y75", 4);
+        push("i7-8086K", 12);
+        push("i7-820QM", 8);
+        push("i7-840QM", 8);
+        push("i7-8500Y", 4);
+        push("i7-8550U", 8);
+        push("i7-8557U", 8);
+        push("i7-8559U", 8);
+        push("i7-8565U", 8);
+        push("i7-8569U", 8);
+        push("i7-860", 8);
+        push("i7-860S", 8);
+        push("i7-8650U", 8);
+        push("i7-8665U", 8);
+        push("i7-8665UE", 8);
+        push("i7-8670", 12);
+        push("i7-8670T", 12);
+        push("i7-870", 8);
+        push("i7-8700", 12);
+        push("i7-8700B", 12);
+        push("i7-8700K", 12);
+        push("i7-8700T", 12);
+        push("i7-8705G", 8);
+        push("i7-8706G", 8);
+        push("i7-8709G", 8);
+        push("i7-870S", 8);
+        push("i7-8750H", 12);
+        push("i7-875K", 8);
+        push("i7-880", 8);
+        push("i7-8809G", 8);
+        push("i7-8850H", 12);
+        push("i7-920", 8);
+        push("i7-920XM", 8);
+        push("i7-930", 8);
+        push("i7-940", 8);
+        push("i7-940XM", 8);
+        push("i7-950", 8);
+        push("i7-960", 8);
+        push("i7-965", 8);
+        push("i7-970", 12);
+        push("i7-9700", 8);
+        push("i7-9700E", 8);
+        push("i7-9700F", 8);
+        push("i7-9700K", 8);
+        push("i7-9700KF", 8);
+        push("i7-9700T", 8);
+        push("i7-9700TE", 8);
+        push("i7-975", 8);
+        push("i7-9750H", 12);
+        push("i7-9750HF", 12);
+        push("i7-980", 12);
+        push("i7-9800X", 16);
+        push("i7-980X", 12);
+        push("i7-9850H", 12);
+        push("i7-9850HE", 12);
+        push("i7-9850HL", 12);
+        push("i7-990X", 12);
+
+        // i9 series
+        push("i9-10850K", 20);
+        push("i9-10885H", 16);
+        push("i9-10900", 20);
+        push("i9-10900E", 20);
+        push("i9-10900F ", 20);
+        push("i9-10900K", 20);
+        push("i9-10900KF", 20);
+        push("i9-10900T", 20);
+        push("i9-10900TE", 20);
+        push("i9-10900X", 20);
+        push("i9-10910", 20);
+        push("i9-10920X", 24);
+        push("i9-10940X", 28);
+        push("i9-10980HK", 16);
+        push("i9-10980XE", 36);
+        push("i9-11900", 16);
+        push("i9-11900F", 16);
+        push("i9-11900H", 16);
+        push("i9-11900K", 16);
+        push("i9-11900KB", 16);
+        push("i9-11900KF", 16);
+        push("i9-11900T", 16);
+        push("i9-11950H", 16);
+        push("i9-11980HK", 16);
+        push("i9-12900", 16);
+        push("i9-12900F", 16);
+        push("i9-12900K", 16);
+        push("i9-12900KF", 16);
+        push("i9-12900KS", 16);
+        push("i9-12900T", 16);
+        push("i9-13900", 16);
+        push("i9-13900E", 16);
+        push("i9-13900F", 16);
+        push("i9-13900HX", 16);
+        push("i9-13900K", 16);
+        push("i9-13900KF", 16);
+        push("i9-13900KS", 16);
+        push("i9-13900T", 16);
+        push("i9-13900TE", 16);
+        push("i9-13950HX", 16);
+        push("i9-13980HX", 16);
+        push("i9-14900", 16);
+        push("i9-14900F", 16);
+        push("i9-14900HX", 16);
+        push("i9-14900K", 16);
+        push("i9-14900KF", 16);
+        push("i9-14900KS", 16);
+        push("i9-14900T", 16);
+        push("i9-7900X", 20);
+        push("i9-7920X", 24);
+        push("i9-7940X", 28);
+        push("i9-7960X", 32);
+        push("i9-7980XE", 36);
+        push("i9-8950HK", 12);
+        push("i9-9820X", 20);
+        push("i9-9880H", 16);
+        push("i9-9900", 16);
+        push("i9-9900K", 16);
+        push("i9-9900KF", 16);
+        push("i9-9900KS", 16);
+        push("i9-9900T", 16);
+        push("i9-9900X", 20);
+        push("i9-9920X", 24);
+        push("i9-9940X", 28);
+        push("i9-9960X", 32);
+        push("i9-9980HK", 16);
+        push("i9-9980XE", 36);
+        push("i9-9990XE", 28);
+
+        // basically means "if there's 0 matches in the database, return false"
+        if (thread_database->count(model.string) == 0) {
+            return false;
+        }
+
+        const u8 threads = thread_database->at(model.string);
+
+        debug("INTEL_THREAD_MISMATCH: thread in database = ", static_cast<u32>(threads));
+
+        return (std::thread::hardware_concurrency() != threads);
+#endif
+    }
+
+
+    /**
+     * @brief Same as above, but for Xeon Intel CPUs
+     * @category All, x86
+     * @link https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
+     */
+    [[nodiscard]] static bool xeon_thread_mismatch() {
+#if (!x86)
+        return false;
+#else
+        if (!cpu::is_intel()) {
+            return false;
+        }
+
+        if (cpu::has_hyperthreading()) {
+            return false;
+        }
+
+        const cpu::model_struct model = cpu::get_model();
+
+        if (!model.found) {
+            return false;
+        }
+
+        if (!model.is_xeon) {
+            return false;
+        }
+
+        debug("XEON_THREAD_MISMATCH: CPU model = ", model.string);
+
+        auto xeon_thread_database = util::make_unique<std::unordered_map<std::string, uint8_t>>();
+
+        auto xeon_push = [&xeon_thread_database](const char* brand_str, const u8 thread_count) -> void {
+            xeon_thread_database->emplace(brand_str, thread_count);
+        };
+
+        // Xeon D
+        xeon_push("D-1518", 8);
+        xeon_push("D-1520", 8);
+        xeon_push("D-1521", 8);
+        xeon_push("D-1527", 8);
+        xeon_push("D-1528", 12);
+        xeon_push("D-1529", 8);
+        xeon_push("D-1531", 12);
+        xeon_push("D-1537", 16);
+        xeon_push("D-1539", 16);
+        xeon_push("D-1540", 16);
+        xeon_push("D-1541", 16);
+        xeon_push("D-1548", 16);
+        xeon_push("D-1557", 24);
+        xeon_push("D-1559", 24);
+        xeon_push("D-1567", 24);
+        xeon_push("D-1571", 32);
+        xeon_push("D-1577", 32);
+        xeon_push("D-1581", 32);
+        xeon_push("D-1587", 32);
+        xeon_push("D-1513N", 8);
+        xeon_push("D-1523N", 8);
+        xeon_push("D-1533N", 12);
+        xeon_push("D-1543N", 16);
+        xeon_push("D-1553N", 16);
+        xeon_push("D-1602", 4);
+        xeon_push("D-1612", 8);
+        xeon_push("D-1622", 8);
+        xeon_push("D-1627", 8);
+        xeon_push("D-1632", 16);
+        xeon_push("D-1637", 12);
+        xeon_push("D-1623N", 8);
+        xeon_push("D-1633N", 12);
+        xeon_push("D-1649N", 16);
+        xeon_push("D-1653N", 16);
+        xeon_push("D-2141I", 16);
+        xeon_push("D-2161I", 24);
+        xeon_push("D-2191", 36);
+        xeon_push("D-2123IT", 8);
+        xeon_push("D-2142IT", 16);
+        xeon_push("D-2143IT", 16);
+        xeon_push("D-2163IT", 24);
+        xeon_push("D-2173IT", 28);
+        xeon_push("D-2183IT", 32);
+        xeon_push("D-2145NT", 16);
+        xeon_push("D-2146NT", 16);
+        xeon_push("D-2166NT", 24);
+        xeon_push("D-2177NT", 28);
+        xeon_push("D-2187NT", 32);
+
+        // Xeon E
+        xeon_push("E-2104G", 4);
+        xeon_push("E-2124", 4);
+        xeon_push("E-2124G", 4);
+        xeon_push("E-2126G", 6);
+        xeon_push("E-2134", 8);
+        xeon_push("E-2136", 12);
+        xeon_push("E-2144G", 8);
+        xeon_push("E-2146G", 12);
+        xeon_push("E-2174G", 8);
+        xeon_push("E-2176G", 12);
+        xeon_push("E-2186G", 12);
+        xeon_push("E-2176M", 12);
+        xeon_push("E-2186M", 12);
+        xeon_push("E-2224", 4);
+        xeon_push("E-2224G", 4);
+        xeon_push("E-2226G", 6);
+        xeon_push("E-2234", 8);
+        xeon_push("E-2236", 12);
+        xeon_push("E-2244G", 8);
+        xeon_push("E-2246G", 12);
+        xeon_push("E-2274G", 8);
+        xeon_push("E-2276G", 12);
+        xeon_push("E-2278G", 16);
+        xeon_push("E-2286G", 12);
+        xeon_push("E-2288G", 16);
+        xeon_push("E-2276M", 12);
+        xeon_push("E-2286M", 16);
+
+        // Xeon W
+        xeon_push("W-2102", 4);
+        xeon_push("W-2104", 4);
+        xeon_push("W-2123", 8);
+        xeon_push("W-2125", 8);
+        xeon_push("W-2133", 12);
+        xeon_push("W-2135", 12);
+        xeon_push("W-2140B", 16);
+        xeon_push("W-2145", 16);
+        xeon_push("W-2150B", 20);
+        xeon_push("W-2155", 20);
+        xeon_push("W-2170B", 28);
+        xeon_push("W-2175", 28);
+        xeon_push("W-2191B", 36);
+        xeon_push("W-2195", 36);
+        xeon_push("W-3175X", 56);
+        xeon_push("W-3223", 16);
+        xeon_push("W-3225", 16);
+        xeon_push("W-3235", 24);
+        xeon_push("W-3245", 32);
+        xeon_push("W-3245M", 32);
+        xeon_push("W-3265", 48);
+        xeon_push("W-3265M", 48);
+        xeon_push("W-3275", 56);
+        xeon_push("W-3275M", 56);
+
+        if (xeon_thread_database->count(model.string) == 0) {
+            return false;
+        }
+
+        const u8 threads = xeon_thread_database->at(model.string);
+
+        debug("XEON_THREAD_MISMATCH: thread in database = ", static_cast<u32>(threads));
+
+        return (std::thread::hardware_concurrency() != threads);
+#endif
+    }
+
+
+    /**
+     * @brief Check for memory regions to detect VM-specific brands
+     * @category Windows
+     * @author Graham Sutherland
+     * @link https://labs.nettitude.com/blog/vm-detection-tricks-part-1-physical-memory-resource-maps/
+     */
+    [[nodiscard]] static bool nettitude_vm_memory() {
+#if (!MSVC)
+        return false;
+#else
+        typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;
+
+#pragma pack(push,4)
+        typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {
+            UCHAR Type;
+            UCHAR ShareDisposition;
+            USHORT Flags;
+            union {
+                struct {
+                    PHYSICAL_ADDRESS Start;
+                    ULONG Length;
+                } Generic;
+                struct {
+                    PHYSICAL_ADDRESS Start;
+                    ULONG Length;
+                } Port;
+                struct {
+#if defined(NT_PROCESSOR_GROUPS)
+                    USHORT Level;
+                    USHORT Group;
+#else
+                    ULONG Level;
+#endif
+                    ULONG Vector;
+                    KAFFINITY Affinity;
+                } Interrupt;
+                struct {
+                    union {
+                        struct {
+#if defined(NT_PROCESSOR_GROUPS)
+                            USHORT Group;
+#else
+                            USHORT Reserved;
+#endif
+                            USHORT MessageCount;
+                            ULONG Vector;
+                            KAFFINITY Affinity;
+                        } Raw;
+                        struct {
+#if defined(NT_PROCESSOR_GROUPS)
+                            USHORT Level;
+                            USHORT Group;
+#else
+                            ULONG Level;
+#endif
+                            ULONG Vector;
+                            KAFFINITY Affinity;
+                        } Translated;
+                    } DUMMYUNIONNAME;
+                } MessageInterrupt;
+                struct {
+                    PHYSICAL_ADDRESS Start;
+                    ULONG Length;
+                } Memory;
+                struct {
+                    ULONG Channel;
+                    ULONG Port;
+                    ULONG Reserved1;
+                } Dma;
+                struct {
+                    ULONG Channel;
+                    ULONG RequestLine;
+                    UCHAR TransferWidth;
+                    UCHAR Reserved1;
+                    UCHAR Reserved2;
+                    UCHAR Reserved3;
+                } DmaV3;
+                struct {
+                    ULONG Data[3];
+                } DevicePrivate;
+                struct {
+                    ULONG Start;
+                    ULONG Length;
+                    ULONG Reserved;
+                } BusNumber;
+                struct {
+                    ULONG DataSize;
+                    ULONG Reserved1;
+                    ULONG Reserved2;
+                } DeviceSpecificData;
+                struct {
+                    PHYSICAL_ADDRESS Start;
+                    ULONG Length40;
+                } Memory40;
+                struct {
+                    PHYSICAL_ADDRESS Start;
+                    ULONG Length48;
+                } Memory48;
+                struct {
+                    PHYSICAL_ADDRESS Start;
+                    ULONG Length64;
+                } Memory64;
+                struct {
+                    UCHAR Class;
+                    UCHAR Type;
+                    UCHAR Reserved1;
+                    UCHAR Reserved2;
+                    ULONG IdLowPart;
+                    ULONG IdHighPart;
+                } Connection;
+            } u;
+        } CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
+#pragma pack(pop,4)
+        typedef enum _INTERFACE_TYPE {
+            InterfaceTypeUndefined,
+            Internal,
+            Isa,
+            Eisa,
+            MicroChannel,
+            TurboChannel,
+            PCIBus,
+            VMEBus,
+            NuBus,
+            PCMCIABus,
+            CBus,
+            MPIBus,
+            MPSABus,
+            ProcessorInternal,
+            InternalPowerBus,
+            PNPISABus,
+            PNPBus,
+            Vmcs,
+            ACPIBus,
+            MaximumInterfaceType
+        } INTERFACE_TYPE, *PINTERFACE_TYPE;
+        typedef struct _CM_PARTIAL_RESOURCE_LIST {
+            USHORT                         Version;
+            USHORT                         Revision;
+            ULONG                          Count;
+            CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
+        } CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
+        typedef struct _CM_FULL_RESOURCE_DESCRIPTOR {
+            INTERFACE_TYPE           InterfaceType;
+            ULONG                    BusNumber;
+            CM_PARTIAL_RESOURCE_LIST PartialResourceList;
+        } *PCM_FULL_RESOURCE_DESCRIPTOR, CM_FULL_RESOURCE_DESCRIPTOR;
+        typedef struct _CM_RESOURCE_LIST {
+            ULONG                       Count;
+            CM_FULL_RESOURCE_DESCRIPTOR List[1];
+        } *PCM_RESOURCE_LIST, CM_RESOURCE_LIST;
+        struct memory_region {
+            ULONG64 size;
+            ULONG64 address;
+        };
+
+        /* registry keys for resource maps */
+#define VM_RESOURCE_CHECK_REGKEY_PHYSICAL 0
+#define VM_RESOURCE_CHECK_REGKEY_RESERVED 1
+#define VM_RESOURCE_CHECK_REGKEY_LOADER_RESERVED 2
+#define ResourceRegistryKeysLength 3
+
+        const struct map_key {
+            LPCTSTR KeyPath;
+            LPCTSTR ValueName;
+        } ResourceRegistryKeys[ResourceRegistryKeysLength] = {
+            {
+                _T("Hardware\\ResourceMap\\System Resources\\Physical Memory"),
+                _T(".Translated")
+            },
+            {
+                _T("Hardware\\ResourceMap\\System Resources\\Reserved"),
+                _T(".Translated")
+            },
+            {
+                _T("Hardware\\ResourceMap\\System Resources\\Loader Reserved"),
+                _T(".Raw")
+            }
+        };
+
+        /* parse a REG_RESOURCE_LIST value for memory descriptors */
+        auto parse_memory_map = [](
+            struct memory_region* regions,
+            struct map_key key
+        ) -> DWORD {
+            HKEY hKey = NULL;
+            LPCTSTR pszSubKey = key.KeyPath;
+            LPCTSTR pszValueName = key.ValueName;
+            LPBYTE lpData = NULL;
+            DWORD dwLength = 0, count = 0, type = 0;;
+            DWORD result;
+            if ((result = RegOpenKeyW(HKEY_LOCAL_MACHINE, reinterpret_cast<LPCWSTR>(pszSubKey), &hKey)) != ERROR_SUCCESS) {
+                debug("NETTITUDE_VM_MEMORY: Could not get reg key: ", result, " / ", GetLastError());
+                return 0;
+            }
+
+            if ((result = RegQueryValueExW(hKey, reinterpret_cast<LPCWSTR>(pszValueName), 0, &type, NULL, &dwLength)) != ERROR_SUCCESS) {
+                debug("NETTITUDE_VM_MEMORY: Could not query hardware key: ", result, " / ", GetLastError());
+                return 0;
+            }
+
+            lpData = (LPBYTE)malloc(dwLength);
+            RegQueryValueEx(hKey, pszValueName, 0, &type, lpData, &dwLength);
+            CM_RESOURCE_LIST* resource_list = (CM_RESOURCE_LIST*)lpData;
+            for (DWORD i = 0; i < resource_list->Count; i++)
+            {
+                for (DWORD j = 0; j < resource_list->List[0].PartialResourceList.Count; j++)
+                {
+                    if (resource_list->List[i].PartialResourceList.PartialDescriptors[j].Type == 3)
+                    {
+                        if (regions != NULL)
+                        {
+                            regions->address = resource_list->List[i].PartialResourceList.PartialDescriptors[j].u.Memory.Start.QuadPart;
+                            regions->size = resource_list->List[i].PartialResourceList.PartialDescriptors[j].u.Memory.Length;
+                            regions++;
+                        }
+                        count++;
+                    }
+                }
+            }
+            return count;
+        };
+
+#define VM_RESOURCE_CHECK_ERROR -1
+#define VM_RESOURCE_CHECK_NO_VM 0
+#define VM_RESOURCE_CHECK_HYPERV 1
+#define VM_RESOURCE_CHECK_VBOX 2
+#define VM_RESOURCE_CHECK_UNKNOWN_PLATFORM 99
+
+        auto vm_resource_check = [](
+            struct memory_region* phys, int phys_count,
+            struct memory_region* reserved, int reserved_count,
+            struct memory_region* loader_reserved, int loader_reserved_count
+        ) -> int {
+                const ULONG64 VBOX_PHYS_LO = 0x0000000000001000ULL;
+                const ULONG64 VBOX_PHYS_HI = 0x000000000009f000ULL;
+                const ULONG64 HYPERV_PHYS_LO = 0x0000000000001000ULL;
+                const ULONG64 HYPERV_PHYS_HI = 0x00000000000a0000ULL;
+
+                const ULONG64 RESERVED_ADDR_LOW = 0x0000000000001000ULL;
+                const ULONG64 LOADER_RESERVED_ADDR_LOW = 0x0000000000000000ULL;
+                if (phys_count <= 0 || reserved_count <= 0 || loader_reserved_count <= 0) {
+                    return VM_RESOURCE_CHECK_ERROR;
+                }
+
+                if (phys == NULL || reserved == NULL || loader_reserved == NULL) {
+                    return VM_RESOURCE_CHECK_ERROR;
+                }
+
+                /* find the reserved address range starting
+                RESERVED_ADDR_LOW, and record its end address */
+                ULONG64 lowestReservedAddrRangeEnd = 0;
+                for (int i = 0; i < reserved_count; i++) {
+                    if (reserved[i].address == RESERVED_ADDR_LOW) {
+                        lowestReservedAddrRangeEnd = reserved[i].address + reserved[i].size;
+                        break;
+                    }
+                }
+
+                if (lowestReservedAddrRangeEnd == 0) {
+                    /* every system tested had a range starting at RESERVED_ADDR_LOW */
+                    /* this is an outlier. error. */
+                    return VM_RESOURCE_CHECK_ERROR;
+                }
+
+                /* find the loader reserved address range starting
+                LOADER_RESERVED_ADDR_LOW, and record its end address */
+                ULONG64 lowestLoaderReservedAddrRangeEnd = 0;
+                for (int i = 0; i < loader_reserved_count; i++) {
+                    if (loader_reserved[i].address == LOADER_RESERVED_ADDR_LOW) {
+                        lowestLoaderReservedAddrRangeEnd = loader_reserved[i].address + loader_reserved[i].size;
+                        break;
+                    }
+                }
+
+                if (lowestLoaderReservedAddrRangeEnd == 0) {
+                    /* every system tested had a range starting at LOADER_RESERVED_ADDR_LOW */
+                    /* this is an outlier. error. */
+                    return VM_RESOURCE_CHECK_ERROR;
+                }
+
+                /* check if the end addresses are equal. if not, we haven't detected a VM */
+                if (lowestReservedAddrRangeEnd != lowestLoaderReservedAddrRangeEnd) {
+                    return VM_RESOURCE_CHECK_NO_VM;
+                }
+
+                /* now find the type of VM by its known physical memory range */
+                for (int i = 0; i < phys_count; i++) {
+                    if (phys[i].address == HYPERV_PHYS_LO && (phys[i].address + phys[i].size) == HYPERV_PHYS_HI) {
+                        /* hyper-v */
+                        return VM_RESOURCE_CHECK_HYPERV;
+                    }
+
+                    if (phys[i].address == VBOX_PHYS_LO && (phys[i].address + phys[i].size) == VBOX_PHYS_HI) {
+                        /* vbox */
+                        return VM_RESOURCE_CHECK_VBOX;
+                    }
+                }
+                /* pretty sure it's a VM, but we don't know what type */
+                return VM_RESOURCE_CHECK_UNKNOWN_PLATFORM;
+            };
+
+        DWORD count;
+
+        struct memory_region* regions[ResourceRegistryKeysLength]{};
+        int region_counts[ResourceRegistryKeysLength]{};
+
+        for (int i = 0; i < ResourceRegistryKeysLength; i++) {
+            debug(
+                "NETTITUDE_VM_MEMORY: Reading data from ",
+                ResourceRegistryKeys[i].KeyPath,
+                "\\",
+                ResourceRegistryKeys[i].ValueName
+            );
+
+            count = parse_memory_map(NULL, ResourceRegistryKeys[i]);
+
+            if (count == 0) {
+                debug("NETTITUDE_VM_MEMORY: Could not find memory region, returning 0.");
+                return 0;
+            }
+
+            regions[i] = (struct memory_region*)malloc(sizeof(struct memory_region) * count);
+
+            if (regions[i] == NULL) {
+                debug("NETTITUDE_VM_MEMORY: Memory allocation failed for regions[i].");
+                return 0;
+            }
+
+            count = parse_memory_map(regions[i], ResourceRegistryKeys[i]);
+
+            if (count <= 0) {
+                debug("NETTITUDE_VM_MEMORY: No regions parsed, freeing allocated memory.");
+                free(regions[i]);  
+                regions[i] = NULL;
+                continue;
+            }
+
+            region_counts[i] = count;
+            for (DWORD r = 0; r < count; r++) {
+                debug(
+                    "NETTITUDE_VM_MEMORY: --> Memory region found: ",
+                    regions[i][r].address,
+                    " - ",
+                    regions[i][r].address + regions[i][r].size
+                );
+            }
+        }
+
+        int check_result = vm_resource_check(
+            regions[VM_RESOURCE_CHECK_REGKEY_PHYSICAL],
+            region_counts[VM_RESOURCE_CHECK_REGKEY_PHYSICAL],
+            regions[VM_RESOURCE_CHECK_REGKEY_RESERVED],
+            region_counts[VM_RESOURCE_CHECK_REGKEY_RESERVED],
+            regions[VM_RESOURCE_CHECK_REGKEY_LOADER_RESERVED],
+            region_counts[VM_RESOURCE_CHECK_REGKEY_LOADER_RESERVED]
+        );
+
+        switch (check_result) {
+            // error
+            case VM_RESOURCE_CHECK_ERROR:
+                debug("NETTITUDE_VM_MEMORY: unknown error, returned false");
+                return false;
+                break;
+
+            // no VM
+            case VM_RESOURCE_CHECK_NO_VM:
+                debug("NETTITUDE_VM_MEMORY: no VM detected");
+                return false;
+                break;
+
+            // Hyper-V
+            case VM_RESOURCE_CHECK_HYPERV:
+                debug("NETTITUDE_VM_MEMORY: Hyper-V detected");
+                return core::add(HYPERV);
+                break;
+
+            // VirtualBox
+            case VM_RESOURCE_CHECK_VBOX:
+                debug("NETTITUDE_VM_MEMORY: Vbox detected");
+                return core::add(VBOX);
+                break;
+
+            // Unknown brand, but likely VM
+            case VM_RESOURCE_CHECK_UNKNOWN_PLATFORM:
+                debug("NETTITUDE_VM_MEMORY: unknown brand, but likely VM (returned true)");
+                return true;
+                break;
+
+            default:
+                debug("NETTITUDE_VM_MEMORY: returned false as default case");
+                return false;
+                break;
+        }
+#endif
+    }
+
+
+    /**
+     * @brief Check for CPUID technique by checking whether all the bits equate to more than 4000 (not sure how this works if i'm honest)
+     * @category x86
+     * @author 一半人生
+     * @link https://unprotect.it/snippet/vmcpuid/195/
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool cpuid_bitset() {
+#if (!x86)
+        return false;
+#else
+        if (util::hyper_x()) {
+            return false;
+        }
+
+        /// See: Feature Information Returned in the ECX Register
+        union CpuFeaturesEcx {
+            u32 all;
+            struct {
+                u32 sse3 : 1;       //!< [0] Streaming SIMD Extensions 3 (SSE3)
+                u32 pclmulqdq : 1;  //!< [1] PCLMULQDQ
+                u32 dtes64 : 1;     //!< [2] 64-bit DS Area
+                u32 monitor : 1;    //!< [3] MONITOR/WAIT
+                u32 ds_cpl : 1;     //!< [4] CPL qualified Debug Store
+                u32 vmx : 1;        //!< [5] Virtual Machine Technology
+                u32 smx : 1;        //!< [6] Safer Mode Extensions
+                u32 est : 1;        //!< [7] Enhanced Intel Speedstep Technology
+                u32 tm2 : 1;        //!< [8] Thermal monitor 2
+                u32 ssse3 : 1;      //!< [9] Supplemental Streaming SIMD Extensions 3
+                u32 cid : 1;        //!< [10] L1 context ID
+                u32 sdbg : 1;       //!< [11] IA32_DEBUG_INTERFACE MSR
+                u32 fma : 1;        //!< [12] FMA extensions using YMM state
+                u32 cx16 : 1;       //!< [13] CMPXCHG16B
+                u32 xtpr : 1;       //!< [14] xTPR Update Control
+                u32 pdcm : 1;       //!< [15] Performance/Debug capability MSR
+                u32 reserved : 1;   //!< [16] Reserved
+                u32 pcid : 1;       //!< [17] Process-context identifiers
+                u32 dca : 1;        //!< [18] prefetch from a memory mapped device
+                u32 sse4_1 : 1;     //!< [19] SSE4.1
+                u32 sse4_2 : 1;     //!< [20] SSE4.2
+                u32 x2_apic : 1;    //!< [21] x2APIC feature
+                u32 movbe : 1;      //!< [22] MOVBE instruction
+                u32 popcnt : 1;     //!< [23] POPCNT instruction
+                u32 reserved3 : 1;  //!< [24] one-shot operation using a TSC deadline
+                u32 aes : 1;        //!< [25] AESNI instruction
+                u32 xsave : 1;      //!< [26] XSAVE/XRSTOR feature
+                u32 osxsave : 1;    //!< [27] enable XSETBV/XGETBV instructions
+                u32 avx : 1;        //!< [28] AVX instruction extensions
+                u32 f16c : 1;       //!< [29] 16-bit floating-point conversion
+                u32 rdrand : 1;     //!< [30] RDRAND instruction
+                u32 not_used : 1;   //!< [31] Always 0 (a.k.a. HypervisorPresent)
+            } fields;
+        };
+
+        i32 cpu_info[4] = {};
+        cpu::cpuid(cpu_info, 0x40000001);
+        i32 vid = 0;
+        vid = (i32)cpu_info[0];
+
+        if (vid >= 4000) {
+            return true;
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for cuckoo directory using crt and WIN API directory functions
+     * @category Windows
+     * @author 一半人生
+     * @link https://unprotect.it/snippet/checking-specific-folder-name/196/
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool cuckoo_dir() {
+#if (!MSVC)
+        return false;
+#else
+        // win api
+        auto IsDirectory2 = [](std::string& strDirName) -> bool {
+            const auto iCode = CreateDirectoryA(strDirName.c_str(), NULL);
+
+            if (ERROR_ALREADY_EXISTS == GetLastError()) {
+                return true;
+            }
+
+            if (iCode) {
+                RemoveDirectoryA(strDirName.c_str());
+            }
+
+            return false;
+        };
+
+        // win api
+        auto IsDirectory1 = [](std::string& strDirName) -> bool {
+            const HANDLE hFile = CreateFileA(
+                strDirName.c_str(),
+                GENERIC_READ,
+                0,
+                NULL,
+                OPEN_EXISTING,
+                FILE_FLAG_BACKUP_SEMANTICS,
+                NULL
+            );
+
+            if (!hFile || (INVALID_HANDLE_VALUE == hFile)) {
+                return false;
+            }
+
+            CloseHandle(hFile);
+
+            return true;
+        };
+
+        // crt
+        auto IsDirectory = [](std::string& strDirName) -> bool {
+            if (0 == _access(strDirName.c_str(), 0)) {
+                return true;
+            }
+
+            return false;
+        };
+
+        std::string strDirName = "C:\\Cuckoo";
+
+        if (
+            IsDirectory(strDirName) ||
+            IsDirectory1(strDirName) ||
+            IsDirectory2(strDirName)
+        ) {
+            return core::add(CUCKOO);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Cuckoo specific piping mechanism
+     * @category Windows
+     * @author Thomas Roccia (fr0gger)
+     * @link https://unprotect.it/snippet/checking-specific-folder-name/196/
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool cuckoo_pipe() {
+#if (!LINUX)
+        return false;
+#else
+        int fd = open("\\\\.\\pipe\\cuckoo", O_RDONLY);
+        bool is_cuckoo = false;
+
+        if (fd >= 0) {
+            is_cuckoo = true;
+        }
+
+        close(fd);
+
+        if (is_cuckoo) {
+            return core::add(CUCKOO);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for default Azure hostname format regex (Azure uses Hyper-V as their base VM brand)
+     * @category Windows, Linux
+     */
+    [[nodiscard]] static bool hyperv_hostname() {
+#if (!(MSVC || LINUX))
+        return false;
+#else
+        std::string hostname = util::get_hostname();
+
+        // most Hyper-V hostnames under Azure have the hostname format of fv-azXXX-XXX where the X is a digit
+        std::regex pattern("fv-az\\d+-\\d+");
+
+        if (std::regex_match(hostname, pattern)) {
+            return core::add(AZURE_HYPERV);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for commonly set hostnames by certain VM brands
+     * @category Windows, Linux
+     * @note Idea from Thomas Roccia (fr0gger)
+     * @link https://unprotect.it/technique/detecting-hostname-username/
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool general_hostname() {
+#if (!(MSVC || LINUX))
+        return false;
+#else
+        std::string hostname = util::get_hostname();
+
+        auto cmp = [&](const char* str2) -> bool {
+            return (hostname == str2);
+        };
+
+        if (
+            cmp("Sandbox") ||
+            cmp("Maltest") ||
+            cmp("Malware") ||
+            cmp("malsand") ||
+            cmp("ClonePC")
+        ) {
+            return true;
+        }
+
+        if (cmp("Cuckoo")) {
+            return core::add(CUCKOO);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for pre-set screen resolutions commonly found in VMs
+     * @category Windows
+     * @note Idea from Thomas Roccia (fr0gger)
+     * @link https://unprotect.it/technique/checking-screen-resolution/
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool screen_resolution() {
+#if (!MSVC)
+        return false;
+#else
+        RECT desktop;
+        const HWND hDesktop = GetDesktopWindow();
+        GetWindowRect(hDesktop, &desktop);
+        const i32 horiz = desktop.right;
+        const i32 verti = desktop.bottom;
+
+        debug("SCREEN_RESOLUTION: horizontal = ", horiz, ", vertical = ", verti);
+
+        if (
+            (horiz == 1024 && verti == 768) ||
+            (horiz == 800 && verti == 600) ||
+            (horiz == 640 && verti == 480)
+        ) {
+            return true;
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check if bogus device string would be accepted
+     * @category Windows
+     * @author Huntress Research Team
+     * @link https://unprotect.it/technique/buildcommdcbandtimeouta/
+     * @copyright MIT
+     */
+    [[nodiscard]] static bool device_string() {
+#if (!MSVC)
+        return false;
+#else
+        DCB dcb = { 0 };
+        COMMTIMEOUTS timeouts = { 0 };
+
+        if (BuildCommDCBAndTimeoutsA("jhl46745fghb", &dcb, &timeouts)) {
+            return true;
+        } else {
+            debug("DEVICE_STRING: BuildCommDCBAndTimeouts failed");
+            return false;
+        }
+#endif
+    }
+
+
+    /**
+     * @brief Check for the presence of BlueStacks-specific folders
+     * @category ARM, Linux
+     */
+    [[nodiscard]] static bool bluestacks() {
+#if (!(ARM && LINUX))
+        return false;
+#else
+        if (
+            util::exists("/mnt/windows/BstSharedFolder") ||
+            util::exists("/sdcard/windows/BstSharedFolder")
+        ) {
+            return core::add(BLUESTACKS);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for signatures in leaf 0x40000001 in CPUID
+     * @link https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/shared/hvgdk_mini/hv_hypervisor_interface.htm
+     * @link https://github.com/ionescu007/SimpleVisor/blob/master/shvvp.c
+     * @category x86
+     */
+    [[nodiscard]] static bool cpuid_signature() {
+#if (!x86)
+        return false;
+#else
+        if (util::hyper_x()) {
+            return false;
+        }
+
+        u32 eax, unused = 0;
+        cpu::cpuid(eax, unused, unused, unused, 0x40000001);
+        UNUSED(unused);
+
+        constexpr u32 hyperv = 0x31237648; // "Hv#1"
+        constexpr u32 nanovisor = 0x766E6258; // "Xbnv" 
+        constexpr u32 simplevisor = 0x00766853; // " vhS"
+
+        debug("CPUID_SIGNATURE: eax = ", eax);
+
+        switch (eax) {
+            case hyperv: return core::add(HYPERV);
+            case nanovisor: return core::add(NANOVISOR);
+            case simplevisor: return core::add(SIMPLEVISOR);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Hyper-V CPUID bitmask range for reserved values
+     * @link https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/feature-discovery
+     * @category x86
+     */
+    [[nodiscard]] static bool hyperv_bitmask() {
+#if (!x86)
+        return false;
+#else
+        if (util::hyper_x()) {
+            return false;
+        }
+
+        enum registers : u8 {
+            EAX = 1,
+            EBX,
+            ECX,
+            EDX
+        };
+
+        auto fetch_register = [](const registers register_id, const u32 leaf) -> u32 {
+            u32 eax, ebx, ecx, edx = 0;
+            cpu::cpuid(eax, ebx, ecx, edx, leaf);
+
+            switch (register_id) {
+                case EAX: return eax;
+                case EBX: return ebx;
+                case ECX: return ecx;
+                case EDX: return edx;
+            }
+
+            return 0;
+        };
+
+        const u32 max_leaf = fetch_register(EAX, 0x40000000);
+
+        debug("HYPERV_BITMASK: max leaf = ", std::hex, max_leaf);
+
+        if (max_leaf < 0x4000000A) {
+            return false; // returned false because we want the most feature leafs as possible for Hyper-V
+        }
+
+/* this is just an ascii tool to check if all the arrows (^) are aligned correctly based on bit position, think of it as a ruler. (ignore this btw)
+||||||||||||||||||||||9876543210
+|||||||||||||||||||||10 
+||||||||||||||||||||11 
+|||||||||||||||||||12 
+||||||||||||||||||13 
+|||||||||||||||||14 
+||||||||||||||||15 
+|||||||||||||||16 
+||||||||||||||17 
+|||||||||||||18 
+||||||||||||19 
+|||||||||||20 
+||||||||||21 
+|||||||||22 
+||||||||23 
+|||||||24 
+||||||25 
+|||||26 
+||||27 
+|||28 
+||29 
+|30 
+31 
+*/
+
+        auto leaf_01 = [&]() -> bool {
+            u32 eax, ebx, ecx, edx = 0;
+            cpu::cpuid(eax, ebx, ecx, edx, 0x40000001);
+
+            debug("01 eax = ", std::bitset<32>(eax));
+            debug("01 ebx = ", std::bitset<32>(ebx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("01 ecx = ", std::bitset<32>(ecx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("01 edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+
+            return (
+                (eax != 0) &&
+                (ebx == 0) &&
+                (ecx == 0) &&
+                (edx == 0)
+            );
+        };
+
+        auto leaf_03 = [&]() -> bool {
+            const u32 ecx = fetch_register(ECX, 0x40000003);
+            const u32 edx = fetch_register(EDX, 0x40000003);
+
+            debug("03 ecx = ", std::bitset<32>(ecx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^    ^^^^^");
+            debug("03 edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^ ^^ ^     ^                ");
+
+            if (ecx == 0 || edx == 0) {
+                return false;
+            } else {
+                return (
+                    ((ecx & 0b11111) == 0) &&
+                    ((ecx >> 9) == 0) &&
+                    ((edx & (1 << 16)) == 0) &&
+                    ((edx & (1 << 22)) == 0) &&
+                    (((edx >> 24) & 0b11) == 0) &&
+                    ((edx >> 27) == 0)
+                );
+            }
+        };
+
+        auto leaf_04 = [&]() -> bool {
+            const u32 eax = fetch_register(EAX, 0x40000004);
+            const u32 ecx = fetch_register(ECX, 0x40000004);
+            const u32 edx = fetch_register(EDX, 0x40000004);
+
+            debug("04 eax = ", std::bitset<32>(eax));
+            debug("         ^^^^^^^^^^^^^  ^       ^        ");
+            debug("04 ecx = ", std::bitset<32>(ecx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^       ");
+            debug("04 edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+
+            if (
+                eax == 0 ||
+                ecx == 0 ||
+                edx != 0   // edx is supposed to be null
+            ) {
+                return false;
+            } else {
+                return (
+                    ((eax & (1 << 8)) == 0) &&
+                    ((eax & (1 << 16)) == 0) &&
+                    ((eax >> 19) == 0) &&
+                    ((ecx >> 7) == 0) &&
+                    (edx == 0)
+                );
+            }
+        };
+
+        auto leaf_05 = [&]() -> bool {
+            const u32 edx = fetch_register(EDX, 0x40000005);
+            debug("05 edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            return (edx == 0);
+        };
+
+        auto leaf_06 = [&]() -> bool {
+            u32 eax, ebx, ecx, edx = 0;
+            cpu::cpuid(eax, ebx, ecx, edx, 0x40000006);
+
+            debug("06 eax = ", std::bitset<32>(eax));
+            debug("         ^^^^^^^         ^               ");
+            debug("06 ebx = ", std::bitset<32>(ebx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("06 ecx = ", std::bitset<32>(ecx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("06 edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+
+            if (
+                eax == 0 ||
+                ebx != 0 ||
+                ecx != 0 ||
+                edx != 0   // edx is supposed to be null
+            ) {
+                return false;
+            } else {
+                return (
+                    ((eax & (1 << 15)) == 0) &&
+                    ((eax >> 25) == 0) &&
+                    (ebx == 0) &&
+                    (ecx == 0) &&
+                    (edx == 0)
+                );
+            }
+        };
+
+        auto leaf_09 = [&]() -> bool {
+            u32 eax, ebx, ecx, edx = 0;
+            cpu::cpuid(eax, ebx, ecx, edx, 0x40000009);
+
+            debug("09 eax = ", std::bitset<32>(eax));
+            debug("         ^^^^^^^^^^^^^^^^^^^ ^^^^^   ^ ^^");
+            debug("09 ebx = ", std::bitset<32>(ebx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("09 ecx = ", std::bitset<32>(ecx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("09 edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^^^^^^^^^^ ^ ^^^^^^^^^^ ^^^^");
+
+            if (
+                eax == 0 ||
+                ebx != 0 ||
+                ecx != 0 ||
+                edx == 0
+            ) {
+                return false;
+            } else {
+                return (
+                    ((eax & 0b11) == 0) &&
+                    ((eax & (1 << 3)) == 0) &&
+                    (((eax >> 7) & 0b11111) == 0) &&
+                    ((eax >> 13) == 0) &&
+                    (ebx == 0) &&
+                    (ecx == 0) &&
+                    ((edx & 0b1111) == 0) &&
+                    (((edx >> 5) & 0b1111111111) == 0) &&
+                    ((edx & (1 << 16)) == 0) &&
+                    ((edx >> 18) == 0)
+                );
+            }
+        };
+
+        auto leaf_0A = [&]() -> bool {
+            u32 eax, ebx, ecx, edx = 0;
+            cpu::cpuid(eax, ebx, ecx, edx, 0x40000009);
+
+            debug("0A eax = ", std::bitset<32>(eax));
+            debug("         ^^^^^^^^^^^    ^                ");
+            debug("0A eax = ", std::bitset<32>(ebx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ");
+            debug("0A ecx = ", std::bitset<32>(ecx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+            debug("0A edx = ", std::bitset<32>(edx));
+            debug("         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+
+            // ebx is left out on purpose due to how likely it can result the overall result to be a false negative
+            if (
+                eax == 0 ||
+                ecx != 0 ||
+                edx != 0
+            ) {
+                return false;
+            } else {
+                return (
+                    ((eax & (1 << 16)) == 0) &&
+                    ((eax >> 21) == 0) &&
+                    ((ebx >> 30) == 0) &&
+                    (ecx == 0) &&
+                    (edx == 0)
+                );
+            }
+        };
+
+        debug("01: ", leaf_01());
+        debug("03: ", leaf_03());
+        debug("04: ", leaf_04());
+        debug("05: ", leaf_05());
+        debug("06: ", leaf_06());
+        debug("09: ", leaf_09());
+        debug("0A: ", leaf_0A());
+
+        if (
+            leaf_01() &&
+            leaf_03() &&
+            leaf_04() &&
+            leaf_05() &&
+            leaf_06() &&
+            leaf_09() &&
+            leaf_0A()
+        ) {
+            return core::add(HYPERV);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for KVM CPUID bitmask range for reserved values
+     * @category x86
+     */
+    [[nodiscard]] static bool kvm_bitmask() {
+#if (!x86)
+        return false;
+#else
+        u32 eax, ebx, ecx, edx = 0;
+        cpu::cpuid(eax, ebx, ecx, edx, 0x40000000);
+
+        // KVM brand and max leaf check
+        if (!(
+            (eax == 0x40000001) &&
+            (ebx == 0x4b4d564b) &&
+            (ecx == 0x564b4d56) &&
+            (edx == 0x4d)
+        )) {
+            return false;
+        }
+
+        cpu::cpuid(eax, ebx, ecx, edx, 0x40000001);
+
+        if (
+            (eax & (1 << 8)) &&
+            (((eax >> 13) & 0b1111111111) == 0) &&
+            ((eax >> 24) == 0)
+        ) {
+            return core::add(KVM);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for Intel KGT (Trusty branch) hypervisor signature in CPUID
+     * @link https://github.com/intel/ikgt-core/blob/7dfd4d1614d788ec43b02602cce7a272ef8d5931/vmm/vmexit/vmexit_cpuid.c
+     * @category x86
+     */
+    [[nodiscard]] static bool intel_kgt_signature() {
+#if (!x86)
+        return false;
+#else
+        u32 unused, ecx, edx = 0;
+        cpu::cpuid(unused, unused, ecx, edx, 3);
+
+        if (
+            // ecx should be "EVMM" and edx is "INTC".
+            // Not sure if it's little endian or big endian, so i'm comparing both
+            ((ecx == 0x4D4D5645) && (edx == 0x43544E49)) ||
+            ((ecx == 0x45564D4D) && (edx == 0x494E5443))
+        ) {
+            return core::add(INTEL_KGT);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for VMware DMI strings in BIOS serial number
+     * @link https://knowledge.broadcom.com/external/article?legacyId=1009458
+     * @category Windows
+     */
+    [[nodiscard]] static bool vmware_dmi() {
+#if (!MSVC)
+        return false;
+#else
+        std::unique_ptr<util::sys_info> info = util::make_unique<util::sys_info>();
+
+        const std::string str = info->get_serialnumber();
+
+        if (util::find(str, "VMware-")) {
+            return core::add(VMWARE);
+        }
+
+        if (util::find(str, "VMW")) {
+            return core::add(VMWARE_FUSION);
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for presence of Hyper-V in the Windows Event Logs
+     * @author Requiem (https://github.com/NotRequiem)
+     * @category Windows
+     */
+    [[nodiscard]] static bool hyperv_event_logs() {
+#if (!MSVC)
+        return false;
+#else
+        // Define the log name and search strings
+        std::wstring logName = L"Microsoft-Windows-Kernel-PnP/Configuration"; // Example: "System", "Application", "Security", or a custom path. In this case, we use Microsoft-Windows-Kernel-PnP/Configuration as a Hyper-V VM artifact
+        std::vector<std::wstring> searchStrings = { L"Virtual_Machine", L"VMBUS" };
+
+        bool found = util::query_event_logs(logName, searchStrings);
+
+        if (found) {
+            return core::add(HYPERV);
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for presence of QEMU in the /sys/devices/virtual/dmi/id directory
+     * @category Linux
+     */
+    [[nodiscard]] static bool qemu_virtual_dmi() {
+#if (!LINUX)
+        return false;
+#else
+        const char* sys_vendor = "/sys/devices/virtual/dmi/id/sys_vendor";
+        const char* modalias = "/sys/devices/virtual/dmi/id/modalias";
+
+        if (
+            util::exists(sys_vendor) &&
+            util::exists(modalias)
+        ) {
+            const std::string sys_vendor_str = util::read_file(sys_vendor);
+            const std::string modalias_str = util::read_file(modalias);
+
+            return (
+                util::find(sys_vendor_str, "QEMU") &&
+                util::find(modalias_str, "QEMU")
+            );
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for presence of QEMU in the /sys/kernel/debug/usb/devices directory
+     * @category Linux
+     */
+    [[nodiscard]] static bool qemu_USB() {
+#if (!LINUX)
+        return false;
+#else
+        if (!util::is_admin()) {
+            return false;
+        }
+
+        const char* usb_path = "/sys/kernel/debug/usb/devices";
+
+        if (util::exists(usb_path)) {
+            const std::string usb_path_str = util::read_file(usb_path);
+            return (util::find(usb_path_str, "QEMU"));
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for presence of any files in /sys/hypervisor directory
+     * @category Linux
+     */
+    [[nodiscard]] static bool hypervisor_dir() {
+#if (!LINUX)
+        return false;
+#else
+        DIR* dir = opendir("/sys/hypervisor");
+
+        if (dir == nullptr) {
+            return false;
+        }
+
+        struct dirent* entry;
+        int count = 0;
+
+        while ((entry = readdir(dir)) != nullptr) {
+            if (
+                (entry->d_name[0] == '.' && entry->d_name[1] == '\0') || 
+                (entry->d_name[1] == '.' && entry->d_name[2] == '\0')
+            ) {
+                continue;
+            }
+
+            count++;
+            break;
+        }
+
+        closedir(dir);
+
+        bool type = false;
+
+        if (util::exists("/sys/hypervisor/type")) {
+            type = true;
+        }
+
+        if (type) {
+            const std::string content = util::read_file("/sys/hypervisor/type");
+            if (util::find(content, "xen")) {
+                return core::add(XEN);
+            }
+        }
+
+        // check if there's a few files in that directory
+        return ((count != 0) && type);
+#endif
+    } 
+
+
+    /**
+     * @brief Check for the "UML" string in the CPU brand
+     * @note idea from https://github.com/ShellCode33/VM-Detection/blob/master/vmdetect/linux.go
+     * @category Linux
+     */
+    [[nodiscard]] static bool uml_cpu() {
+#if (!LINUX)
+        return false;
+#else
+        // method 1, get the CPU brand model
+        const std::string brand = cpu::get_brand();
+
+        if (brand == "UML") {
+            return core::add(UML);
+        }
+
+        // method 2, match for the "User Mode Linux" string in /proc/cpuinfo
+        const char* file = "/proc/cpuinfo";
+
+        if (util::exists(file)) {
+            const std::string file_content = util::read_file(file);
+
+            if (util::find(file_content, "User Mode Linux")) {
+                return core::add(UML);
+            }
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for any indications of hypervisors in the kernel message logs
+     * @note idea from https://github.com/ShellCode33/VM-Detection/blob/master/vmdetect/linux.go
+     * @category Linux
+     */
+    [[nodiscard]] static bool kmsg() {
+#if (!LINUX)
+        return false;
+#else
+        if (!util::is_admin()) {
+            return false;
+        }
+
+        // Open /dev/kmsg
+        int fd = open("/dev/kmsg", O_RDONLY | O_NONBLOCK);
+        if (fd < 0) {
+            debug("KMSG: Failed to open /dev/kmsg");
+            return 1;
+        }
+
+        char buffer[1024];
+        std::stringstream ss;
+
+        while (true) {
+            ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
+
+            if (bytes_read > 0) {
+                buffer[bytes_read] = '\0';
+                ss << buffer;
+            } else if (bytes_read == 0) {
+                usleep(100000); // Sleep for 100 milliseconds
+            } else {
+                if (errno == EAGAIN) {
+                    usleep(100000); // Sleep for 100 milliseconds
+                } else {
+                    debug("KMSG: Error reading /dev/kmsg");
+                    break;
+                }
+            }
+
+            if (bytes_read < 0) {
+                break;
+            }
+        }
+
+        close(fd);
+
+        const std::string content = ss.str();
+
+        if (content.empty()) {
+            return false;
+        }
+
+        return (util::find(content, "Hypervisor detected"));
+#endif
+    } 
+
+
+    /**
+     * @brief Check for a Xen VM process
+     * @note idea from https://github.com/ShellCode33/VM-Detection/blob/master/vmdetect/linux.go
+     * @category Linux
+     */
+    [[nodiscard]] static bool vm_procs() {
+#if (!LINUX)
+        return false;
+#else
+        if (util::exists("/proc/xen")) {
+            return core::add(XEN);
+        }
+
+        if (util::exists("/proc/vz")) {
+            return core::add(OPENVZ);
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for a VBox kernel module
+     * @note idea from https://github.com/ShellCode33/VM-Detection/blob/master/vmdetect/linux.go
+     * @category Linux
+     */
+    [[nodiscard]] static bool vbox_module() {
+#if (!LINUX)
+        return false;
+#else
+        const char* file = "/proc/modules";
+
+        if (!util::exists(file)) {
+            return false;
+        }
+
+        const std::string content = util::read_file(file);
+
+        if (util::find(content, "vboxguest")) {
+            return core::add(VBOX);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for potential VM info in /proc/sysinfo
+     * @note idea from https://github.com/ShellCode33/VM-Detection/blob/master/vmdetect/linux.go
+     * @category Linux
+     */
+    [[nodiscard]] static bool sysinfo_proc() {
+#if (!LINUX)
+        return false;
+#else
+        const char* file = "/proc/sysinfo";
+
+        if (!util::exists(file)) {
+            return false;
+        }
+
+        const std::string content = util::read_file(file);
+
+        if (util::find(content, "VM00")) {
+            return true;
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for specific files in /proc/device-tree directory
+     * @note idea from https://github.com/ShellCode33/VM-Detection/blob/master/vmdetect/linux.go
+     * @category Linux
+     */
+    [[nodiscard]] static bool device_tree() {
+#if (!LINUX)
+        return false;
+#else
+        if (util::exists("/proc/device-tree/fw-cfg")) {
+            return core::add(QEMU);
+        }
+
+        return (util::exists("/proc/device-tree/hypervisor/compatible"));
+#endif
+    } 
+
+
+    /**
+     * @brief Check for string matches of VM brands in the linux DMI
+     * @category Linux
+     */
+    [[nodiscard]] static bool dmi_scan() {
+#if (!LINUX)
+        return false;
+#else
+        /*
+        cat: /sys/class/dmi/id/board_serial: Permission denied
+        cat: /sys/class/dmi/id/chassis_serial: Permission denied
+        cat: /sys/class/dmi/id/product_serial: Permission denied
+        cat: /sys/class/dmi/id/product_uuid: Permission denied
+        */
+
+        constexpr std::array<const char*, 7> dmi_array {
+            "/sys/class/dmi/id/bios_vendor",
+            "/sys/class/dmi/id/board_name",
+            "/sys/class/dmi/id/board_vendor",
+            "/sys/class/dmi/id/chassis_asset_tag",
+            "/sys/class/dmi/id/product_family",
+            "/sys/class/dmi/id/product_sku",
+            "/sys/class/dmi/id/sys_vendor"
+        };
+
+        constexpr std::array<std::pair<const char*, const char*>, 15> vm_table {{
+            { "kvm", KVM },
+            { "openstack", OPENSTACK },
+            { "kubevirt", KUBEVIRT },
+            { "amazon ec2", AWS_NITRO },
+            { "qemu", QEMU },
+            { "vmware", VMWARE },
+            { "innotek gmbh", VBOX },
+            { "virtualbox", VBOX },
+            { "oracle corporation", VBOX },
+            //{ "xen", XEN },
+            { "bochs", BOCHS },
+            { "parallels", PARALLELS },
+            { "bhyve", BHYVE },
+            { "hyper-v", HYPERV },
+            { "apple virtualization", APPLE_VZ },
+            { "google compute engine", GCE }
+        }};
+
+        auto to_lower = [](std::string &str) {
+            for (auto& c : str) {
+                if (c == ' ') {
+                    continue;
+                }
+
+                c = static_cast<char>(tolower(c));
+            }
+        };
+
+        for (const auto &vm_string : vm_table) {
+            for (const auto file : dmi_array) {
+                if (!util::exists(file)) {
+                    continue;
+                }
+
+                std::string content = util::read_file(file);
+
+                to_lower(content);
+
+                if (std::regex_search(content, std::regex(vm_string.first))) {
+                    debug("DMI_SCAN: content = ", content);
+                    if (std::strcmp(vm_string.second, AWS_NITRO) == 0) {
+                        if (smbios_vm_bit()) {
+                            return core::add(AWS_NITRO);
+                        }
+                    } else {
+                        return core::add(vm_string.second);
+                    }
+                }
+            }
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Check for the VM bit in the SMBIOS data
+     * @note idea from https://github.com/systemd/systemd/blob/main/src/basic/virt.c
+     * @category Linux
+     */
+    [[nodiscard]] static bool smbios_vm_bit() {
+#if (!LINUX)
+        return false;
+#else
+        if (!util::is_admin()) {
+            return false;
+        }
+
+        const char* file = "/sys/firmware/dmi/entries/0-0/raw";
+
+        if (!util::exists(file)) {
+            return false;
+        }
+
+        const std::vector<u8> content = util::read_file_binary(file);
+
+        if (content.size() < 20 || content.at(1) < 20) {
+            debug("SMBIOS_VM_BIT: ", "only read ", content.size(), " bytes, expected 20");
+            return false;
+        }
+
+        debug("SMBIOS_VM_BIT: ", "content.at(19) = ", static_cast<int>(content.at(19)));
+
+        return (content.at(19) & (1 << 4));
+#endif
+    } 
+
+
+    /**
+     * @brief Check for podman file in /run/
+     * @note idea from https://github.com/systemd/systemd/blob/main/src/basic/virt.c
+     * @category Linux
+     */
+    [[nodiscard]] static bool podman_file() {
+#if (!LINUX)
+        return false;
+#else
+        if (util::exists("/run/.containerenv")) {
+            return core::add(PODMAN);
+        }
+
+        return false;
+#endif
+    }
+
+
+    /**
+     * @brief Check for WSL or microsoft indications in /proc/ subdirectories
+     * @note idea from https://github.com/systemd/systemd/blob/main/src/basic/virt.c
+     * @category Linux
+     */
+    [[nodiscard]] static bool wsl_proc_subdir() {
+#if (!LINUX)
+        return false;
+#else
+        const char* osrelease = "/proc/sys/kernel/osrelease";
+        const char* version = "/proc/version";
+
+        if (
+            util::exists(osrelease) &&
+            util::exists(version)
+        ) {
+            const std::string osrelease_content = util::read_file(osrelease);
+            const std::string version_content = util::read_file(version);
+
+            if (
+                (util::find(osrelease_content, "WSL") || util::find(osrelease_content, "Microsoft")) &&
+                (util::find(version, "WSL") || util::find(version, "Microsoft"))
+            ) {
+                return core::add(WSL);
+            }
+        }
+
+        return false;
+#endif
+    } 
+
+
+    /**
+     * @brief Use wmic to get the GPU/videocontrollers chip type.
+     * @category Windows
+     * @author utoshu
+     */
+    [[nodiscard]] static bool gpu_chiptype() {
+#if (!MSVC)
+        return false;
+#else
+        if (!wmi::initialize()) {
+            std::cerr << "Failed to initialize WMI.\n";
+            return false;
+        }
+
+        std::vector<wmi::result> results =
+            wmi::execute(L"SELECT * FROM Win32_VideoController", { L"VideoProcessor" });
+
+        std::string result = "";
+        for (const auto& res : results) {
+            if (res.type == wmi::result_type::String) {
+                result += res.strValue + "\n"; // Collect video processor names
+            }
+        }
+
+        std::transform(result.begin(), result.end(), result.begin(), 
+            [](unsigned char c) { 
+                return static_cast<char>(::tolower(c));
+            }
+        );
+
+        if (util::find(result, "vmware")) {
+            return core::add(VMWARE);
+        }
+
+        if (util::find(result, "virtualbox")) {
+            return core::add(VBOX);
+        }
+
+        if (util::find(result, "hyper-v")) {
+            return core::add(HYPERV);
+        }
+
+        wmi::cleanup();
+
+        return false;
+#endif
+    }
+
+    struct core {
+        MSVC_DISABLE_WARNING(PADDING)
+        struct technique {
+            u8 points = 0;                // this is the certainty score between 0 and 100
+            std::function<bool()> run;    // this is the technique function itself
+            bool is_spoofable = false;    // this is to indicate that the technique can be very easily spoofed (not guaranteed)
+        };
+
+        struct custom_technique {
+            u8 points;
+            u16 id;
+            std::function<bool()> run;
+        };
+        MSVC_ENABLE_WARNING(PADDING)
+
+        static const std::map<enum_flags, technique> technique_table;
+
+        static std::vector<custom_technique> custom_table;
+
+        static bool cpuid_supported;
+
+        // VM scoreboard table specifically for VM::brand()
+        static std::map<const char*, brand_score_t> brand_scoreboard;
+
+        // directly return when adding a brand to the scoreboard for a more succint expression
+#if (MSVC)
+        __declspec(noalias)
+#elif (LINUX)
+        [[gnu::const]]
+#endif
+        static inline bool add(const char* p_brand, const char* extra_brand = "") noexcept {
+            core::brand_scoreboard.at(p_brand)++;
+            if (std::strcmp(extra_brand, "") != 0) {
+                core::brand_scoreboard.at(p_brand)++;
+            }
+            return true;
+        }
+
+        // assert if the flag is enabled, far better expression than typing std::bitset member functions
+#if (LINUX && __has_cpp_attribute(gnu::pure))
+        [[gnu::pure]]
+#endif
+        [[nodiscard]] static inline bool is_disabled(const flagset& flags, const u8 flag_bit) noexcept {
+            return (!flags.test(flag_bit));
+        }
+
+        // same as above but for checking enabled flags
+#if (LINUX && __has_cpp_attribute(gnu::pure))
+        [[gnu::pure]]
+#endif
+        [[nodiscard]] static inline bool is_enabled(const flagset& flags, const u8 flag_bit) noexcept {
+            return (flags.test(flag_bit));
+        }
+
+        [[nodiscard]] static bool is_technique_set(const flagset& flags) {
+            for (std::size_t i = technique_begin; i < technique_end; i++) {
+                if (flags.test(i)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        [[nodiscard]] static bool is_setting_flag_set(const flagset& flags) {
+            for (std::size_t i = non_technique_begin; i < non_technique_end; i++) {
+                if (flags.test(i)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        // manage the flag to handle edgecases
+        static void flag_sanitizer(flagset& flags) {
+            if (flags.count() == 0) {
+                flags |= DEFAULT;
+                return;
+            }
+
+            if (flags == DEFAULT) {
+                return;
+            }
+
+            // check if any technique flag is set, which is the "correct" way
+            if (core::is_technique_set(flags)) {
+                return;
+            }
+
+            if (!core::is_setting_flag_set(flags)) {
+                throw std::invalid_argument("Invalid flag option for function parameter found, either leave it empty or add the VM::DEFAULT flag");
+            }
+
+            // at this stage, only settings technique flags are asserted to be set
+            if (
+                flags.test(NO_MEMO) ||
+                flags.test(HIGH_THRESHOLD) ||
+                flags.test(SPOOFABLE) ||
+                flags.test(NULL_ARG) ||
+                flags.test(MULTIPLE)
+            ) {
+                flags |= DEFAULT;
+            } else {
+                throw std::invalid_argument("Invalid flag option found, aborting");
+            }
+        }
+
+        // run every VM detection mechanism in the technique table
+        static u16 run_all(const flagset& flags, const bool shortcut = false) {
+            u16 points = 0;
+
+            const bool memo_enabled = core::is_disabled(flags, NO_MEMO);
+
+            const u16 threshold_points = (core::is_enabled(flags, HIGH_THRESHOLD) ? high_threshold_score : 200);
+
+            // loop through technique table, where all the techniques are stored
+            for (const auto& tmp : technique_table) {
+                const enum_flags technique_macro = tmp.first;
+                const technique technique_data = tmp.second;
+
+                // check if the technique is disabled
+                if (core::is_disabled(flags, technique_macro)) {
+                    continue;
+                }
+
+                // check if it's spoofable, and whether it's enabled
+                if (
+                    technique_data.is_spoofable && 
+                    core::is_disabled(flags, SPOOFABLE)
+                ) {
+                    continue;
+                }
+
+                // check if the technique is cached already
+                if (memo_enabled && memo::is_cached(technique_macro)) {
+                    const memo::data_t data = memo::cache_fetch(technique_macro);
+
+                    if (data.result) {
+                        points += data.points;
+                    }
+
+                    continue;
+                }
+
+                // run the technique
+                const bool result = technique_data.run();
+
+                // accumulate the points if technique detected a VM
+                if (result) {
+                    points += technique_data.points;
+
+                    // this is specific to VM::detected_count() which returns 
+                    // the number of techniques that returned a positive
+                    detected_count_num++;
+                }
+                
+                // for things like VM::detect() and VM::percentage(),
+                // a score of 200+ is guaranteed to be a VM, so
+                // there's no point in running the rest of the techniques
+                if (shortcut && points >= threshold_points) {
+                    return points;
+                }
+
+                // store the current technique result to the cache
+                if (memo_enabled) {
+                    memo::cache_store(technique_macro, result, technique_data.points);
+                }
+            }
+
+            // for custom VM techniques, won't be used most of the time
+            if (!custom_table.empty()) {
+                for (const auto& technique : custom_table) {
+                    if (memo_enabled && memo::is_cached(technique.id)) {
+                        const memo::data_t data = memo::cache_fetch(technique.id);
+
+                        if (data.result) {
+                            points += data.points;
+                        }
+
+                        continue;
+                    }
+
+                    const bool result = technique.run();
+
+                    if (result) {
+                        points += technique.points;
+                        detected_count_num++;
+                    }
+
+                    if (memo_enabled) {
+                        memo::cache_store(
+                            technique.id,
+                            result, 
+                            technique.points
+                        );
+                    }
+                }
+            }
+
+            return points;
+        }
+
+
+        /**
+         * basically what this entire template fuckery does is manage the
+         * variadic arguments being given through the arg_handler function,
+         * which could either be a std::bitset<N>, a uint8_t, or a combination
+         * of both of them. This will handle both argument types and implement
+         * them depending on what their types are. If it's a std::bitset<N>,
+         * do the |= operation on flag_collector. If it's a uint8_t, simply 
+         * .set() that into the flag_collector. That's the gist of it.
+         *
+         * Also I won't even deny, the majority of this section was 90% generated
+         * by chatgpt. Can't be arsed with this C++ templatisation shit.
+         * Like is it really my fault that I have a hard time understanging C++'s 
+         * god awful metaprogramming designs? And don't even get me started on SNIFAE. 
+         * 
+         * You don't need an IQ of 3 digits to realise how dogshit this language
+         * is, when you end up in situations where there's a few correct solutions
+         * to a problem, but with a billion ways you can do the same thing but in 
+         * the "wrong" way. I genuinely can't wait for Carbon to come out.
+         */
+    private:
+        static flagset flag_collector;
+
+        static void flagset_manager(const flagset& flags) {
+            flag_collector |= flags;
+        }
+
+        static void flag_manager(const enum_flags flag) {
+            if (
+                (flag == INVALID) ||
+                (flag > enum_size)
+            ) {
+                throw std::invalid_argument("Non-flag or invalid flag provided for VM::detect(), aborting");
+            }
+
+            flag_collector.set(flag);
+        }
+
+        // Define a base class for different types
+        struct TestHandler {
+            virtual void handle(const flagset& flags) {
+                flagset_manager(flags);
+            }
+
+            virtual void handle(const enum_flags flag) {
+                flag_manager(flag);
+            }
+        };
+
+        // Define derived classes for specific type implementations
+        struct TestBitsetHandler : public TestHandler {
+            void handle(const flagset& flags) override {
+                flagset_manager(flags);
+            }
+        };
+
+        struct TestUint8Handler : public TestHandler {
+            void handle(const enum_flags flag) override {
+                flag_manager(flag);
+            }
+        };
+
+        // Define a function to dispatch handling based on type
+        template <typename T>
+        static void dispatch(const T& value, TestHandler& handler) {
+            handler.handle(value);
+        }
+
+        // Base case for the recursive handling
+        static void handleArgs() {
+            // Base case: Do nothing
+        }
+
+        // Base case for the recursive handling
+        static void handle_disabled_args() {
+            // Base case: Do nothing
+        }
+
+        // Helper function to check if a given argument is of a specific type
+        template <typename T, typename U>
+        static bool isType(U&&) {
+            return std::is_same<T, typename std::decay<U>::type>::value;
+        }
+
+        // Recursive case to handle each argument based on its type
+        template <typename First, typename... Rest>
+        static void handleArgs(First&& first, Rest&&... rest) {
+            TestBitsetHandler bitsetHandler;
+            TestUint8Handler uint8Handler;
+
+            if (isType<flagset>(first)) {
+                dispatch(first, bitsetHandler);
+            } else if (isType<enum_flags>(first)) {
+                dispatch(first, uint8Handler);
+            } else {
+                const std::string msg =
+                    "Arguments must either be a std::bitset<" +
+                    std::to_string(static_cast<u32>(enum_size + 1)) +
+                    "> such as VM::DEFAULT, or a flag such as VM::RDTSC for example";
+
+                throw std::invalid_argument(msg);
+            }
+
+            // Recursively handle the rest of the arguments
+            handleArgs(std::forward<Rest>(rest)...);
+        }
+
+        // Recursive case to handle each argument based on its type
+        template <typename First, typename... Rest>
+        static void handle_disabled_args(First&& first, Rest&&... rest) {
+            TestUint8Handler uint8Handler;
+
+            if (isType<flagset>(first)) {
+                throw std::invalid_argument("Arguments must not contain VM::DEFAULT or VM::ALL, only technique flags are accepted (view the documentation for a full list)");
+            } else if (isType<enum_flags>(first)) {
+                dispatch(first, uint8Handler);
+            } else {
+                throw std::invalid_argument("Arguments must be a technique flag, aborting");
+            }
+
+            // Recursively handle the rest of the arguments
+            handle_disabled_args(std::forward<Rest>(rest)...);
+        }
+
+        template <typename... Args>
+        static constexpr bool is_empty() {
+            return (sizeof...(Args) == 0);
+        }
+
+#if (CPP >= 17)
+#define VMAWARE_CONSTEXPR constexpr
+#else
+#define VMAWARE_CONSTEXPR
+#endif
+
+    public:
+        // fetch the flags, could be an enum value OR a std::bitset.
+        // This will then generate a different std::bitset as the 
+        // return value by enabling the bits based on the argument.
+        template <typename... Args>
+        static flagset arg_handler(Args&&... args) {
+            if VMAWARE_CONSTEXPR (is_empty<Args...>()) {
+                return DEFAULT;
+            }
+
+            flag_collector.reset();
+            global_flags.reset();
+
+            // set the bits in the flag, can take in 
+            // either an enum value or a std::bitset
+            handleArgs(std::forward<Args>(args)...);
+
+            // handle edgecases
+            core::flag_sanitizer(flag_collector);
+
+            global_flags = flag_collector;
+
+            return flag_collector;
+        }
+
+        // same as above but for VM::disable which only accepts technique flags
+        template <typename... Args>
+        static flagset disabled_arg_handler(Args&&... args) {
+            flag_collector.reset();
+
+            if VMAWARE_CONSTEXPR (is_empty<Args...>()) {
+                throw std::invalid_argument("VM::DISABLE() must contain a flag");
+            }
+
+            handle_disabled_args(std::forward<Args>(args)...);
+
+            // check if a settings flag is set, which is not valid
+            if (core::is_setting_flag_set(flag_collector)) {
+                throw std::invalid_argument("VM::DISABLE() must not contain a settings flag, they are disabled by default anyway");
+            }
+
+            return flag_collector;
+        }
+    };
+
+
+public: // START OF PUBLIC FUNCTIONS
+
+    /**
+     * @brief Check for a specific technique based on flag argument
+     * @param u8 (flags from VM wrapper)
+     * @return bool
+     * @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmcheck
+     */
+    [[nodiscard]] static bool check(
+        const enum_flags flag_bit, 
+        const enum_flags memo_arg = NULL_ARG
+        // clang doesn't support std::source_location for some reason
+#if (CPP >= 20 && !CLANG)
+        , const std::source_location& loc = std::source_location::current()
+#endif
+    ) {
+        // lambda to manage exceptions
+        auto throw_error = [&](const char* text) -> void {
+            std::stringstream ss;
+#if (CPP >= 20 && !CLANG)
+            ss << ", error in " << loc.function_name() << " at " << loc.file_name() << ":" << loc.line() << ")";
+#endif
+            ss << ". Consult the documentation's flag handler for VM::check()";
+            throw std::invalid_argument(std::string(text) + ss.str());
+        };
+
+        // check if flag is out of range
+        if (flag_bit > enum_size) {
+            throw_error("Flag argument must be a valid");
+        }
+
+        // check if the bit is a settings flag, which shouldn't be allowed
+        if (
+            (flag_bit == NO_MEMO) ||
+            (flag_bit == HIGH_THRESHOLD) ||
+            (flag_bit == SPOOFABLE) ||
+            (flag_bit == MULTIPLE)
+        ) {
+            throw_error("Flag argument must be a technique flag and not a settings flag");
+        }
+
+        if (
+            (memo_arg != NO_MEMO) && 
+            (memo_arg != NULL_ARG)
+        ) {
+            throw_error("Flag argument for memoization must be either VM::NO_MEMO or left empty");
+        }
+
+        const bool is_memoized = (memo_arg != NO_MEMO);
+
+#if (CPP >= 23)
+        [[assume(flag_bit < technique_end)]];
+#endif
+
+        // if the technique is already cached, return the cached value instead
+        if (memo::is_cached(flag_bit) && is_memoized) {
+            const memo::data_t data = memo::cache_fetch(flag_bit);
+            return data.result;
+        }
+
+        // check if the flag even exists
+        auto it = core::technique_table.find(flag_bit);
+        if (it == core::technique_table.end()) {
+            throw_error("Flag is not known");
+        }
+
+        // initialise and run the technique
+        const core::technique& pair = it->second;
+        const bool result = pair.run();
+
+        if (result) {
+            detected_count_num++;
+        }
+
+#ifdef __VMAWARE_DEBUG__
+        total_points += pair.points;
+#endif
+
+        // store the technique result in the cache table
+        if (is_memoized) {
+            memo::cache_store(flag_bit, result, pair.points);
+        }
+
+        return result;
+    }
+
+
+    /**
+     * @brief Fetch the VM brand
+     * @param any flag combination in VM structure or nothing (VM::MULTIPLE can be added)
+     * @return std::string
+     * @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmbrand
+     */
+    template <typename ...Args>
+    [[nodiscard]] static std::string brand(Args ...args) {
+        flagset flags = core::arg_handler(args...);
+
+        // is the multiple setting flag enabled? (meaning multiple 
+        // brand strings will be outputted if there's a conflict)
+        const bool is_multiple = core::is_enabled(flags, MULTIPLE);
+
+        // are all the techiques already run? if not, run them 
+        // to fetch the necessary info to determine the brand
+        if (!memo::all_present() || core::is_enabled(flags, NO_MEMO)) {
+            core::run_all(flags);
+        }
+
+        // check if the result is already cached and return that instead
+        if (core::is_disabled(flags, NO_MEMO)) {
+            if (is_multiple) {
+                if (memo::multi_brand::is_cached()) {
+                    core_debug("VM::brand(): returned multi brand from cache");
+                    return memo::multi_brand::fetch();
+                }
+            } else {
+                if (memo::brand::is_cached()) {
+                    core_debug("VM::brand(): returned brand from cache");
+                    return memo::brand::fetch();
+                }
+            }
+        }
+
+        // goofy ass C++11 and C++14 linker error workaround, 
+        // and yes, this does look indeed stupid.
+#if (CPP <= 14)
+        constexpr const char* TMP_QEMU = "QEMU";
+        constexpr const char* TMP_KVM = "KVM";
+        constexpr const char* TMP_QEMU_KVM = "QEMU+KVM";
+        constexpr const char* TMP_KVM_HYPERV = "KVM Hyper-V Enlightenment";
+        constexpr const char* TMP_QEMU_KVM_HYPERV = "QEMU+KVM Hyper-V Enlightenment";
+
+        constexpr const char* TMP_VMWARE = "VMware";
+        constexpr const char* TMP_EXPRESS = "VMware Express";
+        constexpr const char* TMP_ESX = "VMware ESX";
+        constexpr const char* TMP_GSX = "VMware GSX";
+        constexpr const char* TMP_WORKSTATION = "VMware Workstation";
+        constexpr const char* TMP_FUSION = "VMware Fusion";
+
+        constexpr const char* TMP_VPC = "Virtual PC";
+        constexpr const char* TMP_HYPERV = "Microsoft Hyper-V";
+        constexpr const char* TMP_HYPERV_VPC = "Microsoft Virtual PC/Hyper-V";
+        constexpr const char* TMP_AZURE = "Microsoft Azure Hyper-V";
+        constexpr const char* TMP_NANOVISOR = "Xbox NanoVisor (Hyper-V)";
+        constexpr const char* TMP_HYPERV_ARTIFACT = "Hyper-V artifact (not an actual VM)";
+#else
+        constexpr const char* TMP_QEMU = QEMU;
+        constexpr const char* TMP_KVM = KVM;
+        constexpr const char* TMP_QEMU_KVM = QEMU_KVM;
+        constexpr const char* TMP_KVM_HYPERV = KVM_HYPERV;
+        constexpr const char* TMP_QEMU_KVM_HYPERV = QEMU_KVM_HYPERV;
+
+        constexpr const char* TMP_VMWARE = VMWARE;
+        constexpr const char* TMP_EXPRESS = VMWARE_EXPRESS;
+        constexpr const char* TMP_ESX = VMWARE_ESX;
+        constexpr const char* TMP_GSX = VMWARE_GSX;
+        constexpr const char* TMP_WORKSTATION = VMWARE_WORKSTATION;
+        constexpr const char* TMP_FUSION = VMWARE_FUSION;
+
+        constexpr const char* TMP_VPC = VPC;
+        constexpr const char* TMP_HYPERV = HYPERV;
+        constexpr const char* TMP_HYPERV_VPC = HYPERV_VPC;
+        constexpr const char* TMP_AZURE = AZURE_HYPERV;
+        constexpr const char* TMP_NANOVISOR = NANOVISOR;
+        constexpr const char* TMP_HYPERV_ARTIFACT = HYPERV_ARTIFACT;
+#endif
+
+        // this is where all the RELEVANT brands are stored.
+        // The ones with no points will be filtered out.
+        std::map<const char*, brand_score_t> brands;
+
+        // add the relevant brands with at least 1 point
+        for (const auto &element : core::brand_scoreboard) {
+            if (element.second > 0) {
+                brands.insert(std::make_pair(element.first, element.second));
+            }
+        }
+
+        // if all brands had a point of 0, return 
+        // "Unknown" (no relevant brands were found)
+        if (brands.empty()) {
+            return "Unknown";
+        }
+
+        // if there's only a single brand, return it. 
+        // This will skip the rest of the function
+        // where it will process and merge certain
+        // brands 
+        if (brands.size() == 1) {
+            return brands.begin()->first;
+        }
+        
+        // remove Hyper-V artifacts if found with other 
+        // brands, because that's not a VM. It's added 
+        // only for the sake of information cuz of the 
+        // fucky wucky Hyper-V problem (see Hyper-X)
+        if (brands.size() > 1) {
+            if (brands.find(TMP_HYPERV_ARTIFACT) != brands.end()) {
+                brands.erase(TMP_HYPERV_ARTIFACT);
+            }
+        }
+
+        // merge 2 brands, and make a single brand out of it.
+        auto merger = [&](const char* a, const char* b, const char* result) -> void {
+            if (
+                (brands.count(a) > 0) &&
+                (brands.count(b) > 0)
+            ) {
+                brands.erase(a);
+                brands.erase(b);
+                brands.emplace(std::make_pair(result, 2));
+            }
+        };
+
+        // same as above, but for 3
+        auto triple_merger = [&](const char* a, const char* b, const char* c, const char* result) -> void {
+            if (
+                (brands.count(a) > 0) &&
+                (brands.count(b) > 0) &&
+                (brands.count(c) > 0)
+            ) {
+                brands.erase(a);
+                brands.erase(b);
+                brands.erase(c);
+                brands.emplace(std::make_pair(result, 2));
+            }
+        };
+
+        // some edgecase handling for Hyper-V and VirtualPC since
+        // they're very similar, and they're both from Microsoft (ew)
+        if ((brands.count(TMP_HYPERV) > brands.count(TMP_VPC))) {
+            brands.erase(TMP_VPC);
+        } else if (brands.count(TMP_HYPERV) < brands.count(TMP_VPC)) {
+            brands.erase(TMP_HYPERV);
+        } else if (
+            (brands.count(TMP_HYPERV) == brands.count(TMP_VPC)) &&
+            ((brands.count(TMP_HYPERV) > 0) && (brands.count(TMP_VPC) > 0))
+        ) {
+            merger(TMP_VPC, TMP_HYPERV, TMP_HYPERV_VPC);
+        }
+
+
+        // this is the section where brand post-processing will be done. 
+        // The reason why this part is necessary is because it will
+        // output a more accurate picture on the VM brand. For example, 
+        // Azure's cloud is based on Hyper-V, but Hyper-V may have 
+        // a higher score due to the prevalence of it in a practical 
+        // setting, which will put Azure to the side. This is stupid 
+        // because there should be an indication that Azure is involved
+        // since it's a better idea to let the end-user know that the
+        // brand is "Azure Hyper-V" instead of just "Hyper-V". So what
+        // this section does is "merge" the brands together to form
+        // a more accurate idea of the brand(s) involved.
+
+
+        merger(TMP_AZURE, TMP_HYPERV,     TMP_AZURE);
+        merger(TMP_AZURE, TMP_VPC,        TMP_AZURE);
+        merger(TMP_AZURE, TMP_HYPERV_VPC, TMP_AZURE);
+
+        merger(TMP_NANOVISOR, TMP_HYPERV,     TMP_NANOVISOR);
+        merger(TMP_NANOVISOR, TMP_VPC,        TMP_NANOVISOR);
+        merger(TMP_NANOVISOR, TMP_HYPERV_VPC, TMP_NANOVISOR);
+        
+        merger(TMP_QEMU,     TMP_KVM,        TMP_QEMU_KVM);
+        merger(TMP_KVM,      TMP_HYPERV,     TMP_KVM_HYPERV);
+        merger(TMP_QEMU,     TMP_HYPERV,     TMP_QEMU_KVM_HYPERV);
+        merger(TMP_QEMU_KVM, TMP_HYPERV,     TMP_QEMU_KVM_HYPERV);
+        merger(TMP_KVM,      TMP_KVM_HYPERV, TMP_KVM_HYPERV);
+        merger(TMP_QEMU,     TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
+        merger(TMP_QEMU_KVM, TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
+
+        triple_merger(TMP_QEMU, TMP_KVM, TMP_KVM_HYPERV, TMP_QEMU_KVM_HYPERV);
+
+        merger(TMP_VMWARE, TMP_FUSION,      TMP_FUSION);
+        merger(TMP_VMWARE, TMP_EXPRESS,     TMP_EXPRESS);
+        merger(TMP_VMWARE, TMP_ESX,         TMP_ESX);
+        merger(TMP_VMWARE, TMP_GSX,         TMP_GSX);
+        merger(TMP_VMWARE, TMP_WORKSTATION, TMP_WORKSTATION);
+
+        // the brand element, which stores the NAME (const char*) and the SCORE (u8)
+        using brand_element_t = std::pair<const char*, brand_score_t>;
+
+        // sort the "brands" map so that the brands with the
+        // highest score appears first in descending order
+        auto sorter = [&]() -> std::vector<brand_element_t> {
+            std::vector<brand_element_t> vec(brands.begin(), brands.end());
+
+            std::sort(vec.begin(), vec.end(), [](
+                const brand_element_t &a,
+                const brand_element_t &b
+            ) {
+                return a.second < b.second;
+            });
+
+            return vec;
+        };
+
+        std::vector<brand_element_t> vec = sorter();
+        std::string ret_str = "Unknown";
+
+        // if the multiple setting flag is NOT set, return the
+        // brand with the highest score. Else, return a std::string
+        // of the brand message (i.e. "VirtualBox or VMware").
+        // See VM::MULTIPLE flag in docs for more information.
+        if (!is_multiple) {
+            ret_str = vec.front().first;
+        } else {
+            std::stringstream ss;
+            std::size_t i = 1;
+
+            ss << vec.front().first;
+            for (; i < vec.size(); i++) {
+                ss << " or ";
+                ss << vec.at(i).first;
+            }
+            ret_str = ss.str();
+        }
+
+        // cache the result if memoization is enabled
+        if (core::is_disabled(flags, NO_MEMO)) {
+            if (is_multiple) {
+                core_debug("VM::brand(): cached multiple brand string");
+                memo::multi_brand::store(ret_str);
+            } else {
+                core_debug("VM::brand(): cached brand string");
+                memo::brand::store(ret_str);
+            }
+        }
+
+        // debug stuff to see the brand scoreboard, ignore this
+#ifdef __VMAWARE_DEBUG__
+        for (const auto p : brands) {
+            core_debug("scoreboard: ", (int)p.second, " : ", p.first);
+        }
+#endif
+
+        return ret_str;
+    }
+
+
+    /**
+     * @brief Detect if running inside a VM
+     * @param any flag combination in VM structure or nothing
+     * @return bool
+     * @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmdetect
+     */
+    template <typename ...Args>
+    static bool detect(Args ...args) {
+        // fetch all the flags in a std::bitset
+        flagset flags = core::arg_handler(args...);
+
+        // run all the techniques based on the 
+        // flags above, and get a total score
+        const u16 points = core::run_all(flags, SHORTCUT);
+
+#if (CPP >= 23)
+        [[assume(points < maximum_points)]];
+#endif
+
+        u16 threshold = 150;
+
+        // if high threshold is set, the points 
+        // will be 300. If not, leave it as 150.
+        if (core::is_enabled(flags, HIGH_THRESHOLD)) {
+            threshold = high_threshold_score;
+        }
+
+        return (points >= threshold);
+    }
+
+
+    /**
+     * @brief Get the percentage of how likely it's a VM
+     * @param any flag combination in VM structure or nothing
+     * @return std::uint8_t
+     * @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmpercentage
+     */
+    template <typename ...Args>
+    static u8 percentage(Args ...args) {
+        // fetch all the flags in a std::bitset
+        const flagset flags = core::arg_handler(args...);
+
+        // run all the techniques based on the 
+        // flags above, and get a total score
+        const u16 points = core::run_all(flags, SHORTCUT);
+
+#if (CPP >= 23)
+        [[assume(points < maximum_points)]];
+#endif
+
+        u8 percent = 0;
+        u16 threshold = 150;
+
+        // set to 300 if high threshold is enabled
+        if (core::is_enabled(flags, HIGH_THRESHOLD)) {
+            threshold = high_threshold_score;
+        }
+
+        // the percentage will be set to 99%, because a score 
+        // of 100 is not entirely robust. 150 is more robust
+        // in my opinion, which is why you need a score of
+        // above 150 to get to 100% 
+        if (points >= threshold) {
+            percent = 100;
+        } else if (points >= 100) {
+            percent = 99;
+        } else {
+            percent = static_cast<u8>(points);
+        }
+
+        return percent;
+    }
+
+
+    /**
+     * @brief Add a custom technique to the VM detection technique collection
+     * @param either a function pointer, lambda function, or std::function<bool()>
+     * @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmaddcustom
+     * @return void
+     */
+    static void add_custom(
+        const std::uint8_t percent,
+        std::function<bool()> detection_func
+        // clang doesn't support std::source_location for some reason
+#if (CPP >= 20 && !CLANG)
+        , const std::source_location& loc = std::source_location::current()
+#endif
+    ) {
+        // lambda to throw the error
+        auto throw_error = [&](const char* text) -> void {
+            std::stringstream ss;
+#if (CPP >= 20 && !CLANG)
+            ss << ", error in " << loc.function_name() << " at " << loc.file_name() << ":" << loc.line() << ")";
+#endif
+            ss << ". Consult the documentation's parameters for VM::add_custom()";
+            throw std::invalid_argument(std::string(text) + ss.str());
+        };
+
+        if (percent > 100) {
+            throw_error("Percentage parameter must be between 0 and 100");
+        }
+
+#if (CPP >= 23)
+        [[assume(percent > 0 && percent <= 100)]];
+#endif
+
+        static u16 id = 0;
+        id++;
+
+        // generate the custom technique struct
+        core::custom_technique query{
+            percent,
+            // this fucking sucks
+            static_cast<u16>(static_cast<int>(base_technique_count) + static_cast<int>(id)),
+            detection_func
+        };
+
+        technique_count++;
+
+        // push it to the custome_table vector
+        core::custom_table.emplace_back(query);
+    }
+
+
+    /**
+     * @brief disable the provided technique flags so they are not counted to the overall result
+     * @param technique flag(s) only
+     * @link https://github.com/kernelwernel/VMAware/blob/main/docs/documentation.md#vmdetect
+     * @return flagset
+     */
+    template <typename ...Args>
+    static flagset DISABLE(Args ...args) {
+        // basically core::arg_handler but in reverse,
+        // it'll clear the bits of the provided flags
+        flagset flags = core::disabled_arg_handler(args...);
+
+        flags.flip();
+        flags.set(NO_MEMO, 0);
+        flags.set(HIGH_THRESHOLD, 0);
+        flags.set(SPOOFABLE, 0);
+        flags.set(MULTIPLE, 0);
+
+        return flags;
+    }
+
+
+    /**
+     * @brief This will convert the technique flag into a string, which will correspond to the technique name
+     * @param single technique flag in VM structure
+     * @warning ⚠️ FOR DEVELOPMENT USAGE ONLY, NOT MEANT FOR PUBLIC USE FOR NOW ⚠️
+     */
+    [[nodiscard]] static std::string flag_to_string(const enum_flags flag) {
+        switch (flag) {
+            case VMID: return "VMID";
+            case CPU_BRAND: return "CPU_BRAND";
+            case HYPERVISOR_BIT: return "HYPERVISOR_BIT";
+            case HYPERVISOR_STR: return "HYPERVISOR_STR";
+            case RDTSC: return "RDTSC";
+            case THREADCOUNT: return "THREADCOUNT";
+            case MAC: return "MAC";
+            case TEMPERATURE: return "TEMPERATURE";
+            case SYSTEMD: return "SYSTEMD";
+            case CVENDOR: return "CVENDOR";
+            case CTYPE: return "CTYPE";
+            case DOCKERENV: return "DOCKERENV";
+            case DMIDECODE: return "DMIDECODE";
+            case DMESG: return "DMESG";
+            case HWMON: return "HWMON";
+            case SIDT5: return "SIDT5";
+            case CURSOR: return "CURSOR";
+            case VMWARE_REG: return "VMWARE_REG";
+            case VBOX_REG: return "VBOX_REG";
+            case USER: return "USER";
+            case DLL: return "DLL";
+            case REGISTRY: return "REGISTRY";
+            case CWSANDBOX_VM: return "CWSANDBOX_VM";
+            case VM_FILES: return "VM_FILES";
+            case HWMODEL: return "HWMODEL";
+            case DISK_SIZE: return "DISK_SIZE";
+            case VBOX_DEFAULT: return "VBOX_DEFAULT";
+            case VBOX_NETWORK: return "VBOX_NETWORK";
+            case VM_PROCESSES: return "VM_PROCESSES";
+            case LINUX_USER_HOST: return "LINUX_USER_HOST";
+            case GAMARUE: return "GAMARUE";
+            case VMID_0X4: return "VMID_0X4";
+            case PARALLELS_VM: return "PARALLELS_VM";
+            case RDTSC_VMEXIT: return "RDTSC_VMEXIT";
+            case QEMU_BRAND: return "QEMU_BRAND";
+            case BOCHS_CPU: return "BOCHS_CPU";
+            case VPC_BOARD: return "VPC_BOARD";
+            case HYPERV_WMI: return "HYPERV_WMI";
+            case HYPERV_REG: return "HYPERV_REG";
+            case BIOS_SERIAL: return "BIOS_SERIAL";
+            case VBOX_FOLDERS: return "VBOX_FOLDERS";
+            case MSSMBIOS: return "MSSMBIOS";
+            case MAC_MEMSIZE: return "MAC_MEMSIZE";
+            case MAC_IOKIT: return "MAC_IOKIT";
+            case IOREG_GREP: return "IOREG_GREP";
+            case MAC_SIP: return "MAC_SIP";
+            case HKLM_REGISTRIES: return "HKLM_REGISTRIES";
+            case QEMU_GA: return "QEMU_GA";
+            case VALID_MSR: return "VALID_MSR";
+            case QEMU_PROC: return "QEMU_PROC";
+            case VPC_PROC: return "VPC_PROC";
+            case VPC_INVALID: return "VPC_INVALID";
+            case SIDT: return "SIDT";
+            case SGDT: return "SGDT";
+            case SLDT: return "SLDT";
+            case OFFSEC_SIDT: return "OFFSEC_SIDT";
+            case OFFSEC_SGDT: return "OFFSEC_SGDT";
+            case OFFSEC_SLDT: return "OFFSEC_SLDT";
+            case HYPERV_BOARD: return "HYPERV_BOARD";
+            case VM_FILES_EXTRA: return "VM_FILES_EXTRA";
+            case VPC_SIDT: return "VPC_SIDT";
+            case VMWARE_IOMEM: return "VMWARE_IOMEM";
+            case VMWARE_IOPORTS: return "VMWARE_IOPORTS";
+            case VMWARE_SCSI: return "VMWARE_SCSI";
+            case VMWARE_DMESG: return "VMWARE_DMESG";
+            case VMWARE_STR: return "VMWARE_STR";
+            case VMWARE_BACKDOOR: return "VMWARE_BACKDOOR";
+            case VMWARE_PORT_MEM: return "VMWARE_PORT_MEM";
+            case SMSW: return "SMSW";
+            case MUTEX: return "MUTEX";
+            case UPTIME: return "UPTIME";
+            case ODD_CPU_THREADS: return "ODD_CPU_THREADS";
+            case INTEL_THREAD_MISMATCH: return "INTEL_THREAD_MISMATCH";
+            case XEON_THREAD_MISMATCH: return "XEON_THREAD_MISMATCH";
+            case NETTITUDE_VM_MEMORY: return "NETTITUDE_VM_MEMORY";
+            case CPUID_BITSET: return "CPUID_BITSET";
+            case CUCKOO_DIR: return "CUCKOO_DIR";
+            case CUCKOO_PIPE: return "CUCKOO_PIPE";
+            case HYPERV_HOSTNAME: return "HYPERV_HOSTNAME";
+            case GENERAL_HOSTNAME: return "GENERAL_HOSTNAME";
+            case SCREEN_RESOLUTION: return "SCREEN_RESOLUTION";
+            case DEVICE_STRING: return "DEVICE_STRING";
+            case BLUESTACKS_FOLDERS: return "BLUESTACKS_FOLDERS";
+            case CPUID_SIGNATURE: return "CPUID_SIGNATURE";
+            case HYPERV_BITMASK: return "HYPERV_BITMASK";
+            case KVM_BITMASK: return "KVM_BITMASK";
+            case KGT_SIGNATURE: return "KGT_SIGNATURE";
+            case VMWARE_DMI: return "VMWARE_DMI";
+            case EVENT_LOGS: return "EVENT_LOGS";
+            case QEMU_VIRTUAL_DMI: return "QEMU_VIRTUAL_DMI";
+            case QEMU_USB: return "QEMU_USB";
+            case HYPERVISOR_DIR: return "HYPERVISOR_DIR";
+            case UML_CPU: return "UML_CPU";
+            case KMSG: return "KMSG";
+            case VM_PROCS: return "VM_PROCS";
+            case VBOX_MODULE: return "VBOX_MODULE";
+            case SYSINFO_PROC: return "SYSINFO_PROC";
+            case DEVICE_TREE: return "DEVICE_TREE";
+            case DMI_SCAN: return "DMI_SCAN";
+            case SMBIOS_VM_BIT: return "SMBIOS_VM_BIT";
+            case PODMAN_FILE: return "PODMAN_FILE";
+            case WSL_PROC: return "WSL_PROC";
+            case GPU_CHIPTYPE: return "GPU_CHIPTYPE";
+            default: return "Unknown flag";
+        }
+    }
+
+
+    /**
+     * @brief return a vector of detected brand strings
+     * @param any flag combination in VM structure or nothing
+     * @warning ⚠️ FOR DEVELOPMENT USAGE ONLY, NOT MEANT FOR PUBLIC USE FOR NOW ⚠️
+     */
+    template <typename ...Args>
+    static std::map<const char*, brand_score_t> brand_map(Args ...args) {
+        flagset flags = core::arg_handler(args...);
+
+        // are all the techiques already run? if not, run all of them to get the necessary info to fetch the brand
+        if (!memo::all_present() || core::is_enabled(flags, NO_MEMO)) {
+            core::run_all(flags);
+        }
+
+        return core::brand_scoreboard;
+    }
+
+
+    /**
+     * @brief Change the certainty score of a technique
+     * @param technique flag, then the new percentage score to overwite
+     * @return void
+     * @warning ⚠️ FOR DEVELOPMENT USAGE ONLY, NOT MEANT FOR PUBLIC USE FOR NOW ⚠️
+     */
+    static void modify_score(
+        const enum_flags flag,
+        const u8 percent
+        // clang doesn't support std::source_location for some reason
+#if (CPP >= 20 && !CLANG)
+        , const std::source_location& loc = std::source_location::current()
+#endif
+    ) {
+        // lambda to throw the error
+        auto throw_error = [&](const char* text) -> void {
+            std::stringstream ss;
+#if (CPP >= 20 && !CLANG)
+            ss << ", error in " << loc.function_name() << " at " << loc.file_name() << ":" << loc.line() << ")";
+#endif
+            ss << ". Consult the documentation's parameters for VM::modify_score()";
+            throw std::invalid_argument(std::string(text) + ss.str());
+        };
+
+        if (percent > 100) {
+            throw_error("Percentage parameter must be between 0 and 100");
+        }
+
+#if (CPP >= 23)
+        [[assume(percent <= 100)]];
+#endif
+
+        // check if the flag provided is a setting flag, which isn't valid.
+        if (static_cast<u8>(flag) >= technique_end) {
+            throw_error("The flag is not a technique flag");
+        }
+
+        // replica type alias of the technique table
+        using table_t = std::map<enum_flags, core::technique>;
+
+        auto modify = [](table_t &table, const enum_flags flag, const u8 percent) -> void {
+            core::technique &tmp = table.at(flag);
+            table[flag] = { percent, tmp.run, tmp.is_spoofable };
+        };
+
+        modify(const_cast<table_t&>(core::technique_table), flag, percent);
+    }
+
+
+    /**
+     * @brief Fetch the total number of detected techniques
+     * @param any flag combination in VM structure or nothing
+     * @return std::uint8_t
+     */
+    template <typename ...Args>
+    static u8 detected_count(Args ...args) {
+        flagset flags = core::arg_handler(args...);
+
+        // run all the techniques, which will set the detected_count variable 
+        core::run_all(flags);
+
+        return detected_count_num;
+    }
+
+
+    /**
+     * @brief Fetch the total number of detected techniques
+     * @param any flag combination in VM structure or nothing
+     * @return std::uint8_t
+     */
+    template <typename ...Args>
+    static std::string type(Args ...args) {
+        flagset flags = core::arg_handler(args...);
+
+        const std::string brand_str = brand(flags);
+
+        // if multiple brands were found, return unknown
+        if (util::find(brand_str, " or ")) {
+            return "Unknown";
+        }
+
+        const std::map<std::string, const char*> type_table {
+            // type 1
+            { XEN, "Hypervisor (type 1)" },
+            { VMWARE_ESX, "Hypervisor (type 1)" },
+            { ACRN, "Hypervisor (type 1)" },
+            { QNX, "Hypervisor (type 1)" },
+            { HYPERV, "Hypervisor (type 1)" },
+            { AZURE_HYPERV, "Hypervisor (type 1)" },
+            { NANOVISOR, "Hypervisor (type 1)" },
+            { KVM, "Hypervisor (type 1)" },
+            { BHYVE, "Hypervisor (type 1)" },
+            { KVM_HYPERV, "Hypervisor (type 1)" },
+            { QEMU_KVM_HYPERV, "Hypervisor (type 1)" },
+            { QEMU_KVM, "Hypervisor (type 1)" },
+            { INTEL_HAXM, "Hypervisor (type 1)" },
+            { INTEL_KGT, "Hypervisor (type 1)" },
+            { SIMPLEVISOR, "Hypervisor (type 1)" },
+            { GCE, "Hypervisor (type 1)" },
+            { OPENSTACK, "Hypervisor (type 1)" },
+            { KUBEVIRT, "Hypervisor (type 1)" },
+            { POWERVM, "Hypervisor (type 1)" },
+            { AWS_NITRO, "Hypervisor (type 1)" },
+
+            // type 2
+            { VBOX, "Hypervisor (type 2)" },
+            { VMWARE, "Hypervisor (type 2)" },
+            { VMWARE_EXPRESS, "Hypervisor (type 2)" },
+            { VMWARE_GSX, "Hypervisor (type 2)" },
+            { VMWARE_WORKSTATION, "Hypervisor (type 2)" },
+            { VMWARE_FUSION, "Hypervisor (type 2)" },
+            { PARALLELS, "Hypervisor (type 2)" },
+            { VPC, "Hypervisor (type 2)" },
+            { NVMM, "Hypervisor (type 2)" },
+            { BSD_VMM, "Hypervisor (type 2)" },
+
+            // sandbox
+            { CUCKOO, "Sandbox" },
+            { SANDBOXIE, "Sandbox" },
+            { HYBRID, "Sandbox" },
+            { CWSANDBOX, "Sandbox" },
+            { JOEBOX, "Sandbox" },
+            { ANUBIS, "Sandbox" },
+            { COMODO, "Sandbox" },
+            { THREATEXPERT, "Sandbox" },
+
+            // misc
+            { BOCHS, "Emulator" },
+            { BLUESTACKS, "Emulator" },
+            { MSXTA, "Emulator" },
+            { QEMU, "Emulator/Hypervisor (type 2)" },
+            { JAILHOUSE, "Partitioning Hypervisor" },
+            { UNISYS, "Partitioning Hypervisor" },
+            { DOCKER, "Container" },
+            { PODMAN, "Container" },
+            { OPENVZ, "Container" },
+            { HYPERV_VPC, "Hypervisor (either type 1 or 2)" },
+            { LMHS, "Hypervisor (unknown type)" },
+            { WINE, "Compatibility layer" },
+            { APPLE_VZ, "Unknown" },
+            { HYPERV_ARTIFACT, "Unknown" },
+            { UML, "Paravirtualised/Hypervisor (type 2)" },
+            { WSL, "Hybrid Hyper-V (type 1 and 2)" }, // debatable tbh
+            { APPLE_ROSETTA, "Binary Translation Layer/Emulator" },
+        };
+
+        auto it = type_table.find(brand_str.c_str());
+
+        if (it != type_table.end()) {
+            return it->second;
+        }
+
+        return "Unknown";
+    }
+
+
+    /**
+     * @brief Fetch the conclusion message based on the brand and percentage
+     * @param any flag combination in VM structure or nothing
+     * @return std::string
+     */
+    template <typename ...Args>
+    static std::string conclusion(Args ...args) {
+        flagset flags = core::arg_handler(args...);
+
+        const std::string brand_tmp = brand(flags);
+        const u8 percent_tmp = percentage(flags);
+
+        constexpr const char* baremetal = "Running in baremetal";
+        constexpr const char* very_unlikely = "Very unlikely a VM";
+        constexpr const char* unlikely = "Unlikely a VM";
+
+        const std::string potentially = "Potentially";
+        const std::string might = "Might be";
+        const std::string likely = "Likely";
+        const std::string very_likely = "Very likely";
+        const std::string inside_vm = "Running inside";
+
+        auto make_conclusion = [&](const std::string &category) -> std::string {
+            std::string article = "";   
+
+            if (brand_tmp == "Unknown") {
+                article = " an ";
+            } else {
+                article = " a ";
+            }
+
+            return (category + article + brand_tmp + " VM"); 
+        };
+
+        if      (percent_tmp == 0)   { return baremetal; } 
+        else if (percent_tmp <= 20)  { return very_unlikely; } 
+        else if (percent_tmp <= 35)  { return unlikely; } 
+        else if (percent_tmp < 50)   { return make_conclusion(potentially); } 
+        else if (percent_tmp <= 62)  { return make_conclusion(might); } 
+        else if (percent_tmp <= 75)  { return make_conclusion(likely); } 
+        else if (percent_tmp < 100)  { return make_conclusion(very_likely); } 
+        else                         { return make_conclusion(inside_vm); }
+    }
+
+    #pragma pack(push, 1)
+    struct vmaware {
+        std::string brand;
+        std::string type;
+        std::string conclusion;
+        bool is_vm;
+        u8 percentage;
+        u8 detected_count;
+        u16 technique_count;
+
+        template <typename ...Args>
+        vmaware(Args ...args) {
+            flagset flags = core::arg_handler(args...);
+
+            brand = VM::brand(flags);
+            type = VM::type(flags);
+            conclusion = VM::conclusion(flags);
+            is_vm = VM::detect(flags);
+            percentage = VM::percentage(flags);
+            detected_count = VM::detected_count(flags);
+            technique_count = VM::technique_count;
+        }
+    };
+    #pragma pack(pop)
+
+
+    static u16 technique_count; // get total number of techniques
+    static std::vector<u8> technique_vector;
+#ifdef __VMAWARE_DEBUG__
+    static u16 total_points;
+#endif
+};
+
+MSVC_ENABLE_WARNING(ASSIGNMENT_OPERATOR NO_INLINE_FUNC SPECTRE)
+
+
+// ============= EXTERNAL DEFINITIONS =============
+// These are added here due to warnings related to C++17 inline variables for C++ standards that are under 17.
+// It's easier to just group them together rather than having C++17<= preprocessors with inline stuff
+
+
+// scoreboard list of brands, if a VM detection technique detects a brand, that will be incremented here as a single point.
+std::map<const char*, VM::brand_score_t> VM::core::brand_scoreboard{
+    { VM::VBOX, 0 },
+    { VM::VMWARE, 0 },
+    { VM::VMWARE_EXPRESS, 0 },
+    { VM::VMWARE_ESX, 0 },
+    { VM::VMWARE_GSX, 0 },
+    { VM::VMWARE_WORKSTATION, 0 },
+    { VM::VMWARE_FUSION, 0 },
+    { VM::BHYVE, 0 },
+    { VM::KVM, 0 },
+    { VM::QEMU, 0 },
+    { VM::QEMU_KVM, 0 },
+    { VM::KVM_HYPERV, 0 },
+    { VM::QEMU_KVM_HYPERV, 0 },
+    { VM::HYPERV, 0 },
+    { VM::HYPERV_VPC, 0 },
+    { VM::MSXTA, 0 },
+    { VM::PARALLELS, 0 },
+    { VM::XEN, 0 },
+    { VM::ACRN, 0 },
+    { VM::QNX, 0 },
+    { VM::HYBRID, 0 },
+    { VM::SANDBOXIE, 0 },
+    { VM::DOCKER, 0 },
+    { VM::WINE, 0 },
+    { VM::APPLE_ROSETTA, 0 },
+    { VM::VPC, 0 },
+    { VM::ANUBIS, 0 },
+    { VM::JOEBOX, 0 },
+    { VM::THREATEXPERT, 0 },
+    { VM::CWSANDBOX, 0 },
+    { VM::COMODO, 0 },
+    { VM::BOCHS, 0 },
+    { VM::NVMM, 0 },
+    { VM::BSD_VMM, 0 },
+    { VM::INTEL_HAXM, 0 },
+    { VM::UNISYS, 0 },
+    { VM::LMHS, 0 },
+    { VM::CUCKOO, 0 },
+    { VM::BLUESTACKS, 0 },
+    { VM::JAILHOUSE, 0 },
+    { VM::APPLE_VZ, 0 },
+    { VM::INTEL_KGT, 0 },
+    { VM::AZURE_HYPERV, 0 },
+    { VM::NANOVISOR, 0 },
+    { VM::SIMPLEVISOR, 0 },
+    { VM::HYPERV_ARTIFACT, 0 },
+    { VM::UML, 0 },
+    { VM::POWERVM, 0 },
+    { VM::GCE, 0 },
+    { VM::OPENSTACK, 0 },
+    { VM::KUBEVIRT, 0 },
+    { VM::AWS_NITRO, 0 },
+    { VM::PODMAN, 0 },
+    { VM::WSL, 0 },
+    { VM::OPENVZ, 0 },
+    { VM::NULL_BRAND, 0 }
+};
+
+
+// initial definitions for cache items because ISO C++ forbids in-class initializations
+std::map<VM::u16, VM::memo::data_t> VM::memo::cache_table;
+VM::flagset VM::memo::cache_keys = 0;
+std::string VM::memo::brand::brand_cache = "";
+std::string VM::memo::multi_brand::brand_cache = "";
+std::string VM::memo::cpu_brand::brand_cache = "";
+VM::hyperx_state VM::memo::hyperx::state = VM::hyperx_state::UNKNOWN;
+bool VM::memo::hyperx::cached = false;
+#if (MSVC)
+IWbemLocator* VM::wmi::pLoc = nullptr;
+IWbemServices* VM::wmi::pSvc = nullptr;
+#endif
+
+#ifdef __VMAWARE_DEBUG__
+VM::u16 VM::total_points = 0;
+#endif
+
+// these are basically the base values for the core::arg_handler function.
+// It's like a bucket that will collect all the bits enabled. If for example 
+// VM::detect(VM::HIGH_THRESHOLD) is passed, the HIGH_THRESHOLD bit will be 
+// collected in this flagset (std::bitset) variable, and eventually be the 
+// return value for actual end-user functions like VM::detect() to rely 
+// and work on. VM::global_flags is just a copy of the flags but visible 
+// globally throughout the whole VM struct, as the name implies.
+VM::flagset VM::core::flag_collector;
+VM::flagset VM::global_flags;
+
+
+VM::u8 VM::detected_count_num = 0;
+
+
+// default flags 
+VM::flagset VM::DEFAULT = []() noexcept -> flagset {
+    flagset tmp;
+
+    // set all bits to 1
+    tmp.set();
+
+    // disable all non-default techniques
+    tmp.flip(CURSOR);
+    tmp.flip(RDTSC);
+    tmp.flip(RDTSC_VMEXIT);
+    tmp.flip(VMWARE_DMESG);
+
+    // disable all the settings flags
+    tmp.flip(NO_MEMO);
+    tmp.flip(HIGH_THRESHOLD);
+    tmp.flip(SPOOFABLE);
+    tmp.flip(MULTIPLE);
+
+    return tmp;
+}();
+
+
+// flag to enable every technique
+VM::flagset VM::ALL = []() noexcept -> flagset {
+    flagset tmp;
+
+    // set all bits to 1
+    tmp.set();
+
+    // disable all the settings technique flags (except SPOOFABLE)
+    tmp.flip(NO_MEMO);
+    tmp.flip(HIGH_THRESHOLD);
+    tmp.flip(MULTIPLE);
+
+    return tmp;
+}();
+
+
+std::vector<VM::u8> VM::technique_vector = []() -> std::vector<VM::u8> {
+    std::vector<VM::u8> tmp{};
+
+    // all the techniques have a macro value starting from 0 to ~90, hence why it's a classic loop
+    for (u8 i = VM::technique_begin; i < VM::technique_end; i++) {
+        tmp.push_back(i);
+    }
+
+    return tmp;
+}();
+
+
+// this value is incremented each time VM::add_custom is called
+VM::u16 VM::technique_count = base_technique_count;
+
+
+// check if cpuid is supported
+bool VM::core::cpuid_supported = []() -> bool {
+#if (x86)
+#if (MSVC)
+    int32_t info[4];
+    __cpuid(info, 0);
+    return (info[0] > 0);
+#elif (LINUX)
+    u32 ext = 0;
+    return (__get_cpuid_max(ext, nullptr) > 0);
+#else
+    return false;
+#endif
+#else
+    return false;
+#endif
+}();
+
+
+// this is initialised as empty, because this is where custom techniques can be added at runtime 
+std::vector<VM::core::custom_technique> VM::core::custom_table = {
+
+};
+
+// the 0~100 points are debatable, but I think it's fine how it is. Feel free to disagree.
+const std::map<VM::enum_flags, VM::core::technique> VM::core::technique_table = {
+    // FORMAT: { VM::<ID>, { certainty%, function pointer, is spoofable? } },
+
+    { VM::VMID, { 100, VM::vmid, false } },
+    { VM::CPU_BRAND, { 50, VM::cpu_brand, false } },
+    { VM::HYPERVISOR_BIT, { 100, VM::hypervisor_bit , false}} , 
+    { VM::HYPERVISOR_STR, { 45, VM::hypervisor_str, false } },
+    { VM::RDTSC, { 10, VM::rdtsc_check, false } },
+    { VM::THREADCOUNT, { 35, VM::thread_count, false } },
+    { VM::MAC, { 60, VM::mac_address_check, true } },
+    { VM::TEMPERATURE, { 15, VM::temperature, false } },
+    { VM::SYSTEMD, { 70, VM::systemd_virt, false } },
+    { VM::CVENDOR, { 65, VM::chassis_vendor, false } },
+    { VM::CTYPE, { 10, VM::chassis_type, false } },
+    { VM::DOCKERENV, { 15, VM::dockerenv, true } },
+    { VM::DMIDECODE, { 55, VM::dmidecode, false } },
+    { VM::DMESG, { 55, VM::dmesg, false } },
+    { VM::HWMON, { 75, VM::hwmon, true } },
+    { VM::SIDT5, { 45, VM::sidt5, false } },
+    { VM::CURSOR, { 5, VM::cursor_check, true } },
+    { VM::VMWARE_REG, { 65, VM::vmware_registry, true } },
+    { VM::VBOX_REG, { 65, VM::vbox_registry, true } },
+    { VM::USER, { 35, VM::user_check, true } },
+    { VM::DLL, { 50, VM::DLL_check, true } },
+    { VM::REGISTRY, { 75, VM::registry_key, true } },
+    { VM::CWSANDBOX_VM, { 10, VM::cwsandbox_check, true } },
+    { VM::VM_FILES, { 60, VM::vm_files, true } },
+    { VM::HWMODEL, { 75, VM::hwmodel, true } },
+    { VM::DISK_SIZE, { 60, VM::disk_size, false } },
+    { VM::VBOX_DEFAULT, { 55, VM::vbox_default_specs, false } },
+    { VM::VBOX_NETWORK, { 70, VM::vbox_network_share, false } },
+    { VM::VM_PROCESSES, { 30, VM::vm_processes, true } },
+    { VM::LINUX_USER_HOST, { 25, VM::linux_user_host, true } },
+    { VM::GAMARUE, { 40, VM::gamarue, true } },
+    { VM::VMID_0X4, { 90, VM::vmid_0x4, false } },
+    { VM::PARALLELS_VM, { 50, VM::parallels, false } },
+    { VM::RDTSC_VMEXIT, { 15, VM::rdtsc_vmexit, false } },
+    { VM::QEMU_BRAND, { 100, VM::cpu_brand_qemu, false } },
+    { VM::BOCHS_CPU, { 95, VM::bochs_cpu, false } },
+    { VM::VPC_BOARD, { 20, VM::vpc_board, false } },
+    { VM::BIOS_SERIAL, { 60, VM::bios_serial, false } },
+    { VM::VBOX_FOLDERS, { 45, VM::vbox_shared_folders, false } },
+    { VM::MSSMBIOS, { 75, VM::mssmbios, false } },
+    { VM::MAC_MEMSIZE, { 30, VM::hw_memsize, true } },
+    { VM::MAC_IOKIT, { 80, VM::io_kit, true } },
+    { VM::IOREG_GREP, { 75, VM::ioreg_grep, true } },
+    { VM::MAC_SIP, { 85, VM::mac_sip, true } },
+    { VM::HKLM_REGISTRIES, { 70, VM::hklm_registries, true } },
+    { VM::QEMU_GA, { 20, VM::qemu_ga, true } },
+    { VM::VALID_MSR, { 35, VM::valid_msr, false } },
+    { VM::QEMU_PROC, { 30, VM::qemu_processes, true } },
+    { VM::VPC_PROC, { 30, VM::vpc_proc, true } },
+    { VM::VPC_INVALID, { 75, VM::vpc_invalid, false } },
+    { VM::SIDT, { 30, VM::sidt, false } },
+    { VM::SGDT, { 30, VM::sgdt, false } },
+    { VM::SLDT, { 15, VM::sldt, false } },
+    { VM::OFFSEC_SIDT, { 60, VM::offsec_sidt, false } },
+    { VM::OFFSEC_SGDT, { 60, VM::offsec_sgdt, false } },
+    { VM::OFFSEC_SLDT, { 20, VM::offsec_sldt, false } },
+    { VM::VPC_SIDT, { 15, VM::vpc_sidt, false } },
+    { VM::HYPERV_BOARD, { 45, VM::hyperv_board, false } },
+    { VM::VM_FILES_EXTRA, { 70, VM::vm_files_extra, true } },
+    { VM::VMWARE_IOMEM, { 65, VM::vmware_iomem, false } },
+    { VM::VMWARE_IOPORTS, { 70, VM::vmware_ioports, false } },
+    { VM::VMWARE_SCSI, { 40, VM::vmware_scsi, false } },
+    { VM::VMWARE_DMESG, { 65, VM::vmware_dmesg, false } },
+    { VM::VMWARE_STR, { 35, VM::vmware_str, false } },
+    { VM::VMWARE_BACKDOOR, { 100, VM::vmware_backdoor, false } },
+    { VM::VMWARE_PORT_MEM, { 85, VM::vmware_port_memory, false } },
+    { VM::SMSW, { 30, VM::smsw, false } },
+    { VM::MUTEX, { 85, VM::mutex, false } },
+    { VM::UPTIME, { 10, VM::uptime, true } },
+    { VM::ODD_CPU_THREADS, { 80, VM::odd_cpu_threads, false } },
+    { VM::INTEL_THREAD_MISMATCH, { 60, VM::intel_thread_mismatch, false } },
+    { VM::XEON_THREAD_MISMATCH, { 85, VM::xeon_thread_mismatch, false } },
+    { VM::NETTITUDE_VM_MEMORY, { 75, VM::nettitude_vm_memory, false } },
+    { VM::CPUID_BITSET, { 20, VM::cpuid_bitset, false } },
+    { VM::CUCKOO_DIR, { 15, VM::cuckoo_dir, true } },
+    { VM::CUCKOO_PIPE, { 20, VM::cuckoo_pipe, true } },
+    { VM::HYPERV_HOSTNAME, { 50, VM::hyperv_hostname, true } },
+    { VM::GENERAL_HOSTNAME, { 20, VM::general_hostname, true } },
+    { VM::SCREEN_RESOLUTION, { 30, VM::screen_resolution, false } },
+    { VM::DEVICE_STRING, { 25, VM::device_string, false } },
+    { VM::BLUESTACKS_FOLDERS, { 15, VM::bluestacks, true } },
+    { VM::CPUID_SIGNATURE, { 95, VM::cpuid_signature, false } },
+    { VM::HYPERV_BITMASK, { 20, VM::hyperv_bitmask, false } },
+    { VM::KVM_BITMASK, { 40, VM::kvm_bitmask, false } },
+    { VM::KGT_SIGNATURE, { 80, VM::intel_kgt_signature, false } },
+    { VM::VMWARE_DMI, { 30, VM::vmware_dmi, false } },
+    { VM::EVENT_LOGS, { 30, VM::hyperv_event_logs, true } },
+    { VM::QEMU_VIRTUAL_DMI, { 40, VM::qemu_virtual_dmi, false } },
+    { VM::QEMU_USB, { 20, VM::qemu_USB, false } },
+    { VM::HYPERVISOR_DIR, { 20, VM::hypervisor_dir, false } },
+    { VM::UML_CPU, { 80, VM::uml_cpu, false } },
+    { VM::KMSG, { 10, VM::kmsg, true } },
+    { VM::VM_PROCS, { 20, VM::vm_procs, true } },
+    { VM::VBOX_MODULE, { 15, VM::vbox_module, false } },
+    { VM::SYSINFO_PROC, { 15, VM::sysinfo_proc, false } },
+    { VM::DEVICE_TREE, { 20, VM::device_tree, false } },
+    { VM::DMI_SCAN, { 50, VM::dmi_scan, false } },
+    { VM::SMBIOS_VM_BIT, { 50, VM::smbios_vm_bit, false } },
+    { VM::PODMAN_FILE, { 15, VM::podman_file, true } },
+    { VM::WSL_PROC, { 30, VM::wsl_proc_subdir, false } },
+    { VM::GPU_CHIPTYPE, { 100, VM::gpu_chiptype, false } }
+};
\ No newline at end of file
diff --git a/al-khaser/.editorconfig b/al-khaser/.editorconfig
new file mode 100644
index 0000000000000000000000000000000000000000..88fbb9a592c4cdde02836a5d1f21200aca4f4d62
--- /dev/null
+++ b/al-khaser/.editorconfig
@@ -0,0 +1,11 @@
+; Top-most EditorConfig file
+root = true
+
+; Windows-style newlines
+[*]
+end_of_line = CRLF
+
+; Tab indentation
+[*.{cpp,h}]
+indent_style = tab
+tab_width = 4
\ No newline at end of file
diff --git a/al-khaser/CHANGELOG.md b/al-khaser/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..734d4b8d37b8a87a2af7e42a7274d18c42bd247d
--- /dev/null
+++ b/al-khaser/CHANGELOG.md
@@ -0,0 +1,173 @@
+#### 0.81
+
+- Add anti-debug trick: Low Fragmentation Heap.
+- Add known hostname / username checks from malware thanks to @recvfrom.
+- Add Anti-VM disk enum registry checks thanks to @recvfrom.
+- Fix Patching int2d check.
+- Fix wrong comment in CheckRemoteDebuggerPresent check thanks to @SpriteOvO.
+- Bug fixes and new checks in ThreadHideFromDebugger.
+- Improve parent process check to avoid false positives.
+- Fix ScanForModules_MemoryWalk_Hidden and add new .NET structure scan.
+- Add github action to build and upload binaries thanks to @graysuit.
+- Add Hyper-V object checks.
+- Add QEMU directory check (guest agent and SPICE tools).
+- Add KVM checks (virtio reg keys, files and directory).
+
+#### 0.80
+
+- Add Windows Genuine check. 
+- Improve GetOSDisplayString by adding Windows Server 2019.
+- Fixed the encoding of some files thanks to @not-matthias.
+- Add Missing manifest makes version checks return incorrect values.
+- Fix EnumProcessModulesEx crash on XP and some versions of Win7.
+- Fixed path names in vmware_files() and vbox_files() due to wow64 fs redirection.
+- Fixed string comparaison in check_adapter_name().
+- Anti anti-debug trick: trap flag.
+- Add check for well known names used by malware sandboxes.
+- Improve ProcessDebugObject anti-debug check thanks to @Mattiwatti
+
+
+#### 0.79
+- Add anti-disassembly trick: Jump with constant condition
+- Add anti-disassembly trick: Jump instruction with same target
+- Add anti-disassembly trick: Impossible disassembly
+- Add anti-disassembly trick: Function Pointers
+- Add anti-disassembly trick: Return Pointer Abuse
+- Add additional tools thanks to @darianvaughanm.
+
+
+#### 0.78
+- Fix anti-dump SizeOfImage() thanks to @Mattiwatti
+- Fix Virtualbox vartype flag check of VARIANT properties from WMI thanks to @Mattiwatti
+- Fix crash for Wow64 binaries in ScanForModules_LDR_Direct thanks to @dvarshavsky
+- Fix IsBadLibrary() FP's for Wow64 binaries thanks to @dvarshavsky
+- Added checks for Win32_PnPDevice for VBOX entries thanks to @gsuberland
+- Added checks for Win32_BaseBoard thanks to @gsuberland
+- Added checks for Win32_Bus to see if only ACPIBus_BUS_0, PCI_BUS_0, PNP_BUS_0 are present thanks to @gsuberland
+- Added checks for Win32_PnPEntity for known VirtualBox hardware thanks to @gsuberland
+- Added checks for vbox devices (PCI\\VEN_80EE&DEV_CAFE) using WMI thanks to @gsuberland
+- Added ATAIdentifyDump and StructDumpCodegen tools to the repo thanks to @gsuberland
+- Add README and CHANGELOG to VS solution file.
+- Delete compiled binaries from repository.
+- Ignores NuGet packages directory from git.
+- Fix false positive in VirtualBox BIOS serial number WMI check thanks to @gsuberland
+
+
+#### 0.77
+- Add a gitattributes to normalize line endings.
+- Update VMDriverServices routine thanks to @hfiref0x
+- Add virtual machine detect by license thanks to @hfiref0x
+- Fix for HardwareBreakpoints routine thanks to @hfiref0x
+- Fix memory leak in check_mac_addr routine thanks to @hfiref0x
+- Update MemoryBreakpoints_PageGuard.cpp thanks to @hfiref0x
+- Fix number of bugs in get_system_firmware thanks to @hfiref0x
+- Fix InitWMI routine and multiple bugs in WMI related routines thanks to @hfiref0x
+- Remove incorrect result checks and wrong printf specifiers in ScanForModules.cpp thanks to @hfiref0x
+- Fix null pointer dereference in qemu_firmware_ACPI routine thanks to @hfiref0x
+- Fix null pointer dereferences in VirtualBox.cpp & VMWare.cpp thanks to @hfiref0x
+- Fix QueueUserAPC_Injection routine by rewrite thanks to @hfiref0x
+- Fix null pointer dereference in setupdi_diskdrive routine thanks to @hfiref0x
+- Add error handling in log_print thanks to @hfiref0x
+- Fix null pointer dereference in print_last_error routine, add more error handling thanks to @hfiref0x
+- Fix signed/unsigned mismatch for specifiers in various *printf calls thanks to @hfiref0x
+- Fix resource leak in timing_IcmpSendEcho routine thanks to @hfiref0x
+- Fix missing VirtualAlloc checks in WriteWatch.cpp thanks to @hfiref0x
+- Remove incorrect return value checks thanks to @hfiref0x
+- Fixed multiple bugs in check_adapter_name & ascii_to_wide_str thanks to @hfiref0x
+- Update and add typecast in IsBadLibrary thanks to @hfiref0x
+- Fix handle leak in GetProccessIDByName routine thanks to @hfiref0x
+- Fix invalid return value check in attempt_to_read_memory_wow64 routine thanks to @hfiref0x
+- Remove double call of SetDebugPrivileges in CreateRemoteThread_Injection thanks to @hfiref0x
+- Fix multiple bugs in SetPrivilege routine thanks to @hfiref0x
+- Fix unexpected behavior in SetHandleInformatiom_ProtectedHandle thanks to @hfiref0x
+- Fix null pointer dereference in get_system_firmware routine thanks to @hfiref0x
+- Fix multiple bugs in {Services, log, Generic, timing, process, ScanForModules cpp files}  thanks to @hfiref0x
+- Fix null pointer derefence in {vmware,vbox,qemu}_firmware_ACPI thanks to @hfiref0x
+- Fix resource leak in ScanForModules_ToolHelp32 routine thanks to @hfiref0x
+- Fix multiple bugs in ProcessJob routine thanks to @hfiref0x
+
+#### 0.76
+- Renamed PEB_BeingDebugged.cpp to BeingDebugged.cpp
+- Renamed CheckRemoteDebuggerPresentAPI.cpp to CheckRemoteDebuggerPresent.cpp
+- Renamed ProcessHeap_NtGlobalFlag.cpp to NtGlobalFlag.cpp
+- Fix expression is always true in ScanForModules_LDR_Direct routine thanks to @hfiref0x
+- Fix multiple bugs in GetSetThreadContext_Injection routine thanks to @hfiref0x
+- Fix multiple bugs in CreateRemoteThread_Injection thanks to @hfiref0x
+- Fix invalid return value check in QueueUserAPC_Injection routine thanks to @hfiref0x
+- Fix multiple bugs in NtCreateThreadEx_Injection and actually make it work thanks to @hfiref0x
+- Fix multiple bugs in RtlCreateUserThread_Injection routine thanks to @hfiref0x
+- Rearrange a bit RtlCreateUserThread_Injection routine thanks to @hfiref0x
+- Fix multiple bugs in GetMainThreadId thanks to @hfiref0x
+- Fix always true expression in PrintAvailabilityReport routine thanks to @hfiref0x
+- Fix resource leak in vmware_devices routine thanks to @hfiref0x
+- Fix resource leak in vbox_devices routine thanks to @hfiref0x
+- Fix invalid comparison in IsBadLibrary routine thanks to @hfiref0x
+- Fix invalid memory allocation size in HardwareBreakpoints routine thanks to @hfiref0x
+- Update print_os routine thanks to @hfiref0x
+- Moved the project to Visual Studio 2017
+- Add AppVeyor CI to build the project and check for errors.
+- Add WMI Win32_Fan anti-vm trick
+- Add DLL injection detection #148 (thanks to @gsuberland):
+    - Enumerate modules with EnumProcessModulesEx (32-bit, 64-bit, and all options)
+    - Enumerate modules with ToolHelp32
+    - Enumerate the process LDR structures
+    - Walk memory with GetModuleInformation
+    - Walk memory for hidden modules
+    - Patch issue with IsWin10OrGreater() due to missing compatibility GUIDs in application manifest
+    - Add support for detecting presence of APIs that were removed in a later OS version
+    - Add some WoW64 memory read/query utility functions for reading the 64-bit address space
+- Added enumerate_memory function for finding all memory allocations in the process thanks to @gsuberland
+
+#### 0.75
+- Fixed a typo in API data structure and move print_os() after API initialization thanks to @hzqst
+- Added page exception breakpoint anti-debug check (mainly focused on Cheat Engine)
+- Added checks for power capabilities (GetPwrCapabilities)
+- Added CreateWaitableTimer and CreateTimerQueueTimer timing attack checks
+- Added Comodo sandbox checks thanks to @kaganisildak
+- Added Hybrid Analysis sandbox checks thanks to @kaganisildak
+- Improved TLS callback checks (no longer requires user interaction)
+- Improved check text output so that it displays the it before the check completes
+- Improved ThreadHideFromDebugger check
+- Improved disk size IOCTL checks
+- Improved reporting of timing checks
+- Overhauled the code to use precompiled headers
+- Added a standardised way to load and check APIs that aren't always available
+- Fixed a bug that caused TLS callbacks to not always work
+- Fixed a bug which resulted in a crash when RtlGetVersion was not available
+- Fixed a string formatting bug in the Xen VM checks
+- Fixed a bug where disk size was not read properly in the disk size WMI check
+- Fixed a bug where the locky timer trick never worked
+
+#### 0.74
+- Added qemu process check (qemu-ga.exe) thanks to @kaganisildak.
+- Added checks for system firmware tables (SMBIOS and ACPI for QEMU).
+- Added checks for Hyper-V/Virtual-PC anti-VM (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters)
+- Added checks for multiple virtualization vendors using WMI (Select SerialNumber from Win32_BIOS).
+- Added checks for multiple virtualization vendors using WMI (Select Model/Manufacturer from Win32_ComputerSystem).
+- Added checks for MAC address for Xen, Parallels.
+- Added checks for ProcessorId using WMI (Select ProcessorId from Win32_Process).
+- Added checks for current CPU temperature using WMI (Select CurrentTemperature from MSAcpi_ThermalZoneTemperature).
+
+#### 0.73
+- Bug fix: GetSystemFirmwareTable should take `resultBufferSize` as an argument for the second call.
+- Bug fix: nullref exception in timing.cpp.
+- New: Add more checks for VMware related processes.
+- New: Add more checks for VMware related files.
+- New: Add more checks for VMWare related registry: SYSTEM\\ControlSet001\\Control\\SystemInformation.
+- New: Add more checks for system firmware tables (SMBIOS and ACPI for VMware).
+- New: Add more loaded dlls check inside process context:  avghookx.dll, avghooka.dll, snxhk.dll.
+- New: Add write watch debugger detection.
+- New: Add service anti-VM checks.
+- New: Add checks for VM related services.
+- Enhancement: add some macros to enable/disable a particular category of checks to easy debugging.
+
+#### 0.72
+- Bug fix: PEB offset in NumberOfProcessors() thanks to @Nxgr.
+- Bug fix: array with duplicate strings in process_tools check thanks to @stxletto.
+- Bug fix: ascii_to_wide_str() wrong argument thanks to @stxletto.
+
+#### 0.71
+- New: Add kernel debugger check using the KUSER_SHARED_DATA struct.
+- New: Add kernel debugger check using NtQuerySystemInformation with SystemKernelDebuggerInformation.
+- New: Added process job anti-debug check.
+- New: Added system firmware tables with GetSystemFirmwareTable (SMBIOS and ACPI for VirtualBox).
\ No newline at end of file
diff --git a/al-khaser/LICENSE b/al-khaser/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..ece019f0a2ba41b3e753d904e2c3d706944ec310
--- /dev/null
+++ b/al-khaser/LICENSE
@@ -0,0 +1,340 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    {description}
+    Copyright (C) {year}  {fullname}
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  {signature of Ty Coon}, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
+
diff --git a/al-khaser/README.md b/al-khaser/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a84d7391e23ec26e217e5a6923d8ef571f1fa70f
--- /dev/null
+++ b/al-khaser/README.md
@@ -0,0 +1,322 @@
+## Al-Khaser v0.81
+
+![Logo](https://www.mindmeister.com/files/avatars/0035/8332/original/avatar.jpg)
+
+## Content
+
+- [Introduction](#introduction)
+- [Possible uses](#uses)
+- [Features](#features)
+ - [Anti-debugging attacks](#antidebug)
+ - [Anti-Dumping](#antidump)
+ - [Timing Attacks](#timingattack)
+ - [Human Interaction](#antidump)
+ - [Anti-VM](#antivm)
+ - [Anti-Disassembly](#antidisassm)
+- [Requirements](#requirements)
+- [License](#license)
+
+
+## Introduction
+
+al-khaser is a PoC "malware" application with good intentions that aims to stress your anti-malware system.
+It performs a bunch of common malware tricks with the goal of seeing if you stay under the radar.
+
+![Logo](https://i.imgur.com/jEFhsJT.png)
+
+
+## Download
+
+You can download built binaries (x86, x64) from this project's [releases page](https://github.com/LordNoteworthy/al-khaser/releases). The password for the 7zs can be found [here](https://github.com/LordNoteworthy/al-khaser/blob/master/.github/workflows/release.yml#L25).
+
+
+## Possible uses
+
+- You are making an anti-debug plugin and you want to check its effectiveness.
+- You want to ensure that your sandbox solution is hidden enough.
+- Or you want to ensure that your malware analysis environment is well hidden.
+
+Please, if you encounter any of the anti-analysis tricks which you have seen in a malware, don't hesitate to contribute.
+
+
+## Features
+### Anti-debugging attacks
+- IsDebuggerPresent
+- CheckRemoteDebuggerPresent
+- Process Environment Block (BeingDebugged)
+- Process Environment Block (NtGlobalFlag)
+- ProcessHeap (Flags)
+- ProcessHeap (ForceFlags)
+- Low Fragmentation Heap (LFH)
+- NtQueryInformationProcess (ProcessDebugPort)
+- NtQueryInformationProcess (ProcessDebugFlags)
+- NtQueryInformationProcess (ProcessDebugObject)
+- WudfIsAnyDebuggerPresent
+- WudfIsKernelDebuggerPresent
+- WudfIsUserDebuggerPresent
+- NtSetInformationThread (HideThreadFromDebugger)
+- NtQueryObject (ObjectTypeInformation)
+- NtQueryObject (ObjectAllTypesInformation)
+- CloseHanlde (NtClose) Invalide Handle
+- SetHandleInformation (Protected Handle)
+- UnhandledExceptionFilter
+- OutputDebugString (GetLastError())
+- Hardware Breakpoints (SEH / GetThreadContext)
+- Software Breakpoints (INT3 / 0xCC)
+- Memory Breakpoints (PAGE_GUARD)
+- Interrupt 0x2d
+- Interrupt 1
+- Trap Flag
+- Parent Process (Explorer.exe)
+- SeDebugPrivilege (Csrss.exe)
+- NtYieldExecution / SwitchToThread
+- TLS callbacks
+- Process jobs
+- Memory write watching
+- Page exception breakpoint detection
+- API hook detection (module bounds based)
+
+### Anti-injection
+- Enumerate modules with EnumProcessModulesEx (32-bit, 64-bit, and all options)
+- Enumerate modules with ToolHelp32  
+- Enumerate the process LDR structures with LdrEnumerateLoadedModules
+- Enumerate the process LDR structures directly
+- Walk memory with GetModuleInformation
+- Walk memory for hidden modules
+
+### Anti-Dumping
+- Erase PE header from memory
+- SizeOfImage
+
+### Timing Attacks [Anti-Sandbox]
+- RDTSC (with CPUID to force a VM Exit)
+- RDTSC (Locky version with GetProcessHeap & CloseHandle)
+- Sleep -> SleepEx -> NtDelayExecution
+- Sleep (in a loop a small delay)
+- Sleep and check if time was accelerated (GetTickCount)
+- SetTimer (Standard Windows Timers)
+- timeSetEvent (Multimedia Timers)
+- WaitForSingleObject -> WaitForSingleObjectEx -> NtWaitForSingleObject
+- WaitForMultipleObjects -> WaitForMultipleObjectsEx -> NtWaitForMultipleObjects
+- IcmpSendEcho (CCleaner Malware)
+- CreateWaitableTimer
+- CreateTimerQueueTimer
+- Big crypto loops (todo)
+
+### Human Interaction / Generic [Anti-Sandbox]
+- Mouse movement
+- File names like `sample.exe` or `sandbox.exe`.
+- Total Physical memory (GlobalMemoryStatusEx)
+- Disk size using DeviceIoControl (IOCTL_DISK_GET_LENGTH_INFO)
+- Disk size using GetDiskFreeSpaceEx (TotalNumberOfBytes)
+- Mouse (Single click / Double click) (todo)
+- DialogBox (todo)
+- Scrolling (todo)
+- Execution after reboot (todo)
+- Count of processors (Win32/Tinba - Win32/Dyre)
+- Sandbox known product IDs (todo)
+- Color of background pixel (todo)
+- Keyboard layout (Win32/Banload) (todo)
+- Genuine Windows installation.
+- Known Sandbox hostnames and usernames
+
+### Anti-Virtualization / Full-System Emulation
+- **Registry key value artifacts**
+  - HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0 (Identifier) (VBOX)
+  - HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0 (Identifier) (QEMU)
+  - HARDWARE\\Description\\System (SystemBiosVersion) (VBOX)
+  - HARDWARE\\Description\\System (SystemBiosVersion) (QEMU)
+  - HARDWARE\\Description\\System (VideoBiosVersion) (VIRTUALBOX)
+  - HARDWARE\\Description\\System (SystemBiosDate) (06/23/99)
+  - HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0 (Identifier) (VMWARE)
+  - HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0 (Identifier) (VMWARE)
+  - HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 2\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0 (Identifier) (VMWARE)
+  - SYSTEM\\ControlSet001\\Control\\SystemInformation (SystemManufacturer) (VMWARE)
+  - SYSTEM\\ControlSet001\\Control\\SystemInformation (SystemProductName) (VMWARE)
+- **Registry Keys artifacts**
+  - HARDWARE\\ACPI\\DSDT\\VBOX__ (VBOX)
+  - HARDWARE\\ACPI\\FADT\\VBOX__ (VBOX)
+  - HARDWARE\\ACPI\\RSDT\\VBOX__ (VBOX)
+  - SOFTWARE\\Oracle\\VirtualBox Guest Additions (VBOX)
+  - SYSTEM\\ControlSet001\\Services\\VBoxGuest (VBOX)
+  - SYSTEM\\ControlSet001\\Services\\VBoxMouse (VBOX)
+  - SYSTEM\\ControlSet001\\Services\\VBoxService (VBOX)
+  - SYSTEM\\ControlSet001\\Services\\VBoxSF (VBOX)
+  - SYSTEM\\ControlSet001\\Services\\VBoxVideo (VBOX)
+  - SOFTWARE\\VMware, Inc.\\VMware Tools (VMWARE)
+  - SOFTWARE\\Wine (WINE)
+  - SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters (HYPER-V)
+  - SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum
+  - SYSTEM\\CurrentControlSet\\Enum\\IDE
+  - SYSTEM\\CurrentControlSet\\Enum\\SCSI
+- **File system artifacts**
+  - "system32\\drivers\\VBoxMouse.sys"
+  - "system32\\drivers\\VBoxGuest.sys"
+  - "system32\\drivers\\VBoxSF.sys"
+  - "system32\\drivers\\VBoxVideo.sys"
+  - "system32\\vboxdisp.dll"
+  - "system32\\vboxhook.dll"
+  - "system32\\vboxmrxnp.dll"
+  - "system32\\vboxogl.dll"
+  - "system32\\vboxoglarrayspu.dll"
+  - "system32\\vboxoglcrutil.dll"
+  - "system32\\vboxoglerrorspu.dll"
+  - "system32\\vboxoglfeedbackspu.dll"
+  - "system32\\vboxoglpackspu.dll"
+  - "system32\\vboxoglpassthroughspu.dll"
+  - "system32\\vboxservice.exe"
+  - "system32\\vboxtray.exe"
+  - "system32\\VBoxControl.exe"
+  - "system32\\drivers\\vmmouse.sys"
+  - "system32\\drivers\\vmhgfs.sys"
+  - "system32\\drivers\\vm3dmp.sys"
+  - "system32\\drivers\\vmci.sys"
+  - "system32\\drivers\\vmhgfs.sys"
+  - "system32\\drivers\\vmmemctl.sys"
+  - "system32\\drivers\\vmmouse.sys"
+  - "system32\\drivers\\vmrawdsk.sys"
+  - "system32\\drivers\\vmusbmouse.sys"
+
+- **Directories artifacts**
+  - "%PROGRAMFILES%\\oracle\\virtualbox guest additions\\"
+  - "%PROGRAMFILES%\\VMWare\\"
+- **Memory artifacts**
+  - Interupt Descriptor Table (IDT) location
+  - Local Descriptor Table (LDT) location
+  - Global Descriptor Table (GDT) location
+  - Task state segment trick with STR
+- **MAC Address**
+  - "\x08\x00\x27" (VBOX)
+  - "\x00\x05\x69" (VMWARE)
+  - "\x00\x0C\x29" (VMWARE)
+  - "\x00\x1C\x14" (VMWARE)
+  - "\x00\x50\x56" (VMWARE)
+  - "\x00\x1C\x42" (Parallels)
+  - "\x00\x16\x3E" (Xen)
+  - "\x0A\x00\x27" (Hybrid Analysis)
+- **Virtual devices**
+  - "\\\\.\\VBoxMiniRdrDN"
+  - "\\\\.\\VBoxGuest"
+  - "\\\\.\\pipe\\VBoxMiniRdDN"
+  - "\\\\.\\VBoxTrayIPC"
+  - "\\\\.\\pipe\\VBoxTrayIPC")
+  - "\\\\.\\HGFS"
+  - "\\\\.\\vmci"
+- **Hardware Device information**
+  - SetupAPI SetupDiEnumDeviceInfo (GUID_DEVCLASS_DISKDRIVE) 
+    - QEMU
+    - VMWare
+    - VBOX
+    - VIRTUAL HD
+  - Power policies (S1-S4 states, thermal control)
+- **System Firmware Tables**
+  - SMBIOS string checks (VirtualBox)
+  - SMBIOS string checks (VMWare)
+  - SMBIOS string checks (Qemu)
+  - SMBIOS number of tables (Qemu, VirtualBox)
+  - ACPI string checks (VirtualBox)
+  - ACPI string checks (VMWare)
+  - ACPI string checks (Qemu)
+- **Driver Services**
+  - VirtualBox
+  - VMWare
+- **Adapter name**
+  - VMWare
+- **Windows Class**
+  - VBoxTrayToolWndClass
+  - VBoxTrayToolWnd
+- **Network shares**
+  - VirtualBox Shared Folders
+- **Processes**
+  - vboxservice.exe	(VBOX)
+  - vboxtray.exe	(VBOX)
+  - vmtoolsd.exe(VMWARE)
+  - vmwaretray.exe(VMWARE)
+  - vmwareuser(VMWARE)
+  - VGAuthService.exe (VMWARE)
+  - vmacthlp.exe (VMWARE)
+  - vmsrvc.exe(VirtualPC)
+  - vmusrvc.exe(VirtualPC)
+  - prl_cc.exe(Parallels)
+  - prl_tools.exe(Parallels)
+  - xenservice.exe(Citrix Xen)
+  - qemu-ga.exe (QEMU)
+- **WMI**
+  - SELECT * FROM Win32_Bios (SerialNumber) (GENERIC)
+  - SELECT * FROM Win32_PnPEntity (DeviceId) (VBOX)
+  - SELECT * FROM Win32_NetworkAdapterConfiguration (MACAddress) (VBOX)
+  - SELECT * FROM Win32_NTEventlogFile (VBOX)
+  - SELECT * FROM Win32_Processor (NumberOfCores and ProcessorId) (GENERIC)
+  - SELECT * FROM Win32_LogicalDisk (Size) (GENERIC)
+  - SELECT * FROM Win32_ComputerSystem (Model and Manufacturer) (GENERIC)
+  - SELECT * FROM MSAcpi_ThermalZoneTemperature CurrentTemperature) (GENERIC)
+  - SELECT * FROM Win32_Fan (GENERIC)
+- **DLL Exports and Loaded DLLs**
+  - avghookx.dll (AVG)
+  - avghooka.dll (AVG)
+  - snxhk.dll (Avast)
+  - kernel32.dll!wine_get_unix_file_nameWine (Wine)
+  - sbiedll.dll (Sandboxie)
+  - dbghelp.dll (MS debugging support routines)
+  - api_log.dll (iDefense Labs)
+  - dir_watch.dll (iDefense Labs)
+  - pstorec.dll (SunBelt Sandbox)
+  - vmcheck.dll (Virtual PC)
+  - wpespy.dll (WPE Pro)
+  - cmdvrt32.dll (Comodo Container)
+  - cmdvrt64.dll (Comodo Container)
+- **CPU**
+  - Hypervisor presence using (EAX=0x1)
+  - Hypervisor vendor using (EAX=0x40000000)
+    - "KVMKVMKVM\0\0\0"	(KVM)
+      - "Microsoft Hv"(Microsoft Hyper-V or Windows Virtual PC)
+      - "VMwareVMware"(VMware)
+      - "XenVMMXenVMM"(Xen)
+      - "prl hyperv  "( Parallels)
+         -"VBoxVBoxVBox"( VirtualBox)
+- NtQueryLicenseValue with Kernel-VMDetection-Private as license value.
+
+### Anti-Analysis
+- **Processes**
+  - OllyDBG / ImmunityDebugger / WinDbg / IDA Pro / X64dbg / Cheat Engine
+  - SysInternals Suite Tools (Process Explorer / Process Monitor / Regmon / Filemon, TCPView, Autoruns)
+  - Wireshark / Dumpcap / Fiddler / Http Debugger
+  - ProcessHacker / SysAnalyzer / HookExplorer / SysInspector
+  - ImportREC / PETools / LordPE
+  - JoeBox Sandbox
+  - Resource Hacker
+  - Frida
+
+### Anti-Disassembly
+- Jump with constant condition
+- Jump instruction with same target
+- Impossible disassembly
+- Function Pointers
+- Return Pointer Abuse
+
+### Macro malware attacks
+- Document_Close / Auto_Close.
+- Application.RecentFiles.Count 
+
+### Code/DLL Injections techniques
+- CreateRemoteThread 
+- SetWindowsHooksEx
+- NtCreateThreadEx
+- RtlCreateUserThread
+- APC (QueueUserAPC / NtQueueApcThread)
+- RunPE (GetThreadContext / SetThreadContext)
+
+## Authors
+- [Mattiwatti](https://github.com/Mattiwatti): Matthijs Lavrijsen
+- [gsuberland](https://twitter.com/gsuberland): Graham Sutherland
+- [hFireF0x](https://github.com/hfiref0x): hfiref0x
+
+Pull requests welcome. Please read the [Developer Guidelines](https://github.com/LordNoteworthy/al-khaser/wiki/Developer-Guidelines) on our wiki if you wish to contribute to the project.
+
+## References
+- An Anti-Reverse Engineering Guide By Josh Jackson.
+- Anti-Unpacker Tricks By Peter Ferrie.
+- The Art Of Unpacking By Mark Vincent Yason.
+- Walied Assar's blog http://waleedassar.blogspot.de/.
+- Pafish tool: https://github.com/a0rtega/pafish.
+- PafishMacro by JoeSecurity: https://github.com/joesecurity/pafishmacro 
diff --git a/al-khaser/Tools/ATAIdentifyDump/ATAIdentifyDump.cpp b/al-khaser/Tools/ATAIdentifyDump/ATAIdentifyDump.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..82bfcbcb9d2bf6fde11c0be4457853ffd37664cb
--- /dev/null
+++ b/al-khaser/Tools/ATAIdentifyDump/ATAIdentifyDump.cpp
@@ -0,0 +1,442 @@
+#include "pch.h"
+
+int main()
+{
+	printf("Dumping data for all disks.\n");
+	printf("\n");
+	for (int driveNumber = 0; driveNumber < 16; driveNumber++)
+	{
+		char deviceNameBuffer[64] = { 0 };
+		sprintf_s(deviceNameBuffer, "\\\\.\\PhysicalDrive%d", driveNumber);
+
+		HANDLE diskHandle = CreateFileA(
+			deviceNameBuffer,
+			GENERIC_READ | GENERIC_WRITE,
+			FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+			0,
+			OPEN_EXISTING,
+			0,
+			0
+		);
+
+		if (diskHandle == INVALID_HANDLE_VALUE)
+		{
+			printf("====================\n");
+			printf("ERROR: Failed to open handle to %s. Last error: %d\n", deviceNameBuffer, GetLastError());
+			printf("====================\n");
+			continue;
+		}
+
+		const unsigned int IdentifyBufferSize = 512;
+		const BYTE IdentifyCommandID = 0xEC;
+		unsigned char Buffer[IdentifyBufferSize + sizeof(ATA_PASS_THROUGH_EX)] = { 0 };
+		ATA_PASS_THROUGH_EX & pte = *reinterpret_cast<ATA_PASS_THROUGH_EX*>(Buffer);
+		pte.Length = sizeof(pte);
+		pte.TimeOutValue = 10;
+		pte.DataTransferLength = 512;
+		pte.DataBufferOffset = sizeof(ATA_PASS_THROUGH_EX);
+
+		IDEREGS* regs = (IDEREGS*)pte.CurrentTaskFile;
+		regs->bCommandReg = IdentifyCommandID;
+		regs->bSectorCountReg = 1;
+
+		pte.AtaFlags = ATA_FLAGS_DATA_IN | ATA_FLAGS_DRDY_REQUIRED;
+
+		DWORD br = 0;
+		BOOL ioctlSuccess = DeviceIoControl(
+			diskHandle,
+			IOCTL_ATA_PASS_THROUGH,
+			&pte,
+			sizeof(Buffer),
+			&pte,
+			sizeof(Buffer),
+			&br,
+			0
+		);
+
+		if (!ioctlSuccess)
+		{
+			printf("====================\n");
+			printf("ATA pass through IOCTL failed for drive %s. Last error: %d\n", deviceNameBuffer, GetLastError());
+			printf("====================\n");
+			CloseHandle(diskHandle);
+			continue;
+		}
+
+		IDENTIFY_DEVICE_DATA *idd = reinterpret_cast<IDENTIFY_DEVICE_DATA*>(Buffer + sizeof(ATA_PASS_THROUGH_EX));
+
+		printf("\n");
+		printf("====================\n");
+		printf("BEGIN IDENTIFY_DEVICE_DATA for %s\n", deviceNameBuffer);
+		printf("====================\n");
+		printf("GeneralConfiguration.Reserved1 = %hu\n", idd->GeneralConfiguration.Reserved1);
+		printf("GeneralConfiguration.Retired3 = %hu\n", idd->GeneralConfiguration.Retired3);
+		printf("GeneralConfiguration.ResponseIncomplete = %hu\n", idd->GeneralConfiguration.ResponseIncomplete);
+		printf("GeneralConfiguration.Retired2 = %hu\n", idd->GeneralConfiguration.Retired2);
+		printf("GeneralConfiguration.FixedDevice = %hu\n", idd->GeneralConfiguration.FixedDevice);
+		printf("GeneralConfiguration.RemovableMedia = %hu\n", idd->GeneralConfiguration.RemovableMedia);
+		printf("GeneralConfiguration.Retired1 = %hu\n", idd->GeneralConfiguration.Retired1);
+		printf("GeneralConfiguration.DeviceType = %hu\n", idd->GeneralConfiguration.DeviceType);
+		printf("NumCylinders = %hu\n", idd->NumCylinders);
+		printf("ReservedWord2 = %hu\n", idd->ReservedWord2);
+		printf("NumHeads = %hu\n", idd->NumHeads);
+		printf("Retired1[0] = %hu\n", idd->Retired1[0]);
+		printf("Retired1[1] = %hu\n", idd->Retired1[1]);
+		printf("NumSectorsPerTrack = %hu\n", idd->NumSectorsPerTrack);
+		printf("VendorUnique1[0] = %hu\n", idd->VendorUnique1[0]);
+		printf("VendorUnique1[1] = %hu\n", idd->VendorUnique1[1]);
+		printf("VendorUnique1[2] = %hu\n", idd->VendorUnique1[2]);
+		printf("SerialNumber = \"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\"\n", idd->SerialNumber[1], idd->SerialNumber[0], idd->SerialNumber[3], idd->SerialNumber[2], idd->SerialNumber[5], idd->SerialNumber[4], idd->SerialNumber[7], idd->SerialNumber[6], idd->SerialNumber[9], idd->SerialNumber[8], idd->SerialNumber[11], idd->SerialNumber[10], idd->SerialNumber[13], idd->SerialNumber[12], idd->SerialNumber[15], idd->SerialNumber[14], idd->SerialNumber[17], idd->SerialNumber[16], idd->SerialNumber[19], idd->SerialNumber[18]);
+		printf("Retired2[0] = %hu\n", idd->Retired2[0]);
+		printf("Retired2[1] = %hu\n", idd->Retired2[1]);
+		printf("Obsolete1 = %hu\n", idd->Obsolete1);
+		printf("FirmwareRevision = \"%c%c%c%c%c%c%c%c\"\n", idd->FirmwareRevision[1], idd->FirmwareRevision[0], idd->FirmwareRevision[3], idd->FirmwareRevision[2], idd->FirmwareRevision[5], idd->FirmwareRevision[4], idd->FirmwareRevision[7], idd->FirmwareRevision[6]);
+		printf("ModelNumber = \"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\"\n", idd->ModelNumber[1], idd->ModelNumber[0], idd->ModelNumber[3], idd->ModelNumber[2], idd->ModelNumber[5], idd->ModelNumber[4], idd->ModelNumber[7], idd->ModelNumber[6], idd->ModelNumber[9], idd->ModelNumber[8], idd->ModelNumber[11], idd->ModelNumber[10], idd->ModelNumber[13], idd->ModelNumber[12], idd->ModelNumber[15], idd->ModelNumber[14], idd->ModelNumber[17], idd->ModelNumber[16], idd->ModelNumber[19], idd->ModelNumber[18], idd->ModelNumber[21], idd->ModelNumber[20], idd->ModelNumber[23], idd->ModelNumber[22], idd->ModelNumber[25], idd->ModelNumber[24], idd->ModelNumber[27], idd->ModelNumber[26], idd->ModelNumber[29], idd->ModelNumber[28], idd->ModelNumber[31], idd->ModelNumber[30], idd->ModelNumber[33], idd->ModelNumber[32], idd->ModelNumber[35], idd->ModelNumber[34], idd->ModelNumber[37], idd->ModelNumber[36], idd->ModelNumber[39], idd->ModelNumber[38]);
+		printf("MaximumBlockTransfer = %d\n", idd->MaximumBlockTransfer);
+		printf("VendorUnique2 = %d\n", idd->VendorUnique2);
+		printf("ReservedWord48 = %hu\n", idd->ReservedWord48);
+		printf("Capabilities.ReservedByte49 = %d\n", idd->Capabilities.ReservedByte49);
+		printf("Capabilities.DmaSupported = %d\n", idd->Capabilities.DmaSupported);
+		printf("Capabilities.LbaSupported = %d\n", idd->Capabilities.LbaSupported);
+		printf("Capabilities.IordyDisable = %d\n", idd->Capabilities.IordyDisable);
+		printf("Capabilities.IordySupported = %d\n", idd->Capabilities.IordySupported);
+		printf("Capabilities.Reserved1 = %d\n", idd->Capabilities.Reserved1);
+		printf("Capabilities.StandybyTimerSupport = %d\n", idd->Capabilities.StandybyTimerSupport);
+		printf("Capabilities.Reserved2 = %d\n", idd->Capabilities.Reserved2);
+		printf("Capabilities.ReservedWord50 = %hu\n", idd->Capabilities.ReservedWord50);
+		printf("ObsoleteWords51[0] = %hu\n", idd->ObsoleteWords51[0]);
+		printf("ObsoleteWords51[1] = %hu\n", idd->ObsoleteWords51[1]);
+		printf("TranslationFieldsValid = %hu\n", idd->TranslationFieldsValid);
+		printf("Reserved3 = %hu\n", idd->Reserved3);
+		printf("NumberOfCurrentCylinders = %hu\n", idd->NumberOfCurrentCylinders);
+		printf("NumberOfCurrentHeads = %hu\n", idd->NumberOfCurrentHeads);
+		printf("CurrentSectorsPerTrack = %hu\n", idd->CurrentSectorsPerTrack);
+		printf("CurrentSectorCapacity = %lu\n", idd->CurrentSectorCapacity);
+		printf("CurrentMultiSectorSetting = %d\n", idd->CurrentMultiSectorSetting);
+		printf("MultiSectorSettingValid = %d\n", idd->MultiSectorSettingValid);
+		printf("ReservedByte59 = %d\n", idd->ReservedByte59);
+		printf("UserAddressableSectors = %lu\n", idd->UserAddressableSectors);
+		printf("ObsoleteWord62 = %hu\n", idd->ObsoleteWord62);
+		printf("MultiWordDMASupport = %hu\n", idd->MultiWordDMASupport);
+		printf("MultiWordDMAActive = %hu\n", idd->MultiWordDMAActive);
+		printf("AdvancedPIOModes = %hu\n", idd->AdvancedPIOModes);
+		printf("ReservedByte64 = %hu\n", idd->ReservedByte64);
+		printf("MinimumMWXferCycleTime = %hu\n", idd->MinimumMWXferCycleTime);
+		printf("RecommendedMWXferCycleTime = %hu\n", idd->RecommendedMWXferCycleTime);
+		printf("MinimumPIOCycleTime = %hu\n", idd->MinimumPIOCycleTime);
+		printf("MinimumPIOCycleTimeIORDY = %hu\n", idd->MinimumPIOCycleTimeIORDY);
+		printf("ReservedWords69[0] = %hu\n", idd->ReservedWords69[0]);
+		printf("ReservedWords69[1] = %hu\n", idd->ReservedWords69[1]);
+		printf("ReservedWords69[2] = %hu\n", idd->ReservedWords69[2]);
+		printf("ReservedWords69[3] = %hu\n", idd->ReservedWords69[3]);
+		printf("ReservedWords69[4] = %hu\n", idd->ReservedWords69[4]);
+		printf("ReservedWords69[5] = %hu\n", idd->ReservedWords69[5]);
+		printf("QueueDepth = %hu\n", idd->QueueDepth);
+		printf("ReservedWord75 = %hu\n", idd->ReservedWord75);
+		printf("ReservedWords76[0] = %hu\n", idd->ReservedWords76[0]);
+		printf("ReservedWords76[1] = %hu\n", idd->ReservedWords76[1]);
+		printf("ReservedWords76[2] = %hu\n", idd->ReservedWords76[2]);
+		printf("ReservedWords76[3] = %hu\n", idd->ReservedWords76[3]);
+		printf("MajorRevision = %hu\n", idd->MajorRevision);
+		printf("MinorRevision = %hu\n", idd->MinorRevision);
+		printf("CommandSetSupport.SmartCommands = %hu\n", idd->CommandSetSupport.SmartCommands);
+		printf("CommandSetSupport.SecurityMode = %hu\n", idd->CommandSetSupport.SecurityMode);
+		printf("CommandSetSupport.RemovableMediaFeature = %hu\n", idd->CommandSetSupport.RemovableMediaFeature);
+		printf("CommandSetSupport.PowerManagement = %hu\n", idd->CommandSetSupport.PowerManagement);
+		printf("CommandSetSupport.Reserved1 = %hu\n", idd->CommandSetSupport.Reserved1);
+		printf("CommandSetSupport.WriteCache = %hu\n", idd->CommandSetSupport.WriteCache);
+		printf("CommandSetSupport.LookAhead = %hu\n", idd->CommandSetSupport.LookAhead);
+		printf("CommandSetSupport.ReleaseInterrupt = %hu\n", idd->CommandSetSupport.ReleaseInterrupt);
+		printf("CommandSetSupport.ServiceInterrupt = %hu\n", idd->CommandSetSupport.ServiceInterrupt);
+		printf("CommandSetSupport.DeviceReset = %hu\n", idd->CommandSetSupport.DeviceReset);
+		printf("CommandSetSupport.HostProtectedArea = %hu\n", idd->CommandSetSupport.HostProtectedArea);
+		printf("CommandSetSupport.Obsolete1 = %hu\n", idd->CommandSetSupport.Obsolete1);
+		printf("CommandSetSupport.WriteBuffer = %hu\n", idd->CommandSetSupport.WriteBuffer);
+		printf("CommandSetSupport.ReadBuffer = %hu\n", idd->CommandSetSupport.ReadBuffer);
+		printf("CommandSetSupport.Nop = %hu\n", idd->CommandSetSupport.Nop);
+		printf("CommandSetSupport.Obsolete2 = %hu\n", idd->CommandSetSupport.Obsolete2);
+		printf("CommandSetSupport.DownloadMicrocode = %hu\n", idd->CommandSetSupport.DownloadMicrocode);
+		printf("CommandSetSupport.DmaQueued = %hu\n", idd->CommandSetSupport.DmaQueued);
+		printf("CommandSetSupport.Cfa = %hu\n", idd->CommandSetSupport.Cfa);
+		printf("CommandSetSupport.AdvancedPm = %hu\n", idd->CommandSetSupport.AdvancedPm);
+		printf("CommandSetSupport.Msn = %hu\n", idd->CommandSetSupport.Msn);
+		printf("CommandSetSupport.PowerUpInStandby = %hu\n", idd->CommandSetSupport.PowerUpInStandby);
+		printf("CommandSetSupport.ManualPowerUp = %hu\n", idd->CommandSetSupport.ManualPowerUp);
+		printf("CommandSetSupport.Reserved2 = %hu\n", idd->CommandSetSupport.Reserved2);
+		printf("CommandSetSupport.SetMax = %hu\n", idd->CommandSetSupport.SetMax);
+		printf("CommandSetSupport.Acoustics = %hu\n", idd->CommandSetSupport.Acoustics);
+		printf("CommandSetSupport.BigLba = %hu\n", idd->CommandSetSupport.BigLba);
+		printf("CommandSetSupport.DeviceConfigOverlay = %hu\n", idd->CommandSetSupport.DeviceConfigOverlay);
+		printf("CommandSetSupport.FlushCache = %hu\n", idd->CommandSetSupport.FlushCache);
+		printf("CommandSetSupport.FlushCacheExt = %hu\n", idd->CommandSetSupport.FlushCacheExt);
+		printf("CommandSetSupport.Resrved3 = %hu\n", idd->CommandSetSupport.Resrved3);
+		printf("CommandSetSupport.SmartErrorLog = %hu\n", idd->CommandSetSupport.SmartErrorLog);
+		printf("CommandSetSupport.SmartSelfTest = %hu\n", idd->CommandSetSupport.SmartSelfTest);
+		printf("CommandSetSupport.MediaSerialNumber = %hu\n", idd->CommandSetSupport.MediaSerialNumber);
+		printf("CommandSetSupport.MediaCardPassThrough = %hu\n", idd->CommandSetSupport.MediaCardPassThrough);
+		printf("CommandSetSupport.StreamingFeature = %hu\n", idd->CommandSetSupport.StreamingFeature);
+		printf("CommandSetSupport.GpLogging = %hu\n", idd->CommandSetSupport.GpLogging);
+		printf("CommandSetSupport.WriteFua = %hu\n", idd->CommandSetSupport.WriteFua);
+		printf("CommandSetSupport.WriteQueuedFua = %hu\n", idd->CommandSetSupport.WriteQueuedFua);
+		printf("CommandSetSupport.WWN64Bit = %hu\n", idd->CommandSetSupport.WWN64Bit);
+		printf("CommandSetSupport.URGReadStream = %hu\n", idd->CommandSetSupport.URGReadStream);
+		printf("CommandSetSupport.URGWriteStream = %hu\n", idd->CommandSetSupport.URGWriteStream);
+		printf("CommandSetSupport.ReservedForTechReport = %hu\n", idd->CommandSetSupport.ReservedForTechReport);
+		printf("CommandSetSupport.IdleWithUnloadFeature = %hu\n", idd->CommandSetSupport.IdleWithUnloadFeature);
+		printf("CommandSetSupport.Reserved4 = %hu\n", idd->CommandSetSupport.Reserved4);
+		printf("CommandSetActive.SmartCommands = %hu\n", idd->CommandSetActive.SmartCommands);
+		printf("CommandSetActive.SecurityMode = %hu\n", idd->CommandSetActive.SecurityMode);
+		printf("CommandSetActive.RemovableMediaFeature = %hu\n", idd->CommandSetActive.RemovableMediaFeature);
+		printf("CommandSetActive.PowerManagement = %hu\n", idd->CommandSetActive.PowerManagement);
+		printf("CommandSetActive.Reserved1 = %hu\n", idd->CommandSetActive.Reserved1);
+		printf("CommandSetActive.WriteCache = %hu\n", idd->CommandSetActive.WriteCache);
+		printf("CommandSetActive.LookAhead = %hu\n", idd->CommandSetActive.LookAhead);
+		printf("CommandSetActive.ReleaseInterrupt = %hu\n", idd->CommandSetActive.ReleaseInterrupt);
+		printf("CommandSetActive.ServiceInterrupt = %hu\n", idd->CommandSetActive.ServiceInterrupt);
+		printf("CommandSetActive.DeviceReset = %hu\n", idd->CommandSetActive.DeviceReset);
+		printf("CommandSetActive.HostProtectedArea = %hu\n", idd->CommandSetActive.HostProtectedArea);
+		printf("CommandSetActive.Obsolete1 = %hu\n", idd->CommandSetActive.Obsolete1);
+		printf("CommandSetActive.WriteBuffer = %hu\n", idd->CommandSetActive.WriteBuffer);
+		printf("CommandSetActive.ReadBuffer = %hu\n", idd->CommandSetActive.ReadBuffer);
+		printf("CommandSetActive.Nop = %hu\n", idd->CommandSetActive.Nop);
+		printf("CommandSetActive.Obsolete2 = %hu\n", idd->CommandSetActive.Obsolete2);
+		printf("CommandSetActive.DownloadMicrocode = %hu\n", idd->CommandSetActive.DownloadMicrocode);
+		printf("CommandSetActive.DmaQueued = %hu\n", idd->CommandSetActive.DmaQueued);
+		printf("CommandSetActive.Cfa = %hu\n", idd->CommandSetActive.Cfa);
+		printf("CommandSetActive.AdvancedPm = %hu\n", idd->CommandSetActive.AdvancedPm);
+		printf("CommandSetActive.Msn = %hu\n", idd->CommandSetActive.Msn);
+		printf("CommandSetActive.PowerUpInStandby = %hu\n", idd->CommandSetActive.PowerUpInStandby);
+		printf("CommandSetActive.ManualPowerUp = %hu\n", idd->CommandSetActive.ManualPowerUp);
+		printf("CommandSetActive.Reserved2 = %hu\n", idd->CommandSetActive.Reserved2);
+		printf("CommandSetActive.SetMax = %hu\n", idd->CommandSetActive.SetMax);
+		printf("CommandSetActive.Acoustics = %hu\n", idd->CommandSetActive.Acoustics);
+		printf("CommandSetActive.BigLba = %hu\n", idd->CommandSetActive.BigLba);
+		printf("CommandSetActive.DeviceConfigOverlay = %hu\n", idd->CommandSetActive.DeviceConfigOverlay);
+		printf("CommandSetActive.FlushCache = %hu\n", idd->CommandSetActive.FlushCache);
+		printf("CommandSetActive.FlushCacheExt = %hu\n", idd->CommandSetActive.FlushCacheExt);
+		printf("CommandSetActive.Resrved3 = %hu\n", idd->CommandSetActive.Resrved3);
+		printf("CommandSetActive.SmartErrorLog = %hu\n", idd->CommandSetActive.SmartErrorLog);
+		printf("CommandSetActive.SmartSelfTest = %hu\n", idd->CommandSetActive.SmartSelfTest);
+		printf("CommandSetActive.MediaSerialNumber = %hu\n", idd->CommandSetActive.MediaSerialNumber);
+		printf("CommandSetActive.MediaCardPassThrough = %hu\n", idd->CommandSetActive.MediaCardPassThrough);
+		printf("CommandSetActive.StreamingFeature = %hu\n", idd->CommandSetActive.StreamingFeature);
+		printf("CommandSetActive.GpLogging = %hu\n", idd->CommandSetActive.GpLogging);
+		printf("CommandSetActive.WriteFua = %hu\n", idd->CommandSetActive.WriteFua);
+		printf("CommandSetActive.WriteQueuedFua = %hu\n", idd->CommandSetActive.WriteQueuedFua);
+		printf("CommandSetActive.WWN64Bit = %hu\n", idd->CommandSetActive.WWN64Bit);
+		printf("CommandSetActive.URGReadStream = %hu\n", idd->CommandSetActive.URGReadStream);
+		printf("CommandSetActive.URGWriteStream = %hu\n", idd->CommandSetActive.URGWriteStream);
+		printf("CommandSetActive.ReservedForTechReport = %hu\n", idd->CommandSetActive.ReservedForTechReport);
+		printf("CommandSetActive.IdleWithUnloadFeature = %hu\n", idd->CommandSetActive.IdleWithUnloadFeature);
+		printf("CommandSetActive.Reserved4 = %hu\n", idd->CommandSetActive.Reserved4);
+		printf("UltraDMASupport = %hu\n", idd->UltraDMASupport);
+		printf("UltraDMAActive = %hu\n", idd->UltraDMAActive);
+		printf("ReservedWord89[0] = %hu\n", idd->ReservedWord89[0]);
+		printf("ReservedWord89[1] = %hu\n", idd->ReservedWord89[1]);
+		printf("ReservedWord89[2] = %hu\n", idd->ReservedWord89[2]);
+		printf("ReservedWord89[3] = %hu\n", idd->ReservedWord89[3]);
+		printf("HardwareResetResult = %hu\n", idd->HardwareResetResult);
+		printf("CurrentAcousticValue = %hu\n", idd->CurrentAcousticValue);
+		printf("RecommendedAcousticValue = %hu\n", idd->RecommendedAcousticValue);
+		printf("ReservedWord95[0] = %hu\n", idd->ReservedWord95[0]);
+		printf("ReservedWord95[1] = %hu\n", idd->ReservedWord95[1]);
+		printf("ReservedWord95[2] = %hu\n", idd->ReservedWord95[2]);
+		printf("ReservedWord95[3] = %hu\n", idd->ReservedWord95[3]);
+		printf("ReservedWord95[4] = %hu\n", idd->ReservedWord95[4]);
+		printf("Max48BitLBA[0] = %lu\n", idd->Max48BitLBA[0]);
+		printf("Max48BitLBA[1] = %lu\n", idd->Max48BitLBA[1]);
+		printf("StreamingTransferTime = %hu\n", idd->StreamingTransferTime);
+		printf("ReservedWord105 = %hu\n", idd->ReservedWord105);
+		printf("PhysicalLogicalSectorSize.LogicalSectorsPerPhysicalSector = %hu\n", idd->PhysicalLogicalSectorSize.LogicalSectorsPerPhysicalSector);
+		printf("PhysicalLogicalSectorSize.Reserved0 = %hu\n", idd->PhysicalLogicalSectorSize.Reserved0);
+		printf("PhysicalLogicalSectorSize.LogicalSectorLongerThan256Words = %hu\n", idd->PhysicalLogicalSectorSize.LogicalSectorLongerThan256Words);
+		printf("PhysicalLogicalSectorSize.MultipleLogicalSectorsPerPhysicalSector = %hu\n", idd->PhysicalLogicalSectorSize.MultipleLogicalSectorsPerPhysicalSector);
+		printf("PhysicalLogicalSectorSize.Reserved1 = %hu\n", idd->PhysicalLogicalSectorSize.Reserved1);
+		printf("InterSeekDelay = %hu\n", idd->InterSeekDelay);
+		printf("WorldWideName[0] = %hu\n", idd->WorldWideName[0]);
+		printf("WorldWideName[1] = %hu\n", idd->WorldWideName[1]);
+		printf("WorldWideName[2] = %hu\n", idd->WorldWideName[2]);
+		printf("WorldWideName[3] = %hu\n", idd->WorldWideName[3]);
+		printf("ReservedForWorldWideName128[0] = %hu\n", idd->ReservedForWorldWideName128[0]);
+		printf("ReservedForWorldWideName128[1] = %hu\n", idd->ReservedForWorldWideName128[1]);
+		printf("ReservedForWorldWideName128[2] = %hu\n", idd->ReservedForWorldWideName128[2]);
+		printf("ReservedForWorldWideName128[3] = %hu\n", idd->ReservedForWorldWideName128[3]);
+		printf("ReservedForTlcTechnicalReport = %hu\n", idd->ReservedForTlcTechnicalReport);
+		printf("WordsPerLogicalSector[0] = %hu\n", idd->WordsPerLogicalSector[0]);
+		printf("WordsPerLogicalSector[1] = %hu\n", idd->WordsPerLogicalSector[1]);
+		printf("CommandSetSupportExt.ReservedForDrqTechnicalReport = %hu\n", idd->CommandSetSupportExt.ReservedForDrqTechnicalReport);
+		printf("CommandSetSupportExt.WriteReadVerifySupported = %hu\n", idd->CommandSetSupportExt.WriteReadVerifySupported);
+		printf("CommandSetSupportExt.Reserved01 = %hu\n", idd->CommandSetSupportExt.Reserved01);
+		printf("CommandSetSupportExt.Reserved1 = %hu\n", idd->CommandSetSupportExt.Reserved1);
+		printf("CommandSetActiveExt.ReservedForDrqTechnicalReport = %hu\n", idd->CommandSetActiveExt.ReservedForDrqTechnicalReport);
+		printf("CommandSetActiveExt.WriteReadVerifyEnabled = %hu\n", idd->CommandSetActiveExt.WriteReadVerifyEnabled);
+		printf("CommandSetActiveExt.Reserved01 = %hu\n", idd->CommandSetActiveExt.Reserved01);
+		printf("CommandSetActiveExt.Reserved1 = %hu\n", idd->CommandSetActiveExt.Reserved1);
+		printf("ReservedForExpandedSupportandActive[0] = %hu\n", idd->ReservedForExpandedSupportandActive[0]);
+		printf("ReservedForExpandedSupportandActive[1] = %hu\n", idd->ReservedForExpandedSupportandActive[1]);
+		printf("ReservedForExpandedSupportandActive[2] = %hu\n", idd->ReservedForExpandedSupportandActive[2]);
+		printf("ReservedForExpandedSupportandActive[3] = %hu\n", idd->ReservedForExpandedSupportandActive[3]);
+		printf("ReservedForExpandedSupportandActive[4] = %hu\n", idd->ReservedForExpandedSupportandActive[4]);
+		printf("ReservedForExpandedSupportandActive[5] = %hu\n", idd->ReservedForExpandedSupportandActive[5]);
+		printf("MsnSupport = %hu\n", idd->MsnSupport);
+		printf("ReservedWord1274 = %hu\n", idd->ReservedWord1274);
+		printf("SecurityStatus.SecuritySupported = %hu\n", idd->SecurityStatus.SecuritySupported);
+		printf("SecurityStatus.SecurityEnabled = %hu\n", idd->SecurityStatus.SecurityEnabled);
+		printf("SecurityStatus.SecurityLocked = %hu\n", idd->SecurityStatus.SecurityLocked);
+		printf("SecurityStatus.SecurityFrozen = %hu\n", idd->SecurityStatus.SecurityFrozen);
+		printf("SecurityStatus.SecurityCountExpired = %hu\n", idd->SecurityStatus.SecurityCountExpired);
+		printf("SecurityStatus.EnhancedSecurityEraseSupported = %hu\n", idd->SecurityStatus.EnhancedSecurityEraseSupported);
+		printf("SecurityStatus.Reserved0 = %hu\n", idd->SecurityStatus.Reserved0);
+		printf("SecurityStatus.SecurityLevel = %hu\n", idd->SecurityStatus.SecurityLevel);
+		printf("SecurityStatus.Reserved1 = %hu\n", idd->SecurityStatus.Reserved1);
+		printf("ReservedWord129[0] = %hu\n", idd->ReservedWord129[0]);
+		printf("ReservedWord129[1] = %hu\n", idd->ReservedWord129[1]);
+		printf("ReservedWord129[2] = %hu\n", idd->ReservedWord129[2]);
+		printf("ReservedWord129[3] = %hu\n", idd->ReservedWord129[3]);
+		printf("ReservedWord129[4] = %hu\n", idd->ReservedWord129[4]);
+		printf("ReservedWord129[5] = %hu\n", idd->ReservedWord129[5]);
+		printf("ReservedWord129[6] = %hu\n", idd->ReservedWord129[6]);
+		printf("ReservedWord129[7] = %hu\n", idd->ReservedWord129[7]);
+		printf("ReservedWord129[8] = %hu\n", idd->ReservedWord129[8]);
+		printf("ReservedWord129[9] = %hu\n", idd->ReservedWord129[9]);
+		printf("ReservedWord129[10] = %hu\n", idd->ReservedWord129[10]);
+		printf("ReservedWord129[11] = %hu\n", idd->ReservedWord129[11]);
+		printf("ReservedWord129[12] = %hu\n", idd->ReservedWord129[12]);
+		printf("ReservedWord129[13] = %hu\n", idd->ReservedWord129[13]);
+		printf("ReservedWord129[14] = %hu\n", idd->ReservedWord129[14]);
+		printf("ReservedWord129[15] = %hu\n", idd->ReservedWord129[15]);
+		printf("ReservedWord129[16] = %hu\n", idd->ReservedWord129[16]);
+		printf("ReservedWord129[17] = %hu\n", idd->ReservedWord129[17]);
+		printf("ReservedWord129[18] = %hu\n", idd->ReservedWord129[18]);
+		printf("ReservedWord129[19] = %hu\n", idd->ReservedWord129[19]);
+		printf("ReservedWord129[20] = %hu\n", idd->ReservedWord129[20]);
+		printf("ReservedWord129[21] = %hu\n", idd->ReservedWord129[21]);
+		printf("ReservedWord129[22] = %hu\n", idd->ReservedWord129[22]);
+		printf("ReservedWord129[23] = %hu\n", idd->ReservedWord129[23]);
+		printf("ReservedWord129[24] = %hu\n", idd->ReservedWord129[24]);
+		printf("ReservedWord129[25] = %hu\n", idd->ReservedWord129[25]);
+		printf("ReservedWord129[26] = %hu\n", idd->ReservedWord129[26]);
+		printf("ReservedWord129[27] = %hu\n", idd->ReservedWord129[27]);
+		printf("ReservedWord129[28] = %hu\n", idd->ReservedWord129[28]);
+		printf("ReservedWord129[29] = %hu\n", idd->ReservedWord129[29]);
+		printf("ReservedWord129[30] = %hu\n", idd->ReservedWord129[30]);
+		printf("CfaPowerModel.MaximumCurrentInMA2 = %hu\n", idd->CfaPowerModel.MaximumCurrentInMA2);
+		printf("CfaPowerModel.CfaPowerMode1Disabled = %hu\n", idd->CfaPowerModel.CfaPowerMode1Disabled);
+		printf("CfaPowerModel.CfaPowerMode1Required = %hu\n", idd->CfaPowerModel.CfaPowerMode1Required);
+		printf("CfaPowerModel.Reserved0 = %hu\n", idd->CfaPowerModel.Reserved0);
+		printf("CfaPowerModel.Word160Supported = %hu\n", idd->CfaPowerModel.Word160Supported);
+		printf("ReservedForCfaWord161[0] = %hu\n", idd->ReservedForCfaWord161[0]);
+		printf("ReservedForCfaWord161[1] = %hu\n", idd->ReservedForCfaWord161[1]);
+		printf("ReservedForCfaWord161[2] = %hu\n", idd->ReservedForCfaWord161[2]);
+		printf("ReservedForCfaWord161[3] = %hu\n", idd->ReservedForCfaWord161[3]);
+		printf("ReservedForCfaWord161[4] = %hu\n", idd->ReservedForCfaWord161[4]);
+		printf("ReservedForCfaWord161[5] = %hu\n", idd->ReservedForCfaWord161[5]);
+		printf("ReservedForCfaWord161[6] = %hu\n", idd->ReservedForCfaWord161[6]);
+		printf("ReservedForCfaWord161[7] = %hu\n", idd->ReservedForCfaWord161[7]);
+		printf("DataSetManagementFeature.SupportsTrim = %hu\n", idd->DataSetManagementFeature.SupportsTrim);
+		printf("DataSetManagementFeature.Reserved0 = %hu\n", idd->DataSetManagementFeature.Reserved0);
+		printf("ReservedForCfaWord170[0] = %hu\n", idd->ReservedForCfaWord170[0]);
+		printf("ReservedForCfaWord170[1] = %hu\n", idd->ReservedForCfaWord170[1]);
+		printf("ReservedForCfaWord170[2] = %hu\n", idd->ReservedForCfaWord170[2]);
+		printf("ReservedForCfaWord170[3] = %hu\n", idd->ReservedForCfaWord170[3]);
+		printf("ReservedForCfaWord170[4] = %hu\n", idd->ReservedForCfaWord170[4]);
+		printf("ReservedForCfaWord170[5] = %hu\n", idd->ReservedForCfaWord170[5]);
+		printf("CurrentMediaSerialNumber[0] = %hu\n", idd->CurrentMediaSerialNumber[0]);
+		printf("CurrentMediaSerialNumber[1] = %hu\n", idd->CurrentMediaSerialNumber[1]);
+		printf("CurrentMediaSerialNumber[2] = %hu\n", idd->CurrentMediaSerialNumber[2]);
+		printf("CurrentMediaSerialNumber[3] = %hu\n", idd->CurrentMediaSerialNumber[3]);
+		printf("CurrentMediaSerialNumber[4] = %hu\n", idd->CurrentMediaSerialNumber[4]);
+		printf("CurrentMediaSerialNumber[5] = %hu\n", idd->CurrentMediaSerialNumber[5]);
+		printf("CurrentMediaSerialNumber[6] = %hu\n", idd->CurrentMediaSerialNumber[6]);
+		printf("CurrentMediaSerialNumber[7] = %hu\n", idd->CurrentMediaSerialNumber[7]);
+		printf("CurrentMediaSerialNumber[8] = %hu\n", idd->CurrentMediaSerialNumber[8]);
+		printf("CurrentMediaSerialNumber[9] = %hu\n", idd->CurrentMediaSerialNumber[9]);
+		printf("CurrentMediaSerialNumber[10] = %hu\n", idd->CurrentMediaSerialNumber[10]);
+		printf("CurrentMediaSerialNumber[11] = %hu\n", idd->CurrentMediaSerialNumber[11]);
+		printf("CurrentMediaSerialNumber[12] = %hu\n", idd->CurrentMediaSerialNumber[12]);
+		printf("CurrentMediaSerialNumber[13] = %hu\n", idd->CurrentMediaSerialNumber[13]);
+		printf("CurrentMediaSerialNumber[14] = %hu\n", idd->CurrentMediaSerialNumber[14]);
+		printf("CurrentMediaSerialNumber[15] = %hu\n", idd->CurrentMediaSerialNumber[15]);
+		printf("CurrentMediaSerialNumber[16] = %hu\n", idd->CurrentMediaSerialNumber[16]);
+		printf("CurrentMediaSerialNumber[17] = %hu\n", idd->CurrentMediaSerialNumber[17]);
+		printf("CurrentMediaSerialNumber[18] = %hu\n", idd->CurrentMediaSerialNumber[18]);
+		printf("CurrentMediaSerialNumber[19] = %hu\n", idd->CurrentMediaSerialNumber[19]);
+		printf("CurrentMediaSerialNumber[20] = %hu\n", idd->CurrentMediaSerialNumber[20]);
+		printf("CurrentMediaSerialNumber[21] = %hu\n", idd->CurrentMediaSerialNumber[21]);
+		printf("CurrentMediaSerialNumber[22] = %hu\n", idd->CurrentMediaSerialNumber[22]);
+		printf("CurrentMediaSerialNumber[23] = %hu\n", idd->CurrentMediaSerialNumber[23]);
+		printf("CurrentMediaSerialNumber[24] = %hu\n", idd->CurrentMediaSerialNumber[24]);
+		printf("CurrentMediaSerialNumber[25] = %hu\n", idd->CurrentMediaSerialNumber[25]);
+		printf("CurrentMediaSerialNumber[26] = %hu\n", idd->CurrentMediaSerialNumber[26]);
+		printf("CurrentMediaSerialNumber[27] = %hu\n", idd->CurrentMediaSerialNumber[27]);
+		printf("CurrentMediaSerialNumber[28] = %hu\n", idd->CurrentMediaSerialNumber[28]);
+		printf("CurrentMediaSerialNumber[29] = %hu\n", idd->CurrentMediaSerialNumber[29]);
+		printf("ReservedWord206 = %hu\n", idd->ReservedWord206);
+		printf("ReservedWord207[0] = %hu\n", idd->ReservedWord207[0]);
+		printf("ReservedWord207[1] = %hu\n", idd->ReservedWord207[1]);
+		printf("BlockAlignment.AlignmentOfLogicalWithinPhysical = %hu\n", idd->BlockAlignment.AlignmentOfLogicalWithinPhysical);
+		printf("BlockAlignment.Word209Supported = %hu\n", idd->BlockAlignment.Word209Supported);
+		printf("BlockAlignment.Reserved0 = %hu\n", idd->BlockAlignment.Reserved0);
+		printf("WriteReadVerifySectorCountMode3Only[0] = %hu\n", idd->WriteReadVerifySectorCountMode3Only[0]);
+		printf("WriteReadVerifySectorCountMode3Only[1] = %hu\n", idd->WriteReadVerifySectorCountMode3Only[1]);
+		printf("WriteReadVerifySectorCountMode2Only[0] = %hu\n", idd->WriteReadVerifySectorCountMode2Only[0]);
+		printf("WriteReadVerifySectorCountMode2Only[1] = %hu\n", idd->WriteReadVerifySectorCountMode2Only[1]);
+		printf("NVCacheCapabilities.NVCachePowerModeEnabled = %hu\n", idd->NVCacheCapabilities.NVCachePowerModeEnabled);
+		printf("NVCacheCapabilities.Reserved0 = %hu\n", idd->NVCacheCapabilities.Reserved0);
+		printf("NVCacheCapabilities.NVCacheFeatureSetEnabled = %hu\n", idd->NVCacheCapabilities.NVCacheFeatureSetEnabled);
+		printf("NVCacheCapabilities.Reserved1 = %hu\n", idd->NVCacheCapabilities.Reserved1);
+		printf("NVCacheCapabilities.NVCachePowerModeVersion = %hu\n", idd->NVCacheCapabilities.NVCachePowerModeVersion);
+		printf("NVCacheCapabilities.NVCacheFeatureSetVersion = %hu\n", idd->NVCacheCapabilities.NVCacheFeatureSetVersion);
+		printf("NVCacheSizeLSW = %hu\n", idd->NVCacheSizeLSW);
+		printf("NVCacheSizeMSW = %hu\n", idd->NVCacheSizeMSW);
+		printf("NominalMediaRotationRate = %hu\n", idd->NominalMediaRotationRate);
+		printf("ReservedWord218 = %hu\n", idd->ReservedWord218);
+		printf("NVCacheOptions.NVCacheEstimatedTimeToSpinUpInSeconds = %d\n", idd->NVCacheOptions.NVCacheEstimatedTimeToSpinUpInSeconds);
+		printf("NVCacheOptions.Reserved = %d\n", idd->NVCacheOptions.Reserved);
+		printf("ReservedWord220[0] = %hu\n", idd->ReservedWord220[0]);
+		printf("ReservedWord220[1] = %hu\n", idd->ReservedWord220[1]);
+		printf("ReservedWord220[2] = %hu\n", idd->ReservedWord220[2]);
+		printf("ReservedWord220[3] = %hu\n", idd->ReservedWord220[3]);
+		printf("ReservedWord220[4] = %hu\n", idd->ReservedWord220[4]);
+		printf("ReservedWord220[5] = %hu\n", idd->ReservedWord220[5]);
+		printf("ReservedWord220[6] = %hu\n", idd->ReservedWord220[6]);
+		printf("ReservedWord220[7] = %hu\n", idd->ReservedWord220[7]);
+		printf("ReservedWord220[8] = %hu\n", idd->ReservedWord220[8]);
+		printf("ReservedWord220[9] = %hu\n", idd->ReservedWord220[9]);
+		printf("ReservedWord220[10] = %hu\n", idd->ReservedWord220[10]);
+		printf("ReservedWord220[11] = %hu\n", idd->ReservedWord220[11]);
+		printf("ReservedWord220[12] = %hu\n", idd->ReservedWord220[12]);
+		printf("ReservedWord220[13] = %hu\n", idd->ReservedWord220[13]);
+		printf("ReservedWord220[14] = %hu\n", idd->ReservedWord220[14]);
+		printf("ReservedWord220[15] = %hu\n", idd->ReservedWord220[15]);
+		printf("ReservedWord220[16] = %hu\n", idd->ReservedWord220[16]);
+		printf("ReservedWord220[17] = %hu\n", idd->ReservedWord220[17]);
+		printf("ReservedWord220[18] = %hu\n", idd->ReservedWord220[18]);
+		printf("ReservedWord220[19] = %hu\n", idd->ReservedWord220[19]);
+		printf("ReservedWord220[20] = %hu\n", idd->ReservedWord220[20]);
+		printf("ReservedWord220[21] = %hu\n", idd->ReservedWord220[21]);
+		printf("ReservedWord220[22] = %hu\n", idd->ReservedWord220[22]);
+		printf("ReservedWord220[23] = %hu\n", idd->ReservedWord220[23]);
+		printf("ReservedWord220[24] = %hu\n", idd->ReservedWord220[24]);
+		printf("ReservedWord220[25] = %hu\n", idd->ReservedWord220[25]);
+		printf("ReservedWord220[26] = %hu\n", idd->ReservedWord220[26]);
+		printf("ReservedWord220[27] = %hu\n", idd->ReservedWord220[27]);
+		printf("ReservedWord220[28] = %hu\n", idd->ReservedWord220[28]);
+		printf("ReservedWord220[29] = %hu\n", idd->ReservedWord220[29]);
+		printf("ReservedWord220[30] = %hu\n", idd->ReservedWord220[30]);
+		printf("ReservedWord220[31] = %hu\n", idd->ReservedWord220[31]);
+		printf("ReservedWord220[32] = %hu\n", idd->ReservedWord220[32]);
+		printf("ReservedWord220[33] = %hu\n", idd->ReservedWord220[33]);
+		printf("ReservedWord220[34] = %hu\n", idd->ReservedWord220[34]);
+		printf("Signature = %hu\n", idd->Signature);
+		printf("CheckSum = %hu\n", idd->CheckSum);
+		printf("====================\n");
+		printf("END IDENTIFY_DEVICE_DATA for %s\n", deviceNameBuffer);
+		printf("====================\n");
+		printf("\n");
+
+		CloseHandle(diskHandle);
+	}
+
+	return 0;
+}
diff --git a/al-khaser/Tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj b/al-khaser/Tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..282badf1977918a9fd1b3d4e61f51d588a042ac0
--- /dev/null
+++ b/al-khaser/Tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>15.0</VCProjectVersion>
+    <ProjectGuid>{245D8670-A888-4ECC-9B51-80584E55B701}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>ATAIdentifyDump</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="IdentifyDeviceData.h" />
+    <ClInclude Include="pch.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="ATAIdentifyDump.cpp" />
+    <ClCompile Include="pch.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/al-khaser/Tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj.filters b/al-khaser/Tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..4e0979e824481faf757d5da21dda0ce307650031
--- /dev/null
+++ b/al-khaser/Tools/ATAIdentifyDump/ATAIdentifyDump.vcxproj.filters
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="pch.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="IdentifyDeviceData.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="pch.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="ATAIdentifyDump.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/al-khaser/Tools/ATAIdentifyDump/IdentifyDeviceData.h b/al-khaser/Tools/ATAIdentifyDump/IdentifyDeviceData.h
new file mode 100644
index 0000000000000000000000000000000000000000..22970c2fc44f23da73df4610b85ab463bfe53572
--- /dev/null
+++ b/al-khaser/Tools/ATAIdentifyDump/IdentifyDeviceData.h
@@ -0,0 +1,250 @@
+#pragma once
+
+typedef struct _IDENTIFY_DEVICE_DATA {
+	struct {
+		USHORT Reserved1 : 1;
+		USHORT Retired3 : 1;
+		USHORT ResponseIncomplete : 1;
+		USHORT Retired2 : 3;
+		USHORT FixedDevice : 1;
+		USHORT RemovableMedia : 1;
+		USHORT Retired1 : 7;
+		USHORT DeviceType : 1;
+	} GeneralConfiguration;
+	USHORT NumCylinders;
+	USHORT ReservedWord2;
+	USHORT NumHeads;
+	USHORT Retired1[2];
+	USHORT NumSectorsPerTrack;
+	USHORT VendorUnique1[3];
+	UCHAR  SerialNumber[20];
+	USHORT Retired2[2];
+	USHORT Obsolete1;
+	UCHAR  FirmwareRevision[8];
+	UCHAR  ModelNumber[40];
+	UCHAR  MaximumBlockTransfer;
+	UCHAR  VendorUnique2;
+	USHORT ReservedWord48;
+	struct {
+		UCHAR  ReservedByte49;
+		UCHAR  DmaSupported : 1;
+		UCHAR  LbaSupported : 1;
+		UCHAR  IordyDisable : 1;
+		UCHAR  IordySupported : 1;
+		UCHAR  Reserved1 : 1;
+		UCHAR  StandybyTimerSupport : 1;
+		UCHAR  Reserved2 : 2;
+		USHORT ReservedWord50;
+	} Capabilities;
+	USHORT ObsoleteWords51[2];
+	USHORT TranslationFieldsValid : 3;
+	USHORT Reserved3 : 13;
+	USHORT NumberOfCurrentCylinders;
+	USHORT NumberOfCurrentHeads;
+	USHORT CurrentSectorsPerTrack;
+	ULONG  CurrentSectorCapacity;
+	UCHAR  CurrentMultiSectorSetting;
+	UCHAR  MultiSectorSettingValid : 1;
+	UCHAR  ReservedByte59 : 7;
+	ULONG  UserAddressableSectors;
+	USHORT ObsoleteWord62;
+	USHORT MultiWordDMASupport : 8;
+	USHORT MultiWordDMAActive : 8;
+	USHORT AdvancedPIOModes : 8;
+	USHORT ReservedByte64 : 8;
+	USHORT MinimumMWXferCycleTime;
+	USHORT RecommendedMWXferCycleTime;
+	USHORT MinimumPIOCycleTime;
+	USHORT MinimumPIOCycleTimeIORDY;
+	USHORT ReservedWords69[6];
+	USHORT QueueDepth : 5;
+	USHORT ReservedWord75 : 11;
+	USHORT ReservedWords76[4];
+	USHORT MajorRevision;
+	USHORT MinorRevision;
+	struct {
+		USHORT SmartCommands : 1;
+		USHORT SecurityMode : 1;
+		USHORT RemovableMediaFeature : 1;
+		USHORT PowerManagement : 1;
+		USHORT Reserved1 : 1;
+		USHORT WriteCache : 1;
+		USHORT LookAhead : 1;
+		USHORT ReleaseInterrupt : 1;
+		USHORT ServiceInterrupt : 1;
+		USHORT DeviceReset : 1;
+		USHORT HostProtectedArea : 1;
+		USHORT Obsolete1 : 1;
+		USHORT WriteBuffer : 1;
+		USHORT ReadBuffer : 1;
+		USHORT Nop : 1;
+		USHORT Obsolete2 : 1;
+		USHORT DownloadMicrocode : 1;
+		USHORT DmaQueued : 1;
+		USHORT Cfa : 1;
+		USHORT AdvancedPm : 1;
+		USHORT Msn : 1;
+		USHORT PowerUpInStandby : 1;
+		USHORT ManualPowerUp : 1;
+		USHORT Reserved2 : 1;
+		USHORT SetMax : 1;
+		USHORT Acoustics : 1;
+		USHORT BigLba : 1;
+		USHORT DeviceConfigOverlay : 1;
+		USHORT FlushCache : 1;
+		USHORT FlushCacheExt : 1;
+		USHORT Resrved3 : 2;
+		USHORT SmartErrorLog : 1;
+		USHORT SmartSelfTest : 1;
+		USHORT MediaSerialNumber : 1;
+		USHORT MediaCardPassThrough : 1;
+		USHORT StreamingFeature : 1;
+		USHORT GpLogging : 1;
+		USHORT WriteFua : 1;
+		USHORT WriteQueuedFua : 1;
+		USHORT WWN64Bit : 1;
+		USHORT URGReadStream : 1;
+		USHORT URGWriteStream : 1;
+		USHORT ReservedForTechReport : 2;
+		USHORT IdleWithUnloadFeature : 1;
+		USHORT Reserved4 : 2;
+	} CommandSetSupport;
+	struct {
+		USHORT SmartCommands : 1;
+		USHORT SecurityMode : 1;
+		USHORT RemovableMediaFeature : 1;
+		USHORT PowerManagement : 1;
+		USHORT Reserved1 : 1;
+		USHORT WriteCache : 1;
+		USHORT LookAhead : 1;
+		USHORT ReleaseInterrupt : 1;
+		USHORT ServiceInterrupt : 1;
+		USHORT DeviceReset : 1;
+		USHORT HostProtectedArea : 1;
+		USHORT Obsolete1 : 1;
+		USHORT WriteBuffer : 1;
+		USHORT ReadBuffer : 1;
+		USHORT Nop : 1;
+		USHORT Obsolete2 : 1;
+		USHORT DownloadMicrocode : 1;
+		USHORT DmaQueued : 1;
+		USHORT Cfa : 1;
+		USHORT AdvancedPm : 1;
+		USHORT Msn : 1;
+		USHORT PowerUpInStandby : 1;
+		USHORT ManualPowerUp : 1;
+		USHORT Reserved2 : 1;
+		USHORT SetMax : 1;
+		USHORT Acoustics : 1;
+		USHORT BigLba : 1;
+		USHORT DeviceConfigOverlay : 1;
+		USHORT FlushCache : 1;
+		USHORT FlushCacheExt : 1;
+		USHORT Resrved3 : 2;
+		USHORT SmartErrorLog : 1;
+		USHORT SmartSelfTest : 1;
+		USHORT MediaSerialNumber : 1;
+		USHORT MediaCardPassThrough : 1;
+		USHORT StreamingFeature : 1;
+		USHORT GpLogging : 1;
+		USHORT WriteFua : 1;
+		USHORT WriteQueuedFua : 1;
+		USHORT WWN64Bit : 1;
+		USHORT URGReadStream : 1;
+		USHORT URGWriteStream : 1;
+		USHORT ReservedForTechReport : 2;
+		USHORT IdleWithUnloadFeature : 1;
+		USHORT Reserved4 : 2;
+	} CommandSetActive;
+	USHORT UltraDMASupport : 8;
+	USHORT UltraDMAActive : 8;
+	USHORT ReservedWord89[4];
+	USHORT HardwareResetResult;
+	USHORT CurrentAcousticValue : 8;
+	USHORT RecommendedAcousticValue : 8;
+	USHORT ReservedWord95[5];
+	ULONG  Max48BitLBA[2];
+	USHORT StreamingTransferTime;
+	USHORT ReservedWord105;
+	struct {
+		USHORT LogicalSectorsPerPhysicalSector : 4;
+		USHORT Reserved0 : 8;
+		USHORT LogicalSectorLongerThan256Words : 1;
+		USHORT MultipleLogicalSectorsPerPhysicalSector : 1;
+		USHORT Reserved1 : 2;
+	} PhysicalLogicalSectorSize;
+	USHORT InterSeekDelay;
+	USHORT WorldWideName[4];
+	USHORT ReservedForWorldWideName128[4];
+	USHORT ReservedForTlcTechnicalReport;
+	USHORT WordsPerLogicalSector[2];
+	struct {
+		USHORT ReservedForDrqTechnicalReport : 1;
+		USHORT WriteReadVerifySupported : 1;
+		USHORT Reserved01 : 11;
+		USHORT Reserved1 : 2;
+	} CommandSetSupportExt;
+	struct {
+		USHORT ReservedForDrqTechnicalReport : 1;
+		USHORT WriteReadVerifyEnabled : 1;
+		USHORT Reserved01 : 11;
+		USHORT Reserved1 : 2;
+	} CommandSetActiveExt;
+	USHORT ReservedForExpandedSupportandActive[6];
+	USHORT MsnSupport : 2;
+	USHORT ReservedWord1274 : 14;
+	struct {
+		USHORT SecuritySupported : 1;
+		USHORT SecurityEnabled : 1;
+		USHORT SecurityLocked : 1;
+		USHORT SecurityFrozen : 1;
+		USHORT SecurityCountExpired : 1;
+		USHORT EnhancedSecurityEraseSupported : 1;
+		USHORT Reserved0 : 2;
+		USHORT SecurityLevel : 1;
+		USHORT Reserved1 : 7;
+	} SecurityStatus;
+	USHORT ReservedWord129[31];
+	struct {
+		USHORT MaximumCurrentInMA2 : 12;
+		USHORT CfaPowerMode1Disabled : 1;
+		USHORT CfaPowerMode1Required : 1;
+		USHORT Reserved0 : 1;
+		USHORT Word160Supported : 1;
+	} CfaPowerModel;
+	USHORT ReservedForCfaWord161[8];
+	struct {
+		USHORT SupportsTrim : 1;
+		USHORT Reserved0 : 15;
+	} DataSetManagementFeature;
+	USHORT ReservedForCfaWord170[6];
+	USHORT CurrentMediaSerialNumber[30];
+	USHORT ReservedWord206;
+	USHORT ReservedWord207[2];
+	struct {
+		USHORT AlignmentOfLogicalWithinPhysical : 14;
+		USHORT Word209Supported : 1;
+		USHORT Reserved0 : 1;
+	} BlockAlignment;
+	USHORT WriteReadVerifySectorCountMode3Only[2];
+	USHORT WriteReadVerifySectorCountMode2Only[2];
+	struct {
+		USHORT NVCachePowerModeEnabled : 1;
+		USHORT Reserved0 : 3;
+		USHORT NVCacheFeatureSetEnabled : 1;
+		USHORT Reserved1 : 3;
+		USHORT NVCachePowerModeVersion : 4;
+		USHORT NVCacheFeatureSetVersion : 4;
+	} NVCacheCapabilities;
+	USHORT NVCacheSizeLSW;
+	USHORT NVCacheSizeMSW;
+	USHORT NominalMediaRotationRate;
+	USHORT ReservedWord218;
+	struct {
+		UCHAR NVCacheEstimatedTimeToSpinUpInSeconds;
+		UCHAR Reserved;
+	} NVCacheOptions;
+	USHORT ReservedWord220[35];
+	USHORT Signature : 8;
+	USHORT CheckSum : 8;
+} IDENTIFY_DEVICE_DATA, *PIDENTIFY_DEVICE_DATA;
\ No newline at end of file
diff --git a/al-khaser/Tools/ATAIdentifyDump/README.md b/al-khaser/Tools/ATAIdentifyDump/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..7dc6907232cfa1cf041ed59ef2247d7a7df20bb5
--- /dev/null
+++ b/al-khaser/Tools/ATAIdentifyDump/README.md
@@ -0,0 +1,5 @@
+# ATAIdentifyDump
+
+ATAIdentifyDump dumps ATA IDENTIFY data from physical disks. This data is useful for identifying VMs.
+
+You must run this tool as an administrator.
\ No newline at end of file
diff --git a/al-khaser/Tools/ATAIdentifyDump/pch.cpp b/al-khaser/Tools/ATAIdentifyDump/pch.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1d9f38c57d63f197d552a5283424f75f885bb1c2
--- /dev/null
+++ b/al-khaser/Tools/ATAIdentifyDump/pch.cpp
@@ -0,0 +1 @@
+#include "pch.h"
diff --git a/al-khaser/Tools/ATAIdentifyDump/pch.h b/al-khaser/Tools/ATAIdentifyDump/pch.h
new file mode 100644
index 0000000000000000000000000000000000000000..d7aee1f515c4b7e63e71e7e367aceb8dfb5702a4
--- /dev/null
+++ b/al-khaser/Tools/ATAIdentifyDump/pch.h
@@ -0,0 +1,9 @@
+#ifndef PCH_H
+#define PCH_H
+
+#include <Windows.h>
+#include <ntddscsi.h>
+#include <stdio.h>
+#include "IdentifyDeviceData.h"
+
+#endif // PCH_H
\ No newline at end of file
diff --git a/al-khaser/Tools/StructDumpCodegen/README.md b/al-khaser/Tools/StructDumpCodegen/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..8b06a60c06a08730219b8c8952202d88bcfd61d3
--- /dev/null
+++ b/al-khaser/Tools/StructDumpCodegen/README.md
@@ -0,0 +1,7 @@
+# Struct Dump Codegen
+
+This is a LINQpad script to turn a struct definition into C++ code that prints out its contents. So far it supports USHORT, ULONG, and UCHAR.
+
+This was written specifically for IDENTIFY_DEVICE_DATA in order to speed up writing ATAIdentifyDump.
+
+This can probably be used for similar structs too, so it might be useful elsewhere.
\ No newline at end of file
diff --git a/al-khaser/Tools/StructDumpCodegen/struct_dump_codegen.linq b/al-khaser/Tools/StructDumpCodegen/struct_dump_codegen.linq
new file mode 100644
index 0000000000000000000000000000000000000000..bc5668357383960786b5f1685447e28b1e89e0de
--- /dev/null
+++ b/al-khaser/Tools/StructDumpCodegen/struct_dump_codegen.linq
@@ -0,0 +1,213 @@
+<Query Kind="Program">
+  <Reference>&lt;RuntimeDirectory&gt;\System.Drawing.dll</Reference>
+  <Reference>&lt;RuntimeDirectory&gt;\System.IO.dll</Reference>
+  <Reference>&lt;RuntimeDirectory&gt;\System.Net.dll</Reference>
+  <Reference>&lt;RuntimeDirectory&gt;\System.Numerics.dll</Reference>
+  <Reference>&lt;RuntimeDirectory&gt;\System.Numerics.Vectors.dll</Reference>
+  <Reference>&lt;RuntimeDirectory&gt;\System.Security.dll</Reference>
+  <Namespace>System.Collections</Namespace>
+  <Namespace>System.Collections.Concurrent</Namespace>
+  <Namespace>System.Collections.Generic</Namespace>
+  <Namespace>System.Collections.Specialized</Namespace>
+  <Namespace>System.Drawing</Namespace>
+  <Namespace>System.Drawing.Imaging</Namespace>
+  <Namespace>System.IO</Namespace>
+  <Namespace>System.IO.MemoryMappedFiles</Namespace>
+  <Namespace>System.IO.Pipes</Namespace>
+  <Namespace>System.IO.Ports</Namespace>
+  <Namespace>System.Net</Namespace>
+  <Namespace>System.Net.Sockets</Namespace>
+  <Namespace>System.Numerics</Namespace>
+  <Namespace>System.Runtime.InteropServices</Namespace>
+  <Namespace>System.Runtime.InteropServices</Namespace>
+  <Namespace>System.Runtime.Serialization</Namespace>
+  <Namespace>System.Runtime.Serialization.Formatters.Binary</Namespace>
+  <Namespace>System.Security</Namespace>
+  <Namespace>System.Security.AccessControl</Namespace>
+  <Namespace>System.Security.Cryptography</Namespace>
+  <Namespace>System.Security.Principal</Namespace>
+  <Namespace>System.Text</Namespace>
+  <Namespace>System.Threading</Namespace>
+  <Namespace>System.Threading.Tasks</Namespace>
+</Query>
+
+/*
+Script to turn a struct definition into C++ code that prints out its contents. So far it supports USHORT, ULONG, and UCHAR.
+
+This was written specifically for IDENTIFY_DEVICE_DATA in order to speed up writing ATAIdentifyDump.
+
+This can probably be used for similar structs too, so it might be useful elsewhere.
+*/
+
+const string SourceFile = @"C:\Users\Graham\Source\Repos\al-khaser\Tools\ATAIdentifyDump\IdentifyDeviceData.h";
+const string StructVar = "idd";
+const bool SwapStringEndian = true; // for IDENTIFY_DEVICE_DATA
+
+void Main()
+{
+	
+	string[] lines = File.ReadAllLines(SourceFile);
+	
+	bool foundStart = false;
+	bool inStruct = false;
+	var structLines = new List<string>();
+	
+	var output = new StringBuilder();
+	
+	foreach (string rawLine in lines)
+	{
+		var line = rawLine.Trim().TrimEnd(';');
+		if (!foundStart)
+		{
+			if (line.StartsWith("typedef struct"))
+			{
+				foundStart = true;
+			}
+			continue;
+		}
+		
+		if (line.StartsWith("struct {"))
+		{
+			if (inStruct)
+			{
+				throw new InvalidDataException();
+			}
+			
+			// we're starting a nested structure
+			inStruct = true;
+			structLines.Clear();
+			continue;
+		}
+		
+		if (line.StartsWith("}"))
+		{
+			if (!inStruct)
+			{
+				Console.WriteLine("// end");
+				break;
+			}
+			
+			// we're ending a nested structure
+			var structNameMatch = Regex.Match(line, "^}\\s+([a-zA-Z0-9]+)$");
+			if (!structNameMatch.Success)
+			{
+				throw new InvalidDataException();
+			}
+			
+			string structName = structNameMatch.Groups[1].Value;
+			
+			inStruct = false;
+			foreach (string structLine in structLines)
+			{
+				ProcessLine(StructVar, structLine, structName);
+			}
+			continue;
+		}
+		
+		if (inStruct)
+		{
+			structLines.Add(line);
+			continue;
+		}
+		
+		ProcessLine(StructVar, line);
+	}
+}
+
+void ProcessLine(string structvar, string line, string structname = null)
+{
+	string[] parts = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
+	
+	string fieldType = null;
+	string fieldName = null;
+	int arraySize = 0;
+	
+	if (parts.Length == 2)
+	{
+		fieldType = parts[0];
+		if (parts[1].Contains("["))
+		{
+			var arrayMatch = Regex.Match(parts[1], "^([a-zA-Z0-9]+)\\[(\\d+)\\]$");
+			if (!arrayMatch.Success)
+			{
+				throw new InvalidDataException();
+			}
+			fieldName = arrayMatch.Groups[1].Value;
+			arraySize = int.Parse(arrayMatch.Groups[2].Value);
+		}
+		else
+		{
+			fieldName = parts[1];
+		}
+	}
+	else
+	{
+		if (!parts.Contains(":"))
+		{
+			throw new InvalidDataException();
+		}
+
+		fieldType = parts[0];
+		fieldName = parts[1];
+	}
+	
+	if (structname != null)
+	{
+		structname += ".";
+	}
+	
+	if (fieldType == "USHORT")
+	{
+		if (arraySize == 0)
+		{
+			Console.WriteLine($"printf(\"{structname ?? ""}{fieldName} = %hu\\r\\n\", {structvar}->{structname ?? ""}{fieldName});");
+		}
+		else
+		{
+			for (int i = 0; i < arraySize; i++)
+			{
+				Console.WriteLine($"printf(\"{structname ?? ""}{fieldName}[{i}] = %hu\\r\\n\", {structvar}->{structname ?? ""}{fieldName}[{i}]);");
+			}
+		}
+	}
+	else if (fieldType == "ULONG")
+	{
+		if (arraySize == 0)
+		{
+			Console.WriteLine($"printf(\"{structname ?? ""}{fieldName} = %lu\\r\\n\", {structvar}->{structname ?? ""}{fieldName});");
+		}
+		else
+		{
+			for (int i = 0; i < arraySize; i++)
+			{
+				Console.WriteLine($"printf(\"{structname ?? ""}{fieldName}[{i}] = %lu\\r\\n\", {structvar}->{structname ?? ""}{fieldName}[{i}]);");
+			}
+		}
+	}
+	else if (fieldType == "UCHAR")
+	{
+		if (arraySize == 0)
+		{
+			Console.WriteLine($"printf(\"{structname ?? ""}{fieldName} = %d\\r\\n\", {structvar}->{structname ?? ""}{fieldName});");
+		}
+		else
+		{
+			string format = string.Concat(Enumerable.Repeat("%c", arraySize));
+			Console.Write($"printf(\"{structname ?? ""}{fieldName} = \\\"{format}\\\"\\r\\n\"");
+			for (int i = 0; i < arraySize; i++)
+			{
+				int ni = i;
+				if (SwapStringEndian)
+				{
+					ni = (i - (i % 2)) + (1 - (i % 2));
+				}
+				Console.Write($", {structvar}->{structname ?? ""}{fieldName}[{ni}]");
+			}
+			Console.WriteLine(");");
+		}
+	}
+	else
+	{
+		throw new InvalidDataException();
+	}
+}
\ No newline at end of file
diff --git a/al-khaser/al-khaser.sln b/al-khaser/al-khaser.sln
new file mode 100644
index 0000000000000000000000000000000000000000..54c3d80faef9c9b3ee6e720860148040f0addca3
--- /dev/null
+++ b/al-khaser/al-khaser.sln
@@ -0,0 +1,45 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28010.2026
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "al-khaser", "al-khaser\al-khaser.vcxproj", "{77AEFBC3-0ECE-46AD-A113-966AAAA838E1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{71BFEE2B-52EC-4526-90F5-D91D98B9C786}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ATAIdentifyDump", "Tools\ATAIdentifyDump\ATAIdentifyDump.vcxproj", "{245D8670-A888-4ECC-9B51-80584E55B701}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Debug|x64.ActiveCfg = Debug|x64
+		{77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Debug|x64.Build.0 = Debug|x64
+		{77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Debug|x86.ActiveCfg = Debug|Win32
+		{77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Debug|x86.Build.0 = Debug|Win32
+		{77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Release|x64.ActiveCfg = Release|x64
+		{77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Release|x64.Build.0 = Release|x64
+		{77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Release|x86.ActiveCfg = Release|Win32
+		{77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Release|x86.Build.0 = Release|Win32
+		{245D8670-A888-4ECC-9B51-80584E55B701}.Debug|x64.ActiveCfg = Debug|x64
+		{245D8670-A888-4ECC-9B51-80584E55B701}.Debug|x64.Build.0 = Debug|x64
+		{245D8670-A888-4ECC-9B51-80584E55B701}.Debug|x86.ActiveCfg = Debug|Win32
+		{245D8670-A888-4ECC-9B51-80584E55B701}.Debug|x86.Build.0 = Debug|Win32
+		{245D8670-A888-4ECC-9B51-80584E55B701}.Release|x64.ActiveCfg = Release|x64
+		{245D8670-A888-4ECC-9B51-80584E55B701}.Release|x64.Build.0 = Release|x64
+		{245D8670-A888-4ECC-9B51-80584E55B701}.Release|x86.ActiveCfg = Release|Win32
+		{245D8670-A888-4ECC-9B51-80584E55B701}.Release|x86.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{245D8670-A888-4ECC-9B51-80584E55B701} = {71BFEE2B-52EC-4526-90F5-D91D98B9C786}
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {0772817E-132F-4922-8377-5DA07255372F}
+	EndGlobalSection
+EndGlobal
diff --git a/al-khaser/al-khaser/Al-khaser.cpp b/al-khaser/al-khaser/Al-khaser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dbacb711c1d5c304494652074a02d843b907d336
--- /dev/null
+++ b/al-khaser/al-khaser/Al-khaser.cpp
@@ -0,0 +1,377 @@
+// al-khaser.cpp : This file contains the 'main' function. Program execution begins and ends there.
+//
+
+#include "pch.h"
+
+
+BOOL ENABLE_TLS_CHECKS = FALSE;
+BOOL ENABLE_DEBUG_CHECKS = FALSE;
+BOOL ENABLE_INJECTION_CHECKS = FALSE;
+BOOL ENABLE_GEN_SANDBOX_CHECKS = FALSE;
+BOOL ENABLE_VBOX_CHECKS = FALSE;
+BOOL ENABLE_VMWARE_CHECKS = FALSE;
+BOOL ENABLE_VPC_CHECKS = FALSE;
+BOOL ENABLE_QEMU_CHECKS = FALSE;
+BOOL ENABLE_KVM_CHECKS = FALSE;
+BOOL ENABLE_XEN_CHECKS = FALSE;
+BOOL ENABLE_WINE_CHECKS = FALSE;
+BOOL ENABLE_PARALLELS_CHECKS = FALSE;
+BOOL ENABLE_HYPERV_CHECKS = FALSE;
+BOOL ENABLE_CODE_INJECTIONS = FALSE;
+BOOL ENABLE_TIMING_ATTACKS = FALSE;
+BOOL ENABLE_DUMPING_CHECK = FALSE;
+BOOL ENABLE_ANALYSIS_TOOLS_CHECK = FALSE;
+BOOL ENABLE_ANTI_DISASSM_CHECKS = FALSE;
+
+
+void EnableDefaultChecks() {
+	ENABLE_TLS_CHECKS = TRUE;
+	ENABLE_DEBUG_CHECKS = TRUE;
+	ENABLE_INJECTION_CHECKS = TRUE;
+	ENABLE_GEN_SANDBOX_CHECKS = TRUE;
+	ENABLE_VBOX_CHECKS = TRUE;
+	ENABLE_VMWARE_CHECKS = TRUE;
+	ENABLE_VPC_CHECKS = TRUE;
+	ENABLE_QEMU_CHECKS = TRUE;
+	ENABLE_KVM_CHECKS = TRUE;
+	ENABLE_XEN_CHECKS = TRUE;
+	ENABLE_WINE_CHECKS = TRUE;
+	ENABLE_PARALLELS_CHECKS = TRUE;
+	ENABLE_HYPERV_CHECKS = TRUE;
+	ENABLE_TIMING_ATTACKS = TRUE;
+	ENABLE_DUMPING_CHECK = TRUE;
+	ENABLE_ANALYSIS_TOOLS_CHECK = TRUE;
+	ENABLE_ANTI_DISASSM_CHECKS = TRUE;
+}
+
+
+void EnableChecks(std::string checkType) {
+	if (checkType == "TLS")						ENABLE_TLS_CHECKS = TRUE;
+	else if (checkType == "DEBUG")				ENABLE_DEBUG_CHECKS = TRUE;
+	else if (checkType == "INJECTION")			ENABLE_INJECTION_CHECKS = TRUE;
+	else if (checkType == "GEN_SANDBOX")		ENABLE_GEN_SANDBOX_CHECKS = TRUE;
+	else if (checkType == "VBOX")				ENABLE_VBOX_CHECKS = TRUE;
+	else if (checkType == "VMWARE")				ENABLE_VMWARE_CHECKS = TRUE;
+	else if (checkType == "VPC")				ENABLE_VPC_CHECKS = TRUE;
+	else if (checkType == "QEMU")				ENABLE_QEMU_CHECKS = TRUE;
+	else if (checkType == "KVM")				ENABLE_KVM_CHECKS = TRUE;
+	else if (checkType == "XEN")				ENABLE_XEN_CHECKS = TRUE;
+	else if (checkType == "WINE")				ENABLE_WINE_CHECKS = TRUE;
+	else if (checkType == "PARALLELS")			ENABLE_PARALLELS_CHECKS = TRUE;
+	else if (checkType == "HYPERV")				ENABLE_HYPERV_CHECKS = TRUE;
+	else if (checkType == "CODE_INJECTIONS")	ENABLE_CODE_INJECTIONS = TRUE;
+	else if (checkType == "TIMING_ATTACKS")		ENABLE_TIMING_ATTACKS = TRUE;
+	else if (checkType == "DUMPING_CHECK")		ENABLE_DUMPING_CHECK = TRUE;
+	else if (checkType == "ANALYSIS_TOOLS")		ENABLE_ANALYSIS_TOOLS_CHECK = TRUE;
+	else if (checkType == "ANTI_DISASSM")		ENABLE_ANTI_DISASSM_CHECKS = TRUE;
+}
+
+
+int main(int argc, char* argv[])
+{
+	/* enable functions */
+	if (argc > 1) {
+		for (int i = 1; i < argc; i += 2) {
+			if (strcmp(argv[i], "--check") == 0 && (i + 1 < argc)) {
+				EnableChecks(argv[i + 1]);
+			}
+		}
+	}
+	else {
+		EnableDefaultChecks();
+	}
+
+	/* Resize the console window for better visibility */
+	resize_console_window();
+
+	/* Display general informations */
+	_tprintf(_T("[al-khaser version 0.82]"));
+
+	print_category(TEXT("Initialisation"));
+	API::Init();
+	print_os();
+	API::PrintAvailabilityReport();
+
+	/* Are we running under WoW64 */
+	if (IsWoW64())
+		_tprintf(_T("Process is running under WOW64\n\n"));
+
+	if (ENABLE_DEBUG_CHECKS) PageExceptionInitialEnum();
+
+	/* TLS checks */
+	if (ENABLE_TLS_CHECKS) {
+		print_category(TEXT("TLS Callbacks"));
+		exec_check(&TLSCallbackProcess, TEXT("TLS process attach callback "));
+		exec_check(&TLSCallbackThread, TEXT("TLS thread attach callback "));
+	}
+
+	/* Debugger Detection */
+	if (ENABLE_DEBUG_CHECKS) {
+		print_category(TEXT("Debugger Detection"));
+		exec_check(&IsDebuggerPresentAPI, TEXT("Checking IsDebuggerPresent API "));
+		exec_check(&IsDebuggerPresentPEB, TEXT("Checking PEB.BeingDebugged "));
+		exec_check(&CheckRemoteDebuggerPresentAPI, TEXT("Checking CheckRemoteDebuggerPresent API "));
+		exec_check(&NtGlobalFlag, TEXT("Checking PEB.NtGlobalFlag "));
+		exec_check(&HeapFlags, TEXT("Checking ProcessHeap.Flags "));
+		exec_check(&HeapForceFlags, TEXT("Checking ProcessHeap.ForceFlags "));
+		exec_check(&LowFragmentationHeap, TEXT("Checking Low Fragmentation Heap"));
+		exec_check(&NtQueryInformationProcess_ProcessDebugPort, TEXT("Checking NtQueryInformationProcess with ProcessDebugPort "));
+		exec_check(&NtQueryInformationProcess_ProcessDebugFlags, TEXT("Checking NtQueryInformationProcess with ProcessDebugFlags "));
+		exec_check(&NtQueryInformationProcess_ProcessDebugObject, TEXT("Checking NtQueryInformationProcess with ProcessDebugObject "));
+		exec_check(&WUDF_IsAnyDebuggerPresent, TEXT("Checking WudfIsAnyDebuggerPresent API "));
+		exec_check(&WUDF_IsKernelDebuggerPresent, TEXT("Checking WudfIsKernelDebuggerPresent API "));
+		exec_check(&WUDF_IsUserDebuggerPresent, TEXT("Checking WudfIsUserDebuggerPresent API "));
+		exec_check(&NtSetInformationThread_ThreadHideFromDebugger, TEXT("Checking NtSetInformationThread with ThreadHideFromDebugger "));
+		exec_check(&CloseHandle_InvalideHandle, TEXT("Checking CloseHandle with an invalide handle "));
+		exec_check(&NtSystemDebugControl_Command, TEXT("Checking NtSystemDebugControl"));
+		exec_check(&UnhandledExcepFilterTest, TEXT("Checking UnhandledExcepFilterTest "));
+		exec_check(&OutputDebugStringAPI, TEXT("Checking OutputDebugString "));
+		exec_check(&HardwareBreakpoints, TEXT("Checking Hardware Breakpoints "));
+		exec_check(&SoftwareBreakpoints, TEXT("Checking Software Breakpoints "));
+		exec_check(&Interrupt_0x2d, TEXT("Checking Interupt 0x2d "));
+		exec_check(&Interrupt_3, TEXT("Checking Interupt 1 "));
+		exec_check(&TrapFlag, TEXT("Checking trap flag"));
+		exec_check(&MemoryBreakpoints_PageGuard, TEXT("Checking Memory Breakpoints PAGE GUARD "));
+		exec_check(&IsParentExplorerExe, TEXT("Checking If Parent Process is explorer.exe "));
+		exec_check(&CanOpenCsrss, TEXT("Checking SeDebugPrivilege "));
+		exec_check(&NtQueryObject_ObjectTypeInformation, TEXT("Checking NtQueryObject with ObjectTypeInformation "));
+		exec_check(&NtQueryObject_ObjectAllTypesInformation, TEXT("Checking NtQueryObject with ObjectAllTypesInformation "));
+		exec_check(&NtYieldExecutionAPI, TEXT("Checking NtYieldExecution "));
+		exec_check(&SetHandleInformatiom_ProtectedHandle, TEXT("Checking CloseHandle protected handle trick  "));
+		exec_check(&NtQuerySystemInformation_SystemKernelDebuggerInformation, TEXT("Checking NtQuerySystemInformation with SystemKernelDebuggerInformation  "));
+		exec_check(&SharedUserData_KernelDebugger, TEXT("Checking SharedUserData->KdDebuggerEnabled  "));
+		exec_check(&ProcessJob, TEXT("Checking if process is in a job  "));
+		exec_check(&VirtualAlloc_WriteWatch_BufferOnly, TEXT("Checking VirtualAlloc write watch (buffer only) "));
+		exec_check(&VirtualAlloc_WriteWatch_APICalls, TEXT("Checking VirtualAlloc write watch (API calls) "));
+		exec_check(&VirtualAlloc_WriteWatch_IsDebuggerPresent, TEXT("Checking VirtualAlloc write watch (IsDebuggerPresent) "));
+		exec_check(&VirtualAlloc_WriteWatch_CodeWrite, TEXT("Checking VirtualAlloc write watch (code write) "));
+		exec_check(&PageExceptionBreakpointCheck, TEXT("Checking for page exception breakpoints "));
+		exec_check(&ModuleBoundsHookCheck, TEXT("Checking for API hooks outside module bounds "));
+	}
+
+	if (ENABLE_INJECTION_CHECKS) {
+		print_category(TEXT("DLL Injection Detection"));
+		exec_check(&ScanForModules_EnumProcessModulesEx_32bit, TEXT("Enumerating modules with EnumProcessModulesEx [32-bit] "));
+		exec_check(&ScanForModules_EnumProcessModulesEx_64bit, TEXT("Enumerating modules with EnumProcessModulesEx [64-bit] "));
+		exec_check(&ScanForModules_EnumProcessModulesEx_All, TEXT("Enumerating modules with EnumProcessModulesEx [ALL] "));
+		exec_check(&ScanForModules_ToolHelp32, TEXT("Enumerating modules with ToolHelp32 "));
+		exec_check(&ScanForModules_LdrEnumerateLoadedModules, TEXT("Enumerating the process LDR via LdrEnumerateLoadedModules "));
+		exec_check(&ScanForModules_LDR_Direct, TEXT("Enumerating the process LDR directly "));
+		exec_check(&ScanForModules_MemoryWalk_GMI, TEXT("Walking process memory with GetModuleInformation "));
+		exec_check(&ScanForModules_MemoryWalk_Hidden, TEXT("Walking process memory for hidden modules "));
+		exec_check(&ScanForModules_DotNetModuleStructures, TEXT("Walking process memory for .NET module structures "));
+	}
+
+	/* Generic sandbox detection */
+	if (ENABLE_GEN_SANDBOX_CHECKS) {
+		print_category(TEXT("Generic Sandboxe/VM Detection"));
+		loaded_dlls();
+		known_file_names();
+		known_usernames();
+		known_hostnames();
+		other_known_sandbox_environment_checks();
+		exec_check(&NumberOfProcessors, TEXT("Checking Number of processors in machine "));
+		exec_check(&idt_trick, TEXT("Checking Interupt Descriptor Table location "));
+		exec_check(&ldt_trick, TEXT("Checking Local Descriptor Table location "));
+		exec_check(&gdt_trick, TEXT("Checking Global Descriptor Table location "));
+		exec_check(&str_trick, TEXT("Checking Store Task Register "));
+		exec_check(&number_cores_wmi, TEXT("Checking Number of cores in machine using WMI "));
+		exec_check(&disk_size_wmi, TEXT("Checking hard disk size using WMI "));
+		exec_check(&dizk_size_deviceiocontrol, TEXT("Checking hard disk size using DeviceIoControl "));
+		exec_check(&setupdi_diskdrive, TEXT("Checking SetupDi_diskdrive "));
+		exec_check(&mouse_movement, TEXT("Checking mouse movement "));
+		exec_check(&lack_user_input, TEXT("Checking lack of user input "));
+		exec_check(&memory_space, TEXT("Checking memory space using GlobalMemoryStatusEx "));
+		exec_check(&disk_size_getdiskfreespace, TEXT("Checking disk size using GetDiskFreeSpaceEx "));
+		exec_check(&cpuid_is_hypervisor, TEXT("Checking if CPU hypervisor field is set using cpuid(0x1)"));
+		exec_check(&cpuid_hypervisor_vendor, TEXT("Checking hypervisor vendor using cpuid(0x40000000)"));
+		exec_check(&accelerated_sleep, TEXT("Check if time has been accelerated "));
+		exec_check(&VMDriverServices, TEXT("VM Driver Services  "));
+		exec_check(&serial_number_bios_wmi, TEXT("Checking SerialNumber from BIOS using WMI "));
+		exec_check(&model_computer_system_wmi, TEXT("Checking Model from ComputerSystem using WMI "));
+		exec_check(&manufacturer_computer_system_wmi, TEXT("Checking Manufacturer from ComputerSystem using WMI "));
+		exec_check(&current_temperature_acpi_wmi, TEXT("Checking Current Temperature using WMI "));
+		exec_check(&process_id_processor_wmi, TEXT("Checking ProcessId using WMI "));
+		exec_check(&power_capabilities, TEXT("Checking power capabilities "));
+		exec_check(&cpu_fan_wmi, TEXT("Checking CPU fan using WMI "));
+		exec_check(&query_license_value, TEXT("Checking NtQueryLicenseValue with Kernel-VMDetection-Private "));
+		exec_check(&cachememory_wmi, TEXT("Checking Win32_CacheMemory with WMI "));
+		exec_check(&physicalmemory_wmi, TEXT("Checking Win32_PhysicalMemory with WMI "));
+		exec_check(&memorydevice_wmi, TEXT("Checking Win32_MemoryDevice with WMI "));
+		exec_check(&memoryarray_wmi, TEXT("Checking Win32_MemoryArray with WMI "));
+		exec_check(&voltageprobe_wmi, TEXT("Checking Win32_VoltageProbe with WMI "));
+		exec_check(&portconnector_wmi, TEXT("Checking Win32_PortConnector with WMI "));
+		exec_check(&smbiosmemory_wmi, TEXT("Checking Win32_SMBIOSMemory with WMI "));
+		exec_check(&perfctrs_thermalzoneinfo_wmi, TEXT("Checking ThermalZoneInfo performance counters with WMI "));
+		exec_check(&cim_memory_wmi, TEXT("Checking CIM_Memory with WMI "));
+		exec_check(&cim_sensor_wmi, TEXT("Checking CIM_Sensor with WMI "));
+		exec_check(&cim_numericsensor_wmi, TEXT("Checking CIM_NumericSensor with WMI "));
+		exec_check(&cim_temperaturesensor_wmi, TEXT("Checking CIM_TemperatureSensor with WMI "));
+		exec_check(&cim_voltagesensor_wmi, TEXT("Checking CIM_VoltageSensor with WMI "));
+		exec_check(&cim_physicalconnector_wmi, TEXT("Checking CIM_PhysicalConnector with WMI "));
+		exec_check(&cim_slot_wmi, TEXT("Checking CIM_Slot with WMI "));
+		exec_check(&pirated_windows, TEXT("Checking if Windows is Genuine "));
+		exec_check(&registry_services_disk_enum, TEXT("Checking Services\\Disk\\Enum entries for VM strings "));
+		exec_check(&registry_disk_enum, TEXT("Checking Enum\\IDE and Enum\\SCSI entries for VM strings "));
+		exec_check(&number_SMBIOS_tables, TEXT("Checking SMBIOS tables  "));
+	}
+
+	/* VirtualBox Detection */
+	if (ENABLE_VBOX_CHECKS) {
+		print_category(TEXT("VirtualBox Detection"));
+		vbox_reg_key_value();
+		exec_check(&vbox_dir, TEXT("Checking VirtualBox Guest Additions directory "));
+		vbox_files();
+		vbox_reg_keys();
+		exec_check(&vbox_check_mac, TEXT("Checking Mac Address start with 08:00:27 "));
+		exec_check(&hybridanalysismacdetect, TEXT("Checking MAC address (Hybrid Analysis) "));
+		vbox_devices();
+		exec_check(&vbox_window_class, TEXT("Checking VBoxTrayToolWndClass / VBoxTrayToolWnd "));
+		exec_check(&vbox_network_share, TEXT("Checking VirtualBox Shared Folders network provider "));
+		vbox_processes();
+		exec_check(&vbox_pnpentity_pcideviceid_wmi, TEXT("Checking Win32_PnPDevice DeviceId from WMI for VBox PCI device "));
+		exec_check(&vbox_pnpentity_controllers_wmi, TEXT("Checking Win32_PnPDevice Name from WMI for VBox controller hardware "));
+		exec_check(&vbox_pnpentity_vboxname_wmi, TEXT("Checking Win32_PnPDevice Name from WMI for VBOX names "));
+		exec_check(&vbox_bus_wmi, TEXT("Checking Win32_Bus from WMI "));
+		exec_check(&vbox_baseboard_wmi, TEXT("Checking Win32_BaseBoard from WMI "));
+		exec_check(&vbox_mac_wmi, TEXT("Checking MAC address from WMI "));
+		exec_check(&vbox_eventlogfile_wmi, TEXT("Checking NTEventLog from WMI "));
+		exec_check(&vbox_firmware_SMBIOS, TEXT("Checking SMBIOS firmware  "));
+		exec_check(&vbox_firmware_ACPI, TEXT("Checking ACPI tables  "));
+	}
+
+	/* VMWare Detection */
+	if (ENABLE_VMWARE_CHECKS) {
+		print_category(TEXT("VMWare Detection"));
+		vmware_reg_key_value();
+		vmware_reg_keys();
+		vmware_files();
+		vmware_mac();
+		exec_check(&vmware_adapter_name, TEXT("Checking VMWare network adapter name "));
+		vmware_devices();
+		exec_check(&vmware_dir, TEXT("Checking VMWare directory "));
+		exec_check(&vmware_firmware_SMBIOS, TEXT("Checking SMBIOS firmware  "));
+		exec_check(&vmware_firmware_ACPI, TEXT("Checking ACPI tables  "));
+	}
+
+	/* Virtual PC Detection */
+	if (ENABLE_VPC_CHECKS) {
+		print_category(TEXT("Virtual PC Detection"));
+		virtual_pc_process();
+		virtual_pc_reg_keys();
+	}
+
+	/* QEMU Detection */
+	if (ENABLE_QEMU_CHECKS) {
+		print_category(TEXT("QEMU Detection"));
+		qemu_reg_key_value();
+		qemu_processes();
+		qemu_dir();
+		exec_check(&qemu_firmware_SMBIOS, TEXT("Checking SMBIOS firmware  "));
+		exec_check(&qemu_firmware_ACPI, TEXT("Checking ACPI tables  "));
+
+	}
+
+	/* Xen Detection */
+	if (ENABLE_XEN_CHECKS) {
+		print_category(TEXT("Xen Detection"));
+		xen_process();
+		exec_check(&xen_check_mac, TEXT("Checking Mac Address start with 08:16:3E "));
+	}
+
+	/* KVM Detection */
+	if (ENABLE_KVM_CHECKS) {
+		print_category(TEXT("Xen Detection"));
+		kvm_files();
+		kvm_reg_keys();
+		exec_check(&kvm_dir, TEXT("Checking KVM virio directory "));
+	}
+
+	/* Wine Detection */
+	if (ENABLE_WINE_CHECKS) {
+		print_category(TEXT("Wine Detection"));
+		exec_check(&wine_exports, TEXT("Checking Wine via dll exports "));
+		wine_reg_keys();
+	}
+
+	/* Paralles Detection */
+	if (ENABLE_PARALLELS_CHECKS) {
+		print_category(TEXT("Paralles Detection"));
+		parallels_process();
+		exec_check(&parallels_check_mac, TEXT("Checking Mac Address start with 00:1C:42 "));
+	}
+
+	if (ENABLE_HYPERV_CHECKS) {
+		print_category(TEXT("Hyper-V Detection"));
+		exec_check(&check_hyperv_driver_objects, TEXT("Checking for Hyper-V driver objects "));
+		exec_check(&check_hyperv_global_objects, TEXT("Checking for Hyper-V global objects "));
+	}
+
+	/* Code injections techniques */
+	if (ENABLE_CODE_INJECTIONS) {
+		CreateRemoteThread_Injection();
+		SetWindowsHooksEx_Injection();
+		NtCreateThreadEx_Injection();
+		RtlCreateUserThread_Injection();
+		QueueUserAPC_Injection();
+		GetSetThreadContext_Injection();
+	}
+
+	/* Timing Attacks */
+	if (ENABLE_TIMING_ATTACKS) {
+		print_category(TEXT("Timing-attacks"));
+		UINT delayInSeconds = 600U;
+		UINT delayInMillis = delayInSeconds * 1000U;
+		printf("\n[*] Delay value is set to %u minutes ...\n", delayInSeconds / 60);
+
+		exec_check(timing_NtDelayexecution, delayInMillis, TEXT("Performing a sleep using NtDelayExecution ..."));
+		exec_check(timing_sleep_loop, delayInMillis, TEXT("Performing a sleep() in a loop ..."));
+		exec_check(timing_SetTimer, delayInMillis, TEXT("Delaying execution using SetTimer ..."));
+		exec_check(timing_timeSetEvent, delayInMillis, TEXT("Delaying execution using timeSetEvent ..."));
+		exec_check(timing_WaitForSingleObject, delayInMillis, TEXT("Delaying execution using WaitForSingleObject ..."));
+		exec_check(timing_WaitForMultipleObjects, delayInMillis, TEXT("Delaying execution using WaitForMultipleObjects ..."));
+		exec_check(timing_IcmpSendEcho, delayInMillis, TEXT("Delaying execution using IcmpSendEcho ..."));
+		exec_check(timing_CreateWaitableTimer, delayInMillis, TEXT("Delaying execution using CreateWaitableTimer ..."));
+		exec_check(timing_CreateTimerQueueTimer, delayInMillis, TEXT("Delaying execution using CreateTimerQueueTimer ..."));
+
+		exec_check(&rdtsc_diff_locky, TEXT("Checking RDTSC Locky trick "));
+		exec_check(&rdtsc_diff_vmexit, TEXT("Checking RDTSC which force a VM Exit (cpuid) "));
+	}
+
+	/* Malware analysis tools */
+	if (ENABLE_ANALYSIS_TOOLS_CHECK) {
+		print_category(TEXT("Analysis-tools"));
+		analysis_tools_process();
+	}
+
+	/* Anti disassembler tricks */
+	if (ENABLE_ANTI_DISASSM_CHECKS) {
+		_tprintf(_T("Begin AntiDisassmConstantCondition\n"));
+		AntiDisassmConstantCondition();
+		_tprintf(_T("Begin AntiDisassmAsmJmpSameTarget\n"));
+		AntiDisassmAsmJmpSameTarget();
+		_tprintf(_T("Begin AntiDisassmImpossibleDiasassm\n"));
+		AntiDisassmImpossibleDiasassm();
+		_tprintf(_T("Begin AntiDisassmFunctionPointer\n"));
+		AntiDisassmFunctionPointer();
+		_tprintf(_T("Begin AntiDisassmReturnPointerAbuse\n"));
+		AntiDisassmReturnPointerAbuse();
+#ifndef _WIN64
+		_tprintf(_T("Begin AntiDisassmSEHMisuse\n"));
+		AntiDisassmSEHMisuse();
+#endif
+	}
+
+	/* Anti Dumping */
+	if (ENABLE_DUMPING_CHECK) {
+		print_category(TEXT("Anti Dumping"));
+		ErasePEHeaderFromMemory();
+		SizeOfImage();
+	}
+
+	_tprintf(_T("\n\nAnalysis done, I hope you didn't get red flags :)"));
+
+	getchar();
+	return 0;
+}
+
diff --git a/al-khaser/al-khaser/AntiAnalysis/pch.h b/al-khaser/al-khaser/AntiAnalysis/pch.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7df92d774ff3829efea501cff3b5b40e5b16f4b
--- /dev/null
+++ b/al-khaser/al-khaser/AntiAnalysis/pch.h
@@ -0,0 +1 @@
+#include "../pch.h"
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiAnalysis/process.cpp b/al-khaser/al-khaser/AntiAnalysis/process.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6c2c2c778dfa52171d7ba0d49752c8d3fa77a1cd
--- /dev/null
+++ b/al-khaser/al-khaser/AntiAnalysis/process.cpp
@@ -0,0 +1,60 @@
+#include "pch.h"
+#pragma once
+#include "process.h"
+
+/*
+Check for process list
+*/
+
+VOID analysis_tools_process()
+{
+	const TCHAR *szProcesses[] = {
+		_T("ollydbg.exe"),						// OllyDebug debugger
+		_T("ollyice.exe"),						// OllyICE debugger
+		_T("ProcessHacker.exe"),				// Process Hacker
+		_T("tcpview.exe"),						// Part of Sysinternals Suite
+		_T("autoruns.exe"),						// Part of Sysinternals Suite
+		_T("autorunsc.exe"),					// Part of Sysinternals Suite
+		_T("filemon.exe"),						// Part of Sysinternals Suite
+		_T("procmon.exe"),						// Part of Sysinternals Suite
+		_T("regmon.exe"),						// Part of Sysinternals Suite
+		_T("procexp.exe"),						// Part of Sysinternals Suite
+		_T("idaq.exe"),							// IDA Pro Interactive Disassembler
+		_T("idaq64.exe"),						// IDA Pro Interactive Disassembler
+		_T("ImmunityDebugger.exe"),				// ImmunityDebugger
+		_T("Wireshark.exe"),					// Wireshark packet sniffer
+		_T("dumpcap.exe"),						// Network traffic dump tool
+		_T("HookExplorer.exe"),					// Find various types of runtime hooks
+		_T("ImportREC.exe"),					// Import Reconstructor
+		_T("PETools.exe"),						// PE Tool
+		_T("LordPE.exe"),						// LordPE
+		_T("SysInspector.exe"),					// ESET SysInspector
+		_T("proc_analyzer.exe"),				// Part of SysAnalyzer iDefense
+		_T("sysAnalyzer.exe"),					// Part of SysAnalyzer iDefense
+		_T("sniff_hit.exe"),					// Part of SysAnalyzer iDefense
+		_T("windbg.exe"),						// Microsoft WinDbg
+		_T("joeboxcontrol.exe"),				// Part of Joe Sandbox
+		_T("joeboxserver.exe"),					// Part of Joe Sandbox
+		_T("ResourceHacker.exe"),				// Resource Hacker
+		_T("x32dbg.exe"),						// x32dbg
+		_T("x64dbg.exe"),						// x64dbg
+		_T("Fiddler.exe"),						// Fiddler
+		_T("httpdebugger.exe"),					// Http Debugger
+		_T("cheatengine-i386.exe"),				// Cheat Engine
+		_T("cheatengine-x86_64.exe"),			// Cheat Engine
+		_T("cheatengine-x86_64-SSE4-AVX2.exe"), // Cheat Engine
+		_T("frida-helper-32.exe"),				// Frida
+		_T("frida-helper-64.exe"),				// Frida
+	};
+
+	WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]);
+	for (int i = 0; i < iLength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking process of malware analysis tool: %s "), szProcesses[i]);
+		if (GetProcessIdFromName(szProcesses[i]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
diff --git a/al-khaser/al-khaser/AntiAnalysis/process.h b/al-khaser/al-khaser/AntiAnalysis/process.h
new file mode 100644
index 0000000000000000000000000000000000000000..f71e75b367f9e8593ccc4fad136903711acc3e74
--- /dev/null
+++ b/al-khaser/al-khaser/AntiAnalysis/process.h
@@ -0,0 +1,11 @@
+#pragma once
+
+VOID analysis_tools_process();
+
+/*
+
+avpui.exe 
+avgui.exe
+bdagent.exe
+
+*/
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/BeingDebugged.cpp b/al-khaser/al-khaser/AntiDebug/BeingDebugged.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e3721b0fc9eea8362d65d285019b795e288eb52a
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/BeingDebugged.cpp
@@ -0,0 +1,36 @@
+#include "pch.h"
+#include "BeingDebugged.h"
+
+
+BOOL
+IsDebuggerPresentPEB(
+	VOID
+)
+/*++
+
+Routine Description:
+
+	Checks if the BeingDebugged flag is set in the Process Environment Block (PEB).
+	This is effectively the same code that IsDebuggerPresent() executes internally.
+	The PEB pointer is fetched from DWORD FS:[0x30] on x86_32 and QWORD GS:[0x60] on x86_64.
+
+Arguments:
+
+	None
+
+Return Value:
+
+	TRUE - if debugger was detected
+	FALSE - otherwise
+--*/
+{
+#if defined (ENV64BIT)
+	PPEB pPeb = (PPEB)__readgsqword(0x60);
+
+#elif defined(ENV32BIT)
+	PPEB pPeb = (PPEB)__readfsdword(0x30);
+
+#endif
+
+	return pPeb->BeingDebugged == 1;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/BeingDebugged.h b/al-khaser/al-khaser/AntiDebug/BeingDebugged.h
new file mode 100644
index 0000000000000000000000000000000000000000..6fedf60c86336f96db2383340a2b067208b4aaa4
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/BeingDebugged.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL IsDebuggerPresentPEB();
diff --git a/al-khaser/al-khaser/AntiDebug/CheckRemoteDebuggerPresent.cpp b/al-khaser/al-khaser/AntiDebug/CheckRemoteDebuggerPresent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9008b8cff3df0a2d81fa6aa2ed6273f7cfd914a7
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/CheckRemoteDebuggerPresent.cpp
@@ -0,0 +1,32 @@
+#include "pch.h"
+#include "CheckRemoteDebuggerPresent.h"
+
+BOOL
+CheckRemoteDebuggerPresentAPI (
+	VOID
+	)
+/*++
+
+Routine Description:
+
+	CheckRemoteDebuggerPresent() is another Win32 Debugging API function;
+	it can be used to check if a remote process is being debugged. However,
+	we can also use this as another method for checking if our own process
+	is being debugged. This API internally calls the NTDLL export
+	NtQueryInformationProcess function with the PROCESSINFOCLASS set to
+	7 (ProcessDebugPort).
+
+Arguments:
+
+	None
+
+Return Value:
+
+	TRUE - if debugger was detected
+	FALSE - otherwise
+--*/
+{
+	BOOL bIsDbgPresent = FALSE;
+	CheckRemoteDebuggerPresent(GetCurrentProcess(), &bIsDbgPresent);
+	return bIsDbgPresent;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/CheckRemoteDebuggerPresent.h b/al-khaser/al-khaser/AntiDebug/CheckRemoteDebuggerPresent.h
new file mode 100644
index 0000000000000000000000000000000000000000..bafff1ed3f13fc04201fda72f36ea3fc3adc14e7
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/CheckRemoteDebuggerPresent.h
@@ -0,0 +1 @@
+BOOL CheckRemoteDebuggerPresentAPI();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/CloseHandle_InvalidHandle.cpp b/al-khaser/al-khaser/AntiDebug/CloseHandle_InvalidHandle.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3ad72e7ea067d67243a73fd3a368894f3e0d24ae
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/CloseHandle_InvalidHandle.cpp
@@ -0,0 +1,43 @@
+#include "pch.h"
+
+
+ /* 
+ APIs making use of the ZwClose syscall (such as CloseHandle, indirectly) 
+ can be used to detect a debugger. When a process is debugged, calling ZwClose 
+ with an invalid handle will generate a STATUS_INVALID_HANDLE (0xC0000008) exception.
+ As with all anti-debugs that rely on information made directly available.
+*/
+
+
+BOOL NtClose_InvalideHandle()
+{
+	auto NtClose_ = static_cast<pNtClose>(API::GetAPI(API_IDENTIFIER::API_NtClose));
+
+	__try {
+		NtClose_(reinterpret_cast<HANDLE>(0x99999999ULL));
+	}
+	__except (EXCEPTION_EXECUTE_HANDLER) {
+		return TRUE;
+	}
+
+	return FALSE;
+
+}
+
+BOOL CloseHandle_InvalideHandle()
+{
+	// Let's try first with user mode API: CloseHandle
+	__try {
+		CloseHandle(reinterpret_cast<HANDLE>(0x99999999ULL));
+	}
+	__except (EXCEPTION_EXECUTE_HANDLER) {
+		return TRUE;
+	}
+
+	// Direct call to NtClose to bypass user mode hooks
+	if (NtClose_InvalideHandle())
+		return TRUE;
+	else
+		return FALSE;
+}
+
diff --git a/al-khaser/al-khaser/AntiDebug/CloseHandle_InvalidHandle.h b/al-khaser/al-khaser/AntiDebug/CloseHandle_InvalidHandle.h
new file mode 100644
index 0000000000000000000000000000000000000000..0364973e44550e32fa0d4ac870e6a8b777090a9d
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/CloseHandle_InvalidHandle.h
@@ -0,0 +1 @@
+BOOL CloseHandle_InvalideHandle();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/HardwareBreakpoints.cpp b/al-khaser/al-khaser/AntiDebug/HardwareBreakpoints.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b7331dda1824093a6220dd654e08b49791d38ec5
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/HardwareBreakpoints.cpp
@@ -0,0 +1,41 @@
+#include "pch.h"
+
+#include "HardwareBreakpoints.h"
+
+/*
+Hardware breakpoints are a technology implemented by Intel in their processor architecture,
+and are controlled by the use of special registers known as Dr0-Dr7.
+Dr0 through Dr3 are 32 bit registers that hold the address of the breakpoint .
+*/
+
+
+BOOL HardwareBreakpoints()
+{
+	BOOL bResult = FALSE;
+
+	// This structure is key to the function and is the 
+	// medium for detection and removal
+	PCONTEXT ctx = PCONTEXT(VirtualAlloc(NULL, sizeof(CONTEXT), MEM_COMMIT, PAGE_READWRITE));
+
+	if (ctx) {
+
+		SecureZeroMemory(ctx, sizeof(CONTEXT));
+
+		// The CONTEXT structure is an in/out parameter therefore we have
+		// to set the flags so Get/SetThreadContext knows what to set or get.
+		ctx->ContextFlags = CONTEXT_DEBUG_REGISTERS;
+
+		// Get the registers
+		if (GetThreadContext(GetCurrentThread(), ctx)) {
+
+			// Now we can check for hardware breakpoints, its not 
+			// necessary to check Dr6 and Dr7, however feel free to
+			if (ctx->Dr0 != 0 || ctx->Dr1 != 0 || ctx->Dr2 != 0 || ctx->Dr3 != 0)
+				bResult = TRUE;
+		}
+
+		VirtualFree(ctx, 0, MEM_RELEASE);
+	}
+
+	return bResult;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/HardwareBreakpoints.h b/al-khaser/al-khaser/AntiDebug/HardwareBreakpoints.h
new file mode 100644
index 0000000000000000000000000000000000000000..d6f2c31fd2481418b7c2b9a4293131666e827349
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/HardwareBreakpoints.h
@@ -0,0 +1 @@
+BOOL HardwareBreakpoints();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/Interrupt_0x2d.cpp b/al-khaser/al-khaser/AntiDebug/Interrupt_0x2d.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2dfc262a9923aa87d33b192e7f006d816876625a
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/Interrupt_0x2d.cpp
@@ -0,0 +1,37 @@
+#include "pch.h"
+
+#include "Interrupt_0x2d.h"
+
+/*
+The Interrupt_0x2d function will check to see if a debugger is attached to the current process. It does this by setting up
+SEH and using the Int 2D instruction which will only cause an exception if there is no debugger. Also when used in OllyDBG
+it will skip a byte in the disassembly which could be used to detect the debugger.
+
+Vectored Exception Handling is used here because SEH is an anti-debug trick in itself.
+*/
+
+extern "C" void __int2d();
+
+static BOOL SwallowedException = TRUE;
+
+static LONG CALLBACK VectoredHandler(
+	_In_ PEXCEPTION_POINTERS ExceptionInfo
+)
+{
+	SwallowedException = FALSE;
+	if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
+	{
+		//The Int 2D instruction already increased EIP/RIP so we don't do that (although it wouldnt hurt).
+		return EXCEPTION_CONTINUE_EXECUTION;
+	}
+	return EXCEPTION_CONTINUE_SEARCH;
+}
+
+BOOL Interrupt_0x2d()
+{
+	PVOID Handle = AddVectoredExceptionHandler(1, VectoredHandler);
+	SwallowedException = TRUE;
+	__int2d();
+	RemoveVectoredExceptionHandler(Handle);
+	return SwallowedException;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/Interrupt_0x2d.h b/al-khaser/al-khaser/AntiDebug/Interrupt_0x2d.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d997e0600a8ddfc5a41341f47f89cae93000008
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/Interrupt_0x2d.h
@@ -0,0 +1 @@
+BOOL Interrupt_0x2d();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/Interrupt_3.cpp b/al-khaser/al-khaser/AntiDebug/Interrupt_3.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..571bc6e6d2f71ffd545b4c29170dc638a62b825f
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/Interrupt_3.cpp
@@ -0,0 +1,43 @@
+#include "pch.h"
+
+#include "Interrupt_3.h"
+
+/*
+INT 3 generates a call to trap in the debugger and is triggered by opcode 0xCC within the executing process.
+When a debugger is attached, the 0xCC execution will cause the debugger to catch the breakpoint and handle
+the resulting exception. If a debugger is not attached, the exception is passed through to a structured
+exception handler thus informing the process that no debugger is present.
+
+Vectored Exception Handling is used here because SEH is an anti-debug trick in itself.
+*/
+
+static BOOL SwallowedException = TRUE;
+
+static LONG CALLBACK VectoredHandler(
+	_In_ PEXCEPTION_POINTERS ExceptionInfo
+)
+{
+	SwallowedException = FALSE;
+	if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
+	{
+		//Increase EIP/RIP to continue execution.
+#ifdef _WIN64
+		ExceptionInfo->ContextRecord->Rip++;
+#else
+		ExceptionInfo->ContextRecord->Eip++;
+#endif
+		return EXCEPTION_CONTINUE_EXECUTION;
+	}
+	return EXCEPTION_CONTINUE_SEARCH;
+}
+
+
+
+BOOL Interrupt_3()
+{
+	PVOID Handle = AddVectoredExceptionHandler(1, VectoredHandler);
+	SwallowedException = TRUE;
+	__debugbreak();
+	RemoveVectoredExceptionHandler(Handle);
+	return SwallowedException;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/Interrupt_3.h b/al-khaser/al-khaser/AntiDebug/Interrupt_3.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b67d61feea6737c2902c412c41079271eba3a08
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/Interrupt_3.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL Interrupt_3();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/IsDebuggerPresent.cpp b/al-khaser/al-khaser/AntiDebug/IsDebuggerPresent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..77bf94782151594dc9f1bbac1fb2d21bee773e02
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/IsDebuggerPresent.cpp
@@ -0,0 +1,28 @@
+#include "pch.h"
+#include "IsDebuggerPresent.h"
+
+BOOL
+IsDebuggerPresentAPI (
+	VOID
+	)
+/*++
+
+Routine Description:
+
+	Calls the IsDebuggerPresent() API. This function is part of the
+	Win32 Debugging API and it returns TRUE if a user mode debugger
+	is present. Internally, it simply returns the value of the
+	PEB->BeingDebugged flag.
+
+Arguments:
+
+	None
+
+Return Value:
+
+	TRUE - if debugger was detected
+	FALSE - otherwise
+--*/
+{
+	return IsDebuggerPresent();
+}
diff --git a/al-khaser/al-khaser/AntiDebug/IsDebuggerPresent.h b/al-khaser/al-khaser/AntiDebug/IsDebuggerPresent.h
new file mode 100644
index 0000000000000000000000000000000000000000..97dad4aee6c1bf200627723354345c8e87a8f10e
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/IsDebuggerPresent.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL IsDebuggerPresentAPI();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/LowFragmentationHeap.cpp b/al-khaser/al-khaser/AntiDebug/LowFragmentationHeap.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a19a048bb195ee13cc981c08f62f5a0d08b831fc
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/LowFragmentationHeap.cpp
@@ -0,0 +1,61 @@
+#include "pch.h"
+#include "LowFragmentationHeap.h"
+
+
+BOOL
+LowFragmentationHeap(
+	VOID
+)
+/*++
+
+Routine Description:
+	Originally found by Souhail Hammou:
+	http://rce4fun.blogspot.com/2014/02/anti-debugging-trick-checking-for-low.html
+	Under a debugger, the process does not have a Low Fragmentation Heap (LFH)
+	The routine simply checks whether the nt!_HEAP.FrontEndHeap is NULL.
+
+Arguments:
+
+	None
+
+Return Value:
+
+	TRUE - if debugger was detected
+	FALSE - otherwise
+--*/
+{
+
+	PINT_PTR FrontEndHeap = NULL;
+
+	// Get the default process heap.
+	HANDLE hHeap = GetProcessHeap();
+
+	// The FrontEndHeap offset of the _HEAP structure
+	// is found on different locations depending of the OS.
+
+	if (IsWindowsVista() || IsWindows7()) {
+#if defined (ENV64BIT)
+		FrontEndHeap = (PINT_PTR)((CHAR*)hHeap + 0x178);
+
+#elif defined(ENV32BIT)
+		FrontEndHeap = (PINT_PTR)((CHAR*)hHeap + 0xd4);
+#endif
+	}
+
+	if (IsWindows8or8PointOne()) {
+#if defined (ENV64BIT)
+		FrontEndHeap = (PINT_PTR)((CHAR*)hHeap + 0x170);
+
+#elif defined(ENV32BIT)
+		FrontEndHeap = (PINT_PTR)((CHAR*)hHeap + 0xd0);
+#endif
+	}
+
+	// In Windows 10. the offset changes very often.
+	// Ignoring it from now.
+	if (FrontEndHeap && *FrontEndHeap == NULL) {
+		return TRUE;
+	}
+
+	return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/LowFragmentationHeap.h b/al-khaser/al-khaser/AntiDebug/LowFragmentationHeap.h
new file mode 100644
index 0000000000000000000000000000000000000000..5bb67c6805d4f509866c19f4eea4a553c515a92b
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/LowFragmentationHeap.h
@@ -0,0 +1,6 @@
+#pragma once
+
+BOOL
+LowFragmentationHeap(
+	VOID
+);
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/MemoryBreakpoints_PageGuard.cpp b/al-khaser/al-khaser/AntiDebug/MemoryBreakpoints_PageGuard.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6e2062d92d07ba11227d185dedcb871158772766
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/MemoryBreakpoints_PageGuard.cpp
@@ -0,0 +1,47 @@
+#include "pch.h"
+
+#include "MemoryBreakpoints_PageGuard.h"
+
+/*
+In essence, what occurs is that we allocate a dynamic buffer and write a RET to the buffer.
+We then mark the page as a guard page and push a potential return address onto the stack. Next, we jump to our page,
+and if we're under a debugger, specifically OllyDBG, then we will hit the RET instruction and return to the address we pushed onto
+the stack before we jumped to our page. Otherwise, a STATUS_GUARD_PAGE_VIOLATION exception will occur, and we know we're not being
+debugged by OllyDBG.
+*/
+
+BOOL MemoryBreakpoints_PageGuard()
+{
+	UCHAR *pMem = NULL;
+	SYSTEM_INFO SystemInfo = { 0 };
+	DWORD OldProtect = 0;
+	PVOID pAllocation = NULL; // Get the page size for the system 
+
+	// Retrieves information about the current system.
+	GetSystemInfo(&SystemInfo);
+
+	// Allocate memory 
+	pAllocation = VirtualAlloc(NULL, SystemInfo.dwPageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+	if (pAllocation == NULL)
+		return FALSE;
+
+	// Write a ret to the buffer (opcode 0xc3)
+	RtlFillMemory(pAllocation, 1, 0xC3);
+
+	// Make the page a guard page         
+	if (VirtualProtect(pAllocation, SystemInfo.dwPageSize, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &OldProtect) == 0)
+		return FALSE;
+
+	__try
+	{
+		((void(*)())pAllocation)(); // Exception or execution, which shall it be :D?
+	}
+	__except (GetExceptionCode() == STATUS_GUARD_PAGE_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
+	{
+		VirtualFree(pAllocation, 0, MEM_RELEASE);
+		return FALSE;
+	}
+
+	VirtualFree(pAllocation, 0, MEM_RELEASE);
+	return TRUE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/MemoryBreakpoints_PageGuard.h b/al-khaser/al-khaser/AntiDebug/MemoryBreakpoints_PageGuard.h
new file mode 100644
index 0000000000000000000000000000000000000000..9a319ad0a8d0a8bbd1821172415c0491b066058a
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/MemoryBreakpoints_PageGuard.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL MemoryBreakpoints_PageGuard();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/ModuleBoundsHookCheck.cpp b/al-khaser/al-khaser/AntiDebug/ModuleBoundsHookCheck.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cd6ab4305c41c770191da33737e280a5ef969f24
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/ModuleBoundsHookCheck.cpp
@@ -0,0 +1,108 @@
+#include "pch.h"
+
+/*
+
+This check works by asking for the addresses of a whole load of APIs from a library, then checking that the resulting pointer is within that library's memory addrress space.
+
+Note that this is an incomplete set of APIs on purpose. Some APIs are redirected to alternative implementations on Windows 10, and those APIs have been omitted.
+
+*/
+
+char apis_kernel32[] = "ActivateActCtx ActivateActCtxWorker AddAtomA AddAtomW AddConsoleAliasA AddConsoleAliasW AddIntegrityLabelToBoundaryDescriptor AddLocalAlternateComputerNameA AddLocalAlternateComputerNameW AddRefActCtx AddRefActCtxWorker AddResourceAttributeAce AddSIDToBoundaryDescriptor AddScopedPolicyIDAce AddSecureMemoryCacheCallback AdjustCalendarDate AllocConsole AllocateUserPhysicalPages AllocateUserPhysicalPagesNuma ApplicationRecoveryFinished ApplicationRecoveryInProgress AreFileApisANSI AssignProcessToJobObject AttachConsole BackupRead BackupSeek BackupWrite BaseCheckAppcompatCache BaseCheckAppcompatCacheEx BaseCheckAppcompatCacheExWorker BaseCheckAppcompatCacheWorker BaseCheckElevation BaseCleanupAppcompatCacheSupport BaseCleanupAppcompatCacheSupportWorker BaseDestroyVDMEnvironment BaseDllReadWriteIniFile BaseDumpAppcompatCache BaseDumpAppcompatCacheWorker BaseElevationPostProcessing BaseFlushAppcompatCache BaseFlushAppcompatCacheWorker BaseFormatObjectAttributes BaseFormatTimeOut BaseFreeAppCompatDataForProcessWorker BaseGenerateAppCompatData BaseGetNamedObjectDirectory BaseInitAppcompatCacheSupport BaseInitAppcompatCacheSupportWorker BaseIsAppcompatInfrastructureDisabled BaseIsAppcompatInfrastructureDisabledWorker BaseIsDosApplication BaseQueryModuleData BaseReadAppCompatDataForProcessWorker BaseSetLastNTError BaseThreadInitThunk BaseUpdateAppcompatCache BaseUpdateAppcompatCacheWorker BaseUpdateVDMEntry BaseVerifyUnicodeString BaseWriteErrorElevationRequiredEvent Basep8BitStringToDynamicUnicodeString BasepAllocateActivationContextActivationBlock BasepAnsiStringToDynamicUnicodeString BasepAppContainerEnvironmentExtension BasepAppXExtension BasepCheckAppCompat BasepCheckWebBladeHashes BasepCheckWinSaferRestrictions BasepConstructSxsCreateProcessMessage BasepCopyEncryption BasepFreeActivationContextActivationBlock BasepFreeAppCompatData BasepGetAppCompatData BasepGetComputerNameFromNtPath BasepGetExeArchType BasepInitAppCompatData BasepIsProcessAllowed " \
+"BasepMapModuleHandle BasepNotifyLoadStringResource BasepPostSuccessAppXExtension BasepProcessInvalidImage BasepQueryAppCompat BasepQueryModuleChpeSettings BasepReleaseAppXContext BasepReleaseSxsCreateProcessUtilityStruct BasepReportFault BasepSetFileEncryptionCompression Beep BeginUpdateResourceA BeginUpdateResourceW BindIoCompletionCallback BuildCommDCBA BuildCommDCBAndTimeoutsA BuildCommDCBAndTimeoutsW BuildCommDCBW CallNamedPipeA CallNamedPipeW CallbackMayRunLong CancelDeviceWakeupRequest CancelIo CancelIoEx CancelSynchronousIo CancelTimerQueueTimer CancelWaitableTimer ChangeTimerQueueTimer CheckAllowDecryptedRemoteDestinationPolicy CheckElevation CheckElevationEnabled CheckForReadOnlyResource CheckForReadOnlyResourceFilter CheckNameLegalDOS8Dot3A CheckNameLegalDOS8Dot3W CheckRemoteDebuggerPresent CheckTokenCapability CheckTokenMembershipEx ClearCommBreak ClearCommError CloseConsoleHandle CloseHandle ClosePrivateNamespace CloseProfileUserMapping CmdBatNotification CommConfigDialogA CommConfigDialogW CompareCalendarDates CompareFileTime CompareStringA CompareStringEx CompareStringOrdinal CompareStringW ConnectNamedPipe ConsoleMenuControl ContinueDebugEvent ConvertCalDateTimeToSystemTime ConvertDefaultLocale ConvertFiberToThread ConvertNLSDayOfWeekToWin32DayOfWeek ConvertSystemTimeToCalDateTime ConvertThreadToFiber ConvertThreadToFiberEx CopyContext CopyFile2 CopyFileA CopyFileExA CopyFileExW CopyFileTransactedA CopyFileTransactedW CopyFileW CopyLZFile CreateActCtxA CreateActCtxW CreateActCtxWWorker CreateBoundaryDescriptorA CreateBoundaryDescriptorW CreateConsoleScreenBuffer CreateDirectoryA CreateDirectoryExA CreateDirectoryExW CreateDirectoryTransactedA CreateDirectoryTransactedW CreateDirectoryW CreateEventA CreateEventExA CreateEventExW CreateEventW CreateFiber CreateFiberEx CreateFile2 CreateFileA CreateFileMappingA CreateFileMappingNumaA CreateFileMappingNumaW CreateFileMappingW CreateFileTransactedA CreateFileTransactedW CreateFileW CreateHardLinkA CreateHardLinkTransactedA " \
+"CreateHardLinkTransactedW CreateHardLinkW CreateIoCompletionPort CreateJobObjectA CreateJobObjectW CreateJobSet CreateMailslotA CreateMailslotW CreateMemoryResourceNotification CreateMutexA CreateMutexExA CreateMutexExW CreateMutexW CreateNamedPipeA CreateNamedPipeW CreatePipe CreatePrivateNamespaceA CreatePrivateNamespaceW CreateProcessA CreateProcessAsUserA CreateProcessAsUserW CreateProcessInternalA CreateProcessInternalW CreateProcessW CreateRemoteThread CreateSemaphoreA CreateSemaphoreExA CreateSemaphoreExW CreateSemaphoreW CreateSymbolicLinkA CreateSymbolicLinkTransactedA CreateSymbolicLinkTransactedW CreateSymbolicLinkW CreateTapePartition CreateThread CreateThreadpool CreateThreadpoolCleanupGroup CreateThreadpoolIo CreateThreadpoolTimer CreateThreadpoolWait CreateThreadpoolWork CreateTimerQueue CreateTimerQueueTimer CreateToolhelp32Snapshot CreateUmsCompletionList CreateUmsThreadContext CreateWaitableTimerA CreateWaitableTimerExA CreateWaitableTimerExW CreateWaitableTimerW DeactivateActCtx DeactivateActCtxWorker DebugActiveProcess DebugActiveProcessStop DebugBreak DebugBreakProcess DebugSetProcessKillOnExit DefineDosDeviceA DefineDosDeviceW DelayLoadFailureHook DeleteAtom DeleteBoundaryDescriptor DeleteFiber DeleteFileA DeleteFileTransactedA DeleteFileTransactedW DeleteFileW DeleteSynchronizationBarrier DeleteTimerQueue DeleteTimerQueueEx DeleteTimerQueueTimer DeleteUmsCompletionList DeleteUmsThreadContext DeleteVolumeMountPointA DeleteVolumeMountPointW DequeueUmsCompletionListItems DeviceIoControl DisableThreadLibraryCalls DisableThreadProfiling DisconnectNamedPipe DnsHostnameToComputerNameA DnsHostnameToComputerNameExW DnsHostnameToComputerNameW DosDateTimeToFileTime DosPathToSessionPathA DosPathToSessionPathW DuplicateConsoleHandle DuplicateEncryptionInfoFileExt DuplicateHandle EnableThreadProfiling EndUpdateResourceA EndUpdateResourceW EnterSynchronizationBarrier EnterUmsSchedulingMode EnumCalendarInfoA EnumCalendarInfoExA EnumCalendarInfoExEx EnumCalendarInfoExW " \
+"EnumCalendarInfoW EnumDateFormatsA EnumDateFormatsExA EnumDateFormatsExEx EnumDateFormatsExW EnumDateFormatsW EnumLanguageGroupLocalesA EnumLanguageGroupLocalesW EnumResourceLanguagesA EnumResourceLanguagesExA EnumResourceLanguagesExW EnumResourceLanguagesW EnumResourceNamesA EnumResourceNamesExA EnumResourceNamesExW EnumResourceNamesW EnumResourceTypesA EnumResourceTypesExA EnumResourceTypesExW EnumResourceTypesW EnumSystemCodePagesA EnumSystemCodePagesW EnumSystemFirmwareTables EnumSystemGeoID EnumSystemGeoNames EnumSystemLanguageGroupsA EnumSystemLanguageGroupsW EnumSystemLocalesA EnumSystemLocalesEx EnumSystemLocalesW EnumTimeFormatsA EnumTimeFormatsEx EnumTimeFormatsW EnumUILanguagesA EnumUILanguagesW EnumerateLocalComputerNamesA EnumerateLocalComputerNamesW EraseTape EscapeCommFunction ExecuteUmsThread ExitProcess ExitVDM ExpandEnvironmentStringsA ExpandEnvironmentStringsW ExpungeConsoleCommandHistoryA ExpungeConsoleCommandHistoryW FatalAppExitA FatalAppExitW FatalExit FileTimeToDosDateTime FileTimeToLocalFileTime FileTimeToSystemTime FillConsoleOutputAttribute FillConsoleOutputCharacterA FillConsoleOutputCharacterW FindActCtxSectionGuid FindActCtxSectionGuidWorker FindActCtxSectionStringA FindActCtxSectionStringW FindActCtxSectionStringWWorker FindAtomA FindAtomW FindClose FindCloseChangeNotification FindFirstChangeNotificationA FindFirstChangeNotificationW FindFirstFileA FindFirstFileExA FindFirstFileExW FindFirstFileNameTransactedW FindFirstFileNameW FindFirstFileTransactedA FindFirstFileTransactedW FindFirstFileW FindFirstStreamTransactedW FindFirstVolumeA FindFirstVolumeMountPointA FindFirstVolumeMountPointW FindFirstVolumeW FindNLSString FindNLSStringEx FindNextChangeNotification FindNextFileA FindNextFileNameW FindNextFileW FindNextVolumeA FindNextVolumeMountPointA FindNextVolumeMountPointW FindNextVolumeW FindResourceA FindResourceExA FindResourceExW FindResourceW FindStringOrdinal FindVolumeClose FindVolumeMountPointClose FlsAlloc FlsFree FlsGetValue FlsSetValue " \
+"FlushConsoleInputBuffer FlushFileBuffers FlushInstructionCache FlushViewOfFile FoldStringA FoldStringW FormatMessageA FormatMessageW FreeConsole FreeEnvironmentStringsA FreeEnvironmentStringsW FreeLibrary FreeLibraryAndExitThread FreeMemoryJobObject FreeResource FreeUserPhysicalPages GenerateConsoleCtrlEvent GetACP GetActiveProcessorCount GetActiveProcessorGroupCount GetAppContainerAce GetAppContainerNamedObjectPath GetApplicationRecoveryCallback GetApplicationRecoveryCallbackWorker GetApplicationRestartSettings GetApplicationRestartSettingsWorker GetAtomNameA GetAtomNameW GetBinaryType GetBinaryTypeA GetBinaryTypeW GetCPInfo GetCPInfoExA GetCPInfoExW GetCachedSigningLevel GetCalendarDateFormat GetCalendarDateFormatEx GetCalendarDaysInMonth GetCalendarDifferenceInDays GetCalendarInfoA GetCalendarInfoEx GetCalendarInfoW GetCalendarMonthsInYear GetCalendarSupportedDateRange GetCalendarWeekNumber GetComPlusPackageInstallStatus GetCommConfig GetCommMask GetCommModemStatus GetCommProperties GetCommState GetCommTimeouts GetCommandLineA GetCommandLineW GetCompressedFileSizeA GetCompressedFileSizeTransactedA GetCompressedFileSizeTransactedW GetCompressedFileSizeW GetComputerNameA GetComputerNameExA GetComputerNameExW GetComputerNameW GetConsoleAliasA GetConsoleAliasExesA GetConsoleAliasExesLengthA GetConsoleAliasExesLengthW GetConsoleAliasExesW GetConsoleAliasW GetConsoleAliasesA GetConsoleAliasesLengthA GetConsoleAliasesLengthW GetConsoleAliasesW GetConsoleCP GetConsoleCharType GetConsoleCommandHistoryA GetConsoleCommandHistoryLengthA GetConsoleCommandHistoryLengthW GetConsoleCommandHistoryW GetConsoleCursorInfo GetConsoleCursorMode GetConsoleDisplayMode GetConsoleFontInfo GetConsoleFontSize GetConsoleHardwareState GetConsoleHistoryInfo GetConsoleInputWaitHandle GetConsoleKeyboardLayoutNameA GetConsoleKeyboardLayoutNameW GetConsoleMode GetConsoleNlsMode GetConsoleOriginalTitleA GetConsoleOriginalTitleW GetConsoleOutputCP GetConsoleProcessList GetConsoleScreenBufferInfo GetConsoleScreenBufferInfoEx " \
+"GetConsoleSelectionInfo GetConsoleTitleA GetConsoleTitleW GetConsoleWindow GetCurrencyFormatA GetCurrencyFormatEx GetCurrencyFormatW GetCurrentActCtx GetCurrentActCtxWorker GetCurrentConsoleFont GetCurrentConsoleFontEx GetCurrentDirectoryA GetCurrentDirectoryW GetCurrentProcess GetCurrentProcessId GetCurrentThread GetCurrentThreadId GetCurrentUmsThread GetDateFormatA GetDateFormatAWorker GetDateFormatEx GetDateFormatW GetDateFormatWWorker GetDefaultCommConfigA GetDefaultCommConfigW GetDevicePowerState GetDiskFreeSpaceA GetDiskFreeSpaceExA GetDiskFreeSpaceExW GetDiskFreeSpaceW GetDllDirectoryA GetDllDirectoryW GetDriveTypeA GetDriveTypeW GetDurationFormat GetDurationFormatEx GetDynamicTimeZoneInformation GetEnabledXStateFeatures GetEncryptedFileVersionExt GetEnvironmentStrings GetEnvironmentStringsA GetEnvironmentStringsW GetEnvironmentVariableA GetEnvironmentVariableW GetEraNameCountedString GetErrorMode GetExitCodeProcess GetExitCodeThread GetExpandedNameA GetExpandedNameW GetFileAttributesA GetFileAttributesExA GetFileAttributesExW GetFileAttributesTransactedA GetFileAttributesTransactedW GetFileAttributesW GetFileBandwidthReservation GetFileInformationByHandle GetFileInformationByHandleEx GetFileMUIInfo GetFileMUIPath GetFileSize GetFileSizeEx GetFileTime GetFileType GetFinalPathNameByHandleA GetFinalPathNameByHandleW GetFirmwareEnvironmentVariableA GetFirmwareEnvironmentVariableExA GetFirmwareEnvironmentVariableExW GetFirmwareEnvironmentVariableW GetFirmwareType GetFullPathNameA GetFullPathNameTransactedA GetFullPathNameTransactedW GetFullPathNameW GetGeoInfoA GetGeoInfoEx GetGeoInfoW GetHandleInformation GetLargePageMinimum GetLargestConsoleWindowSize GetLastError GetLocalTime GetLocaleInfoA GetLocaleInfoEx GetLocaleInfoW GetLogicalDriveStringsA GetLogicalDriveStringsW GetLogicalDrives GetLogicalProcessorInformation GetLongPathNameA GetLongPathNameTransactedA GetLongPathNameTransactedW GetLongPathNameW GetMailslotInfo GetMaximumProcessorCount GetMaximumProcessorGroupCount " \
+"GetMemoryErrorHandlingCapabilities GetModuleFileNameA GetModuleFileNameW GetModuleHandleA GetModuleHandleExA GetModuleHandleExW GetModuleHandleW GetNLSVersion GetNLSVersionEx GetNamedPipeAttribute GetNamedPipeClientComputerNameA GetNamedPipeClientComputerNameW GetNamedPipeClientProcessId GetNamedPipeClientSessionId GetNamedPipeHandleStateA GetNamedPipeHandleStateW GetNamedPipeServerProcessId GetNamedPipeServerSessionId GetNativeSystemInfo GetNextUmsListItem GetNextVDMCommand GetNumaAvailableMemoryNode GetNumaAvailableMemoryNodeEx GetNumaHighestNodeNumber GetNumaNodeNumberFromHandle GetNumaNodeProcessorMask GetNumaNodeProcessorMaskEx GetNumaProcessorNode GetNumaProcessorNodeEx GetNumaProximityNode GetNumaProximityNodeEx GetNumberFormatA GetNumberFormatEx GetNumberFormatW GetNumberOfConsoleFonts GetNumberOfConsoleInputEvents GetNumberOfConsoleMouseButtons GetOEMCP GetOverlappedResult GetPhysicallyInstalledSystemMemory GetPriorityClass GetPrivateProfileIntA GetPrivateProfileIntW GetPrivateProfileSectionA GetPrivateProfileSectionNamesA GetPrivateProfileSectionNamesW GetPrivateProfileSectionW GetPrivateProfileStringA GetPrivateProfileStringW GetPrivateProfileStructA GetPrivateProfileStructW GetProcAddress GetProcessAffinityMask GetProcessDEPPolicy GetProcessGroupAffinity GetProcessHandleCount GetProcessHeap GetProcessHeaps GetProcessId GetProcessIdOfThread GetProcessInformation GetProcessIoCounters GetProcessPreferredUILanguages GetProcessPriorityBoost GetProcessShutdownParameters GetProcessTimes GetProcessVersion GetProcessWorkingSetSize GetProcessWorkingSetSizeEx GetProductInfo GetProfileIntA GetProfileIntW GetProfileSectionA GetProfileSectionW GetProfileStringA GetProfileStringW GetQueuedCompletionStatus GetQueuedCompletionStatusEx GetShortPathNameA GetShortPathNameW GetStartupInfoA GetStartupInfoW GetStdHandle GetStringScripts GetStringTypeA GetStringTypeExA GetStringTypeExW GetStringTypeW GetSystemDEPPolicy GetSystemDefaultLCID GetSystemDefaultLangID GetSystemDefaultLocaleName " \
+"GetSystemDefaultUILanguage GetSystemDirectoryA GetSystemDirectoryW GetSystemFileCacheSize GetSystemFirmwareTable GetSystemInfo GetSystemPowerStatus GetSystemPreferredUILanguages GetSystemRegistryQuota GetSystemTime GetSystemTimeAdjustment GetSystemTimeAsFileTime GetSystemTimePreciseAsFileTime GetSystemTimes GetSystemWindowsDirectoryA GetSystemWindowsDirectoryW GetSystemWow64DirectoryA GetSystemWow64DirectoryW GetTapeParameters GetTapePosition GetTapeStatus GetTempFileNameA GetTempFileNameW GetTempPathA GetTempPathW GetThreadContext GetThreadErrorMode GetThreadGroupAffinity GetThreadIOPendingFlag GetThreadId GetThreadIdealProcessorEx GetThreadInformation GetThreadLocale GetThreadPreferredUILanguages GetThreadPriority GetThreadPriorityBoost GetThreadSelectorEntry GetThreadTimes GetThreadUILanguage GetTickCount GetTickCount64 GetTimeFormatA GetTimeFormatAWorker GetTimeFormatEx GetTimeFormatW GetTimeFormatWWorker GetTimeZoneInformation GetTimeZoneInformationForYear GetUILanguageInfo GetUmsCompletionListEvent GetUmsSystemThreadInformation GetUserDefaultGeoName GetUserDefaultLCID GetUserDefaultLangID GetUserDefaultLocaleName GetUserDefaultUILanguage GetUserGeoID GetUserPreferredUILanguages GetVDMCurrentDirectories GetVersion GetVersionExA GetVersionExW GetVolumeInformationA GetVolumeInformationByHandleW GetVolumeInformationW GetVolumeNameForVolumeMountPointA GetVolumeNameForVolumeMountPointW GetVolumePathNameA GetVolumePathNameW GetVolumePathNamesForVolumeNameA GetVolumePathNamesForVolumeNameW GetWindowsDirectoryA GetWindowsDirectoryW GetWriteWatch GetXStateFeaturesMask GlobalAddAtomA GlobalAddAtomExA GlobalAddAtomExW GlobalAddAtomW GlobalAlloc GlobalCompact GlobalDeleteAtom GlobalFindAtomA GlobalFindAtomW GlobalFix GlobalFlags GlobalFree GlobalGetAtomNameA GlobalGetAtomNameW GlobalHandle GlobalLock GlobalMemoryStatus GlobalMemoryStatusEx GlobalReAlloc GlobalSize GlobalUnWire GlobalUnfix GlobalUnlock GlobalWire Heap32First Heap32ListFirst Heap32ListNext Heap32Next HeapCompact " \
+"HeapCreate HeapDestroy HeapFree HeapLock HeapQueryInformation HeapSetInformation HeapSummary HeapUnlock HeapValidate HeapWalk IdnToAscii IdnToNameprepUnicode IdnToUnicode InitAtomTable InitializeContext InitializeCriticalSectionAndSpinCount InitializeCriticalSectionEx InitializeSynchronizationBarrier InvalidateConsoleDIBits IsBadCodePtr IsBadHugeReadPtr IsBadHugeWritePtr IsBadReadPtr IsBadStringPtrA IsBadStringPtrW IsBadWritePtr IsCalendarLeapDay IsCalendarLeapMonth IsCalendarLeapYear IsDBCSLeadByte IsDBCSLeadByteEx IsDebuggerPresent IsNLSDefinedString IsNativeVhdBoot IsNormalizedString IsProcessInJob IsProcessorFeaturePresent IsSystemResumeAutomatic IsThreadAFiber IsValidCalDateTime IsValidCodePage IsValidLanguageGroup IsValidLocale IsValidLocaleName IsValidNLSVersion IsWow64Process K32EmptyWorkingSet K32EnumDeviceDrivers K32EnumPageFilesA K32EnumPageFilesW K32EnumProcessModules K32EnumProcessModulesEx K32EnumProcesses K32GetDeviceDriverBaseNameA K32GetDeviceDriverBaseNameW K32GetDeviceDriverFileNameA K32GetDeviceDriverFileNameW K32GetMappedFileNameA K32GetMappedFileNameW K32GetModuleBaseNameA K32GetModuleBaseNameW K32GetModuleFileNameExA K32GetModuleFileNameExW K32GetModuleInformation K32GetPerformanceInfo K32GetProcessImageFileNameA K32GetProcessImageFileNameW K32GetProcessMemoryInfo K32GetWsChanges K32GetWsChangesEx K32InitializeProcessForWsWatch K32QueryWorkingSet K32QueryWorkingSetEx LCIDToLocaleName LCMapStringA LCMapStringEx LCMapStringW LZClose LZCloseFile LZCopy LZCreateFileW LZDone LZInit LZOpenFileA LZOpenFileW LZRead LZSeek LZStart LoadAppInitDlls LoadLibraryA LoadLibraryExA LoadLibraryExW LoadLibraryW LoadModule LoadPackagedLibrary LoadResource LoadStringBaseExW LoadStringBaseW LocalAlloc LocalCompact LocalFileTimeToFileTime LocalFlags LocalFree LocalHandle LocalLock LocalReAlloc LocalShrink LocalSize LocalUnlock LocaleNameToLCID LocateXStateFeature LockFile LockFileEx LockResource MapUserPhysicalPages MapUserPhysicalPagesScatter MapViewOfFile MapViewOfFileEx " \
+"MapViewOfFileExNuma Module32First Module32FirstW Module32Next Module32NextW MoveFileA MoveFileExA MoveFileExW MoveFileTransactedA MoveFileTransactedW MoveFileW MoveFileWithProgressA MoveFileWithProgressW MulDiv MultiByteToWideChar NeedCurrentDirectoryForExePathA NeedCurrentDirectoryForExePathW NlsCheckPolicy NlsEventDataDescCreate NlsGetCacheUpdateCount NlsUpdateLocale NlsUpdateSystemLocale NlsWriteEtwEvent NormalizeString NotifyMountMgr NotifyUILanguageChange NtVdm64CreateProcessInternalW OOBEComplete OpenConsoleW OpenConsoleWStub OpenEventA OpenEventW OpenFile OpenFileById OpenFileMappingA OpenFileMappingW OpenJobObjectA OpenJobObjectW OpenMutexA OpenMutexW OpenPrivateNamespaceA OpenPrivateNamespaceW OpenProcess OpenProfileUserMapping OpenSemaphoreA OpenSemaphoreW OpenThread OpenWaitableTimerA OpenWaitableTimerW OutputDebugStringA OutputDebugStringW PeekConsoleInputA PeekConsoleInputW PeekNamedPipe PostQueuedCompletionStatus PowerClearRequest PowerCreateRequest PowerSetRequest PrepareTape PrivCopyFileExW PrivMoveFileIdentityW Process32First Process32FirstW Process32Next Process32NextW ProcessIdToSessionId PssCaptureSnapshot PssDuplicateSnapshot PssFreeSnapshot PssQuerySnapshot PssWalkMarkerCreate PssWalkMarkerFree PssWalkMarkerGetPosition PssWalkMarkerRewind PssWalkMarkerSeek PssWalkMarkerSeekToBeginning PssWalkMarkerSetPosition PssWalkMarkerTell PssWalkSnapshot PulseEvent PurgeComm QueryActCtxSettingsW QueryActCtxSettingsWWorker QueryActCtxW QueryActCtxWWorker QueryDosDeviceA QueryDosDeviceW QueryFullProcessImageNameA QueryFullProcessImageNameW QueryIdleProcessorCycleTime QueryIdleProcessorCycleTimeEx QueryInformationJobObject QueryIoRateControlInformationJobObject QueryMemoryResourceNotification QueryPerformanceCounter QueryPerformanceFrequency QueryProcessAffinityUpdateMode QueryProcessCycleTime QueryThreadCycleTime QueryThreadProfiling QueryThreadpoolStackInformation QueryUmsThreadInformation QueryUnbiasedInterruptTime QueueUserAPC QueueUserWorkItem QuirkGetData2Worker " \
+"QuirkGetDataWorker QuirkIsEnabled2Worker QuirkIsEnabled3Worker QuirkIsEnabledForPackage2Worker QuirkIsEnabledForPackage3Worker QuirkIsEnabledForPackage4Worker QuirkIsEnabledForPackageWorker QuirkIsEnabledForProcessWorker QuirkIsEnabledWorker RaiseException RaiseInvalid16BitExeError ReOpenFile ReadConsoleA ReadConsoleInputA ReadConsoleInputW ReadConsoleOutputA ReadConsoleOutputAttribute ReadConsoleOutputCharacterA ReadConsoleOutputCharacterW ReadConsoleOutputW ReadConsoleW ReadDirectoryChangesExW ReadDirectoryChangesW ReadFile ReadFileEx ReadFileScatter ReadProcessMemory ReadThreadProfilingData RegCloseKey RegCopyTreeW RegCreateKeyExA RegCreateKeyExW RegDeleteKeyExA RegDeleteKeyExW RegDeleteTreeA RegDeleteTreeW RegDeleteValueA RegDeleteValueW RegDisablePredefinedCacheEx RegEnumKeyExA RegEnumKeyExW RegEnumValueA RegEnumValueW RegFlushKey RegGetKeySecurity RegGetValueA RegGetValueW RegLoadKeyA RegLoadKeyW RegLoadMUIStringA RegLoadMUIStringW RegNotifyChangeKeyValue RegOpenCurrentUser RegOpenKeyExA RegOpenKeyExW RegOpenUserClassesRoot RegQueryInfoKeyA RegQueryInfoKeyW RegQueryValueExA RegQueryValueExW RegRestoreKeyA RegRestoreKeyW RegSaveKeyExA RegSaveKeyExW RegSetKeySecurity RegSetValueExA RegSetValueExW RegUnLoadKeyA RegUnLoadKeyW RegisterApplicationRecoveryCallback RegisterApplicationRestart RegisterBadMemoryNotification RegisterConsoleIME RegisterConsoleOS2 RegisterConsoleVDM RegisterWaitForInputIdle RegisterWaitForSingleObject RegisterWaitForSingleObjectEx RegisterWaitUntilOOBECompleted RegisterWowBaseHandlers RegisterWowExec ReleaseActCtx ReleaseActCtxWorker ReleaseMutex ReleaseSemaphore RemoveDirectoryA RemoveDirectoryTransactedA RemoveDirectoryTransactedW RemoveDirectoryW RemoveLocalAlternateComputerNameA RemoveLocalAlternateComputerNameW RemoveSecureMemoryCacheCallback ReplaceFile ReplaceFileA ReplaceFileW ReplacePartitionUnit RequestDeviceWakeup RequestWakeupLatency ResetEvent ResetWriteWatch ResolveLocaleName ResumeThread RtlAddFunctionTable RtlCaptureContext RtlCaptureStackBackTrace " \
+"RtlCompareMemory RtlCopyMemory RtlDeleteFunctionTable RtlFillMemory RtlInstallFunctionTableCallback RtlLookupFunctionEntry RtlMoveMemory RtlPcToFileHeader RtlRaiseException RtlRestoreContext RtlUnwind RtlUnwindEx RtlVirtualUnwind ScrollConsoleScreenBufferA ScrollConsoleScreenBufferW SearchPathA SearchPathW SetCachedSigningLevel SetCalendarInfoA SetCalendarInfoW SetComPlusPackageInstallStatus SetCommBreak SetCommConfig SetCommMask SetCommState SetCommTimeouts SetComputerNameA SetComputerNameEx2W SetComputerNameExA SetComputerNameExW SetComputerNameW SetConsoleActiveScreenBuffer SetConsoleCP SetConsoleCtrlHandler SetConsoleCursor SetConsoleCursorInfo SetConsoleCursorMode SetConsoleCursorPosition SetConsoleDisplayMode SetConsoleFont SetConsoleHardwareState SetConsoleHistoryInfo SetConsoleIcon SetConsoleKeyShortcuts SetConsoleLocalEUDC SetConsoleMaximumWindowSize SetConsoleMenuClose SetConsoleMode SetConsoleNlsMode SetConsoleNumberOfCommandsA SetConsoleNumberOfCommandsW SetConsoleOS2OemFormat SetConsoleOutputCP SetConsolePalette SetConsoleScreenBufferInfoEx SetConsoleScreenBufferSize SetConsoleTextAttribute SetConsoleTitleA SetConsoleTitleW SetConsoleWindowInfo SetCurrentConsoleFontEx SetCurrentDirectoryA SetCurrentDirectoryW SetDefaultCommConfigA SetDefaultCommConfigW SetDllDirectoryA SetDllDirectoryW SetDynamicTimeZoneInformation SetEndOfFile SetEnvironmentStringsA SetEnvironmentStringsW SetEnvironmentVariableA SetEnvironmentVariableW SetErrorMode SetEvent SetFileApisToANSI SetFileApisToOEM SetFileAttributesA SetFileAttributesTransactedA SetFileAttributesTransactedW SetFileAttributesW SetFileBandwidthReservation SetFileCompletionNotificationModes SetFileInformationByHandle SetFileIoOverlappedRange SetFilePointer SetFilePointerEx SetFileShortNameA SetFileShortNameW SetFileTime SetFileValidData SetFirmwareEnvironmentVariableA SetFirmwareEnvironmentVariableExA SetFirmwareEnvironmentVariableExW SetFirmwareEnvironmentVariableW SetHandleCount SetHandleInformation SetInformationJobObject " \
+"SetIoRateControlInformationJobObject SetLastError SetLocalPrimaryComputerNameA SetLocalPrimaryComputerNameW SetLocalTime SetLocaleInfoA SetLocaleInfoW SetMailslotInfo SetMessageWaitingIndicator SetNamedPipeAttribute SetNamedPipeHandleState SetPriorityClass SetProcessAffinityMask SetProcessAffinityUpdateMode SetProcessDEPPolicy SetProcessInformation SetProcessPreferredUILanguages SetProcessPriorityBoost SetProcessShutdownParameters SetProcessWorkingSetSize SetProcessWorkingSetSizeEx SetSearchPathMode SetStdHandle SetStdHandleEx SetSystemFileCacheSize SetSystemPowerState SetSystemTime SetSystemTimeAdjustment SetTapeParameters SetTapePosition SetTermsrvAppInstallMode SetThreadAffinityMask SetThreadContext SetThreadErrorMode SetThreadExecutionState SetThreadGroupAffinity SetThreadIdealProcessor SetThreadIdealProcessorEx SetThreadInformation SetThreadLocale SetThreadPreferredUILanguages SetThreadPriority SetThreadPriorityBoost SetThreadStackGuarantee SetThreadUILanguage SetThreadpoolStackInformation SetThreadpoolThreadMinimum SetTimeZoneInformation SetTimerQueueTimer SetUmsThreadInformation SetUnhandledExceptionFilter SetUserGeoID SetUserGeoName SetVDMCurrentDirectories SetVolumeLabelA SetVolumeLabelW SetVolumeMountPointA SetVolumeMountPointW SetVolumeMountPointWStub SetWaitableTimer SetXStateFeaturesMask SetupComm ShowConsoleCursor SignalObjectAndWait SizeofResource Sleep SleepEx SortCloseHandle SortGetHandle SuspendThread SwitchToFiber SwitchToThread SystemTimeToFileTime SystemTimeToTzSpecificLocalTime TerminateJobObject TerminateProcess TerminateThread TermsrvAppInstallMode TermsrvConvertSysRootToUserDir TermsrvCreateRegEntry TermsrvDeleteKey TermsrvDeleteValue TermsrvGetPreSetValue TermsrvGetWindowsDirectoryA TermsrvGetWindowsDirectoryW TermsrvOpenRegEntry TermsrvOpenUserClasses TermsrvRestoreKey TermsrvSetKeySecurity TermsrvSetValueKey TermsrvSyncUserIniFileExt Thread32First Thread32Next TlsAlloc TlsFree TlsGetValue TlsSetValue Toolhelp32ReadProcessMemory TransactNamedPipe " \
+"TransmitCommChar TrySubmitThreadpoolCallback TzSpecificLocalTimeToSystemTime UTRegister UTUnRegister UmsThreadYield UnhandledExceptionFilter UnlockFile UnlockFileEx UnmapViewOfFile UnregisterApplicationRecoveryCallback UnregisterApplicationRestart UnregisterBadMemoryNotification UnregisterConsoleIME UnregisterWait UnregisterWaitEx UnregisterWaitUntilOOBECompleted UpdateCalendarDayOfWeek UpdateResourceA UpdateResourceW VDMConsoleOperation VDMOperationStarted VerLanguageNameA VerLanguageNameW VerifyConsoleIoHandle VerifyScripts VerifyVersionInfoA VerifyVersionInfoW VirtualAlloc VirtualAllocEx VirtualAllocExNuma VirtualFree VirtualFreeEx VirtualLock VirtualProtect VirtualProtectEx VirtualQuery VirtualQueryEx VirtualUnlock WTSGetActiveConsoleSessionId WaitCommEvent WaitForDebugEvent WaitForMultipleObjects WaitForMultipleObjectsEx WaitForSingleObject WaitForSingleObjectEx WaitNamedPipeA WaitNamedPipeW WerGetFlags WerGetFlagsWorker WerRegisterAdditionalProcess WerRegisterAppLocalDump WerRegisterCustomMetadata WerRegisterExcludedMemoryBlock WerRegisterFile WerRegisterFileWorker WerRegisterMemoryBlock WerRegisterMemoryBlockWorker WerRegisterRuntimeExceptionModule WerRegisterRuntimeExceptionModuleWorker WerSetFlags WerSetFlagsWorker WerUnregisterAdditionalProcess WerUnregisterAppLocalDump WerUnregisterCustomMetadata WerUnregisterExcludedMemoryBlock WerUnregisterFile WerUnregisterFileWorker WerUnregisterMemoryBlock WerUnregisterMemoryBlockWorker WerUnregisterRuntimeExceptionModule WerUnregisterRuntimeExceptionModuleWorker WerpGetDebugger WerpInitiateRemoteRecovery WerpLaunchAeDebug WerpNotifyLoadStringResourceWorker WerpNotifyUseStringResourceWorker WideCharToMultiByte WinExec Wow64DisableWow64FsRedirection Wow64EnableWow64FsRedirection Wow64GetThreadContext Wow64GetThreadSelectorEntry Wow64RevertWow64FsRedirection Wow64SetThreadContext Wow64SuspendThread WriteConsoleA WriteConsoleInputA WriteConsoleInputVDMA WriteConsoleInputVDMW WriteConsoleInputW WriteConsoleOutputA WriteConsoleOutputAttribute " \
+"WriteConsoleOutputCharacterA WriteConsoleOutputCharacterW WriteConsoleOutputW WriteConsoleW WriteFile WriteFileEx WriteFileGather WritePrivateProfileSectionA WritePrivateProfileSectionW WritePrivateProfileStringA WritePrivateProfileStringW WritePrivateProfileStructA WritePrivateProfileStructW WriteProcessMemory WriteProfileSectionA WriteProfileSectionW WriteProfileStringA WriteProfileStringW WriteTapemark ZombifyActCtx ZombifyActCtxWorker _hread _hwrite _lclose _lcreat _llseek _lopen _lread _lwrite lstrcat lstrcatA lstrcatW lstrcmp lstrcmpA lstrcmpW lstrcmpi lstrcmpiA lstrcmpiW lstrcpy lstrcpyA lstrcpyW lstrcpyn lstrcpynA lstrcpynW lstrlen lstrlenA lstrlenW timeBeginPeriod timeEndPeriod timeGetDevCaps timeGetSystemTime timeGetTime uaw_lstrcmpW uaw_lstrcmpiW uaw_lstrlenW uaw_wcschr uaw_wcscpy uaw_wcsicmp uaw_wcslen uaw_wcsrchr";
+
+char apis_ntdll[] = "A_SHAFinal A_SHAInit A_SHAUpdate AlpcAdjustCompletionListConcurrencyCount AlpcFreeCompletionListMessage AlpcGetCompletionListLastMessageInformation AlpcGetCompletionListMessageAttributes AlpcGetHeaderSize AlpcGetMessageAttribute AlpcGetMessageFromCompletionList AlpcGetOutstandingCompletionListMessageCount AlpcInitializeMessageAttribute AlpcMaxAllowedMessageLength AlpcRegisterCompletionList AlpcRegisterCompletionListWorkerThread AlpcRundownCompletionList AlpcUnregisterCompletionList AlpcUnregisterCompletionListWorkerThread ApiSetQueryApiSetPresence CsrAllocateCaptureBuffer CsrAllocateMessagePointer CsrCaptureMessageBuffer CsrCaptureMessageMultiUnicodeStringsInPlace CsrCaptureMessageString CsrCaptureTimeout CsrClientCallServer CsrClientConnectToServer CsrFreeCaptureBuffer CsrGetProcessId CsrIdentifyAlertableThread CsrSetPriorityClass CsrVerifyRegion DbgBreakPoint DbgPrint DbgPrintEx DbgPrintReturnControlC DbgPrompt DbgQueryDebugFilterState DbgSetDebugFilterState DbgUiConnectToDbg DbgUiContinue DbgUiConvertStateChangeStructure DbgUiConvertStateChangeStructureEx DbgUiDebugActiveProcess DbgUiGetThreadDebugObject DbgUiIssueRemoteBreakin DbgUiRemoteBreakin DbgUiSetThreadDebugObject DbgUiStopDebugging DbgUiWaitStateChange DbgUserBreakPoint EtwCheckCoverage EtwCreateTraceInstanceId EtwDeliverDataBlock EtwEnumerateProcessRegGuids EtwEventActivityIdControl EtwEventEnabled EtwEventProviderEnabled EtwEventRegister EtwEventSetInformation EtwEventUnregister EtwEventWrite EtwEventWriteEndScenario EtwEventWriteEx EtwEventWriteFull EtwEventWriteNoRegistration EtwEventWriteStartScenario EtwEventWriteString EtwEventWriteTransfer EtwGetTraceEnableFlags EtwGetTraceEnableLevel EtwGetTraceLoggerHandle EtwLogTraceEvent EtwNotificationRegister EtwNotificationUnregister EtwProcessPrivateLoggerRequest EtwRegisterSecurityProvider EtwRegisterTraceGuidsA EtwRegisterTraceGuidsW EtwReplyNotification EtwSendNotification EtwSetMark EtwTraceEventInstance EtwTraceMessage EtwTraceMessageVa " \
+"EtwUnregisterTraceGuids EtwWriteUMSecurityEvent EtwpCreateEtwThread EtwpGetCpuSpeed EvtIntReportAuthzEventAndSourceAsync EvtIntReportEventAndSourceAsync ExpInterlockedPopEntrySListEnd ExpInterlockedPopEntrySListFault ExpInterlockedPopEntrySListResume KiRaiseUserExceptionDispatcher KiUserApcDispatcher KiUserCallbackDispatcher KiUserExceptionDispatcher KiUserInvertedFunctionTable LdrAccessResource LdrAddDllDirectory LdrAddLoadAsDataTable LdrAddRefDll LdrAppxHandleIntegrityFailure LdrCallEnclave LdrControlFlowGuardEnforced LdrCreateEnclave LdrDeleteEnclave LdrDisableThreadCalloutsForDll LdrEnumResources LdrEnumerateLoadedModules LdrFastFailInLoaderCallout LdrFindEntryForAddress LdrFindResourceDirectory_U LdrFindResourceEx_U LdrFindResource_U LdrFlushAlternateResourceModules LdrGetDllDirectory LdrGetDllFullName LdrGetDllHandle LdrGetDllHandleByMapping LdrGetDllHandleByName LdrGetDllHandleEx LdrGetDllPath LdrGetFailureData LdrGetFileNameFromLoadAsDataTable LdrGetKnownDllSectionHandle LdrGetProcedureAddress LdrGetProcedureAddressEx LdrGetProcedureAddressForCaller LdrInitShimEngineDynamic LdrInitializeEnclave LdrInitializeThunk LdrLoadAlternateResourceModule LdrLoadAlternateResourceModuleEx LdrLoadDll LdrLoadEnclaveModule LdrLockLoaderLock LdrOpenImageFileOptionsKey LdrProcessInitializationComplete LdrProcessRelocationBlock LdrProcessRelocationBlockEx LdrQueryImageFileExecutionOptions LdrQueryImageFileExecutionOptionsEx LdrQueryImageFileKeyOption LdrQueryModuleServiceTags LdrQueryOptionalDelayLoadedAPI LdrQueryProcessModuleInformation LdrRegisterDllNotification LdrRemoveDllDirectory LdrRemoveLoadAsDataTable LdrResFindResource LdrResFindResourceDirectory LdrResGetRCConfig LdrResRelease LdrResSearchResource LdrResolveDelayLoadedAPI LdrResolveDelayLoadsFromDll LdrRscIsTypeExist LdrSetAppCompatDllRedirectionCallback LdrSetDefaultDllDirectories LdrSetDllDirectory LdrSetDllManifestProber LdrSetImplicitPathOptions LdrSetMUICacheType LdrShutdownProcess LdrShutdownThread LdrStandardizeSystemPath " \
+"LdrSystemDllInitBlock LdrUnloadAlternateResourceModule LdrUnloadAlternateResourceModuleEx LdrUnloadDll LdrUnlockLoaderLock LdrUnregisterDllNotification LdrUpdatePackageSearchPath LdrVerifyImageMatchesChecksum LdrVerifyImageMatchesChecksumEx LdrpResGetMappingSize LdrpResGetResourceDirectory MD4Final MD4Init MD4Update MD5Final MD5Init MD5Update NlsAnsiCodePage NlsMbCodePageTag NlsMbOemCodePageTag NtAcceptConnectPort NtAccessCheck NtAccessCheckAndAuditAlarm NtAccessCheckByType NtAccessCheckByTypeAndAuditAlarm NtAccessCheckByTypeResultList NtAccessCheckByTypeResultListAndAuditAlarm NtAccessCheckByTypeResultListAndAuditAlarmByHandle NtAcquireProcessActivityReference NtAddAtom NtAddAtomEx NtAddBootEntry NtAddDriverEntry NtAdjustGroupsToken NtAdjustPrivilegesToken NtAdjustTokenClaimsAndDeviceGroups NtAlertResumeThread NtAlertThread NtAlertThreadByThreadId NtAllocateLocallyUniqueId NtAllocateReserveObject NtAllocateUserPhysicalPages NtAllocateUuids NtAllocateVirtualMemory NtAllocateVirtualMemoryEx NtAlpcAcceptConnectPort NtAlpcCancelMessage NtAlpcConnectPort NtAlpcConnectPortEx NtAlpcCreatePort NtAlpcCreatePortSection NtAlpcCreateResourceReserve NtAlpcCreateSectionView NtAlpcCreateSecurityContext NtAlpcDeletePortSection NtAlpcDeleteResourceReserve NtAlpcDeleteSectionView NtAlpcDeleteSecurityContext NtAlpcDisconnectPort NtAlpcImpersonateClientContainerOfPort NtAlpcImpersonateClientOfPort NtAlpcOpenSenderProcess NtAlpcOpenSenderThread NtAlpcQueryInformation NtAlpcQueryInformationMessage NtAlpcRevokeSecurityContext NtAlpcSendWaitReceivePort NtAlpcSetInformation NtApphelpCacheControl NtAreMappedFilesTheSame NtAssignProcessToJobObject NtAssociateWaitCompletionPacket NtCallEnclave NtCallbackReturn NtCancelIoFile NtCancelIoFileEx NtCancelSynchronousIoFile NtCancelTimer NtCancelTimer2 NtCancelWaitCompletionPacket NtClearEvent NtClose NtCloseObjectAuditAlarm NtCommitComplete NtCommitEnlistment NtCommitRegistryTransaction NtCommitTransaction NtCompactKeys NtCompareObjects NtCompareSigningLevels " \
+"NtCompareTokens NtCompleteConnectPort NtCompressKey NtConnectPort NtContinue NtConvertBetweenAuxiliaryCounterAndPerformanceCounter NtCreateDebugObject NtCreateDirectoryObject NtCreateDirectoryObjectEx NtCreateEnclave NtCreateEnlistment NtCreateEvent NtCreateEventPair NtCreateFile NtCreateIRTimer NtCreateIoCompletion NtCreateJobObject NtCreateJobSet NtCreateKey NtCreateKeyTransacted NtCreateKeyedEvent NtCreateLowBoxToken NtCreateMailslotFile NtCreateMutant NtCreateNamedPipeFile NtCreatePagingFile NtCreatePartition NtCreatePort NtCreatePrivateNamespace NtCreateProcess NtCreateProcessEx NtCreateProfile NtCreateProfileEx NtCreateRegistryTransaction NtCreateResourceManager NtCreateSection NtCreateSemaphore NtCreateSymbolicLinkObject NtCreateThread NtCreateThreadEx NtCreateTimer NtCreateTimer2 NtCreateToken NtCreateTokenEx NtCreateTransaction NtCreateTransactionManager NtCreateUserProcess NtCreateWaitCompletionPacket NtCreateWaitablePort NtCreateWnfStateName NtCreateWorkerFactory NtDebugActiveProcess NtDebugContinue NtDelayExecution NtDeleteAtom NtDeleteBootEntry NtDeleteDriverEntry NtDeleteFile NtDeleteKey NtDeleteObjectAuditAlarm NtDeletePrivateNamespace NtDeleteValueKey NtDeleteWnfStateData NtDeleteWnfStateName NtDeviceIoControlFile NtDisableLastKnownGood NtDisplayString NtDrawText NtDuplicateObject NtDuplicateToken NtEnableLastKnownGood NtEnumerateBootEntries NtEnumerateDriverEntries NtEnumerateKey NtEnumerateSystemEnvironmentValuesEx NtEnumerateTransactionObject NtEnumerateValueKey NtExtendSection NtFilterBootOption NtFilterToken NtFilterTokenEx NtFindAtom NtFlushBuffersFile NtFlushBuffersFileEx NtFlushInstallUILanguage NtFlushInstructionCache NtFlushKey NtFlushProcessWriteBuffers NtFlushVirtualMemory NtFlushWriteBuffer NtFreeUserPhysicalPages NtFreeVirtualMemory NtFreezeRegistry NtFreezeTransactions NtFsControlFile NtGetCachedSigningLevel NtGetCompleteWnfStateSubscription NtGetContextThread NtGetCurrentProcessorNumber NtGetCurrentProcessorNumberEx NtGetDevicePowerState " \
+"NtGetMUIRegistryInfo NtGetNextProcess NtGetNextThread NtGetNlsSectionPtr NtGetNotificationResourceManager NtGetTickCount NtGetWriteWatch NtImpersonateAnonymousToken NtImpersonateClientOfPort NtImpersonateThread NtInitializeEnclave NtInitializeNlsFiles NtInitializeRegistry NtInitiatePowerAction NtIsProcessInJob NtIsSystemResumeAutomatic NtIsUILanguageComitted NtListenPort NtLoadDriver NtLoadEnclaveData NtLoadHotPatch NtLoadKey NtLoadKey2 NtLoadKeyEx NtLockFile NtLockProductActivationKeys NtLockRegistryKey NtLockVirtualMemory NtMakePermanentObject NtMakeTemporaryObject NtManagePartition NtMapCMFModule NtMapUserPhysicalPages NtMapUserPhysicalPagesScatter NtMapViewOfSection NtMapViewOfSectionEx NtModifyBootEntry NtModifyDriverEntry NtNotifyChangeDirectoryFile NtNotifyChangeDirectoryFileEx NtNotifyChangeKey NtNotifyChangeMultipleKeys NtNotifyChangeSession NtOpenDirectoryObject NtOpenEnlistment NtOpenEvent NtOpenEventPair NtOpenFile NtOpenIoCompletion NtOpenJobObject NtOpenKey NtOpenKeyEx NtOpenKeyTransacted NtOpenKeyTransactedEx NtOpenKeyedEvent NtOpenMutant NtOpenObjectAuditAlarm NtOpenPartition NtOpenPrivateNamespace NtOpenProcess NtOpenProcessToken NtOpenProcessTokenEx NtOpenRegistryTransaction NtOpenResourceManager NtOpenSection NtOpenSemaphore NtOpenSession NtOpenSymbolicLinkObject NtOpenThread NtOpenThreadToken NtOpenThreadTokenEx NtOpenTimer NtOpenTransaction NtOpenTransactionManager NtPlugPlayControl NtPowerInformation NtPrePrepareComplete NtPrePrepareEnlistment NtPrepareComplete NtPrepareEnlistment NtPrivilegeCheck NtPrivilegeObjectAuditAlarm NtPrivilegedServiceAuditAlarm NtPropagationComplete NtPropagationFailed NtProtectVirtualMemory NtPulseEvent NtQueryAttributesFile NtQueryAuxiliaryCounterFrequency NtQueryBootEntryOrder NtQueryBootOptions NtQueryDebugFilterState NtQueryDefaultLocale NtQueryDefaultUILanguage NtQueryDirectoryFile NtQueryDirectoryFileEx NtQueryDirectoryObject NtQueryDriverEntryOrder NtQueryEaFile NtQueryEvent NtQueryFullAttributesFile NtQueryInformationAtom " \
+"NtQueryInformationByName NtQueryInformationEnlistment NtQueryInformationFile NtQueryInformationJobObject NtQueryInformationPort NtQueryInformationProcess NtQueryInformationResourceManager NtQueryInformationThread NtQueryInformationToken NtQueryInformationTransaction NtQueryInformationTransactionManager NtQueryInformationWorkerFactory NtQueryInstallUILanguage NtQueryIntervalProfile NtQueryIoCompletion NtQueryKey NtQueryLicenseValue NtQueryMultipleValueKey NtQueryMutant NtQueryObject NtQueryOpenSubKeys NtQueryOpenSubKeysEx NtQueryPerformanceCounter NtQueryPortInformationProcess NtQueryQuotaInformationFile NtQuerySection NtQuerySecurityAttributesToken NtQuerySecurityObject NtQuerySecurityPolicy NtQuerySemaphore NtQuerySymbolicLinkObject NtQuerySystemEnvironmentValue NtQuerySystemEnvironmentValueEx NtQuerySystemInformation NtQuerySystemInformationEx NtQuerySystemTime NtQueryTimer NtQueryTimerResolution NtQueryValueKey NtQueryVirtualMemory NtQueryVolumeInformationFile NtQueryWnfStateData NtQueryWnfStateNameInformation NtQueueApcThread NtQueueApcThreadEx NtRaiseException NtRaiseHardError NtReadFile NtReadFileScatter NtReadOnlyEnlistment NtReadRequestData NtReadVirtualMemory NtRecoverEnlistment NtRecoverResourceManager NtRecoverTransactionManager NtRegisterProtocolAddressInformation NtRegisterThreadTerminatePort NtReleaseKeyedEvent NtReleaseMutant NtReleaseSemaphore NtReleaseWorkerFactoryWorker NtRemoveIoCompletion NtRemoveIoCompletionEx NtRemoveProcessDebug NtRenameKey NtRenameTransactionManager NtReplaceKey NtReplacePartitionUnit NtReplyPort NtReplyWaitReceivePort NtReplyWaitReceivePortEx NtReplyWaitReplyPort NtRequestPort NtRequestWaitReplyPort NtResetEvent NtResetWriteWatch NtRestoreKey NtResumeProcess NtResumeThread NtRevertContainerImpersonation NtRollbackComplete NtRollbackEnlistment NtRollbackRegistryTransaction NtRollbackTransaction NtRollforwardTransactionManager NtSaveKey NtSaveKeyEx NtSaveMergedKeys NtSecureConnectPort NtSerializeBoot NtSetBootEntryOrder NtSetBootOptions " \
+"NtSetCachedSigningLevel NtSetCachedSigningLevel2 NtSetContextThread NtSetDebugFilterState NtSetDefaultHardErrorPort NtSetDefaultLocale NtSetDefaultUILanguage NtSetDriverEntryOrder NtSetEaFile NtSetEvent NtSetEventBoostPriority NtSetHighEventPair NtSetHighWaitLowEventPair NtSetIRTimer NtSetInformationDebugObject NtSetInformationEnlistment NtSetInformationFile NtSetInformationJobObject NtSetInformationKey NtSetInformationObject NtSetInformationProcess NtSetInformationResourceManager NtSetInformationSymbolicLink NtSetInformationThread NtSetInformationToken NtSetInformationTransaction NtSetInformationTransactionManager NtSetInformationVirtualMemory NtSetInformationWorkerFactory NtSetIntervalProfile NtSetIoCompletion NtSetIoCompletionEx NtSetLdtEntries NtSetLowEventPair NtSetLowWaitHighEventPair NtSetQuotaInformationFile NtSetSecurityObject NtSetSystemEnvironmentValue NtSetSystemEnvironmentValueEx NtSetSystemInformation NtSetSystemPowerState NtSetSystemTime NtSetThreadExecutionState NtSetTimer NtSetTimer2 NtSetTimerEx NtSetTimerResolution NtSetUuidSeed NtSetValueKey NtSetVolumeInformationFile NtSetWnfProcessNotificationEvent NtShutdownSystem NtShutdownWorkerFactory NtSignalAndWaitForSingleObject NtSinglePhaseReject NtStartProfile NtStopProfile NtSubscribeWnfStateChange NtSuspendProcess NtSuspendThread NtSystemDebugControl NtTerminateEnclave NtTerminateJobObject NtTerminateProcess NtTerminateThread NtTestAlert NtThawRegistry NtThawTransactions NtTraceControl NtTraceEvent NtTranslateFilePath NtUmsThreadYield NtUnloadDriver NtUnloadKey NtUnloadKey2 NtUnloadKeyEx NtUnlockFile NtUnlockVirtualMemory NtUnmapViewOfSection NtUnmapViewOfSectionEx NtUnsubscribeWnfStateChange NtUpdateWnfStateData NtVdmControl NtWaitForAlertByThreadId NtWaitForDebugEvent NtWaitForKeyedEvent NtWaitForMultipleObjects NtWaitForMultipleObjects32 NtWaitForSingleObject NtWaitForWorkViaWorkerFactory NtWaitHighEventPair NtWaitLowEventPair NtWorkerFactoryWorkerReady NtWriteFile NtWriteFileGather NtWriteRequestData " \
+"NtWriteVirtualMemory NtYieldExecution NtdllDefWindowProc_A NtdllDefWindowProc_W NtdllDialogWndProc_A NtdllDialogWndProc_W PfxFindPrefix PfxInitialize PfxInsertPrefix PfxRemovePrefix PssNtCaptureSnapshot PssNtDuplicateSnapshot PssNtFreeRemoteSnapshot PssNtFreeSnapshot PssNtFreeWalkMarker PssNtQuerySnapshot PssNtValidateDescriptor PssNtWalkSnapshot RtlAbortRXact RtlAbsoluteToSelfRelativeSD RtlAcquirePebLock RtlAcquirePrivilege RtlAcquireReleaseSRWLockExclusive RtlAcquireResourceExclusive RtlAcquireResourceShared RtlAcquireSRWLockExclusive RtlAcquireSRWLockShared RtlActivateActivationContext RtlActivateActivationContextEx RtlActivateActivationContextUnsafeFast RtlAddAccessAllowedAce RtlAddAccessAllowedAceEx RtlAddAccessAllowedObjectAce RtlAddAccessDeniedAce RtlAddAccessDeniedAceEx RtlAddAccessDeniedObjectAce RtlAddAccessFilterAce RtlAddAce RtlAddActionToRXact RtlAddAtomToAtomTable RtlAddAttributeActionToRXact RtlAddAuditAccessAce RtlAddAuditAccessAceEx RtlAddAuditAccessObjectAce RtlAddCompoundAce RtlAddFunctionTable RtlAddGrowableFunctionTable RtlAddIntegrityLabelToBoundaryDescriptor RtlAddMandatoryAce RtlAddProcessTrustLabelAce RtlAddRefActivationContext RtlAddRefMemoryStream RtlAddResourceAttributeAce RtlAddSIDToBoundaryDescriptor RtlAddScopedPolicyIDAce RtlAddVectoredContinueHandler RtlAddVectoredExceptionHandler RtlAddressInSectionTable RtlAdjustPrivilege RtlAllocateActivationContextStack RtlAllocateAndInitializeSid RtlAllocateAndInitializeSidEx RtlAllocateHandle RtlAllocateHeap RtlAllocateMemoryBlockLookaside RtlAllocateMemoryZone RtlAllocateWnfSerializationGroup RtlAnsiCharToUnicodeChar RtlAnsiStringToUnicodeSize RtlAnsiStringToUnicodeString RtlAppendAsciizToString RtlAppendPathElement RtlAppendStringToString RtlAppendUnicodeStringToString RtlAppendUnicodeToString RtlApplicationVerifierStop RtlApplyRXact RtlApplyRXactNoFlush RtlAppxIsFileOwnedByTrustedInstaller RtlAreAllAccessesGranted RtlAreAnyAccessesGranted RtlAreBitsClear RtlAreBitsSet RtlAreLongPathsEnabled RtlAssert " \
+"RtlAvlInsertNodeEx RtlAvlRemoveNode RtlBarrier RtlBarrierForDelete RtlCallEnclaveReturn RtlCancelTimer RtlCanonicalizeDomainName RtlCapabilityCheck RtlCapabilityCheckForSingleSessionSku RtlCaptureContext RtlCaptureStackBackTrace RtlCharToInteger RtlCheckBootStatusIntegrity RtlCheckForOrphanedCriticalSections RtlCheckPortableOperatingSystem RtlCheckRegistryKey RtlCheckSandboxedToken RtlCheckSystemBootStatusIntegrity RtlCheckTokenCapability RtlCheckTokenMembership RtlCheckTokenMembershipEx RtlCleanUpTEBLangLists RtlClearAllBits RtlClearBit RtlClearBits RtlClearThreadWorkOnBehalfTicket RtlCloneMemoryStream RtlCloneUserProcess RtlCmDecodeMemIoResource RtlCmEncodeMemIoResource RtlCommitDebugInfo RtlCommitMemoryStream RtlCompactHeap RtlCompareAltitudes RtlCompareMemory RtlCompareMemoryUlong RtlCompareString RtlCompareUnicodeString RtlCompareUnicodeStrings RtlCompleteProcessCloning RtlCompressBuffer RtlComputeCrc32 RtlComputeImportTableHash RtlComputePrivatizedDllName_U RtlConnectToSm RtlConsoleMultiByteToUnicodeN RtlContractHashTable RtlConvertDeviceFamilyInfoToString RtlConvertExclusiveToShared RtlConvertLCIDToString RtlConvertSRWLockExclusiveToShared RtlConvertSharedToExclusive RtlConvertSidToUnicodeString RtlConvertToAutoInheritSecurityObject RtlCopyBitMap RtlCopyContext RtlCopyExtendedContext RtlCopyLuid RtlCopyLuidAndAttributesArray RtlCopyMappedMemory RtlCopyMemory RtlCopyMemoryNonTemporal RtlCopyMemoryStreamTo RtlCopyOutOfProcessMemoryStreamTo RtlCopySecurityDescriptor RtlCopySid RtlCopySidAndAttributesArray RtlCopyString RtlCopyUnicodeString RtlCrc32 RtlCrc64 RtlCreateAcl RtlCreateActivationContext RtlCreateAndSetSD RtlCreateAtomTable RtlCreateBootStatusDataFile RtlCreateBoundaryDescriptor RtlCreateEnvironment RtlCreateEnvironmentEx RtlCreateHashTable RtlCreateHashTableEx RtlCreateHeap RtlCreateMemoryBlockLookaside RtlCreateMemoryZone RtlCreateProcessParameters RtlCreateProcessParametersEx RtlCreateProcessReflection RtlCreateQueryDebugBuffer RtlCreateRegistryKey RtlCreateSecurityDescriptor " \
+"RtlCreateServiceSid RtlCreateSystemVolumeInformationFolder RtlCreateTagHeap RtlCreateTimer RtlCreateTimerQueue RtlCreateUmsCompletionList RtlCreateUmsThreadContext RtlCreateUnicodeString RtlCreateUnicodeStringFromAsciiz RtlCreateUserProcess RtlCreateUserProcessEx RtlCreateUserSecurityObject RtlCreateUserStack RtlCreateUserThread RtlCreateVirtualAccountSid RtlCultureNameToLCID RtlCustomCPToUnicodeN RtlCutoverTimeToSystemTime RtlDeCommitDebugInfo RtlDeNormalizeProcessParams RtlDeactivateActivationContext RtlDeactivateActivationContextUnsafeFast RtlDebugPrintTimes RtlDecodePointer RtlDecodeRemotePointer RtlDecodeSystemPointer RtlDecompressBuffer RtlDecompressBufferEx RtlDecompressFragment RtlDefaultNpAcl RtlDelete RtlDeleteAce RtlDeleteAtomFromAtomTable RtlDeleteBarrier RtlDeleteBoundaryDescriptor RtlDeleteCriticalSection RtlDeleteElementGenericTable RtlDeleteElementGenericTableAvl RtlDeleteElementGenericTableAvlEx RtlDeleteFunctionTable RtlDeleteGrowableFunctionTable RtlDeleteHashTable RtlDeleteNoSplay RtlDeleteRegistryValue RtlDeleteResource RtlDeleteSecurityObject RtlDeleteTimer RtlDeleteTimerQueue RtlDeleteTimerQueueEx RtlDeleteUmsCompletionList RtlDeleteUmsThreadContext RtlDequeueUmsCompletionListItems RtlDeregisterSecureMemoryCacheCallback RtlDeregisterWait RtlDeregisterWaitEx RtlDeriveCapabilitySidsFromName RtlDestroyAtomTable RtlDestroyEnvironment RtlDestroyHandleTable RtlDestroyHeap RtlDestroyMemoryBlockLookaside RtlDestroyMemoryZone RtlDestroyProcessParameters RtlDestroyQueryDebugBuffer RtlDetectHeapLeaks RtlDetermineDosPathNameType_U RtlDisableThreadProfiling RtlDllShutdownInProgress RtlDnsHostNameToComputerName RtlDoesFileExists_U RtlDosApplyFileIsolationRedirection_Ustr RtlDosLongPathNameToNtPathName_U_WithStatus RtlDosLongPathNameToRelativeNtPathName_U_WithStatus RtlDosPathNameToNtPathName_U RtlDosPathNameToNtPathName_U_WithStatus RtlDosPathNameToRelativeNtPathName_U RtlDosPathNameToRelativeNtPathName_U_WithStatus RtlDosSearchPath_U RtlDosSearchPath_Ustr RtlDowncaseUnicodeChar " \
+"RtlDowncaseUnicodeString RtlDrainNonVolatileFlush RtlDumpResource RtlDuplicateUnicodeString RtlEmptyAtomTable RtlEnableEarlyCriticalSectionEventCreation RtlEnableThreadProfiling RtlEnclaveCallDispatch RtlEnclaveCallDispatchReturn RtlEncodePointer RtlEncodeRemotePointer RtlEncodeSystemPointer RtlEndEnumerationHashTable RtlEndStrongEnumerationHashTable RtlEndWeakEnumerationHashTable RtlEnterCriticalSection RtlEnterUmsSchedulingMode RtlEnumProcessHeaps RtlEnumerateEntryHashTable RtlEnumerateGenericTable RtlEnumerateGenericTableAvl RtlEnumerateGenericTableLikeADirectory RtlEnumerateGenericTableWithoutSplaying RtlEnumerateGenericTableWithoutSplayingAvl RtlEqualComputerName RtlEqualDomainName RtlEqualLuid RtlEqualPrefixSid RtlEqualSid RtlEqualString RtlEqualUnicodeString RtlEqualWnfChangeStamps RtlEraseUnicodeString RtlEthernetAddressToStringA RtlEthernetAddressToStringW RtlEthernetStringToAddressA RtlEthernetStringToAddressW RtlExecuteUmsThread RtlExitUserProcess RtlExitUserThread RtlExpandEnvironmentStrings RtlExpandEnvironmentStrings_U RtlExpandHashTable RtlExtendCorrelationVector RtlExtendMemoryBlockLookaside RtlExtendMemoryZone RtlExtractBitMap RtlFillMemory RtlFinalReleaseOutOfProcessMemoryStream RtlFindAceByType RtlFindActivationContextSectionGuid RtlFindActivationContextSectionString RtlFindCharInUnicodeString RtlFindClearBits RtlFindClearBitsAndSet RtlFindClearRuns RtlFindClosestEncodableLength RtlFindExportedRoutineByName RtlFindLastBackwardRunClear RtlFindLeastSignificantBit RtlFindLongestRunClear RtlFindMessage RtlFindMostSignificantBit RtlFindNextForwardRunClear RtlFindSetBits RtlFindSetBitsAndClear RtlFindUnicodeSubstring RtlFirstEntrySList RtlFirstFreeAce RtlFlsAlloc RtlFlsFree RtlFlushHeaps RtlFlushNonVolatileMemory RtlFlushNonVolatileMemoryRanges RtlFlushSecureMemoryCache RtlFormatCurrentUserKeyPath RtlFormatMessage RtlFormatMessageEx RtlFreeActivationContextStack RtlFreeAnsiString RtlFreeHandle RtlFreeHeap RtlFreeMemoryBlockLookaside RtlFreeNonVolatileToken " \
+"RtlFreeOemString RtlFreeSid RtlFreeThreadActivationContextStack RtlFreeUnicodeString RtlFreeUserStack RtlGUIDFromString RtlGenerate8dot3Name RtlGetAce RtlGetActiveActivationContext RtlGetActiveConsoleId RtlGetAppContainerNamedObjectPath RtlGetAppContainerParent RtlGetAppContainerSidType RtlGetCallersAddress RtlGetCompressionWorkSpaceSize RtlGetConsoleSessionForegroundProcessId RtlGetControlSecurityDescriptor RtlGetCriticalSectionRecursionCount RtlGetCurrentDirectory_U RtlGetCurrentPeb RtlGetCurrentProcessorNumber RtlGetCurrentProcessorNumberEx RtlGetCurrentServiceSessionId RtlGetCurrentTransaction RtlGetCurrentUmsThread RtlGetDaclSecurityDescriptor RtlGetDeviceFamilyInfoEnum RtlGetElementGenericTable RtlGetElementGenericTableAvl RtlGetEnabledExtendedFeatures RtlGetExePath RtlGetExtendedContextLength RtlGetExtendedFeaturesMask RtlGetFileMUIPath RtlGetFrame RtlGetFullPathName_U RtlGetFullPathName_UEx RtlGetFullPathName_UstrEx RtlGetFunctionTableListHead RtlGetGroupSecurityDescriptor RtlGetIntegerAtom RtlGetInterruptTimePrecise RtlGetLastNtStatus RtlGetLastWin32Error RtlGetLengthWithoutLastFullDosOrNtPathElement RtlGetLengthWithoutTrailingPathSeperators RtlGetLocaleFileMappingAddress RtlGetLongestNtPathLength RtlGetNativeSystemInformation RtlGetNextEntryHashTable RtlGetNextUmsListItem RtlGetNonVolatileToken RtlGetNtGlobalFlags RtlGetNtProductType RtlGetNtSystemRoot RtlGetNtVersionNumbers RtlGetOwnerSecurityDescriptor RtlGetParentLocaleName RtlGetPersistedStateLocation RtlGetProcessHeaps RtlGetProcessPreferredUILanguages RtlGetProductInfo RtlGetSaclSecurityDescriptor RtlGetSearchPath RtlGetSecurityDescriptorRMControl RtlGetSessionProperties RtlGetSetBootStatusData RtlGetSuiteMask RtlGetSystemBootStatus RtlGetSystemBootStatusEx RtlGetSystemPreferredUILanguages RtlGetSystemTimePrecise RtlGetThreadErrorMode RtlGetThreadLangIdByIndex RtlGetThreadPreferredUILanguages RtlGetThreadWorkOnBehalfTicket RtlGetTokenNamedObjectPath RtlGetUILanguageInfo RtlGetUmsCompletionListEvent RtlGetUnloadEventTrace " \
+"RtlGetUnloadEventTraceEx RtlGetUserInfoHeap RtlGetUserPreferredUILanguages RtlGetVersion RtlGrowFunctionTable RtlGuardCheckLongJumpTarget RtlHashUnicodeString RtlHeapTrkInitialize RtlIdentifierAuthoritySid RtlIdnToAscii RtlIdnToNameprepUnicode RtlIdnToUnicode RtlImageDirectoryEntryToData RtlImageNtHeader RtlImageNtHeaderEx RtlImageRvaToSection RtlImageRvaToVa RtlImpersonateSelf RtlImpersonateSelfEx RtlIncrementCorrelationVector RtlInitAnsiString RtlInitAnsiStringEx RtlInitBarrier RtlInitCodePageTable RtlInitEnumerationHashTable RtlInitMemoryStream RtlInitNlsTables RtlInitOutOfProcessMemoryStream RtlInitString RtlInitStringEx RtlInitStrongEnumerationHashTable RtlInitUnicodeString RtlInitUnicodeStringEx RtlInitWeakEnumerationHashTable RtlInitializeAtomPackage RtlInitializeBitMap RtlInitializeBitMapEx RtlInitializeConditionVariable RtlInitializeContext RtlInitializeCorrelationVector RtlInitializeCriticalSection RtlInitializeCriticalSectionAndSpinCount RtlInitializeCriticalSectionEx RtlInitializeExtendedContext RtlInitializeGenericTable RtlInitializeGenericTableAvl RtlInitializeHandleTable RtlInitializeNtUserPfn RtlInitializeRXact RtlInitializeResource RtlInitializeSListHead RtlInitializeSRWLock RtlInitializeSid RtlInitializeSidEx RtlInsertElementGenericTable RtlInsertElementGenericTableAvl RtlInsertElementGenericTableFull RtlInsertElementGenericTableFullAvl RtlInsertEntryHashTable RtlInstallFunctionTableCallback RtlInt64ToUnicodeString RtlIntegerToChar RtlIntegerToUnicodeString RtlInterlockedClearBitRun RtlInterlockedFlushSList RtlInterlockedPopEntrySList RtlInterlockedPushEntrySList RtlInterlockedPushListSList RtlInterlockedPushListSListEx RtlInterlockedSetBitRun RtlIoDecodeMemIoResource RtlIoEncodeMemIoResource RtlIpv4AddressToStringA RtlIpv4AddressToStringExA RtlIpv4AddressToStringExW RtlIpv4AddressToStringW RtlIpv4StringToAddressA RtlIpv4StringToAddressExA RtlIpv4StringToAddressExW RtlIpv4StringToAddressW RtlIpv6AddressToStringA RtlIpv6AddressToStringExA RtlIpv6AddressToStringExW " \
+"RtlIpv6AddressToStringW RtlIpv6StringToAddressA RtlIpv6StringToAddressExA RtlIpv6StringToAddressExW RtlIpv6StringToAddressW RtlIsActivationContextActive RtlIsCapabilitySid RtlIsCloudFilesPlaceholder RtlIsCriticalSectionLocked RtlIsCriticalSectionLockedByThread RtlIsCurrentProcess RtlIsCurrentThread RtlIsCurrentThreadAttachExempt RtlIsDosDeviceName_U RtlIsElevatedRid RtlIsGenericTableEmpty RtlIsGenericTableEmptyAvl RtlIsMultiSessionSku RtlIsMultiUsersInSessionSku RtlIsNameInExpression RtlIsNameInUnUpcasedExpression RtlIsNameLegalDOS8Dot3 RtlIsNonEmptyDirectoryReparsePointAllowed RtlIsNormalizedString RtlIsPackageSid RtlIsParentOfChildAppContainer RtlIsPartialPlaceholder RtlIsPartialPlaceholderFileHandle RtlIsPartialPlaceholderFileInfo RtlIsProcessorFeaturePresent RtlIsStateSeparationEnabled RtlIsTextUnicode RtlIsThreadWithinLoaderCallout RtlIsUntrustedObject RtlIsValidHandle RtlIsValidIndexHandle RtlIsValidLocaleName RtlIsValidProcessTrustLabelSid RtlKnownExceptionFilter RtlLCIDToCultureName RtlLargeIntegerToChar RtlLcidToLocaleName RtlLeaveCriticalSection RtlLengthRequiredSid RtlLengthSecurityDescriptor RtlLengthSid RtlLengthSidAsUnicodeString RtlLoadString RtlLocalTimeToSystemTime RtlLocaleNameToLcid RtlLocateExtendedFeature RtlLocateExtendedFeature2 RtlLocateLegacyContext RtlLockBootStatusData RtlLockCurrentThread RtlLockHeap RtlLockMemoryBlockLookaside RtlLockMemoryStreamRegion RtlLockMemoryZone RtlLockModuleSection RtlLogStackBackTrace RtlLookupAtomInAtomTable RtlLookupElementGenericTable RtlLookupElementGenericTableAvl RtlLookupElementGenericTableFull RtlLookupElementGenericTableFullAvl RtlLookupEntryHashTable RtlLookupFirstMatchingElementGenericTableAvl RtlLookupFunctionEntry RtlLookupFunctionTable RtlMakeSelfRelativeSD RtlMapGenericMask RtlMapSecurityErrorToNtStatus RtlMoveMemory RtlMultiAppendUnicodeStringBuffer RtlMultiByteToUnicodeN RtlMultiByteToUnicodeSize RtlMultipleAllocateHeap RtlMultipleFreeHeap RtlNewInstanceSecurityObject RtlNewSecurityGrantedAccess " \
+"RtlNewSecurityObject RtlNewSecurityObjectEx RtlNewSecurityObjectWithMultipleInheritance RtlNormalizeProcessParams RtlNormalizeString RtlNtPathNameToDosPathName RtlNtStatusToDosError RtlNtStatusToDosErrorNoTeb RtlNtdllName RtlNumberGenericTableElements RtlNumberGenericTableElementsAvl RtlNumberOfClearBits RtlNumberOfClearBitsInRange RtlNumberOfSetBits RtlNumberOfSetBitsInRange RtlNumberOfSetBitsUlongPtr RtlOemStringToUnicodeSize RtlOemStringToUnicodeString RtlOemToUnicodeN RtlOpenCurrentUser RtlOsDeploymentState RtlOwnerAcesPresent RtlPcToFileHeader RtlPinAtomInAtomTable RtlPopFrame RtlPrefixString RtlPrefixUnicodeString RtlPrepareForProcessCloning RtlProcessFlsData RtlProtectHeap RtlPublishWnfStateData RtlPushFrame RtlQueryActivationContextApplicationSettings RtlQueryAtomInAtomTable RtlQueryCriticalSectionOwner RtlQueryDepthSList RtlQueryDynamicTimeZoneInformation RtlQueryElevationFlags RtlQueryEnvironmentVariable RtlQueryEnvironmentVariable_U RtlQueryHeapInformation RtlQueryImageMitigationPolicy RtlQueryInformationAcl RtlQueryInformationActivationContext RtlQueryInformationActiveActivationContext RtlQueryInterfaceMemoryStream RtlQueryModuleInformation RtlQueryPackageClaims RtlQueryPackageIdentity RtlQueryPackageIdentityEx RtlQueryPerformanceCounter RtlQueryPerformanceFrequency RtlQueryProcessBackTraceInformation RtlQueryProcessDebugInformation RtlQueryProcessHeapInformation RtlQueryProcessLockInformation RtlQueryProcessPlaceholderCompatibilityMode RtlQueryProtectedPolicy RtlQueryRegistryValueWithFallback RtlQueryRegistryValues RtlQueryRegistryValuesEx RtlQueryResourcePolicy RtlQuerySecurityObject RtlQueryTagHeap RtlQueryThreadPlaceholderCompatibilityMode RtlQueryThreadProfiling RtlQueryTimeZoneInformation RtlQueryTokenHostIdAsUlong64 RtlQueryUmsThreadInformation RtlQueryUnbiasedInterruptTime RtlQueryValidationRunlevel RtlQueryWnfMetaNotification RtlQueryWnfStateData RtlQueryWnfStateDataWithExplicitScope RtlQueueApcWow64Thread RtlQueueWorkItem RtlRaiseCustomSystemEventTrigger " \
+"RtlRaiseException RtlRaiseStatus RtlRandom RtlRandomEx RtlRbInsertNodeEx RtlRbRemoveNode RtlReAllocateHeap RtlReadMemoryStream RtlReadOutOfProcessMemoryStream RtlReadThreadProfilingData RtlRealPredecessor RtlRealSuccessor RtlRegisterForWnfMetaNotification RtlRegisterSecureMemoryCacheCallback RtlRegisterThreadWithCsrss RtlRegisterWait RtlReleaseActivationContext RtlReleaseMemoryStream RtlReleasePath RtlReleasePebLock RtlReleasePrivilege RtlReleaseRelativeName RtlReleaseResource RtlReleaseSRWLockExclusive RtlReleaseSRWLockShared RtlRemoteCall RtlRemoveEntryHashTable RtlRemovePrivileges RtlRemoveVectoredContinueHandler RtlRemoveVectoredExceptionHandler RtlReplaceSidInSd RtlReplaceSystemDirectoryInPath RtlReportException RtlReportExceptionEx RtlReportSilentProcessExit RtlReportSqmEscalation RtlResetMemoryBlockLookaside RtlResetMemoryZone RtlResetNtUserPfn RtlResetRtlTranslations RtlRestoreBootStatusDefaults RtlRestoreContext RtlRestoreLastWin32Error RtlRestoreSystemBootStatusDefaults RtlRetrieveNtUserPfn RtlRevertMemoryStream RtlRunDecodeUnicodeString RtlRunEncodeUnicodeString RtlRunOnceBeginInitialize RtlRunOnceComplete RtlRunOnceExecuteOnce RtlRunOnceInitialize RtlSecondsSince1970ToTime RtlSecondsSince1980ToTime RtlSeekMemoryStream RtlSelfRelativeToAbsoluteSD RtlSelfRelativeToAbsoluteSD2 RtlSendMsgToSm RtlSetAllBits RtlSetAttributesSecurityDescriptor RtlSetBit RtlSetBits RtlSetControlSecurityDescriptor RtlSetCriticalSectionSpinCount RtlSetCurrentDirectory_U RtlSetCurrentEnvironment RtlSetCurrentTransaction RtlSetDaclSecurityDescriptor RtlSetDynamicTimeZoneInformation RtlSetEnvironmentStrings RtlSetEnvironmentVar RtlSetEnvironmentVariable RtlSetExtendedFeaturesMask RtlSetGroupSecurityDescriptor RtlSetHeapInformation RtlSetImageMitigationPolicy RtlSetInformationAcl RtlSetIoCompletionCallback RtlSetLastWin32Error RtlSetLastWin32ErrorAndNtStatusFromNtStatus RtlSetMemoryStreamSize RtlSetOwnerSecurityDescriptor RtlSetPortableOperatingSystem RtlSetProcessDebugInformation RtlSetProcessIsCritical " \
+"RtlSetProcessPlaceholderCompatibilityMode RtlSetProcessPreferredUILanguages RtlSetProtectedPolicy RtlSetProxiedProcessId RtlSetSaclSecurityDescriptor RtlSetSearchPathMode RtlSetSecurityDescriptorRMControl RtlSetSecurityObject RtlSetSecurityObjectEx RtlSetSystemBootStatus RtlSetSystemBootStatusEx RtlSetThreadErrorMode RtlSetThreadIsCritical RtlSetThreadPlaceholderCompatibilityMode RtlSetThreadPoolStartFunc RtlSetThreadPreferredUILanguages RtlSetThreadSubProcessTag RtlSetThreadWorkOnBehalfTicket RtlSetTimeZoneInformation RtlSetTimer RtlSetUmsThreadInformation RtlSetUnhandledExceptionFilter RtlSetUserFlagsHeap RtlSetUserValueHeap RtlSidDominates RtlSidDominatesForTrust RtlSidEqualLevel RtlSidHashInitialize RtlSidHashLookup RtlSidIsHigherLevel RtlSizeHeap RtlSleepConditionVariableCS RtlSleepConditionVariableSRW RtlSplay RtlStartRXact RtlStatMemoryStream RtlStringFromGUID RtlStringFromGUIDEx RtlStronglyEnumerateEntryHashTable RtlSubAuthorityCountSid RtlSubAuthoritySid RtlSubscribeWnfStateChangeNotification RtlSubtreePredecessor RtlSubtreeSuccessor RtlSwitchedVVI RtlSystemTimeToLocalTime RtlTestAndPublishWnfStateData RtlTestBit RtlTestBitEx RtlTestProtectedAccess RtlTimeFieldsToTime RtlTimeToElapsedTimeFields RtlTimeToSecondsSince1970 RtlTimeToSecondsSince1980 RtlTimeToTimeFields RtlTraceDatabaseAdd RtlTraceDatabaseCreate RtlTraceDatabaseDestroy RtlTraceDatabaseEnumerate RtlTraceDatabaseFind RtlTraceDatabaseLock RtlTraceDatabaseUnlock RtlTraceDatabaseValidate RtlTryAcquirePebLock RtlTryAcquireSRWLockExclusive RtlTryAcquireSRWLockShared RtlTryConvertSRWLockSharedToExclusiveOrRelease RtlTryEnterCriticalSection RtlUTF8ToUnicodeN RtlUmsThreadYield RtlUnhandledExceptionFilter RtlUnhandledExceptionFilter2 RtlUnicodeStringToAnsiSize RtlUnicodeStringToAnsiString RtlUnicodeStringToCountedOemString RtlUnicodeStringToInteger RtlUnicodeStringToOemSize RtlUnicodeStringToOemString RtlUnicodeToCustomCPN RtlUnicodeToMultiByteN RtlUnicodeToMultiByteSize RtlUnicodeToOemN RtlUnicodeToUTF8N RtlUniform " \
+"RtlUnlockBootStatusData RtlUnlockCurrentThread RtlUnlockHeap RtlUnlockMemoryBlockLookaside RtlUnlockMemoryStreamRegion RtlUnlockMemoryZone RtlUnlockModuleSection RtlUnsubscribeWnfNotificationWaitForCompletion RtlUnsubscribeWnfNotificationWithCompletionCallback RtlUnsubscribeWnfStateChangeNotification RtlUnwind RtlUnwindEx RtlUpcaseUnicodeChar RtlUpcaseUnicodeString RtlUpcaseUnicodeStringToAnsiString RtlUpcaseUnicodeStringToCountedOemString RtlUpcaseUnicodeStringToOemString RtlUpcaseUnicodeToCustomCPN RtlUpcaseUnicodeToMultiByteN RtlUpcaseUnicodeToOemN RtlUpdateClonedCriticalSection RtlUpdateClonedSRWLock RtlUpdateTimer RtlUpperChar RtlUpperString RtlUserThreadStart RtlValidAcl RtlValidProcessProtection RtlValidRelativeSecurityDescriptor RtlValidSecurityDescriptor RtlValidSid RtlValidateCorrelationVector RtlValidateHeap RtlValidateProcessHeaps RtlValidateUnicodeString RtlVerifyVersionInfo RtlVirtualUnwind RtlWaitForWnfMetaNotification RtlWaitOnAddress RtlWakeAddressAll RtlWakeAddressAllNoFence RtlWakeAddressSingle RtlWakeAddressSingleNoFence RtlWakeAllConditionVariable RtlWakeConditionVariable RtlWalkFrameChain RtlWalkHeap RtlWeaklyEnumerateEntryHashTable RtlWerpReportException RtlWnfCompareChangeStamp RtlWnfDllUnloadCallback RtlWow64CallFunction64 RtlWow64EnableFsRedirection RtlWow64EnableFsRedirectionEx RtlWow64GetCpuAreaInfo RtlWow64GetCurrentCpuArea RtlWow64GetCurrentMachine RtlWow64GetEquivalentMachineCHPE RtlWow64GetProcessMachines RtlWow64GetSharedInfoProcess RtlWow64GetThreadContext RtlWow64GetThreadSelectorEntry RtlWow64IsWowGuestMachineSupported RtlWow64LogMessageInEventLogger RtlWow64PopAllCrossProcessWork RtlWow64PopCrossProcessWork RtlWow64PushCrossProcessWork RtlWow64SetThreadContext RtlWow64SuspendThread RtlWriteMemoryStream RtlWriteNonVolatileMemory RtlWriteRegistryValue RtlZeroHeap RtlZeroMemory RtlZombifyActivationContext RtlpApplyLengthFunction RtlpCheckDynamicTimeZoneInformation RtlpCleanupRegistryKeys RtlpConvertAbsoluteToRelativeSecurityAttribute " \
+"RtlpConvertCultureNamesToLCIDs RtlpConvertLCIDsToCultureNames RtlpConvertRelativeToAbsoluteSecurityAttribute RtlpCreateProcessRegistryInfo RtlpEnsureBufferSize RtlpExecuteUmsThread RtlpFreezeTimeBias RtlpGetDeviceFamilyInfoEnum RtlpGetLCIDFromLangInfoNode RtlpGetNameFromLangInfoNode RtlpGetSystemDefaultUILanguage RtlpGetUserOrMachineUILanguage4NLS RtlpInitializeLangRegistryInfo RtlpIsQualifiedLanguage RtlpLoadMachineUIByPolicy RtlpLoadUserUIByPolicy RtlpMergeSecurityAttributeInformation RtlpMuiFreeLangRegistryInfo RtlpMuiRegCreateRegistryInfo RtlpMuiRegFreeRegistryInfo RtlpMuiRegLoadRegistryInfo RtlpNotOwnerCriticalSection RtlpNtCreateKey RtlpNtEnumerateSubKey RtlpNtMakeTemporaryKey RtlpNtOpenKey RtlpNtQueryValueKey RtlpNtSetValueKey RtlpQueryDefaultUILanguage RtlpQueryProcessDebugInformationFromWow64 RtlpQueryProcessDebugInformationRemote RtlpRefreshCachedUILanguage RtlpSetInstallLanguage RtlpSetPreferredUILanguages RtlpSetUserPreferredUILanguages RtlpUmsExecuteYieldThreadEnd RtlpUmsThreadYield RtlpUnWaitCriticalSection RtlpVerifyAndCommitUILanguageSettings RtlpWaitForCriticalSection RtlxAnsiStringToUnicodeSize RtlxOemStringToUnicodeSize RtlxUnicodeStringToAnsiSize RtlxUnicodeStringToOemSize SbExecuteProcedure SbSelectProcedure ShipAssert ShipAssertGetBufferInfo ShipAssertMsgA ShipAssertMsgW TpAllocAlpcCompletion TpAllocAlpcCompletionEx TpAllocCleanupGroup TpAllocIoCompletion TpAllocJobNotification TpAllocPool TpAllocTimer TpAllocWait TpAllocWork TpAlpcRegisterCompletionList TpAlpcUnregisterCompletionList TpCallbackDetectedUnrecoverableError TpCallbackIndependent TpCallbackLeaveCriticalSectionOnCompletion TpCallbackMayRunLong TpCallbackReleaseMutexOnCompletion TpCallbackReleaseSemaphoreOnCompletion TpCallbackSendAlpcMessageOnCompletion TpCallbackSendPendingAlpcMessage TpCallbackSetEventOnCompletion TpCallbackUnloadDllOnCompletion TpCancelAsyncIoOperation TpCaptureCaller TpCheckTerminateWorker TpDbgDumpHeapUsage TpDbgSetLogRoutine TpDisablePoolCallbackChecks TpDisassociateCallback " \
+"TpIsTimerSet TpPostWork TpQueryPoolStackInformation TpReleaseAlpcCompletion TpReleaseCleanupGroup TpReleaseCleanupGroupMembers TpReleaseIoCompletion TpReleaseJobNotification TpReleasePool TpReleaseTimer TpReleaseWait TpReleaseWork TpSetDefaultPoolMaxThreads TpSetDefaultPoolStackInformation TpSetPoolMaxThreads TpSetPoolMaxThreadsSoftLimit TpSetPoolMinThreads TpSetPoolStackInformation TpSetPoolThreadBasePriority TpSetPoolWorkerThreadIdleTimeout TpSetTimer TpSetTimerEx TpSetWait TpSetWaitEx TpSimpleTryPost TpStartAsyncIoOperation TpTimerOutstandingCallbackCount TpTrimPools TpWaitForAlpcCompletion TpWaitForIoCompletion TpWaitForJobNotification TpWaitForTimer TpWaitForWait TpWaitForWork VerSetConditionMask WerReportExceptionWorker WerReportSQMEvent WinSqmAddToAverageDWORD WinSqmAddToStream WinSqmAddToStreamEx WinSqmCheckEscalationAddToStreamEx WinSqmCheckEscalationSetDWORD WinSqmCheckEscalationSetDWORD64 WinSqmCheckEscalationSetString WinSqmCommonDatapointDelete WinSqmCommonDatapointSetDWORD WinSqmCommonDatapointSetDWORD64 WinSqmCommonDatapointSetStreamEx WinSqmCommonDatapointSetString WinSqmEndSession WinSqmEventEnabled WinSqmEventWrite WinSqmGetEscalationRuleStatus WinSqmGetInstrumentationProperty WinSqmIncrementDWORD WinSqmIsOptedIn WinSqmIsOptedInEx WinSqmIsSessionDisabled WinSqmSetDWORD WinSqmSetDWORD64 WinSqmSetEscalationInfo WinSqmSetIfMaxDWORD WinSqmSetIfMinDWORD WinSqmSetString WinSqmStartSession WinSqmStartSessionForPartner WinSqmStartSqmOptinListener ZwAcceptConnectPort ZwAccessCheck ZwAccessCheckAndAuditAlarm ZwAccessCheckByType ZwAccessCheckByTypeAndAuditAlarm ZwAccessCheckByTypeResultList ZwAccessCheckByTypeResultListAndAuditAlarm ZwAccessCheckByTypeResultListAndAuditAlarmByHandle ZwAcquireProcessActivityReference ZwAddAtom ZwAddAtomEx ZwAddBootEntry ZwAddDriverEntry ZwAdjustGroupsToken ZwAdjustPrivilegesToken ZwAdjustTokenClaimsAndDeviceGroups ZwAlertResumeThread ZwAlertThread ZwAlertThreadByThreadId ZwAllocateLocallyUniqueId ZwAllocateReserveObject ZwAllocateUserPhysicalPages " \
+"ZwAllocateUuids ZwAllocateVirtualMemory ZwAllocateVirtualMemoryEx ZwAlpcAcceptConnectPort ZwAlpcCancelMessage ZwAlpcConnectPort ZwAlpcConnectPortEx ZwAlpcCreatePort ZwAlpcCreatePortSection ZwAlpcCreateResourceReserve ZwAlpcCreateSectionView ZwAlpcCreateSecurityContext ZwAlpcDeletePortSection ZwAlpcDeleteResourceReserve ZwAlpcDeleteSectionView ZwAlpcDeleteSecurityContext ZwAlpcDisconnectPort ZwAlpcImpersonateClientContainerOfPort ZwAlpcImpersonateClientOfPort ZwAlpcOpenSenderProcess ZwAlpcOpenSenderThread ZwAlpcQueryInformation ZwAlpcQueryInformationMessage ZwAlpcRevokeSecurityContext ZwAlpcSendWaitReceivePort ZwAlpcSetInformation ZwApphelpCacheControl ZwAreMappedFilesTheSame ZwAssignProcessToJobObject ZwAssociateWaitCompletionPacket ZwCallEnclave ZwCallbackReturn ZwCancelIoFile ZwCancelIoFileEx ZwCancelSynchronousIoFile ZwCancelTimer ZwCancelTimer2 ZwCancelWaitCompletionPacket ZwClearEvent ZwClose ZwCloseObjectAuditAlarm ZwCommitComplete ZwCommitEnlistment ZwCommitRegistryTransaction ZwCommitTransaction ZwCompactKeys ZwCompareObjects ZwCompareSigningLevels ZwCompareTokens ZwCompleteConnectPort ZwCompressKey ZwConnectPort ZwContinue ZwConvertBetweenAuxiliaryCounterAndPerformanceCounter ZwCreateDebugObject ZwCreateDirectoryObject ZwCreateDirectoryObjectEx ZwCreateEnclave ZwCreateEnlistment ZwCreateEvent ZwCreateEventPair ZwCreateFile ZwCreateIRTimer ZwCreateIoCompletion ZwCreateJobObject ZwCreateJobSet ZwCreateKey ZwCreateKeyTransacted ZwCreateKeyedEvent ZwCreateLowBoxToken ZwCreateMailslotFile ZwCreateMutant ZwCreateNamedPipeFile ZwCreatePagingFile ZwCreatePartition ZwCreatePort ZwCreatePrivateNamespace ZwCreateProcess ZwCreateProcessEx ZwCreateProfile ZwCreateProfileEx ZwCreateRegistryTransaction ZwCreateResourceManager ZwCreateSection ZwCreateSemaphore ZwCreateSymbolicLinkObject ZwCreateThread ZwCreateThreadEx ZwCreateTimer ZwCreateTimer2 ZwCreateToken ZwCreateTokenEx ZwCreateTransaction ZwCreateTransactionManager ZwCreateUserProcess ZwCreateWaitCompletionPacket ZwCreateWaitablePort " \
+"ZwCreateWnfStateName ZwCreateWorkerFactory ZwDebugActiveProcess ZwDebugContinue ZwDelayExecution ZwDeleteAtom ZwDeleteBootEntry ZwDeleteDriverEntry ZwDeleteFile ZwDeleteKey ZwDeleteObjectAuditAlarm ZwDeletePrivateNamespace ZwDeleteValueKey ZwDeleteWnfStateData ZwDeleteWnfStateName ZwDeviceIoControlFile ZwDisableLastKnownGood ZwDisplayString ZwDrawText ZwDuplicateObject ZwDuplicateToken ZwEnableLastKnownGood ZwEnumerateBootEntries ZwEnumerateDriverEntries ZwEnumerateKey ZwEnumerateSystemEnvironmentValuesEx ZwEnumerateTransactionObject ZwEnumerateValueKey ZwExtendSection ZwFilterBootOption ZwFilterToken ZwFilterTokenEx ZwFindAtom ZwFlushBuffersFile ZwFlushBuffersFileEx ZwFlushInstallUILanguage ZwFlushInstructionCache ZwFlushKey ZwFlushProcessWriteBuffers ZwFlushVirtualMemory ZwFlushWriteBuffer ZwFreeUserPhysicalPages ZwFreeVirtualMemory ZwFreezeRegistry ZwFreezeTransactions ZwFsControlFile ZwGetCachedSigningLevel ZwGetCompleteWnfStateSubscription ZwGetContextThread ZwGetCurrentProcessorNumber ZwGetCurrentProcessorNumberEx ZwGetDevicePowerState ZwGetMUIRegistryInfo ZwGetNextProcess ZwGetNextThread ZwGetNlsSectionPtr ZwGetNotificationResourceManager ZwGetWriteWatch ZwImpersonateAnonymousToken ZwImpersonateClientOfPort ZwImpersonateThread ZwInitializeEnclave ZwInitializeNlsFiles ZwInitializeRegistry ZwInitiatePowerAction ZwIsProcessInJob ZwIsSystemResumeAutomatic ZwIsUILanguageComitted ZwListenPort ZwLoadDriver ZwLoadEnclaveData ZwLoadHotPatch ZwLoadKey ZwLoadKey2 ZwLoadKeyEx ZwLockFile ZwLockProductActivationKeys ZwLockRegistryKey ZwLockVirtualMemory ZwMakePermanentObject ZwMakeTemporaryObject ZwManagePartition ZwMapCMFModule ZwMapUserPhysicalPages ZwMapUserPhysicalPagesScatter ZwMapViewOfSection ZwMapViewOfSectionEx ZwModifyBootEntry ZwModifyDriverEntry ZwNotifyChangeDirectoryFile ZwNotifyChangeDirectoryFileEx ZwNotifyChangeKey ZwNotifyChangeMultipleKeys ZwNotifyChangeSession ZwOpenDirectoryObject ZwOpenEnlistment ZwOpenEvent ZwOpenEventPair ZwOpenFile ZwOpenIoCompletion " \
+"ZwOpenJobObject ZwOpenKey ZwOpenKeyEx ZwOpenKeyTransacted ZwOpenKeyTransactedEx ZwOpenKeyedEvent ZwOpenMutant ZwOpenObjectAuditAlarm ZwOpenPartition ZwOpenPrivateNamespace ZwOpenProcess ZwOpenProcessToken ZwOpenProcessTokenEx ZwOpenRegistryTransaction ZwOpenResourceManager ZwOpenSection ZwOpenSemaphore ZwOpenSession ZwOpenSymbolicLinkObject ZwOpenThread ZwOpenThreadToken ZwOpenThreadTokenEx ZwOpenTimer ZwOpenTransaction ZwOpenTransactionManager ZwPlugPlayControl ZwPowerInformation ZwPrePrepareComplete ZwPrePrepareEnlistment ZwPrepareComplete ZwPrepareEnlistment ZwPrivilegeCheck ZwPrivilegeObjectAuditAlarm ZwPrivilegedServiceAuditAlarm ZwPropagationComplete ZwPropagationFailed ZwProtectVirtualMemory ZwPulseEvent ZwQueryAttributesFile ZwQueryAuxiliaryCounterFrequency ZwQueryBootEntryOrder ZwQueryBootOptions ZwQueryDebugFilterState ZwQueryDefaultLocale ZwQueryDefaultUILanguage ZwQueryDirectoryFile ZwQueryDirectoryFileEx ZwQueryDirectoryObject ZwQueryDriverEntryOrder ZwQueryEaFile ZwQueryEvent ZwQueryFullAttributesFile ZwQueryInformationAtom ZwQueryInformationByName ZwQueryInformationEnlistment ZwQueryInformationFile ZwQueryInformationJobObject ZwQueryInformationPort ZwQueryInformationProcess ZwQueryInformationResourceManager ZwQueryInformationThread ZwQueryInformationToken ZwQueryInformationTransaction ZwQueryInformationTransactionManager ZwQueryInformationWorkerFactory ZwQueryInstallUILanguage ZwQueryIntervalProfile ZwQueryIoCompletion ZwQueryKey ZwQueryLicenseValue ZwQueryMultipleValueKey ZwQueryMutant ZwQueryObject ZwQueryOpenSubKeys ZwQueryOpenSubKeysEx ZwQueryPerformanceCounter ZwQueryPortInformationProcess ZwQueryQuotaInformationFile ZwQuerySection ZwQuerySecurityAttributesToken ZwQuerySecurityObject ZwQuerySecurityPolicy ZwQuerySemaphore ZwQuerySymbolicLinkObject ZwQuerySystemEnvironmentValue ZwQuerySystemEnvironmentValueEx ZwQuerySystemInformation ZwQuerySystemInformationEx ZwQuerySystemTime ZwQueryTimer ZwQueryTimerResolution ZwQueryValueKey ZwQueryVirtualMemory " \
+"ZwQueryVolumeInformationFile ZwQueryWnfStateData ZwQueryWnfStateNameInformation ZwQueueApcThread ZwQueueApcThreadEx ZwRaiseException ZwRaiseHardError ZwReadFile ZwReadFileScatter ZwReadOnlyEnlistment ZwReadRequestData ZwReadVirtualMemory ZwRecoverEnlistment ZwRecoverResourceManager ZwRecoverTransactionManager ZwRegisterProtocolAddressInformation ZwRegisterThreadTerminatePort ZwReleaseKeyedEvent ZwReleaseMutant ZwReleaseSemaphore ZwReleaseWorkerFactoryWorker ZwRemoveIoCompletion ZwRemoveIoCompletionEx ZwRemoveProcessDebug ZwRenameKey ZwRenameTransactionManager ZwReplaceKey ZwReplacePartitionUnit ZwReplyPort ZwReplyWaitReceivePort ZwReplyWaitReceivePortEx ZwReplyWaitReplyPort ZwRequestPort ZwRequestWaitReplyPort ZwResetEvent ZwResetWriteWatch ZwRestoreKey ZwResumeProcess ZwResumeThread ZwRevertContainerImpersonation ZwRollbackComplete ZwRollbackEnlistment ZwRollbackRegistryTransaction ZwRollbackTransaction ZwRollforwardTransactionManager ZwSaveKey ZwSaveKeyEx ZwSaveMergedKeys ZwSecureConnectPort ZwSerializeBoot ZwSetBootEntryOrder ZwSetBootOptions ZwSetCachedSigningLevel ZwSetCachedSigningLevel2 ZwSetContextThread ZwSetDebugFilterState ZwSetDefaultHardErrorPort ZwSetDefaultLocale ZwSetDefaultUILanguage ZwSetDriverEntryOrder ZwSetEaFile ZwSetEvent ZwSetEventBoostPriority ZwSetHighEventPair ZwSetHighWaitLowEventPair ZwSetIRTimer ZwSetInformationDebugObject ZwSetInformationEnlistment ZwSetInformationFile ZwSetInformationJobObject ZwSetInformationKey ZwSetInformationObject ZwSetInformationProcess ZwSetInformationResourceManager ZwSetInformationSymbolicLink ZwSetInformationThread ZwSetInformationToken ZwSetInformationTransaction ZwSetInformationTransactionManager ZwSetInformationVirtualMemory ZwSetInformationWorkerFactory ZwSetIntervalProfile ZwSetIoCompletion ZwSetIoCompletionEx ZwSetLdtEntries ZwSetLowEventPair ZwSetLowWaitHighEventPair ZwSetQuotaInformationFile ZwSetSecurityObject ZwSetSystemEnvironmentValue ZwSetSystemEnvironmentValueEx ZwSetSystemInformation ZwSetSystemPowerState " \
+"ZwSetSystemTime ZwSetThreadExecutionState ZwSetTimer ZwSetTimer2 ZwSetTimerEx ZwSetTimerResolution ZwSetUuidSeed ZwSetValueKey ZwSetVolumeInformationFile ZwSetWnfProcessNotificationEvent ZwShutdownSystem ZwShutdownWorkerFactory ZwSignalAndWaitForSingleObject ZwSinglePhaseReject ZwStartProfile ZwStopProfile ZwSubscribeWnfStateChange ZwSuspendProcess ZwSuspendThread ZwSystemDebugControl ZwTerminateEnclave ZwTerminateJobObject ZwTerminateProcess ZwTerminateThread ZwTestAlert ZwThawRegistry ZwThawTransactions ZwTraceControl ZwTraceEvent ZwTranslateFilePath ZwUmsThreadYield ZwUnloadDriver ZwUnloadKey ZwUnloadKey2 ZwUnloadKeyEx ZwUnlockFile ZwUnlockVirtualMemory ZwUnmapViewOfSection ZwUnmapViewOfSectionEx ZwUnsubscribeWnfStateChange ZwUpdateWnfStateData ZwVdmControl ZwWaitForAlertByThreadId ZwWaitForDebugEvent ZwWaitForKeyedEvent ZwWaitForMultipleObjects ZwWaitForMultipleObjects32 ZwWaitForSingleObject ZwWaitForWorkViaWorkerFactory ZwWaitHighEventPair ZwWaitLowEventPair ZwWorkerFactoryWorkerReady ZwWriteFile ZwWriteFileGather ZwWriteRequestData ZwWriteVirtualMemory ZwYieldExecution __C_specific_handler __chkstk __isascii __iscsym __iscsymf __misaligned_access __toascii _atoi64 _errno _fltused _i64toa _i64toa_s _i64tow _i64tow_s _itoa _itoa_s _itow _itow_s _lfind _local_unwind _ltoa _ltoa_s _ltow _ltow_s _makepath_s _memccpy _memicmp _setjmp _setjmpex _snprintf _snprintf_s _snscanf_s _snwprintf _snwprintf_s _snwscanf_s _splitpath _splitpath_s _strcmpi _stricmp _strlwr _strlwr_s _strnicmp _strnset_s _strset_s _strupr _strupr_s _swprintf _ui64toa _ui64toa_s _ui64tow _ui64tow_s _ultoa _ultoa_s _ultow _ultow_s _vscprintf _vscwprintf _vsnprintf _vsnprintf_s _vsnwprintf _vsnwprintf_s _vswprintf _wcsicmp _wcslwr _wcslwr_s _wcsnicmp _wcsnset_s _wcsset_s _wcstoi64 _wcstoui64 _wcsupr _wcsupr_s _wmakepath_s _wsplitpath_s _wtoi _wtoi64 _wtol abs atan atan2 atoi atol bsearch bsearch_s ceil cos fabs floor isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper iswalnum " \
+"iswalpha iswascii iswctype iswdigit iswgraph iswlower iswprint iswspace iswxdigit isxdigit labs log longjmp mbstowcs memchr memcmp memcpy memcpy_s memmove memmove_s memset pow qsort qsort_s sin sprintf sprintf_s sqrt sscanf sscanf_s strcat strcat_s strchr strcmp strcpy strcpy_s strcspn strlen strncat strncat_s strncmp strncpy strncpy_s strnlen strpbrk strrchr strspn strstr strtok_s strtol strtoul swprintf swprintf_s swscanf_s tan tolower toupper towlower towupper vDbgPrintEx vDbgPrintExWithPrefix vsprintf vsprintf_s vswprintf_s wcscat wcscat_s wcschr wcscmp wcscpy wcscpy_s wcscspn wcslen wcsncat wcsncat_s wcsncmp wcsncpy wcsncpy_s wcsnlen wcspbrk wcsrchr wcsspn wcsstr wcstok_s wcstol wcstombs wcstoul";
+
+char apis_user32[] = "ActivateKeyboardLayout AddClipboardFormatListener AdjustWindowRect AdjustWindowRectEx AdjustWindowRectExForDpi AlignRects AllowForegroundActivation AllowSetForegroundWindow AnimateWindow AnyPopup AppendMenuA AppendMenuW AreDpiAwarenessContextsEqual ArrangeIconicWindows AttachThreadInput BeginDeferWindowPos BeginPaint BlockInput BringWindowToTop BroadcastSystemMessage BroadcastSystemMessageA BroadcastSystemMessageExA BroadcastSystemMessageExW BroadcastSystemMessageW BuildReasonArray CalcMenuBar CalculatePopupWindowPosition CallMsgFilter CallMsgFilterA CallMsgFilterW CallNextHookEx CallWindowProcA CallWindowProcW CancelShutdown CascadeChildWindows CascadeWindows ChangeClipboardChain ChangeDisplaySettingsA ChangeDisplaySettingsExA ChangeDisplaySettingsExW ChangeDisplaySettingsW ChangeMenuA ChangeMenuW ChangeWindowMessageFilter ChangeWindowMessageFilterEx CharLowerA CharLowerBuffA CharLowerBuffW CharLowerW CharNextA CharNextExA CharNextW CharPrevA CharPrevExA CharPrevW CharToOemA CharToOemBuffA CharToOemBuffW CharToOemW CharUpperA CharUpperBuffA CharUpperBuffW CharUpperW CheckDBCSEnabledExt CheckDlgButton CheckMenuItem CheckMenuRadioItem CheckProcessForClipboardAccess CheckProcessSession CheckRadioButton CheckWindowThreadDesktop ChildWindowFromPoint ChildWindowFromPointEx CliImmSetHotKey ClientThreadSetup ClientToScreen ClipCursor CloseClipboard CloseDesktop CloseGestureInfoHandle CloseTouchInputHandle CloseWindow CloseWindowStation ConsoleControl ControlMagnification CopyAcceleratorTableA CopyAcceleratorTableW CopyIcon CopyImage CopyRect CountClipboardFormats CreateAcceleratorTableA CreateAcceleratorTableW CreateCaret CreateCursor CreateDCompositionHwndTarget CreateDesktopA CreateDesktopExA CreateDesktopExW CreateDesktopW CreateDialogIndirectParamA CreateDialogIndirectParamAorW CreateDialogIndirectParamW CreateDialogParamA CreateDialogParamW CreateIcon CreateIconFromResource CreateIconFromResourceEx CreateIconIndirect CreateMDIWindowA CreateMDIWindowW " \
+"CreateMenu CreatePalmRejectionDelayZone CreatePopupMenu CreateSystemThreads CreateWindowExA CreateWindowExW CreateWindowInBand CreateWindowInBandEx CreateWindowIndirect CreateWindowStationA CreateWindowStationW CsrBroadcastSystemMessageExW CtxInitUser32 DWMBindCursorToOutputConfig DWMCommitInputSystemOutputConfig DWMSetCursorOrientation DWMSetInputSystemOutputConfig DdeAbandonTransaction DdeAccessData DdeAddData DdeClientTransaction DdeCmpStringHandles DdeConnect DdeConnectList DdeCreateDataHandle DdeCreateStringHandleA DdeCreateStringHandleW DdeDisconnect DdeDisconnectList DdeEnableCallback DdeFreeDataHandle DdeFreeStringHandle DdeGetData DdeGetLastError DdeGetQualityOfService DdeImpersonateClient DdeInitializeA DdeInitializeW DdeKeepStringHandle DdeNameService DdePostAdvise DdeQueryConvInfo DdeQueryNextServer DdeQueryStringA DdeQueryStringW DdeReconnect DdeSetQualityOfService DdeSetUserHandle DdeUnaccessData DdeUninitialize DefFrameProcA DefFrameProcW DefMDIChildProcA DefMDIChildProcW DefRawInputProc DeferWindowPos DeferWindowPosAndBand DelegateInput DeleteMenu DeregisterShellHookWindow DestroyAcceleratorTable DestroyCaret DestroyCursor DestroyDCompositionHwndTarget DestroyIcon DestroyMenu DestroyPalmRejectionDelayZone DestroyReasons DestroyWindow DialogBoxIndirectParamA DialogBoxIndirectParamAorW DialogBoxIndirectParamW DialogBoxParamA DialogBoxParamW DisableProcessWindowsGhosting DispatchMessageA DispatchMessageW DisplayConfigGetDeviceInfo DisplayConfigSetDeviceInfo DisplayExitWindowsWarnings DlgDirListA DlgDirListComboBoxA DlgDirListComboBoxW DlgDirListW DlgDirSelectComboBoxExA DlgDirSelectComboBoxExW DlgDirSelectExA DlgDirSelectExW DoSoundConnect DoSoundDisconnect DragDetect DragObject DrawAnimatedRects DrawCaption DrawCaptionTempA DrawCaptionTempW DrawEdge DrawFocusRect DrawFrame DrawFrameControl DrawIcon DrawIconEx DrawMenuBar DrawMenuBarTemp DrawStateA DrawStateW DrawTextA DrawTextExA DrawTextExW DrawTextW " \
+"DwmGetDxRgn DwmGetDxSharedSurface DwmGetRemoteSessionOcclusionEvent DwmGetRemoteSessionOcclusionState DwmKernelShutdown DwmKernelStartup DwmLockScreenUpdates DwmValidateWindow EditWndProc EmptyClipboard EnableMenuItem EnableMouseInPointer EnableNonClientDpiScaling EnableOneCoreTransformMode EnableScrollBar EnableSessionForMMCSS EnableWindow EndDeferWindowPos EndDeferWindowPosEx EndDialog EndMenu EndPaint EndTask EnterReaderModeHelper EnumChildWindows EnumClipboardFormats EnumDesktopWindows EnumDesktopsA EnumDesktopsW EnumDisplayDevicesA EnumDisplayDevicesW EnumDisplayMonitors EnumDisplaySettingsA EnumDisplaySettingsExA EnumDisplaySettingsExW EnumDisplaySettingsW EnumPropsA EnumPropsExA EnumPropsExW EnumPropsW EnumThreadWindows EnumWindowStationsA EnumWindowStationsW EnumWindows EqualRect EvaluateProximityToPolygon EvaluateProximityToRect ExcludeUpdateRgn ExitWindowsEx FillRect FindWindowA FindWindowExA FindWindowExW FindWindowW FlashWindow FlashWindowEx FrameRect FreeDDElParam FrostCrashedWindow GetActiveWindow GetAltTabInfo GetAltTabInfoA GetAltTabInfoW GetAncestor GetAppCompatFlags GetAppCompatFlags2 GetAsyncKeyState GetAutoRotationState GetAwarenessFromDpiAwarenessContext GetCIMSSM GetCapture GetCaretBlinkTime GetCaretPos GetClassInfoA GetClassInfoExA GetClassInfoExW GetClassInfoW GetClassLongA GetClassLongPtrA GetClassLongPtrW GetClassLongW GetClassNameA GetClassNameW GetClassWord GetClientRect GetClipCursor GetClipboardAccessToken GetClipboardData GetClipboardFormatNameA GetClipboardFormatNameW GetClipboardOwner GetClipboardSequenceNumber GetClipboardViewer GetComboBoxInfo GetCurrentInputMessageSource GetCursor GetCursorFrameInfo GetCursorInfo GetCursorPos GetDC GetDCEx GetDesktopID GetDesktopWindow GetDialogBaseUnits GetDialogControlDpiChangeBehavior GetDialogDpiChangeBehavior GetDisplayAutoRotationPreferences GetDisplayConfigBufferSizes GetDlgCtrlID GetDlgItem GetDlgItemInt GetDlgItemTextA GetDlgItemTextW GetDoubleClickTime GetDpiForMonitorInternal GetDpiForSystem " \
+"GetDpiForWindow GetDpiFromDpiAwarenessContext GetFocus GetForegroundWindow GetGUIThreadInfo GetGestureConfig GetGestureExtraArgs GetGestureInfo GetGuiResources GetIconInfo GetIconInfoExA GetIconInfoExW GetInputDesktop GetInputLocaleInfo GetInputState GetInternalWindowPos GetKBCodePage GetKeyNameTextA GetKeyNameTextW GetKeyState GetKeyboardLayout GetKeyboardLayoutList GetKeyboardLayoutNameA GetKeyboardLayoutNameW GetKeyboardState GetKeyboardType GetLastActivePopup GetLastInputInfo GetLayeredWindowAttributes GetListBoxInfo GetMagnificationDesktopColorEffect GetMagnificationDesktopMagnification GetMagnificationDesktopSamplingMode GetMagnificationLensCtxInformation GetMenu GetMenuBarInfo GetMenuCheckMarkDimensions GetMenuContextHelpId GetMenuDefaultItem GetMenuInfo GetMenuItemCount GetMenuItemID GetMenuItemInfoA GetMenuItemInfoW GetMenuItemRect GetMenuState GetMenuStringA GetMenuStringW GetMessageA GetMessageExtraInfo GetMessagePos GetMessageTime GetMessageW GetMonitorInfoA GetMonitorInfoW GetMouseMovePointsEx GetNextDlgGroupItem GetNextDlgTabItem GetOpenClipboardWindow GetParent GetPhysicalCursorPos GetPointerCursorId GetPointerDevice GetPointerDeviceCursors GetPointerDeviceProperties GetPointerDeviceRects GetPointerDevices GetPointerFrameArrivalTimes GetPointerFrameInfo GetPointerFrameInfoHistory GetPointerFramePenInfo GetPointerFramePenInfoHistory GetPointerFrameTouchInfo GetPointerFrameTouchInfoHistory GetPointerInfo GetPointerInfoHistory GetPointerInputTransform GetPointerPenInfo GetPointerPenInfoHistory GetPointerTouchInfo GetPointerTouchInfoHistory GetPointerType GetPriorityClipboardFormat GetProcessDefaultLayout GetProcessDpiAwarenessInternal GetProcessUIContextInformation GetProcessWindowStation GetProgmanWindow GetPropA GetPropW GetQueueStatus GetRawInputBuffer GetRawInputData GetRawInputDeviceInfoA GetRawInputDeviceInfoW GetRawInputDeviceList GetRawPointerDeviceData GetReasonTitleFromReasonCode GetRegisteredRawInputDevices GetScrollBarInfo GetScrollInfo GetScrollPos " \
+"GetScrollRange GetSendMessageReceiver GetShellWindow GetSubMenu GetSysColor GetSysColorBrush GetSystemDpiForProcess GetSystemMenu GetSystemMetrics GetSystemMetricsForDpi GetTabbedTextExtentA GetTabbedTextExtentW GetTaskmanWindow GetThreadDesktop GetThreadDpiAwarenessContext GetThreadDpiHostingBehavior GetTitleBarInfo GetTopLevelWindow GetTopWindow GetTouchInputInfo GetUnpredictedMessagePos GetUpdateRect GetUpdateRgn GetUpdatedClipboardFormats GetUserObjectInformationA GetUserObjectInformationW GetUserObjectSecurity GetWinStationInfo GetWindow GetWindowBand GetWindowCompositionAttribute GetWindowCompositionInfo GetWindowContextHelpId GetWindowDC GetWindowDisplayAffinity GetWindowDpiAwarenessContext GetWindowDpiHostingBehavior GetWindowFeedbackSetting GetWindowInfo GetWindowLongA GetWindowLongPtrA GetWindowLongPtrW GetWindowLongW GetWindowMinimizeRect GetWindowModuleFileName GetWindowModuleFileNameA GetWindowModuleFileNameW GetWindowPlacement GetWindowProcessHandle GetWindowRect GetWindowRgn GetWindowRgnBox GetWindowRgnEx GetWindowTextA GetWindowTextLengthA GetWindowTextLengthW GetWindowTextW GetWindowThreadProcessId GetWindowWord GhostWindowFromHungWindow GrayStringA GrayStringW HandleDelegatedInput HideCaret HiliteMenuItem HungWindowFromGhostWindow IMPGetIMEA IMPGetIMEW IMPQueryIMEA IMPQueryIMEW IMPSetIMEA IMPSetIMEW ImpersonateDdeClientWindow InSendMessage InSendMessageEx InflateRect InheritWindowMonitor InitDManipHook InitializeGenericHidInjection InitializeInputDeviceInjection InitializeLpkHooks InitializePointerDeviceInjection InitializePointerDeviceInjectionEx InitializeTouchInjection InjectDeviceInput InjectGenericHidInput InjectKeyboardInput InjectMouseInput InjectPointerInput InjectTouchInput InsertMenuA InsertMenuItemA InsertMenuItemW InsertMenuW InternalGetWindowIcon InternalGetWindowText IntersectRect InvalidateRect InvalidateRgn InvertRect IsCharAlphaA IsCharAlphaNumericA IsCharAlphaNumericW IsCharAlphaW IsCharLowerA IsCharLowerW IsCharUpperA IsCharUpperW " \
+"IsChild IsClipboardFormatAvailable IsDialogMessage IsDialogMessageA IsDialogMessageW IsDlgButtonChecked IsGUIThread IsHungAppWindow IsIconic IsImmersiveProcess IsInDesktopWindowBand IsMenu IsMouseInPointerEnabled IsOneCoreTransformMode IsProcessDPIAware IsQueueAttached IsRectEmpty IsSETEnabled IsServerSideWindow IsThreadDesktopComposited IsThreadMessageQueueAttached IsThreadTSFEventAware IsTopLevelWindow IsTouchWindow IsValidDpiAwarenessContext IsWinEventHookInstalled IsWindow IsWindowArranged IsWindowEnabled IsWindowInDestroy IsWindowRedirectedForPrint IsWindowUnicode IsWindowVisible IsWow64Message IsZoomed KillTimer LoadAcceleratorsA LoadAcceleratorsW LoadBitmapA LoadBitmapW LoadCursorA LoadCursorFromFileA LoadCursorFromFileW LoadCursorW LoadIconA LoadIconW LoadImageA LoadImageW LoadKeyboardLayoutA LoadKeyboardLayoutEx LoadKeyboardLayoutW LoadLocalFonts LoadMenuA LoadMenuIndirectA LoadMenuIndirectW LoadMenuW LoadRemoteFonts LoadStringA LoadStringW LockSetForegroundWindow LockWindowStation LockWindowUpdate LockWorkStation LogicalToPhysicalPoint LogicalToPhysicalPointForPerMonitorDPI LookupIconIdFromDirectory LookupIconIdFromDirectoryEx MBToWCSEx MBToWCSExt MB_GetString MITActivateInputProcessing MITBindInputTypeToMonitors MITCoreMsgKGetConnectionHandle MITCoreMsgKOpenConnectionTo MITCoreMsgKSend MITDeactivateInputProcessing MITDisableMouseIntercept MITDispatchCompletion MITEnableMouseIntercept MITGetCursorUpdateHandle MITInjectLegacyISMTouchFrame MITRegisterManipulationThread MITSetForegroundRoutingInfo MITSetInputCallbacks MITSetInputDelegationMode MITSetLastInputRecipient MITSetManipulationInputTarget MITStopAndEndInertia MITSynthesizeMouseInput MITSynthesizeMouseWheel MITSynthesizeTouchInput MITUpdateInputGlobals MITWaitForMultipleObjectsEx MakeThreadTSFEventAware MapDialogRect MapVirtualKeyA MapVirtualKeyExA MapVirtualKeyExW MapVirtualKeyW MapVisualRelativePoints MapWindowPoints MenuItemFromPoint MenuWindowProcA MenuWindowProcW MessageBeep MessageBoxA MessageBoxExA " \
+"MessageBoxExW MessageBoxIndirectA MessageBoxIndirectW MessageBoxTimeoutA MessageBoxTimeoutW MessageBoxW ModifyMenuA ModifyMenuW MonitorFromPoint MonitorFromRect MonitorFromWindow MoveWindow MsgWaitForMultipleObjects MsgWaitForMultipleObjectsEx NotifyOverlayWindow NotifyWinEvent OemKeyScan OemToCharA OemToCharBuffA OemToCharBuffW OemToCharW OffsetRect OpenClipboard OpenDesktopA OpenDesktopW OpenIcon OpenInputDesktop OpenThreadDesktop OpenWindowStationA OpenWindowStationW PackDDElParam PackTouchHitTestingProximityEvaluation PaintDesktop PaintMenuBar PaintMonitor PeekMessageA PeekMessageW PhysicalToLogicalPoint PhysicalToLogicalPointForPerMonitorDPI PostMessageA PostMessageW PostQuitMessage PostThreadMessageA PostThreadMessageW PrintWindow PrivateExtractIconExA PrivateExtractIconExW PrivateExtractIconsA PrivateExtractIconsW PrivateRegisterICSProc PtInRect QueryBSDRWindow QueryDisplayConfig QuerySendMessage RIMAddInputObserver RIMAreSiblingDevices RIMDeviceIoControl RIMEnableMonitorMappingForDevice RIMFreeInputBuffer RIMGetDevicePreparsedData RIMGetDevicePreparsedDataLockfree RIMGetDeviceProperties RIMGetDevicePropertiesLockfree RIMGetPhysicalDeviceRect RIMGetSourceProcessId RIMObserveNextInput RIMOnPnpNotification RIMOnTimerNotification RIMReadInput RIMRegisterForInput RIMRemoveInputObserver RIMSetTestModeStatus RIMUnregisterForInput RIMUpdateInputObserverRegistration RealChildWindowFromPoint RealGetWindowClass RealGetWindowClassA RealGetWindowClassW ReasonCodeNeedsBugID ReasonCodeNeedsComment RecordShutdownReason RedrawWindow RegisterBSDRWindow RegisterClassA RegisterClassExA RegisterClassExW RegisterClassW RegisterClipboardFormatA RegisterClipboardFormatW RegisterDManipHook RegisterDeviceNotificationA RegisterDeviceNotificationW RegisterErrorReportingDialog RegisterFrostWindow RegisterGhostWindow RegisterHotKey RegisterLogonProcess RegisterMessagePumpHook RegisterPointerDeviceNotifications RegisterPointerInputTarget RegisterPointerInputTargetEx RegisterPowerSettingNotification " \
+"RegisterRawInputDevices RegisterServicesProcess RegisterSessionPort RegisterShellHookWindow RegisterSuspendResumeNotification RegisterSystemThread RegisterTasklist RegisterTouchHitTestingWindow RegisterTouchWindow RegisterUserApiHook RegisterWindowMessageA RegisterWindowMessageW ReleaseCapture ReleaseDC ReleaseDwmHitTestWaiters RemoveClipboardFormatListener RemoveInjectionDevice RemoveMenu RemovePropA RemovePropW RemoveThreadTSFEventAwareness ReplyMessage ReportInertia ResolveDesktopForWOW ReuseDDElParam ScreenToClient ScrollChildren ScrollDC ScrollWindow ScrollWindowEx SendDlgItemMessageA SendDlgItemMessageW SendIMEMessageExA SendIMEMessageExW SendInput SendMessageA SendMessageCallbackA SendMessageCallbackW SendMessageTimeoutA SendMessageTimeoutW SendMessageW SendNotifyMessageA SendNotifyMessageW SetActiveWindow SetCapture SetCaretBlinkTime SetCaretPos SetClassLongA SetClassLongPtrA SetClassLongPtrW SetClassLongW SetClassWord SetClipboardData SetClipboardViewer SetCoalescableTimer SetCoreWindow SetCursor SetCursorContents SetCursorPos SetDebugErrorLevel SetDeskWallpaper SetDesktopColorTransform SetDialogControlDpiChangeBehavior SetDialogDpiChangeBehavior SetDisplayAutoRotationPreferences SetDisplayConfig SetDlgItemInt SetDlgItemTextA SetDlgItemTextW SetDoubleClickTime SetFeatureReportResponse SetFocus SetForegroundWindow SetGestureConfig SetInternalWindowPos SetKeyboardState SetLastErrorEx SetLayeredWindowAttributes SetMagnificationDesktopColorEffect SetMagnificationDesktopMagnification SetMagnificationDesktopSamplingMode SetMagnificationLensCtxInformation SetMenu SetMenuContextHelpId SetMenuDefaultItem SetMenuInfo SetMenuItemBitmaps SetMenuItemInfoA SetMenuItemInfoW SetMessageExtraInfo SetMessageQueue SetMirrorRendering SetParent SetPhysicalCursorPos SetProcessDPIAware SetProcessDefaultLayout SetProcessDpiAwarenessContext SetProcessDpiAwarenessInternal SetProcessRestrictionExemption SetProcessWindowStation SetProgmanWindow SetPropA SetPropW SetRect SetRectEmpty SetScrollInfo " \
+"SetScrollPos SetScrollRange SetShellWindow SetShellWindowEx SetSysColors SetSysColorsTemp SetSystemCursor SetSystemMenu SetTaskmanWindow SetThreadDesktop SetThreadDpiAwarenessContext SetThreadDpiHostingBehavior SetThreadInputBlocked SetTimer SetUserObjectInformationA SetUserObjectInformationW SetUserObjectSecurity SetWinEventHook SetWindowBand SetWindowCompositionAttribute SetWindowCompositionTransition SetWindowContextHelpId SetWindowDisplayAffinity SetWindowFeedbackSetting SetWindowLongA SetWindowLongPtrA SetWindowLongPtrW SetWindowLongW SetWindowPlacement SetWindowPos SetWindowRgn SetWindowRgnEx SetWindowStationUser SetWindowTextA SetWindowTextW SetWindowWord SetWindowsHookA SetWindowsHookExA SetWindowsHookExW SetWindowsHookW ShowCaret ShowCursor ShowOwnedPopups ShowScrollBar ShowStartGlass ShowSystemCursor ShowWindow ShowWindowAsync ShutdownBlockReasonCreate ShutdownBlockReasonDestroy ShutdownBlockReasonQuery SignalRedirectionStartComplete SkipPointerFrameMessages SoftModalMessageBox SoundSentry SubtractRect SwapMouseButton SwitchDesktop SwitchDesktopWithFade SwitchToThisWindow SystemParametersInfoA SystemParametersInfoForDpi SystemParametersInfoW TabbedTextOutA TabbedTextOutW TileChildWindows TileWindows ToAscii ToAsciiEx ToUnicode ToUnicodeEx TrackMouseEvent TrackPopupMenu TrackPopupMenuEx TranslateAccelerator TranslateAcceleratorA TranslateAcceleratorW TranslateMDISysAccel TranslateMessage TranslateMessageEx UndelegateInput UnhookWinEvent UnhookWindowsHook UnhookWindowsHookEx UnionRect UnloadKeyboardLayout UnlockWindowStation UnpackDDElParam UnregisterClassA UnregisterClassW UnregisterDeviceNotification UnregisterHotKey UnregisterMessagePumpHook UnregisterPointerInputTarget UnregisterPointerInputTargetEx UnregisterPowerSettingNotification UnregisterSessionPort UnregisterSuspendResumeNotification UnregisterTouchWindow UnregisterUserApiHook UpdateDefaultDesktopThumbnail UpdateLayeredWindow UpdateLayeredWindowIndirect UpdatePerUserSystemParameters UpdateWindow UpdateWindowInputSinkHints " \
+"User32InitializeImmEntryTable UserClientDllInitialize UserHandleGrantAccess UserLpkPSMTextOut UserLpkTabbedTextOut UserRealizePalette UserRegisterWowHandlers VRipOutput VTagOutput ValidateRect ValidateRgn VkKeyScanA VkKeyScanExA VkKeyScanExW VkKeyScanW WCSToMBEx WINNLSEnableIME WINNLSGetEnableStatus WINNLSGetIMEHotkey WaitForInputIdle WaitForRedirectionStartComplete WaitMessage WinHelpA WinHelpW WindowFromDC WindowFromPhysicalPoint WindowFromPoint _UserTestTokenForInteractive gSharedInfo gapfnScSendMessage keybd_event mouse_event wsprintfA wsprintfW wvsprintfA wvsprintfW";
+
+bool ModuleBoundsHookCheckSingle(HMODULE dll, char* apiList)
+{
+	MODULEINFO moduleInfo;
+	if (GetModuleInformation(GetCurrentProcess(), dll, &moduleInfo, sizeof(MODULEINFO)) == FALSE)
+	{
+		// todo: error condition
+		return FALSE;
+	}
+
+	PVOID moduleBottom = moduleInfo.lpBaseOfDll;
+	PVOID moduleTop = reinterpret_cast<PVOID>((reinterpret_cast<unsigned char*>(moduleBottom) + moduleInfo.SizeOfImage));
+
+	char* currentAPI = NULL;
+	char* nextAPI = NULL;
+	currentAPI = strtok_s(apiList, " ", &nextAPI);
+
+	bool foundHook = false;
+
+	while (currentAPI != NULL)
+	{
+		PVOID procAddr = GetProcAddress(dll, currentAPI);
+		if (procAddr != NULL)
+		{
+			if (procAddr < moduleBottom || procAddr >= moduleTop)
+			{
+				foundHook = true;
+				//printf("Caught hook on API '%s'\n", currentAPI);
+			}
+		}
+
+		currentAPI = strtok_s(NULL, " ", &nextAPI);
+	}
+
+	return foundHook;
+}
+
+BOOL ModuleBoundsHookCheck()
+{
+	bool foundHook = ModuleBoundsHookCheckSingle(LoadLibrary(_T("kernel32.dll")), apis_kernel32) &&
+		ModuleBoundsHookCheckSingle(LoadLibrary(_T("ntdll.dll")), apis_ntdll) &&
+		ModuleBoundsHookCheckSingle(LoadLibrary(_T("user32.dll")), apis_user32);
+
+	return foundHook ? TRUE : FALSE;
+}
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/ModuleBoundsHookCheck.h b/al-khaser/al-khaser/AntiDebug/ModuleBoundsHookCheck.h
new file mode 100644
index 0000000000000000000000000000000000000000..764ad29a95315256bf73bd5313cea6a8412b8226
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/ModuleBoundsHookCheck.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL ModuleBoundsHookCheck();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/NtGlobalFlag.cpp b/al-khaser/al-khaser/AntiDebug/NtGlobalFlag.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2b7d7f4f11ac40434c6136b4e7a50cf7cbcb38f6
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtGlobalFlag.cpp
@@ -0,0 +1,63 @@
+#include "pch.h"
+#include "NtGlobalFlag.h"
+
+
+BOOL
+NtGlobalFlag (
+	VOID
+	)
+/*++
+
+Routine Description:
+
+	NtGlobalFlag is a DWORD value inside the process PEB. This value
+	contains many flags set by the OS that affects the way the process
+	runs. When a process is being debugged, the flags:
+		- FLG_HEAP_ENABLE_TAIL_CHECK (0x10)
+		- FLG_HEAP_ENABLE_FREE_CHECK (0x20)
+		- FLG_HEAP_VALIDATE_PARAMETERS(0x40) are set for the process
+
+	If the 32-bit executable is being run on a 64-bit system, both the
+	32-bit and 64-bit PEBs are checked. The WoW64 PEB address is 
+	fetched via the WoW64 Thread Environment Block (TEB) at FS:[0x18]-0x2000.
+
+Arguments:
+
+	None
+
+Return Value:
+
+	TRUE - if debugger was detected
+	FALSE - otherwise
+--*/
+{
+	PDWORD pNtGlobalFlag = NULL, pNtGlobalFlagWoW64 = NULL;
+
+#if defined (ENV64BIT)
+	pNtGlobalFlag = (PDWORD)(__readgsqword(0x60) + 0xBC);
+
+#elif defined(ENV32BIT)
+	/* NtGlobalFlags for real 32-bits OS */
+	BYTE* _teb32 = (BYTE*)__readfsdword(0x18);
+	DWORD _peb32 = *(DWORD*)(_teb32 + 0x30);
+	pNtGlobalFlag = (PDWORD)(_peb32 + 0x68);
+
+	if (IsWoW64())
+	{
+		/* In Wow64, there is a separate PEB for the 32-bit portion and the 64-bit portion
+		which we can double-check */
+		
+		BYTE* _teb64 = (BYTE*)__readfsdword(0x18) - 0x2000;
+		DWORD64 _peb64 = *(DWORD64*)(_teb64 + 0x60);
+		pNtGlobalFlagWoW64 = (PDWORD)(_peb64 + 0xBC);
+	}
+#endif
+
+	BOOL normalDetected = pNtGlobalFlag && *pNtGlobalFlag & 0x00000070;
+	BOOL wow64Detected = pNtGlobalFlagWoW64 && *pNtGlobalFlagWoW64 & 0x00000070;
+	
+	if(normalDetected || wow64Detected)
+		return TRUE;
+	else
+		return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/NtGlobalFlag.h b/al-khaser/al-khaser/AntiDebug/NtGlobalFlag.h
new file mode 100644
index 0000000000000000000000000000000000000000..13bdf364de764c523bd40dacdc5309ee319d93e5
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtGlobalFlag.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL NtGlobalFlag();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.cpp b/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5f40267b74f20e3f59af7e74a43135727dd851ab
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.cpp
@@ -0,0 +1,26 @@
+#include "pch.h"
+
+#include "NtQueryInformationProcess_ProcessDebugFlags.h"
+
+/*
+When NtQueryProcessInformation is called with the ProcessDebugFlags class, the function will return the inverse of EPROCESS->NoDebugInherit,
+which means that if a debugger is present, then this function will return FALSE if the process is being debugged.
+ */
+
+BOOL NtQueryInformationProcess_ProcessDebugFlags()
+{
+   	// ProcessDebugFlags
+	const int ProcessDebugFlags =  0x1f;
+
+	auto NtQueryInfoProcess = static_cast<pNtQueryInformationProcess>(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess));
+
+	// Other Vars
+	NTSTATUS Status;
+	DWORD NoDebugInherit = 0; 
+
+	Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessDebugFlags, &NoDebugInherit, sizeof(DWORD), NULL);
+	if (Status == 0x00000000 && NoDebugInherit == 0)
+		return TRUE;
+	else        
+		return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.h b/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.h
new file mode 100644
index 0000000000000000000000000000000000000000..919a9a5ac977c4a704088a6b3e51e5209016ecc0
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL NtQueryInformationProcess_ProcessDebugFlags();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.cpp b/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5fb10e376df99482d270121edb9325b84f8fa4c2
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.cpp
@@ -0,0 +1,49 @@
+#include "pch.h"
+
+#include "NtQueryInformationProcess_ProcessDebugObject.h"
+
+/*
+This function uses NtQuerySystemInformation to try to retrieve a handle to the current process's debug object handle.
+If the function is successful it'll return true which means we're being debugged or it'll return false if it fails
+the process isn't being debugged
+*/
+
+BOOL NtQueryInformationProcess_ProcessDebugObject()
+{
+	// ProcessDebugObjectHandle
+	const int ProcessDebugObjectHandle =  0x1e;
+
+	auto NtQueryInfoProcess = static_cast<pNtQueryInformationProcess>(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess));
+
+	// Other Vars
+	NTSTATUS Status;
+	HANDLE hDebugObject = NULL;
+
+#if defined (ENV64BIT)
+	DWORD dProcessInformationLength = sizeof(ULONG) * 2;
+	DWORD64 IsRemotePresent = 0;
+
+#elif defined(ENV32BIT)
+	DWORD dProcessInformationLength = sizeof(ULONG);
+	DWORD32 IsRemotePresent = 0;
+#endif
+
+	// Regular check
+	Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessDebugObjectHandle, &hDebugObject, dProcessInformationLength, NULL);
+
+	if (Status != STATUS_PORT_NOT_SET)
+		return TRUE;
+	if (hDebugObject != NULL)
+		return TRUE;
+
+	// Check with overlapping return length and debug object handle buffers to find anti-anti-debuggers
+	Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessDebugObjectHandle, &hDebugObject, dProcessInformationLength, (PULONG)&hDebugObject);
+	if (Status != STATUS_PORT_NOT_SET)
+		return TRUE;
+	if (hDebugObject == NULL)
+		return TRUE; // Handle incorrectly zeroed
+	if ((ULONG)(ULONG_PTR)hDebugObject != dProcessInformationLength)
+		return TRUE; // Return length incorrectly overwritten
+
+	return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.h b/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.h
new file mode 100644
index 0000000000000000000000000000000000000000..9f609ab754bbdddee035fc89c460aabe4382781f
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.h
@@ -0,0 +1,5 @@
+#pragma once
+
+BOOL NtQueryInformationProcess_ProcessDebugObject();
+
+#define STATUS_PORT_NOT_SET ((NTSTATUS)0xC0000353L)
diff --git a/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.cpp b/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..eca5a836123ef5514d33889a3f1256752505214b
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.cpp
@@ -0,0 +1,35 @@
+#include "pch.h"
+
+#include "NtQueryInformationProcess_ProcessDebugPort.h"
+
+/* 
+Instead of calling CheckRemoteDebuggerPresent an individual could also make directly the call to
+NtQueryInformationProcess process theirself.
+*/
+
+BOOL NtQueryInformationProcess_ProcessDebugPort ()
+{
+	auto NtQueryInfoProcess = static_cast<pNtQueryInformationProcess>(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess));
+ 
+	// ProcessDebugPort
+	const int ProcessDbgPort = 7;
+ 
+	// Other Vars
+	NTSTATUS Status;
+	
+#if defined (ENV64BIT)
+	DWORD dProcessInformationLength = sizeof(ULONG) * 2;
+	DWORD64 IsRemotePresent = 0;
+
+#elif defined(ENV32BIT)
+	DWORD dProcessInformationLength = sizeof(ULONG);
+	DWORD32 IsRemotePresent = 0;
+#endif
+
+	Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessDbgPort, &IsRemotePresent, dProcessInformationLength, NULL);
+	if(Status == 0x00000000 && IsRemotePresent != 0)
+		return TRUE;
+	else 
+		return FALSE;
+}
+
diff --git a/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.h b/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.h
new file mode 100644
index 0000000000000000000000000000000000000000..796d2a5f210f0547eaf1690ecba8f97716569b23
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL NtQueryInformationProcess_ProcessDebugPort();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/NtQueryObject_AllTypesInformation.cpp b/al-khaser/al-khaser/AntiDebug/NtQueryObject_AllTypesInformation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4103171b0a9a0804c0e2876f2d1cbf734f77b28f
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtQueryObject_AllTypesInformation.cpp
@@ -0,0 +1,87 @@
+#include "pch.h"
+
+#include "NtQueryObject_ObjectInformation.h"
+
+/*
+Windows XP introduced a "debug object". When a debugging session begins, a debug object is created,
+and a handle is associated with it. Using the ntdll NtQueryObject() function  with class: ObjectAllTypesInformation.
+ObjectAllTypesInformation (3) will return a list with all existing object type, we should iterate over objects to 
+locate "DebugObject". Todo: Support for Win10
+*/
+
+
+BOOL NtQueryObject_ObjectAllTypesInformation()
+{
+	//NOTE this check is unreliable, a debugger present on the system doesn't mean it's attached to you
+
+	auto NtQueryObject = static_cast<pNtQueryObject>(API::GetAPI(API_IDENTIFIER::API_NtQueryObject));
+
+	// Some vars
+	ULONG size;
+	PVOID pMemory = NULL;
+	POBJECT_ALL_INFORMATION pObjectAllInfo = NULL;
+	NTSTATUS Status;
+
+	// Get the size of the information needed
+	Status = NtQueryObject(NULL, 3, &size, sizeof(ULONG), &size);
+
+	// Alocate memory for the list
+	pMemory = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+	if (pMemory == NULL)
+		return FALSE;
+
+	// Now we can actually retrieve the list
+	Status = NtQueryObject((HANDLE)-1, 3, pMemory, size, NULL);
+
+	// Status != STATUS_SUCCESS
+	if (Status != 0x00000000)
+	{
+		VirtualFree(pMemory, 0, MEM_RELEASE);
+		return FALSE;
+	}
+
+	// We have the information we need
+	pObjectAllInfo = (POBJECT_ALL_INFORMATION)pMemory;
+	UCHAR *pObjInfoLocation = (UCHAR*)pObjectAllInfo->ObjectTypeInformation;
+	ULONG NumObjects = pObjectAllInfo->NumberOfObjects;
+
+	for (UINT i = 0; i < NumObjects; i++)
+	{
+
+		POBJECT_TYPE_INFORMATION pObjectTypeInfo = (POBJECT_TYPE_INFORMATION)pObjInfoLocation;
+
+		// The debug object will always be present
+		if (StrCmp(_T("DebugObject"), pObjectTypeInfo->TypeName.Buffer) == 0)
+		{
+			// Are there any objects?
+			if (pObjectTypeInfo->TotalNumberOfObjects > 0)
+			{
+				VirtualFree(pMemory, 0, MEM_RELEASE);
+				return TRUE;
+			}
+			else
+			{
+				VirtualFree(pMemory, 0, MEM_RELEASE);
+				return FALSE;
+			}
+		}
+
+		// Get the address of the current entries
+		// string so we can find the end
+		pObjInfoLocation = (unsigned char*)pObjectTypeInfo->TypeName.Buffer;
+
+		// Add the size
+		pObjInfoLocation += pObjectTypeInfo->TypeName.MaximumLength;
+
+		// Skip the trailing null and alignment bytes
+		ULONG_PTR tmp = ((ULONG_PTR)pObjInfoLocation) & -(int)sizeof(void*);
+
+		// Not pretty but it works
+		if ((ULONG_PTR)tmp != (ULONG_PTR)pObjInfoLocation)
+			tmp += sizeof(void*);
+		pObjInfoLocation = ((unsigned char*)tmp);
+	}
+
+	VirtualFree(pMemory, 0, MEM_RELEASE);
+	return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/NtQueryObject_ObjectInformation.h b/al-khaser/al-khaser/AntiDebug/NtQueryObject_ObjectInformation.h
new file mode 100644
index 0000000000000000000000000000000000000000..af8624d55cc777a5eb4c416624cb43242261d3a6
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtQueryObject_ObjectInformation.h
@@ -0,0 +1,24 @@
+#pragma once
+
+BOOL NtQueryObject_ObjectAllTypesInformation();
+BOOL NtQueryObject_ObjectTypeInformation();
+
+
+#define DEBUG_READ_EVENT 0x0001
+#define DEBUG_PROCESS_ASSIGN 0x0002
+#define DEBUG_SET_INFORMATION 0x0004
+#define DEBUG_QUERY_INFORMATION 0x0008
+#define DEBUG_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
+    DEBUG_READ_EVENT | DEBUG_PROCESS_ASSIGN | DEBUG_SET_INFORMATION | \
+    DEBUG_QUERY_INFORMATION)
+
+typedef struct _OBJECT_TYPE_INFORMATION {
+	UNICODE_STRING TypeName;
+	ULONG TotalNumberOfHandles;
+	ULONG TotalNumberOfObjects;
+}OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
+
+typedef struct _OBJECT_ALL_INFORMATION {
+	ULONG NumberOfObjects;
+	OBJECT_TYPE_INFORMATION ObjectTypeInformation[1];
+}OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION;
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/NtQueryObject_ObjectTypeInformation.cpp b/al-khaser/al-khaser/AntiDebug/NtQueryObject_ObjectTypeInformation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0c0ba17e99a2eb0ada46ce84c694e9dfafcfd133
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtQueryObject_ObjectTypeInformation.cpp
@@ -0,0 +1,54 @@
+#include "pch.h"
+
+#include "NtQueryObject_ObjectInformation.h"
+
+/* 
+Windows XP introduced a "debug object". When a debugging session begins, a debug object is created,
+and a handle is associated with it. Using the ntdll NtQueryObject() function  with class: ObjectTypeInformation. 
+ObjectTypeInformation will return the type information of the supplied handle.
+*/
+
+
+BOOL NtQueryObject_ObjectTypeInformation()
+{
+	//NOTE this check now only detects if NtQueryObject is hooked to set ObjectInformation->TotalNumberOfObjects = 0
+
+	// We have to import the function
+	auto NtQueryObject = static_cast<pNtQueryObject>(API::GetAPI(API_IDENTIFIER::API_NtQueryObject));
+	auto NtCreateDebugObject = static_cast<pNtCreateDebugObject>(API::GetAPI(API_IDENTIFIER::API_NtCreateDebugObject));
+
+	// Some vars
+	HANDLE DebugObjectHandle;
+	OBJECT_ATTRIBUTES ObjectAttributes;
+	InitializeObjectAttributes(&ObjectAttributes, 0, 0, 0, 0);
+	BYTE memory[0x1000] = { 0 };
+	POBJECT_TYPE_INFORMATION ObjectInformation = (POBJECT_TYPE_INFORMATION)memory;
+	NTSTATUS Status;
+
+	NtCreateDebugObject(&DebugObjectHandle, DEBUG_ALL_ACCESS, &ObjectAttributes, FALSE);
+
+	if (API::IsAvailable(API_IDENTIFIER::API_NtQueryObject))
+	{
+		Status = NtQueryObject(DebugObjectHandle, ObjectTypeInformation, ObjectInformation, sizeof(memory), 0);
+		
+		// Make sure to not screw up later checks
+		CloseHandle(DebugObjectHandle);
+		
+
+		if (Status >= 0)
+		{
+			if (ObjectInformation->TotalNumberOfObjects == 0)
+				return TRUE; //There should be at least one object (we just created it).
+			else
+				return FALSE;
+		}
+		else
+		{
+			//NOTE: this should actually never happen on a valid handle (so this check can be bypassed by failing NtQueryObject)
+			return FALSE;
+		}
+	}
+	else
+		return FALSE;
+
+}
diff --git a/al-khaser/al-khaser/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.cpp b/al-khaser/al-khaser/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aa03fd2346958f59215f568cfefc144e14800482
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.cpp
@@ -0,0 +1,30 @@
+#include "pch.h"
+
+#include "NtQuerySystemInformation_SystemKernelDebuggerInformation.h"
+
+/*
+When NtQuerySystemInformation is called with the SystemKernelDebuggerInformation class, the function will return
+a SYSTEM_KERNEL_DEBUGGER_INFORMATION struct which will reveal the presence of a kernel debugger.
+*/
+
+BOOL NtQuerySystemInformation_SystemKernelDebuggerInformation()
+{
+   	// SystemKernelDebuggerInformation
+	const int SystemKernelDebuggerInformation = 0x23;
+
+	// The debugger information struct
+	SYSTEM_KERNEL_DEBUGGER_INFORMATION KdDebuggerInfo;
+
+	auto NtQuerySystemInformation = static_cast<pNtQuerySystemInformation>(API::GetAPI(API_IDENTIFIER::API_NtQuerySystemInformation));
+
+	// Call NtQuerySystemInformation
+	NTSTATUS Status = NtQuerySystemInformation(SystemKernelDebuggerInformation, &KdDebuggerInfo, sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION), NULL);
+	if (Status >= 0)
+	{
+		// KernelDebuggerEnabled almost always implies !KernelDebuggerNotPresent. KernelDebuggerNotPresent can sometimes
+		// change if the debugger is temporarily disconnected, but either of these means a debugger is enabled.
+		if (KdDebuggerInfo.KernelDebuggerEnabled || !KdDebuggerInfo.KernelDebuggerNotPresent)
+			return TRUE;
+	}
+	return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.h b/al-khaser/al-khaser/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.h
new file mode 100644
index 0000000000000000000000000000000000000000..746867fc5121139c5a304e9b8443798623c8165b
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.h
@@ -0,0 +1,9 @@
+#pragma once
+
+BOOL NtQuerySystemInformation_SystemKernelDebuggerInformation();
+
+typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION
+{
+	BOOLEAN KernelDebuggerEnabled;
+	BOOLEAN KernelDebuggerNotPresent;
+} SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION;
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.cpp b/al-khaser/al-khaser/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ff7b1afc44d65a562f28fbae70fb9541ff64a60d
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.cpp
@@ -0,0 +1,133 @@
+#include "pch.h"
+
+#include "NtSetInformationThread_ThreadHideFromDebugger.h"
+
+/*
+Calling NtSetInformationThread will attempt with ThreadInformationClass set to  x11 (ThreadHideFromDebugger)
+to hide a thread from the debugger, Passing NULL for hThread will cause the function to hide the thread the
+function is running in. Also, the function returns false on failure and true on success. When  the  function
+is called, the thread will continue  to run but a debugger will no longer receive any events related to that thread.
+
+These checks also look for hooks on the NtSetInformationThread API that try to block ThreadHideFromDebugger.
+*/
+
+#ifndef STATUS_INFO_LENGTH_MISMATCH
+#define STATUS_INFO_LENGTH_MISMATCH ((DWORD)0xC0000004L)
+#endif
+#ifndef STATUS_DATATYPE_MISALIGNMENT
+#define STATUS_DATATYPE_MISALIGNMENT ((DWORD)0x80000002L)
+#endif
+
+
+BOOL NtSetInformationThread_ThreadHideFromDebugger()
+{
+	// this is needed because the bool data type can be at unaligned memory locations, whereas the NtQueryInformationThread API expects 32-bit aligned pointers.
+	struct AlignedBool
+	{
+		alignas(4) bool Value;
+	};
+
+	// ThreadHideFromDebugger
+	const int ThreadHideFromDebugger =  0x11;
+
+	auto NtSetInformationThread = static_cast<pNtSetInformationThread>(API::GetAPI(API_IDENTIFIER::API_NtSetInformationThread));
+	auto NtQueryInformationThread = static_cast<pNtQueryInformationThread>(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationThread));
+	
+	NTSTATUS Status;
+	bool doQITcheck = false;
+
+	// only do the QueryInformationThread check if we're on Vista and the API is available.
+	// this is because the ThreadHideFromDebugger class can only be queried from Vista onwards.
+	if (API::IsAvailable(API_IDENTIFIER::API_NtQueryInformationThread))
+	{
+		doQITcheck = IsWindowsVistaOrGreater();
+	}
+
+	AlignedBool isThreadHidden;
+	isThreadHidden.Value = false;
+	
+	// First issue a bogus call with an incorrect length parameter. If it succeeds, we know NtSetInformationThread was hooked.
+	Status = NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, &isThreadHidden, 12345);
+	if (Status == 0)
+		return TRUE;
+
+	// Next try again but give it a bogus thread handle. If it succeeds, again we know NtSetInformationThread was hooked.
+	Status = NtSetInformationThread((HANDLE)0xFFFF, ThreadHideFromDebugger, NULL, 0);
+	if (Status == 0)
+		return TRUE;
+	
+	// Now try a legitimate call.
+	Status = NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, NULL, 0);
+
+	if (Status == 0)
+	{
+		if (doQITcheck)
+		{
+			// note: the ThreadHideFromDebugger query expects a bool (1 byte), not a BOOL (4 bytes)
+			// if a BOOL is used, the kernel returns 0xC0000004 (STATUS_INFO_LENGTH_MISMATCH) because BOOL is typedef int.
+
+			// first do a legitimate call. this should succeed or return an error such as access denied.
+			Status = NtQueryInformationThread(GetCurrentThread(), ThreadHideFromDebugger, &isThreadHidden.Value, sizeof(bool), NULL);
+
+			// this shouldn't happen, because we used the correct length. this will only happen if a buggy hook mistakenly expects a BOOL rather than a bool.
+			if (Status == STATUS_INFO_LENGTH_MISMATCH)
+			{
+				// we found a buggy hook that expects some size other than 1
+				return TRUE;
+			}
+
+			// if the legitimate call succeeded, continue with additional bogus API call checks
+			if (Status == 0)
+			{
+				AlignedBool bogusIsThreadHidden;
+				bogusIsThreadHidden.Value = false;
+
+				// now do a bogus call with the wrong size. this will catch buggy hooks that accept BOOL (4 bytes) or just don't have any size checks
+				Status = NtQueryInformationThread(GetCurrentThread(), ThreadHideFromDebugger, &bogusIsThreadHidden.Value, sizeof(BOOL), NULL);
+				if (Status != STATUS_INFO_LENGTH_MISMATCH)
+				{
+					// we found a buggy hook that allows for incorrect size values
+					return TRUE;
+				}
+
+				// NtQueryInformationThread explicitly requires the ThreadInformation pointer to be aligned. as such, it should reject unaligned pointers.
+				// hooks are almost certainly guaranteed to not retain this behaviour, so it's a very nice way to catch them out.
+				const size_t UnalignedCheckCount = 8;
+				bool bogusUnalignedValues[UnalignedCheckCount];
+				int alignmentErrorCount = 0;
+#if _WIN64
+				// on 64-bit, up to two elements in the array should be aligned.
+				const size_t MaxAlignmentCheckSuccessCount = 2;
+#else
+				// on 32-bit, there should be either two or four aligned elements (unsure how WoW64 affects this, so I'm just gonna assume 2 or 4 are ok)
+				const size_t MaxAlignmentCheckSuccessCount = 4;
+#endif
+				for (size_t i = 0; i < UnalignedCheckCount; i++)
+				{
+					Status = NtQueryInformationThread(GetCurrentThread(), ThreadHideFromDebugger, &(bogusUnalignedValues[i]), sizeof(BOOL), NULL);
+					if (Status == STATUS_DATATYPE_MISALIGNMENT)
+					{
+						alignmentErrorCount++;
+					}
+				}
+				// if there weren't enough alignment errors, we know that the API must be hooked and not checking alignment properly!
+				if (UnalignedCheckCount - MaxAlignmentCheckSuccessCount > alignmentErrorCount)
+				{
+					return TRUE;
+				}
+
+				// the legitimate call was successful, and the bogus call was unsuccessful, so return false (no detection) if the HideFromDebugger flag was properly set.
+				// if the HideFromDebugger flag was not set, i.e. the NtSetInformationThread call lied to us about being successful, then return true (debugger/hook detected)
+				return isThreadHidden.Value ? FALSE : TRUE;
+			}
+		}
+	}
+	else
+	{
+		// call failed, should've succeeded
+		return TRUE;
+	}
+
+	// we didn't find any hooks.
+	return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.h b/al-khaser/al-khaser/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.h
new file mode 100644
index 0000000000000000000000000000000000000000..6fc8469dded366ef8355b3f5e41fe27394f4ee1f
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL NtSetInformationThread_ThreadHideFromDebugger();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/NtSystemDebugControl.cpp b/al-khaser/al-khaser/AntiDebug/NtSystemDebugControl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ce7a5b37db3291914af68c5d694e1d5712e853e3
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtSystemDebugControl.cpp
@@ -0,0 +1,19 @@
+#include "pch.h"
+
+BOOL NtSystemDebugControl_Command() {
+	auto NtSystemDebugControl_ = static_cast<pNtSystemDebugControl>(API::GetAPI(API_IDENTIFIER::API_NtSystemDebugControl));
+
+	auto status = NtSystemDebugControl_(SYSDBG_COMMAND::SysDbgCheckLowMemory, 0, 0, 0, 0, 0);
+
+	const auto STATUS_DEBUGGER_INACTIVE = 0xC0000354L;
+	const auto STATUS_ACCESS_DENIED = 0xC0000022L;
+	if (status == STATUS_DEBUGGER_INACTIVE) {
+		return FALSE;
+	} else {
+		// kernel debugger found
+		if (status != STATUS_ACCESS_DENIED) {
+			// usermode debugger too
+		}
+		return TRUE;
+	}
+}
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/NtSystemDebugControl.h b/al-khaser/al-khaser/AntiDebug/NtSystemDebugControl.h
new file mode 100644
index 0000000000000000000000000000000000000000..d0c482aa303abe2acdf454f501ff0c836823a32b
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtSystemDebugControl.h
@@ -0,0 +1 @@
+BOOL NtSystemDebugControl_Command();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/NtYieldExecution.cpp b/al-khaser/al-khaser/AntiDebug/NtYieldExecution.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2e6d546bccc40b3feb48aeecde581be34b4407b9
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtYieldExecution.cpp
@@ -0,0 +1,38 @@
+#include "pch.h"
+#include "NtYieldExecution.h"
+
+/*
+The ntdll function NtYieldExecution or its kernel32 equivalent SwitchToThread function allows the current
+thread to offer to give up the rest of its time slice, and allow the next scheduled thread to
+execute. If no threads are scheduled to execute (or when the system is busy in particular ways and will
+not allow a switch to occur), then the ntdll NtYieldExecution() function returns the
+STATUS_NO_YIELD_PERFORMED (0x40000024) status, which causes the kernel32 SwitchToThread() function to
+return a zero. When an application is being debugged, the act of single-stepping through the
+code causes debug events and often results in no yield being allowed. However, this is a hopelessly
+unreliable method for detecting a debugger because it will also detect the presence of a thread that is running with high priority. 
+*/
+
+
+BOOL NtYieldExecutionAPI()
+{
+	//NOTE: this check is unreliable, don't actually use this in a real environment
+
+	auto NtYieldExecution = static_cast<pNtYieldExecution>(API::GetAPI(API_IDENTIFIER::API_NtYieldExecution));
+
+	INT iDebugged = 0;
+
+	for (int i = 0; i < 0x20; i++)
+	{
+		Sleep(0xf);
+
+		if (NtYieldExecution() != STATUS_NO_YIELD_PERFORMED)
+			iDebugged++;
+	}
+
+	if (iDebugged <= 3)
+		return FALSE;
+	else
+		return TRUE;
+	
+
+}
diff --git a/al-khaser/al-khaser/AntiDebug/NtYieldExecution.h b/al-khaser/al-khaser/AntiDebug/NtYieldExecution.h
new file mode 100644
index 0000000000000000000000000000000000000000..7d4a2b2035826e1610fce4f3a6c7a6314935d5ae
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/NtYieldExecution.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#define STATUS_NO_YIELD_PERFORMED 0x40000024 
+
+BOOL NtYieldExecutionAPI();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/OutputDebugStringAPI.cpp b/al-khaser/al-khaser/AntiDebug/OutputDebugStringAPI.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..adf2a7f2649012d107140d96ed4cba03feb12da3
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/OutputDebugStringAPI.cpp
@@ -0,0 +1,34 @@
+#include "pch.h"
+
+#include "OutputDebugStringAPI.h"
+
+/*
+OutputDebugString() is typically used to output a string value to the debugging data stream.
+This string is then displayed in the debugger. Due to this fact, the function OutputDebugString()
+acts differently based on the existence of a debugger on the running process. If a debugger is
+attached to the process, the function will execute normally and no error state will be registered;
+however if there is no debugger attached, LastError will be set by the process letting us know that
+we are debugger free. To execute this method we set LastError to an arbitrary value of our choosing
+and then call OutputDebugString(). We then check GetLastError() and if our error code remains,
+we know we are debugger free. This Works only in Windows XP/2000 
+*/
+
+BOOL OutputDebugStringAPI()
+{
+
+	BOOL IsDbgPresent = FALSE;
+	DWORD Val = 0x29A;
+
+	// This is working only in Windows XP/2000
+	if (IsWindowsXPOr2k())
+	{
+		SetLastError(Val);
+		OutputDebugString(_T("random"));
+
+		if (GetLastError() == Val)
+			IsDbgPresent = TRUE;
+	}
+		
+	return IsDbgPresent;
+}
+
diff --git a/al-khaser/al-khaser/AntiDebug/OutputDebugStringAPI.h b/al-khaser/al-khaser/AntiDebug/OutputDebugStringAPI.h
new file mode 100644
index 0000000000000000000000000000000000000000..600134ff4f9880751ceb45a72ed2c9f22e959894
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/OutputDebugStringAPI.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL OutputDebugStringAPI();
diff --git a/al-khaser/al-khaser/AntiDebug/PageExceptionBreakpointCheck.cpp b/al-khaser/al-khaser/AntiDebug/PageExceptionBreakpointCheck.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..16cd329d386b609c85ac0e216fecbea6847ff266
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/PageExceptionBreakpointCheck.cpp
@@ -0,0 +1,139 @@
+#include "pch.h"
+
+#ifdef _DEBUG
+#define OutputDebugStringDbgOnly(S) OutputDebugString(S)
+#else
+#define OutputDebugStringDbgOnly(S) do {} while(0);
+#endif
+
+std::vector<PVOID> executablePages = {};
+
+void PageExceptionInitialEnum()
+{
+	SYSTEM_INFO sysInfo;
+	GetSystemInfo(&sysInfo);
+	size_t pageSize = sysInfo.dwPageSize;
+
+	HMODULE hMainModule;
+	MODULEINFO moduleInfo;
+
+	MEMORY_BASIC_INFORMATION memInfo = { 0 };
+
+	// Get the main module handle from an address stored within it (pointer to this method)
+	if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)PageExceptionBreakpointCheck, &hMainModule))
+	{
+		// Get information about the main module (we want to know the size of it)
+		if (GetModuleInformation(GetCurrentProcess(), hMainModule, &moduleInfo, sizeof(MODULEINFO)))
+		{
+			// cast the module to a pointer
+			unsigned char* module = static_cast<unsigned char*>(moduleInfo.lpBaseOfDll);
+			for (size_t ofs = 0; ofs < moduleInfo.SizeOfImage; ofs += pageSize)
+			{
+				if (VirtualQuery(module + ofs, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) >= sizeof(MEMORY_BASIC_INFORMATION))
+				{
+					if ((memInfo.Protect & PAGE_EXECUTE) == PAGE_EXECUTE ||
+						(memInfo.Protect & PAGE_EXECUTE_READ) == PAGE_EXECUTE_READ ||
+						(memInfo.Protect & PAGE_EXECUTE_WRITECOPY) == PAGE_EXECUTE_WRITECOPY ||
+						(memInfo.Protect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE)
+					{
+						executablePages.push_back(module + ofs);
+					}
+				}
+			}
+		}
+	}
+}
+
+BOOL PageExceptionBreakpointCheck()
+{
+	SYSTEM_INFO sysInfo;
+	GetSystemInfo(&sysInfo);
+	size_t pageSize = sysInfo.dwPageSize;
+
+	HMODULE hMainModule;
+	MODULEINFO moduleInfo;
+
+	MEMORY_BASIC_INFORMATION memInfo = { 0 };
+
+	wchar_t buffer[512];
+
+	// first we check if any of the pages are executable+guard or noaccess
+
+	// Get the main module handle from an address stored within it (pointer to this method)
+	if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)PageExceptionBreakpointCheck, &hMainModule))
+	{
+		// Get information about the main module (we want to know the size of it)
+		if (GetModuleInformation(GetCurrentProcess(), hMainModule, &moduleInfo, sizeof(MODULEINFO)))
+		{
+			// cast the module to a pointer
+			unsigned char* module = static_cast<unsigned char*>(moduleInfo.lpBaseOfDll);
+			for (size_t ofs = 0; ofs < moduleInfo.SizeOfImage; ofs += pageSize)
+			{
+				SecureZeroMemory(buffer, 512);
+				wsprintf(buffer, L"Scanning %p... ", module + ofs);
+				OutputDebugStringDbgOnly(buffer);
+				if (VirtualQuery(module + ofs, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) >= sizeof(MEMORY_BASIC_INFORMATION))
+				{
+					if (memInfo.AllocationProtect == 0)
+						OutputDebugStringDbgOnly(L"^ AllocationProtect is zero. Potential shenanigans.");
+					if (memInfo.Protect == 0)
+						OutputDebugStringDbgOnly(L"^ Protect is zero. Potential shenanigans.");
+
+					if ((memInfo.Protect & PAGE_EXECUTE) == PAGE_EXECUTE ||
+						(memInfo.Protect & PAGE_EXECUTE_READ) == PAGE_EXECUTE_READ ||
+						(memInfo.Protect & PAGE_EXECUTE_WRITECOPY) == PAGE_EXECUTE_WRITECOPY ||
+						(memInfo.Protect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE)
+					{
+						// this is an executable page
+						OutputDebugStringDbgOnly(L"^ is executable.");
+
+						if ((memInfo.Protect & PAGE_GUARD) == PAGE_GUARD ||
+							(memInfo.AllocationProtect & PAGE_GUARD) == PAGE_GUARD)
+						{
+							// this is an executable guard page, page exception debugging detected
+							OutputDebugStringDbgOnly(L"^ is guard page !!!!!!");
+							return TRUE;
+						}
+					}
+
+					if ((memInfo.Protect & PAGE_NOACCESS) == PAGE_NOACCESS)
+					{
+						// this is a NOACCESS page, which shouldn't exist here (alternative way to set page exception BPs)
+						OutputDebugStringDbgOnly(L"^ is NOACCESS !!!!!!!");
+						return TRUE;
+					}
+				}
+				else OutputDebugStringDbgOnly(L"^ FAILED!");
+			}
+		}
+
+		OutputDebugStringDbgOnly(L"Moving on to delta check...");
+
+		for (PVOID page : executablePages)
+		{
+			SecureZeroMemory(buffer, 512);
+			wsprintf(buffer, L"Scanning delta for %p... ", page);
+			OutputDebugStringDbgOnly(buffer);
+
+			if (VirtualQuery(page, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) >= sizeof(MEMORY_BASIC_INFORMATION))
+			{
+				if (memInfo.AllocationProtect == 0)
+					OutputDebugStringDbgOnly(L"^ AllocationProtect is zero. Potential shenanigans.");
+				if (memInfo.Protect == 0)
+					OutputDebugStringDbgOnly(L"^ Protect is zero. Potential shenanigans.");
+
+				if (!((memInfo.Protect & PAGE_EXECUTE) == PAGE_EXECUTE ||
+					(memInfo.Protect & PAGE_EXECUTE_READ) == PAGE_EXECUTE_READ ||
+					(memInfo.Protect & PAGE_EXECUTE_WRITECOPY) == PAGE_EXECUTE_WRITECOPY ||
+					(memInfo.Protect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE))
+				{
+					// page was executable, now isn't!
+					OutputDebugStringDbgOnly(L"^ was executable, now isn't !!!!!!");
+					return TRUE;
+				}
+			}
+		}
+	}
+
+	return FALSE;
+}
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/PageExceptionBreakpointCheck.h b/al-khaser/al-khaser/AntiDebug/PageExceptionBreakpointCheck.h
new file mode 100644
index 0000000000000000000000000000000000000000..08302c9b8fe193026c4fcb319d9b3ed9007fd4ff
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/PageExceptionBreakpointCheck.h
@@ -0,0 +1,4 @@
+#pragma once
+
+void PageExceptionInitialEnum();
+BOOL PageExceptionBreakpointCheck();
diff --git a/al-khaser/al-khaser/AntiDebug/ParentProcess.cpp b/al-khaser/al-khaser/AntiDebug/ParentProcess.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..87f21b31e02907d1963216a8a3e1062f8da13ddb
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/ParentProcess.cpp
@@ -0,0 +1,85 @@
+#include "pch.h"
+#include "ParentProcess.h"
+
+#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
+#include <experimental/filesystem>
+
+DWORD GetExplorerPIDbyShellWindow()
+{
+	DWORD dwProcessId = 0;
+
+	// Get the PID of explorer by its windows handle
+	GetWindowThreadProcessId(GetShellWindow(), &dwProcessId);
+
+	return dwProcessId;
+}
+
+DWORD GetParentProcessId()
+{
+	auto NtQueryInfoProcess = static_cast<pNtQueryInformationProcess>(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess));
+
+	NTSTATUS Status = 0;
+	ALK_PROCESS_BASIC_INFORMATION pbi;
+	SecureZeroMemory(&pbi, sizeof(ALK_PROCESS_BASIC_INFORMATION));
+
+	const UINT ProcessBasicInformation = 0;
+
+	Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessBasicInformation, (PVOID)&pbi, sizeof(ALK_PROCESS_BASIC_INFORMATION), 0);
+
+	if (Status != 0)
+	{
+		return 0;
+	}
+	else
+	{
+		return (DWORD)pbi.ParentProcessId;
+	}
+}
+
+BOOL IsParentExplorerExe()
+{
+	// this check will throw a false positive if you're running an alternative shell.
+
+	DWORD parentPid = GetParentProcessId();
+
+	bool parentPidEqualsExplorerPid = false;
+
+	if (parentPid > 0)
+	{
+		// first check 
+		HANDLE hParent = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, parentPid);
+		if (hParent != INVALID_HANDLE_VALUE)
+		{
+			WCHAR winDir[MAX_PATH];
+			WCHAR parentProcessPath[MAX_PATH];
+			if (GetModuleFileNameExW(hParent, NULL, parentProcessPath, MAX_PATH) && GetWindowsDirectory(winDir, MAX_PATH))
+			{
+				CloseHandle(hParent);
+
+				// get path to X:\Windows\explorer.exe
+				auto expectedPath = std::experimental::filesystem::path(winDir);
+				expectedPath = expectedPath.append("explorer.exe");
+
+				// get path to parent process
+				auto actualPath = std::experimental::filesystem::path(parentProcessPath);
+
+				// if the paths are equivalent, no detection.
+				return std::experimental::filesystem::equivalent(expectedPath, actualPath) ? FALSE : TRUE;
+			}
+			CloseHandle(hParent);
+		}
+
+		// if the first check couldn't be completed, fall back to the shell window approach.
+		// this check is less ideal because it throws false positives if you have explorer process isolation enabled (i.e. one process per explorer window)
+		DWORD explorerPid = GetExplorerPIDbyShellWindow();
+		if (explorerPid > 0)
+		{
+			if (parentPid != explorerPid)
+			{
+				return TRUE;
+			}
+		}
+	}
+
+	return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/ParentProcess.h b/al-khaser/al-khaser/AntiDebug/ParentProcess.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e4a32b23667011feb1344512dbf3810b92ed62a
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/ParentProcess.h
@@ -0,0 +1,11 @@
+#pragma once
+
+typedef struct _ALK_PROCESS_BASIC_INFORMATION {
+	PVOID Reserved1;
+	void* PebBaseAddress;
+	PVOID Reserved2[2];
+	ULONG_PTR UniqueProcessId;
+	ULONG_PTR ParentProcessId;
+} ALK_PROCESS_BASIC_INFORMATION;
+
+BOOL IsParentExplorerExe();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/ProcessHeap_Flags.cpp b/al-khaser/al-khaser/AntiDebug/ProcessHeap_Flags.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..22887fa7eb6c5147fe38eb4f4f4f018de33381fe
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/ProcessHeap_Flags.cpp
@@ -0,0 +1,66 @@
+#include "pch.h"
+
+#include "ProcessHeap_Flags.h"
+
+/* 
+When a program is run under a debugger, and is created using the debug process creation flags, the heap flags are changed.
+These Flags exit at a different location depending upon the version of the operating system.
+On Windows XP, these flags exist at 0x0C offset from heap base in 32bit system and offset 0x14 in 64bits
+On Windows 7, these flags exist at 0x40 offset from heap base in 32bit system and offset 0x70 in 64bits. 
+*/
+
+#if defined (ENV64BIT)
+PUINT32 GetHeapFlags_x64()
+{
+	PINT64 pProcessHeap = NULL;
+	PUINT32 pHeapFlags = NULL;
+	if (IsWindowsVistaOrGreater()){
+		pProcessHeap = (PINT64)(__readgsqword(0x60) + 0x30);
+		pHeapFlags = (PUINT32)(*pProcessHeap + 0x70);
+	}
+
+	else {
+		pProcessHeap = (PINT64)(__readgsqword(0x60) + 0x30);
+		pHeapFlags = (PUINT32)(*pProcessHeap + 0x14);
+	}
+	
+	return pHeapFlags;
+}
+
+#elif defined(ENV32BIT)
+PUINT32 GetHeapFlags_x86()
+{
+	PUINT32 pProcessHeap, pHeapFlags = NULL;
+
+	if (IsWindowsVistaOrGreater()){
+		pProcessHeap = (PUINT32)(__readfsdword(0x30) + 0x18);
+		pHeapFlags = (PUINT32)(*pProcessHeap + 0x40);
+	}
+
+	else {
+		pProcessHeap = (PUINT32)(__readfsdword(0x30) + 0x18);
+		pHeapFlags = (PUINT32)(*pProcessHeap + 0x0C);
+	}
+
+	return pHeapFlags;
+}
+#endif
+
+
+BOOL HeapFlags()
+{
+	PUINT32 pHeapFlags = NULL;
+
+#if defined (ENV64BIT)
+	pHeapFlags = GetHeapFlags_x64();
+
+#elif defined(ENV32BIT)
+	pHeapFlags = GetHeapFlags_x86();
+
+#endif
+
+	if (*pHeapFlags > 2)
+		return TRUE;
+	else
+		return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/ProcessHeap_Flags.h b/al-khaser/al-khaser/AntiDebug/ProcessHeap_Flags.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c0bb8958b638afa9cc843bcea43575f1535a439
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/ProcessHeap_Flags.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL HeapFlags();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/ProcessHeap_ForceFlags.cpp b/al-khaser/al-khaser/AntiDebug/ProcessHeap_ForceFlags.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..485274f403894a472b58ac01a702d8c6854e6ce6
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/ProcessHeap_ForceFlags.cpp
@@ -0,0 +1,68 @@
+#include "pch.h"
+
+#include "ProcessHeap_ForceFlags.h"
+
+/* 
+When a program is run under a debugger, and is created using the debug process creation flags. The heap flags are changed.
+These Flags exit at a different location depending upon the version of the operating system.
+On Windows XP, these flags exist at 0x10 offset from heap base in 32bit system and offset 0x18 in bits.
+On Windows 7, these flags exist at 0x44 offset from heap base in 32bit system and offset 0x74 in 64bits. 
+*/
+
+
+#if defined (ENV64BIT)
+PUINT32 GetForceFlags_x64()
+{
+	PINT64 pProcessHeap = NULL;
+	PUINT32 pHeapForceFlags = NULL;
+	if (IsWindowsVistaOrGreater()){
+		pProcessHeap = (PINT64)(__readgsqword(0x60) + 0x30);
+		pHeapForceFlags = (PUINT32)(*pProcessHeap + 0x74);
+	}
+
+	else {
+		pProcessHeap = (PINT64)(__readgsqword(0x60) + 0x30);
+		pHeapForceFlags = (PUINT32)(*pProcessHeap + 0x18);
+	}
+
+	return pHeapForceFlags;
+}
+
+#elif defined(ENV32BIT)
+PUINT32 GetForceFlags_x86()
+{
+	PUINT32 pProcessHeap, pHeapForceFlags = NULL;
+	if (IsWindowsVistaOrGreater())
+	{
+		pProcessHeap = (PUINT32)(__readfsdword(0x30) + 0x18);
+		pHeapForceFlags = (PUINT32)(*pProcessHeap + 0x44);
+
+	}
+
+	else {
+		pProcessHeap = (PUINT32)(__readfsdword(0x30) + 0x18);
+		pHeapForceFlags = (PUINT32)(*pProcessHeap + 0x10);
+	}
+
+	return pHeapForceFlags;
+}
+#endif
+
+BOOL HeapForceFlags()
+{
+	PUINT32 pHeapForceFlags = NULL;
+
+#if defined (ENV64BIT)
+	pHeapForceFlags = GetForceFlags_x64();
+
+#elif defined(ENV32BIT)
+	pHeapForceFlags = GetForceFlags_x86();
+
+#endif
+
+	if (*pHeapForceFlags > 0)
+		return TRUE;
+	else
+		return FALSE;
+
+}
diff --git a/al-khaser/al-khaser/AntiDebug/ProcessHeap_ForceFlags.h b/al-khaser/al-khaser/AntiDebug/ProcessHeap_ForceFlags.h
new file mode 100644
index 0000000000000000000000000000000000000000..99c4181b259499a20e35dc9bd2dbfcea07908246
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/ProcessHeap_ForceFlags.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL HeapForceFlags();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/ProcessJob.cpp b/al-khaser/al-khaser/AntiDebug/ProcessJob.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..26513f4f3136c600ad6b9e7127e7a3655277b466
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/ProcessJob.cpp
@@ -0,0 +1,78 @@
+#include "pch.h"
+
+#include "ProcessJob.h"
+
+/*
+ * ProcessJob  -  Contributed by Graham Sutherland (https://github.com/gsuberland)
+ * 
+ * Checks whether the process is part of a job object and, if so, any non-whitelisted processes are part of that job.
+ * 
+ * Debuggers and other analysis applications usually place processes inside a job so that child processes will exit
+ * when the parent process exits.
+ * You can observe this with Visual Studio by running al-khaser with Debug -> Start Without Debugging.
+ *
+ */
+
+BOOL ProcessJob()
+{
+	BOOL foundProblem = FALSE;
+
+	DWORD jobProcessStructSize = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + sizeof(ULONG_PTR) * 1024;
+	JOBOBJECT_BASIC_PROCESS_ID_LIST* jobProcessIdList = static_cast<JOBOBJECT_BASIC_PROCESS_ID_LIST*>(malloc(jobProcessStructSize));
+
+	if (jobProcessIdList) {
+
+		SecureZeroMemory(jobProcessIdList, jobProcessStructSize);
+
+		jobProcessIdList->NumberOfProcessIdsInList = 1024;
+
+		if (QueryInformationJobObject(NULL, JobObjectBasicProcessIdList, jobProcessIdList, jobProcessStructSize, NULL))
+		{
+			int ok_processes = 0;
+			for (DWORD i = 0; i < jobProcessIdList->NumberOfAssignedProcesses; i++)
+			{
+				ULONG_PTR processId = jobProcessIdList->ProcessIdList[i];
+
+				// is this the current process? if so that's ok
+				if (processId == (ULONG_PTR)GetCurrentProcessId())
+				{
+					ok_processes++;
+				}
+				else
+				{
+
+					// find the process name for this job process
+					HANDLE hJobProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)processId);
+					if (hJobProcess != NULL)
+					{
+						const int processNameBufferSize = 4096;
+						LPTSTR processName = static_cast<LPTSTR>(malloc(sizeof(TCHAR) * processNameBufferSize));
+						if (processName) {
+							SecureZeroMemory(processName, sizeof(TCHAR) * processNameBufferSize);
+
+							if (GetProcessImageFileName(hJobProcess, processName, processNameBufferSize) > 0)
+							{
+								String pnStr(processName);
+
+								// ignore conhost.exe (this hosts the al-khaser executable in a console)
+								if (pnStr.find(String(L"\\Windows\\System32\\conhost.exe")) != std::string::npos)
+								{
+									ok_processes++;
+								}
+							}
+
+							free(processName);
+						}
+						CloseHandle(hJobProcess);
+					}
+				}
+			}
+
+			// if we found other processes in the job other than the current process and conhost, report a problem
+			foundProblem = ok_processes != jobProcessIdList->NumberOfAssignedProcesses;
+		}
+
+		free(jobProcessIdList);
+	}
+	return foundProblem;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/ProcessJob.h b/al-khaser/al-khaser/AntiDebug/ProcessJob.h
new file mode 100644
index 0000000000000000000000000000000000000000..de03ba295e647d498ff73936329d3abaf0a38d67
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/ProcessJob.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#ifndef UNICODE  
+typedef std::string String;
+#else
+typedef std::wstring String;
+#endif
+
+BOOL ProcessJob();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/ScanForModules.cpp b/al-khaser/al-khaser/AntiDebug/ScanForModules.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..898eee13ded4a8ad3db19c9785250660516e5de1
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/ScanForModules.cpp
@@ -0,0 +1,711 @@
+#include "pch.h"
+
+#define NUMCHARS(a) (sizeof(a)/sizeof(*a))
+
+static HRESULT NormalizeNTPathOld(wchar_t* pszPath, size_t nMax)
+// Normalizes the path returned by GetProcessImageFileName
+{
+	wchar_t* pszSlash = wcschr(&pszPath[1], '\\');
+	if (pszSlash) pszSlash = wcschr(pszSlash + 1, '\\');
+	if (!pszSlash)
+		return E_FAIL;
+	wchar_t cSave = *pszSlash;
+	*pszSlash = 0;
+
+	wchar_t szNTPath[_MAX_PATH];
+	wchar_t szDrive[_MAX_PATH] = L"A:";
+	// We'll need to query the NT device names for the drives to find a match with pszPath
+	for (wchar_t cDrive = 'A'; cDrive < 'Z'; ++cDrive)
+	{
+		szDrive[0] = cDrive;
+		szNTPath[0] = 0;
+		if (0 != QueryDosDevice(szDrive, szNTPath, NUMCHARS(szNTPath)) &&
+			0 == _wcsicmp(szNTPath, pszPath))
+		{
+			// Match
+			wcscat_s(szDrive, NUMCHARS(szDrive), L"\\");
+			wcscat_s(szDrive, NUMCHARS(szDrive), pszSlash + 1);
+			wcscpy_s(pszPath, nMax, szDrive);
+			return S_OK;
+		}
+	}
+	*pszSlash = cSave;
+	return E_FAIL;
+}
+
+static HRESULT NormalizeNTPath(TCHAR* pszPath, size_t nMax)
+// Normalizes the path returned by GetProcessImageFileName
+{
+	TCHAR* pszSlash = StrChr(&pszPath[1], '\\');
+	if (pszSlash) pszSlash = StrChr(pszSlash + 1, '\\');
+	if (!pszSlash)
+		return E_FAIL;
+	TCHAR cSave = *pszSlash;
+	*pszSlash = 0;
+
+	TCHAR szNTPath[_MAX_PATH];
+	TCHAR szDrive[_MAX_PATH] = L"A:";
+	// We'll need to query the NT device names for the drives to find a match with pszPath
+	for (TCHAR cDrive = 'A'; cDrive < 'Z'; ++cDrive)
+	{
+		szDrive[0] = cDrive;
+		szNTPath[0] = 0;
+		if (0 != QueryDosDevice(szDrive, szNTPath, NUMCHARS(szNTPath)) &&
+			0 == StrCmpI(szNTPath, pszPath))
+		{
+			// Match
+			StringCbCat(szDrive, NUMCHARS(szDrive), _T("\\"));
+			StringCbCat(szDrive, NUMCHARS(szDrive), pszSlash + 1);
+			StringCbCopy(pszPath, nMax, szDrive);
+			return S_OK;
+		}
+	}
+	*pszSlash = cSave;
+	return E_FAIL;
+}
+
+bool IsGlobalizationNls(TCHAR* filename)
+{
+	// exclude this nls
+	// consider removing this hack with proper implementation of memory scan
+	PCTSTR ret = StrStrI(filename, _T("\\Windows\\Globalization\\Sorting\\SortDefault.nls"));
+	return (ret != NULL);
+}
+
+bool IsBadLibrary(TCHAR* filename, DWORD filenameLength)
+{
+	TCHAR systemDrive[MAX_PATH];
+	TCHAR systemDriveDevice[MAX_PATH];
+	TCHAR systemRootPath[MAX_PATH];
+	TCHAR exePath[MAX_PATH];
+	TCHAR normalisedPath[MAX_PATH];
+
+	if (IsGlobalizationNls(filename))
+		return false;
+
+	StringCbCopy(normalisedPath, MAX_PATH, filename);
+	NormalizeNTPath(normalisedPath, MAX_PATH);
+	size_t normalisedPathLength = 0;
+	StringCbLength(normalisedPath, MAX_PATH, &normalisedPathLength);
+
+	if (filenameLength == INVALID_FILE_SIZE)
+	{
+		size_t filenameActualLength = 0;
+		StringCbLength(filename, MAX_PATH, &filenameActualLength);
+		filenameLength = (DWORD)filenameActualLength;
+	}
+
+	GetSystemDirectory(systemRootPath, MAX_PATH);
+
+#ifdef _X86_
+	TCHAR syswow64Path[MAX_PATH];
+	SHGetFolderPath (NULL, CSIDL_SYSTEMX86, NULL, 0, syswow64Path);
+	StringCbCat(syswow64Path, MAX_PATH, _T("\\"));
+	size_t syswow64PathLength = 0;
+	StringCbLength(syswow64Path, MAX_PATH, &syswow64PathLength);
+#endif
+
+	size_t exePathLength = GetProcessImageFileName(GetCurrentProcess(), exePath, MAX_PATH);
+	NormalizeNTPath(exePath, MAX_PATH);
+	StringCbLength(exePath, MAX_PATH, &exePathLength);
+
+
+	if (GetEnvironmentVariable(_T("SystemDrive"), systemDrive, MAX_PATH) > 0)
+	{
+		if (QueryDosDeviceW(systemDrive, systemDriveDevice, MAX_PATH) > 0)
+		{
+			StringCbCat(systemDriveDevice, MAX_PATH, _T("\\Windows\\System32\\"));
+			size_t systemDriveDevicelength = 0;
+			StringCbLength(systemDriveDevice, MAX_PATH, &systemDriveDevicelength);
+
+			//printf("systemDriveDevice: %S (%d)\n", systemDriveDevice, systemDriveDevicelength);
+
+			if (StrNCmpI(systemDriveDevice, filename, (int)(min(systemDriveDevicelength, filenameLength) / sizeof(TCHAR)) ) == 0)
+			{
+				// path matched the NT file path
+				return false;
+			}
+
+			StringCbCat(systemRootPath, MAX_PATH, _T("\\"));
+			size_t systemRootPathLength = 0;
+			StringCbLength(systemRootPath, MAX_PATH, &systemRootPathLength);
+
+			//printf("systemRootPath: %S (%d)\n", systemRootPath, systemRootPathLength);
+
+			if (StrNCmpI(systemRootPath, normalisedPath, (int)(min(systemRootPathLength, normalisedPathLength) / sizeof(TCHAR)) ) == 0)
+			{
+				// path matched the regular system path
+				return false;
+			}
+
+#ifdef _X86_
+			if (IsWoW64() && StrNCmpI(syswow64Path, normalisedPath, (int)(min(syswow64PathLength, normalisedPathLength) / sizeof(TCHAR)) ) == 0)
+			{
+				// path matched the wow64 system path
+				return false;
+			}
+#endif
+
+			if (StrCmpI(exePath, normalisedPath) == 0)
+			{
+				// path matched the executable path
+				return false;
+			}
+		}
+	}
+	return true;
+}
+
+BOOL ScanForModules_EnumProcessModulesEx_Internal(DWORD moduleFlag)
+{
+	//printf("EnumProcessModulesEx()\n");
+	HMODULE* moduleList;
+	HMODULE* tmp;
+	DWORD currentSize = 1024 * sizeof(HMODULE);
+	DWORD requiredSize = 0;
+	bool anyBadLibs = false;
+	
+	// the EnumProcessModulesEx API was moved from psapi.dll into kernel32.dll for Windows 7, then back out afterwards.
+	// check for availability of either.
+	if (!API::IsAvailable(API_EnumProcessModulesEx_PSAPI) && !API::IsAvailable(API_EnumProcessModulesEx_Kernel))
+	{
+		// neither available
+		return FALSE;
+	}
+	
+	// API is available in one of the two libraries, use whichever is available.
+	pEnumProcessModulesEx fnEnumProcessModulesEx;
+	if (API::IsAvailable(API_EnumProcessModulesEx_PSAPI))
+	{
+		fnEnumProcessModulesEx = static_cast<pEnumProcessModulesEx>(API::GetAPI(API_IDENTIFIER::API_EnumProcessModulesEx_PSAPI));
+	}
+	else
+	{
+		fnEnumProcessModulesEx = static_cast<pEnumProcessModulesEx>(API::GetAPI(API_IDENTIFIER::API_EnumProcessModulesEx_Kernel));
+	}
+
+	moduleList = static_cast<HMODULE*>(calloc(1024, sizeof(HMODULE)));
+	if (moduleList) {
+
+		if (fnEnumProcessModulesEx(GetCurrentProcess(), moduleList, currentSize, &requiredSize, moduleFlag))
+		{
+			bool success = true;
+			if (requiredSize > currentSize)
+			{
+				currentSize = requiredSize;
+				tmp = static_cast<HMODULE*>(realloc(moduleList, currentSize));
+				if (tmp) {
+					moduleList = tmp;
+					if (fnEnumProcessModulesEx(GetCurrentProcess(), moduleList, currentSize, &requiredSize, moduleFlag) == FALSE)
+					{
+						success = false;
+					}
+				}
+				else {
+					success = false; //realloc failed
+				}
+			}
+			if (success)
+			{
+				DWORD count = requiredSize / sizeof(HMODULE);
+				TCHAR moduleName[MAX_PATH];
+				for (DWORD i = 0; i < count; i++)
+				{
+					DWORD len;
+					if ((len = GetModuleFileNameEx(GetCurrentProcess(), moduleList[i], moduleName, MAX_PATH)) > 0)
+					{
+						bool isBad = IsBadLibrary(moduleName, len);
+						if (isBad)
+							printf(" [!] Injected library: %S\n", moduleName);
+						anyBadLibs |= isBad;
+					}
+				}
+			}
+		}
+
+		free(moduleList);
+	}
+	return anyBadLibs ? TRUE : FALSE;
+}
+
+BOOL ScanForModules_EnumProcessModulesEx_32bit()
+{
+	return ScanForModules_EnumProcessModulesEx_Internal(LIST_MODULES_32BIT);
+}
+
+BOOL ScanForModules_EnumProcessModulesEx_64bit()
+{
+	
+	return ScanForModules_EnumProcessModulesEx_Internal(LIST_MODULES_64BIT);
+}
+
+BOOL ScanForModules_EnumProcessModulesEx_All()
+{
+	return ScanForModules_EnumProcessModulesEx_Internal(LIST_MODULES_ALL);
+}
+
+BOOL ScanForModules_MemoryWalk_GMI()
+{
+	// TODO: Convert this to the new enumerate_memory() API for speed!
+
+	MEMORY_BASIC_INFORMATION memInfo = { 0 };
+	HMODULE moduleHandle = 0;
+	TCHAR moduleName[MAX_PATH];
+	MODULEINFO moduleInfo = { 0 };
+
+	auto memoryRegions = enumerate_memory();
+
+	bool anyBadLibs = false;
+
+	for (PMEMORY_BASIC_INFORMATION region : *memoryRegions)
+	{
+		if (region->State == MEM_FREE)
+		{
+			delete region;
+			continue;
+		}
+
+		PBYTE addr = static_cast<PBYTE>(region->BaseAddress);
+		PBYTE regionEnd = addr + region->RegionSize;
+
+		//printf("Scanning %p - %p ...\n", addr, regionEnd);
+
+		while(addr < regionEnd)
+		{
+			bool skippedForward = false;
+			if (VirtualQuery(addr, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) >= sizeof(MEMORY_BASIC_INFORMATION))
+			{
+				if (memInfo.State != MEM_FREE)
+				{
+					if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (TCHAR*)addr, &moduleHandle))
+					{
+						SecureZeroMemory(moduleName, MAX_PATH * sizeof(TCHAR));
+						DWORD len = GetModuleFileName(moduleHandle, moduleName, MAX_PATH);
+						//printf(" [!] %p: %S\n", addr, moduleName);
+						bool isBad = IsBadLibrary(moduleName, len);
+						if (isBad)
+							printf(" [!] Injected library: %S\n", moduleName);
+						anyBadLibs |= isBad;
+
+						if (GetModuleInformation(GetCurrentProcess(), moduleHandle, &moduleInfo, sizeof(MODULEINFO)))
+						{
+							size_t moduleSizeRoundedUp = (moduleInfo.SizeOfImage + 1);
+							moduleSizeRoundedUp += 4096 - (moduleSizeRoundedUp % 4096);
+							PBYTE nextPos = static_cast<PBYTE>(moduleInfo.lpBaseOfDll) + moduleSizeRoundedUp;
+							if (nextPos > addr)
+							{
+								//printf(" -> Moving from %x to %x\n", addr, nextPos);
+								addr = nextPos;
+								skippedForward = true;
+							}
+						}
+					}
+				}
+			}
+			if (!skippedForward)
+				addr += 4096;
+		}
+		delete region;
+	}
+	delete memoryRegions;
+
+	return anyBadLibs ? TRUE : FALSE;
+}
+
+BOOL ScanForModules_MemoryWalk_Hidden()
+{
+	HMODULE moduleHandle = 0;
+	TCHAR moduleName[MAX_PATH];
+
+	auto memoryRegions = enumerate_memory();
+
+	bool anyBadLibs = false;
+
+	bool firstPrint = true;
+	for (PMEMORY_BASIC_INFORMATION region : *memoryRegions)
+	{
+		if (region->State == MEM_FREE)
+		{
+			delete region;
+			continue;
+		}
+
+		PBYTE addr = static_cast<PBYTE>(region->BaseAddress);
+		PBYTE regionEnd = addr + region->RegionSize;
+
+		//printf("Scanning %p - %p ...\n", addr, regionEnd);
+
+		while (addr < regionEnd)
+		{
+			bool skippedForward = false;
+			
+			if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (TCHAR*)addr, &moduleHandle) == FALSE)
+			{
+				// not a known module
+				if ((region->State & MEM_COMMIT) == MEM_COMMIT &&
+					((region->Protect == PAGE_READONLY) ||
+					(region->Protect == PAGE_READWRITE) || 
+					(region->Protect == PAGE_EXECUTE_READ) || 
+					(region->Protect == PAGE_EXECUTE_READWRITE) || 
+					(region->Protect == PAGE_EXECUTE_WRITECOPY)))
+				{
+					auto moduleData = static_cast<PBYTE>(region->BaseAddress);
+					if (moduleData[0] == 'M' && moduleData[1] == 'Z')
+					{
+						if (firstPrint)
+						{
+							firstPrint = false;
+							printf("\n\n");
+
+							if (IsWoW64())
+							{
+								printf(" [!] Running on WoW64, there will be false positives due to wow64 DLLs.\n");
+							}
+						}
+
+						printf(" [!] Executable at %p\n", region->BaseAddress);
+						anyBadLibs = true;
+					}
+				}
+			}
+			else
+			{
+				MODULEINFO modInfo = { 0 };
+				if (GetModuleInformation(GetCurrentProcess(), moduleHandle, &modInfo, sizeof(MODULEINFO)))
+				{
+					size_t moduleSizeRoundedUp = (modInfo.SizeOfImage + 1);
+					moduleSizeRoundedUp += 4096 - (moduleSizeRoundedUp % 4096);
+					PBYTE nextPos = static_cast<PBYTE>(modInfo.lpBaseOfDll) + moduleSizeRoundedUp;
+					if (nextPos > addr)
+					{
+						//printf(" -> Moving from %x to %x\n", addr, nextPos);
+						addr = nextPos;
+						skippedForward = true;
+					}
+				}
+			}
+
+			SecureZeroMemory(moduleName, sizeof(TCHAR)*MAX_PATH);
+			DWORD len;
+			if ((len = GetMappedFileName(GetCurrentProcess(), region->AllocationBase, moduleName, MAX_PATH)) > 0)
+			{
+				bool isBad = IsBadLibrary(moduleName, len);
+				if (isBad)
+					printf(" [!] Injected library: %S\n", moduleName);
+				anyBadLibs |= isBad;
+
+				// mapped files take up a whole region, so just skip to the end of the region
+				addr = regionEnd;
+				skippedForward = true;
+			}
+
+			if (!skippedForward)
+				addr += 4096;
+		}
+
+		delete region;
+	}
+	delete memoryRegions;
+
+	return anyBadLibs ? TRUE : FALSE;
+}
+
+BOOL ScanForModules_DotNetModuleStructures()
+{
+	HMODULE moduleHandle = 0;
+	TCHAR moduleName[MAX_PATH];
+
+	auto memoryRegions = enumerate_memory();
+
+	bool anyBadLibs = false;
+
+	/*
+	This works because the .NET runtime loads structures into memory that describe modules. This happens even if the module is loaded dynamically, from memory.
+	If al-khaser were a .NET application we'd need to apply some additional checks on the results, but since it isn't then we can just report every .NET module we find.
+	This check is quite effective because it catches pretty much any kind of .NET injection, even if the injector uses tricks like messing with PE headers or patching EWT.
+	*/
+
+	bool firstPrint = true;
+	for (PMEMORY_BASIC_INFORMATION region : *memoryRegions)
+	{
+		if (region->State == MEM_FREE || region->Type == MEM_MAPPED || region->Type == MEM_IMAGE)
+		{
+			//printf("region %p skipped for being free, mapped, or image.\n", region->BaseAddress);
+			delete region;
+			continue;
+		}
+
+		if ((region->State & MEM_COMMIT) == MEM_COMMIT &&
+			region->Protect == PAGE_READWRITE &&
+			region->AllocationProtect == PAGE_READWRITE)
+		{
+			uint64_t* addr = static_cast<uint64_t*>(region->BaseAddress);
+			uint64_t* regionEnd = addr + (region->RegionSize / sizeof(uint64_t));
+
+			// check first qword at region base address. should be zero.
+			if (*addr == 0)
+			{
+				// find the pattern of QWORDs we want (0, 0, 0, 0, 0, 0, pointer, length, 1, 2, 0, 2, 0, 2, 0)
+				while (addr < regionEnd - 32)
+				{
+					uint64_t* ptr = addr;
+					bool sixZeroes = true;
+					for (int i = 0; i < 6; i++)
+					{
+						sixZeroes &= *(ptr++) == 0;
+					}
+					if (sixZeroes)
+					{
+						//printf("got six zeroes at %p\n", ptr);
+						uint64_t stringPtrVal = *ptr;
+						PCWSTR stringPtr = reinterpret_cast<PCWSTR>(*ptr);
+						ptr++;
+						uint64_t stringLen = *ptr;
+						ptr++;
+						if (*ptr++ == 1 && *ptr++ == 2 && *ptr++ == 0 && *ptr++ == 2 && *ptr++ == 0 && *ptr++ == 2 && *ptr++ == 0)
+						{
+							// pattern matches, check string addr
+							if ((stringPtrVal & 0xFFFFFFFF00000000ULL) == ((uint64_t)ptr & 0xFFFFFFFF00000000ULL))
+							{
+								// check string length is sane
+								if (stringLen < MAX_PATH * sizeof(wchar_t))
+								{
+									// ok, we're sure it's the right structure. report it.
+
+									if (firstPrint)
+									{
+										printf("\n\n");
+									}
+									printf(" [!] Found module: %S (structure address %p)\n", stringPtr, stringPtr);
+									anyBadLibs = true;
+								}
+							}
+						}
+					}
+					addr++;
+				}
+			}
+		}
+
+		delete region;
+	}
+	delete memoryRegions;
+
+	return anyBadLibs ? TRUE : FALSE;
+}
+
+std::vector<LDR_DATA_TABLE_ENTRY*>* WalkLDR(PPEB_LDR_DATA ldrData)
+{
+	auto entryList = new std::vector<LDR_DATA_TABLE_ENTRY*>();
+
+	LIST_ENTRY* head = ldrData->InMemoryOrderModuleList.Flink;
+	LIST_ENTRY* node = head;
+
+	do
+	{
+		LDR_DATA_TABLE_ENTRY ldrEntry = { 0 };
+		LDR_DATA_TABLE_ENTRY* pLdrEntry = CONTAINING_RECORD(node, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
+
+		if (attempt_to_read_memory(pLdrEntry, &ldrEntry, sizeof(ldrEntry)))
+		{
+			entryList->push_back(new LDR_DATA_TABLE_ENTRY(ldrEntry));
+
+			node = ldrEntry.InMemoryOrderLinks.Flink;
+		}
+		else
+		{
+			printf(" [!] Error reading entry.\n");
+			break;
+		}
+	}
+	while (node != head);
+
+	entryList->pop_back();
+
+	return entryList;
+}
+
+std::vector<LDR_DATA_TABLE_ENTRY64*>* WalkLDR(PPEB_LDR_DATA64 ldrData)
+{
+	auto entryList = new std::vector<LDR_DATA_TABLE_ENTRY64*>();
+
+	LIST_ENTRY64 head;
+	if (!attempt_to_read_memory_wow64(&head, sizeof(LIST_ENTRY64), ldrData->InMemoryOrderModuleList.Flink))
+	{
+		printf(" [!] Error reading list head.\n");
+	}
+	ULONGLONG nodeAddr = ldrData->InMemoryOrderModuleList.Flink;
+	LIST_ENTRY64 node = head;
+	LDR_DATA_TABLE_ENTRY64 ldrEntry = { 0 };
+
+	do
+	{
+		if (attempt_to_read_memory_wow64(&ldrEntry, sizeof(LDR_DATA_TABLE_ENTRY64), nodeAddr - sizeof(LIST_ENTRY64)))
+		{
+			entryList->push_back(new LDR_DATA_TABLE_ENTRY64(ldrEntry));
+
+			if (!attempt_to_read_memory_wow64(&node, sizeof(LIST_ENTRY64), ldrEntry.InMemoryOrderLinks.Flink))
+			{
+				break;
+			}
+
+			nodeAddr = ldrEntry.InMemoryOrderLinks.Flink;
+		}
+		else
+		{
+			break;
+		}
+	} while (nodeAddr != ldrData->InMemoryOrderModuleList.Flink);
+
+	entryList->pop_back();
+
+	return entryList;
+}
+
+BOOL ScanForModules_LDR_Direct()
+{
+	PROCESS_BASIC_INFORMATION pbi = { 0 };
+	THREAD_BASIC_INFORMATION tbi = { 0 };
+
+	//printf("MemoryWalk_LDR()\n");
+
+	bool anyBadLibs = false;
+
+	auto NtQueryInformationProcess = static_cast<pNtQueryInformationProcess>(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess));
+	NTSTATUS status = NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), nullptr);
+	if (status != 0)
+	{
+		printf("Failed to get process information. Status: %d\n", status);
+	}
+	else
+	{
+		if (pbi.PebBaseAddress != nullptr)
+		{
+			PPEB peb = pbi.PebBaseAddress;
+			if (peb->Ldr != nullptr)
+			{
+				PPEB_LDR_DATA ldrData = peb->Ldr;
+
+				auto ldrEntries = WalkLDR(ldrData);
+				for (LDR_DATA_TABLE_ENTRY* ldrEntry : *ldrEntries)
+				{
+					//printf(" -> %S\n", ldrEntry->FullDllName.Buffer);
+					bool isBad = IsBadLibrary(ldrEntry->FullDllName.Buffer, ldrEntry->FullDllName.Length);
+					if (isBad)
+						printf(" [!] Injected library: %S\n", ldrEntry->FullDllName.Buffer);
+					anyBadLibs |= isBad;
+					delete ldrEntry;
+				}
+				delete ldrEntries;
+			}
+
+			if (IsWoW64())
+			{
+				PPEB64 peb64 = reinterpret_cast<PPEB64>(GetPeb64());
+				PEB_LDR_DATA64 ldrData = { 0 };
+				
+				if (peb64 && attempt_to_read_memory_wow64(&ldrData, sizeof(PEB_LDR_DATA64), peb64->Ldr))
+				{
+					auto ldrEntries = WalkLDR(&ldrData);
+					for (LDR_DATA_TABLE_ENTRY64* ldrEntry : *ldrEntries)
+					{
+						WCHAR* dllNameBuffer = new WCHAR[ldrEntry->FullDllName.Length + 1];
+						SecureZeroMemory(dllNameBuffer, (ldrEntry->FullDllName.Length + 1) * sizeof(WCHAR));
+						if (attempt_to_read_memory_wow64(dllNameBuffer, ldrEntry->FullDllName.Length * sizeof(WCHAR), ldrEntry->FullDllName.Buffer))
+						{
+							//printf(" -> %S\n", dllNameBuffer);
+							bool isBad = IsBadLibrary(dllNameBuffer, ldrEntry->FullDllName.Length);
+							if (isBad)
+								printf(" [!] Injected library (WOW64): %S\n", dllNameBuffer);
+							anyBadLibs |= isBad;
+						}
+						else
+						{
+							printf(" [!] Failed to read module name at %llx.\n", reinterpret_cast<ULONGLONG>(ldrEntry->FullDllName.Buffer));
+						}
+						delete [] dllNameBuffer;
+						delete ldrEntry;
+					}
+					delete ldrEntries;
+				}
+			}
+		}
+	}
+
+	return anyBadLibs ? TRUE : FALSE;
+}
+
+VOID NTAPI LdrEnumCallback(_In_ PLDR_DATA_TABLE_ENTRY ModuleInformation, _In_ PVOID Parameter, _Out_ BOOLEAN *Stop)
+{
+	// add ldr entry to table from param
+	auto ldtEntries = static_cast<std::vector<LDR_DATA_TABLE_ENTRY>*>(Parameter);
+
+	ldtEntries->push_back(LDR_DATA_TABLE_ENTRY(*ModuleInformation));
+
+	Stop = FALSE;
+}
+
+BOOL ScanForModules_LdrEnumerateLoadedModules()
+{
+	if (!API::IsAvailable(API_IDENTIFIER::API_LdrEnumerateLoadedModules))
+		return FALSE;
+
+	auto LdrEnumerateLoadedModules = static_cast<pLdrEnumerateLoadedModules>(API::GetAPI(API_IDENTIFIER::API_LdrEnumerateLoadedModules));
+
+	auto ldrEntries = new std::vector<LDR_DATA_TABLE_ENTRY>();
+
+	NTSTATUS status;
+	if ((status = LdrEnumerateLoadedModules(FALSE, &LdrEnumCallback, ldrEntries)) != 0)
+	{
+		printf("LdrEnumerateLoadedModules failed. Status: %x\n", status);
+		delete ldrEntries;
+		return FALSE;
+	}
+
+	bool anyBadEntries = false;
+	for (LDR_DATA_TABLE_ENTRY ldrEntry : *ldrEntries)
+	{
+		bool isBad = IsBadLibrary(ldrEntry.FullDllName.Buffer, ldrEntry.FullDllName.Length);
+		anyBadEntries |= isBad;
+	}
+
+	delete ldrEntries;
+	return anyBadEntries ? TRUE : FALSE;
+}
+
+BOOL ScanForModules_ToolHelp32()
+{
+	bool anyBadLibs = false;
+
+	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, GetCurrentProcessId());
+	//printf("Snapshot: %p\n", snapshot);
+	if (snapshot == INVALID_HANDLE_VALUE)
+	{
+		printf("Failed to get snapshot. Last error: %u\n", GetLastError());
+	}
+	else
+	{
+		MODULEENTRY32 module = { 0 };
+		module.dwSize = sizeof(MODULEENTRY32);
+		if (Module32First(snapshot, &module) != FALSE)
+		{
+			do
+			{
+				bool isBad = IsBadLibrary(module.szExePath, INVALID_FILE_SIZE);
+				if (isBad)
+					printf(" [!] Injected library: %S\n", module.szExePath);
+				anyBadLibs |= isBad;
+				//printf(" [!] %S\n", module.szModule);
+
+			} while (Module32Next(snapshot, &module) != FALSE);
+		}
+		else
+		{
+			printf("Failed to get first module. Last error: %u\n", GetLastError());
+		}
+
+		CloseHandle(snapshot);
+	}
+
+	return anyBadLibs ? TRUE : FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/ScanForModules.h b/al-khaser/al-khaser/AntiDebug/ScanForModules.h
new file mode 100644
index 0000000000000000000000000000000000000000..8baede0d95fe20e1f8bc1ab194c83c5f2497db61
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/ScanForModules.h
@@ -0,0 +1,11 @@
+#pragma once
+
+BOOL ScanForModules_EnumProcessModulesEx_32bit();
+BOOL ScanForModules_EnumProcessModulesEx_64bit();
+BOOL ScanForModules_EnumProcessModulesEx_All();
+BOOL ScanForModules_ToolHelp32();
+BOOL ScanForModules_LDR_Direct();
+BOOL ScanForModules_LdrEnumerateLoadedModules();
+BOOL ScanForModules_MemoryWalk_GMI();
+BOOL ScanForModules_MemoryWalk_Hidden();
+BOOL ScanForModules_DotNetModuleStructures();
diff --git a/al-khaser/al-khaser/AntiDebug/SeDebugPrivilege.cpp b/al-khaser/al-khaser/AntiDebug/SeDebugPrivilege.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0239ebfc57e2718277b1cef7377d7695ca80c720
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/SeDebugPrivilege.cpp
@@ -0,0 +1,36 @@
+#include "pch.h"
+
+#include "SeDebugPrivilege.h"
+
+/*
+If we're being debugged and the process has SeDebugPrivileges privileges then OpenProcess call will be successful.
+This requires administrator privilege !
+In Windows XP, Vista and 7, calling OpenProcess with PROCESS_ALL_ACCESS will fait even with SeDebugPrivilege enabled,
+That's why I used PROCESS_QUERY_LIMITED_INFORMATION
+*/
+
+
+DWORD GetCsrssProcessId()
+{
+	if (API::IsAvailable(API_IDENTIFIER::API_CsrGetProcessId))
+	{
+		auto CsrGetProcessId = static_cast<pCsrGetId>(API::GetAPI(API_IDENTIFIER::API_CsrGetProcessId));
+
+		return CsrGetProcessId();
+	}
+	else
+		return GetProcessIdFromName(_T("csrss.exe"));
+}
+
+
+BOOL CanOpenCsrss()
+{
+	 HANDLE hCsrss = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, GetCsrssProcessId());
+	 if (hCsrss != NULL)
+	{
+		CloseHandle(hCsrss);
+		return TRUE;
+	}
+	else
+		return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/SeDebugPrivilege.h b/al-khaser/al-khaser/AntiDebug/SeDebugPrivilege.h
new file mode 100644
index 0000000000000000000000000000000000000000..282f1ee42193da42f27b9fa60171d46f4934bdb9
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/SeDebugPrivilege.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL CanOpenCsrss();
diff --git a/al-khaser/al-khaser/AntiDebug/SetHandleInformation_API.cpp b/al-khaser/al-khaser/AntiDebug/SetHandleInformation_API.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1efcbd55c0438a93e54014626c7a8664a4b430d4
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/SetHandleInformation_API.cpp
@@ -0,0 +1,33 @@
+#include "pch.h"
+
+#include "SetHandleInformation_API.h"
+
+
+BOOL SetHandleInformatiom_ProtectedHandle()
+{
+	/* some vars */
+	HANDLE hMutex;
+
+	/* Create a mutex so we can get a handle */
+	hMutex = CreateMutex(NULL, FALSE, _T("Random name"));
+
+	if (hMutex) {
+
+		/* Protect our handle */
+		SetHandleInformation(hMutex, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE);
+
+
+		__try {
+			/* Then, let's try close it */
+			CloseHandle(hMutex);
+		}
+
+		__except (EXCEPTION_EXECUTE_HANDLER) {
+			return TRUE;
+		}
+
+	}
+
+	return FALSE;
+
+}
diff --git a/al-khaser/al-khaser/AntiDebug/SetHandleInformation_API.h b/al-khaser/al-khaser/AntiDebug/SetHandleInformation_API.h
new file mode 100644
index 0000000000000000000000000000000000000000..5b2671b0caa6217f66b5b8f79d8aa04f4611b410
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/SetHandleInformation_API.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL SetHandleInformatiom_ProtectedHandle();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/SharedUserData_KernelDebugger.cpp b/al-khaser/al-khaser/AntiDebug/SharedUserData_KernelDebugger.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0b310e534e7ed35bb8f24164e3b9914ddbf17c1c
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/SharedUserData_KernelDebugger.cpp
@@ -0,0 +1,32 @@
+#include "pch.h"
+
+#include "SharedUserData_KernelDebugger.h"
+
+/*
+NtQuerySystemInformation can be used to detect the presence of a kernel debugger. However, the
+same information can be obtained from user mode with no system calls at all. This is done by
+reading from the KUSER_SHARED_DATA struct, which is has a fixed user mode address of 0x7FFE0000 in all versions
+of Windows in both 32 and 64 bit. In kernel mode it is located at 0xFFDF0000 (32 bit) or 0xFFFFF78000000000 (64 bit).
+Detailed information about KUSER_SHARED_DATA can be found here: http://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/kuser_shared_data.htm
+*/
+
+BOOL SharedUserData_KernelDebugger()
+{
+	// The fixed user mode address of KUSER_SHARED_DATA
+	const ULONG_PTR UserSharedData = 0x7FFE0000;
+
+	// UserSharedData->KdDebuggerEnabled is a BOOLEAN according to ntddk.h, which gives the false impression that it is
+	// either true or false. However, this field is actually a set of bit flags, and is only zero if no debugger is present.
+	const UCHAR KdDebuggerEnabledByte = *(UCHAR*)(UserSharedData + 0x2D4); // 0x2D4 = the offset of the field
+
+	// Extract the flags.
+	// The meaning of these is the same as in NtQuerySystemInformation(SystemKernelDebuggerInformation).
+	// Normally if a debugger is attached, KdDebuggerEnabled is true, KdDebuggerNotPresent is false and the byte is 0x3.
+	const BOOLEAN KdDebuggerEnabled = (KdDebuggerEnabledByte & 0x1) == 0x1;
+	const BOOLEAN KdDebuggerNotPresent = (KdDebuggerEnabledByte & 0x2) == 0;
+
+	if (KdDebuggerEnabled || !KdDebuggerNotPresent)
+		return TRUE;
+
+	return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/SharedUserData_KernelDebugger.h b/al-khaser/al-khaser/AntiDebug/SharedUserData_KernelDebugger.h
new file mode 100644
index 0000000000000000000000000000000000000000..991ed19a889fa2857ff772c9d1941758b63d1087
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/SharedUserData_KernelDebugger.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL SharedUserData_KernelDebugger();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/SoftwareBreakpoints.cpp b/al-khaser/al-khaser/AntiDebug/SoftwareBreakpoints.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..83f5d32c3ad65d95e83ae3751ae5fdb2823dcdb6
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/SoftwareBreakpoints.cpp
@@ -0,0 +1,44 @@
+#include "pch.h"
+
+#include "SoftwareBreakpoints.h"
+
+
+/*
+Software breakpoints aka INT 3 represented in the IA-32 instruction set with the opcode CC (0xCC).
+Given a memory addresse and size, it is relatively simple to scan for the byte 0xCC -> if(pTmp[i] == 0xCC)
+An obfuscated method would be to check if our memory byte xored with 0x55 is equal 0x99 for example ... 
+*/
+
+VOID My_Critical_Function()
+{
+	int a = 1;
+	int b = 2;
+	int c = a + b;
+	_tprintf(_T("I am critical function, you should protect against int3 bps %d"), c);
+}
+
+
+VOID Myfunction_Adresss_Next()
+{
+	My_Critical_Function();
+	/*
+	There is no guaranteed way of determining the size of a function at run time(and little reason to do so)
+	however if you assume that the linker located functions that are adjacent in the source code sequentially in memory,
+	then the following may give an indication of the size of a function Critical_Function by using :
+	int Critical_Function_length = (int)Myfunction_Adresss_Next - (int)Critical_Function
+	Works only if you compile the file in Release mode.
+	*/
+};
+
+BOOL SoftwareBreakpoints()
+{
+	//NOTE this check might not work on x64 because of alignment 0xCC bytes
+	size_t sSizeToCheck = (size_t)(Myfunction_Adresss_Next)-(size_t)(My_Critical_Function);
+	PUCHAR Critical_Function = (PUCHAR)My_Critical_Function;
+
+	for (size_t i = 0; i < sSizeToCheck; i++) {
+		if (Critical_Function[i] == 0xCC) // Adding another level of indirection : 0xCC xor 0x55 = 0x99
+			return TRUE;
+	}
+	return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/SoftwareBreakpoints.h b/al-khaser/al-khaser/AntiDebug/SoftwareBreakpoints.h
new file mode 100644
index 0000000000000000000000000000000000000000..3a12214f089b3686217e7ed7c188f37be6656e6d
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/SoftwareBreakpoints.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL SoftwareBreakpoints();
diff --git a/al-khaser/al-khaser/AntiDebug/TLS_callbacks.cpp b/al-khaser/al-khaser/AntiDebug/TLS_callbacks.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..73121bfcb666d6eee0cdb914bbe0b4ebc5dd1af3
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/TLS_callbacks.cpp
@@ -0,0 +1,136 @@
+#include "pch.h"
+
+#include "TLS_callbacks.h"
+
+// The Thread Local Storage (TLS) callback is called before the execution of the EntryPoint of the application
+// Malware takes advantages to perform anti-debug and anti-vm checks.
+// There could be more than one callback, and sometimes, inside one call back, one can create one in the fly.
+
+
+volatile bool has_run = false;
+
+VOID WINAPI tls_callback(PVOID hModule, DWORD dwReason, PVOID pContext)
+{
+	if (!has_run)
+	{
+		has_run = true;
+		tls_callback_thread_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+		tls_callback_process_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+	}
+
+	if (dwReason == DLL_THREAD_ATTACH)
+	{
+		OutputDebugString(L"TLS callback: thread attach");
+		tls_callback_thread_data = 0xDEADBEEF;
+		SetEvent(tls_callback_thread_event);
+	}
+
+	if (dwReason == DLL_PROCESS_ATTACH)
+	{
+		OutputDebugString(L"TLS callback: process attach");
+		tls_callback_process_data = 0xDEADBEEF;
+		SetEvent(tls_callback_process_event);
+	}
+}
+
+DWORD WINAPI TLSCallbackDummyThread(
+	_In_ LPVOID lpParameter
+)
+{
+	OutputDebugString(L"TLS callback: dummy thread launched");
+	return 0;
+}
+
+BOOL TLSCallbackThread()
+{
+	const int BLOWN = 1000;
+
+	if (CreateThread(NULL, 0, &TLSCallbackDummyThread, NULL, 0, NULL) == NULL)
+	{
+		OutputDebugString(L"TLS callback: couldn't start dummy thread");
+	}
+
+	int fuse = 0;
+	while (tls_callback_thread_event == NULL && ++fuse != BLOWN) { SwitchToThread(); }
+	if (fuse >= BLOWN)
+	{
+		OutputDebugString(L"TLSCallbackThread timeout on event creation.");
+		return TRUE;
+	}
+
+	DWORD waitStatus = WaitForSingleObject(tls_callback_thread_event, 5000);
+	if (waitStatus != WAIT_OBJECT_0)
+	{
+		if (waitStatus == WAIT_FAILED)
+			OutputDebugString(L"TLSCallbackThread wait failed.");
+		else if (waitStatus == WAIT_ABANDONED)
+			OutputDebugString(L"TLSCallbackThread wait abandoned.");
+		else
+			OutputDebugString(L"TLSCallbackThread timeout on event wait.");
+		return TRUE;
+	}
+
+	if (tls_callback_thread_data != 0xDEADBEEF)
+		OutputDebugString(L"TLSCallbackThread data did not match.");
+	else
+		OutputDebugString(L"All seems fine for TLSCallbackThread.");
+
+	return tls_callback_thread_data == 0xDEADBEEF ? FALSE : TRUE;
+}
+
+BOOL TLSCallbackProcess()
+{
+	const int BLOWN = 1000;
+
+	int fuse = 0;
+	while (tls_callback_process_event == NULL && ++fuse != BLOWN) { SwitchToThread(); }
+	if (fuse >= BLOWN)
+	{
+		OutputDebugString(L"TLSCallbackProcess timeout on event creation.");
+		return TRUE;
+	}
+
+	DWORD waitStatus = WaitForSingleObject(tls_callback_process_event, 5000);
+	if (waitStatus != WAIT_OBJECT_0)
+	{
+		if (waitStatus == WAIT_FAILED)
+			OutputDebugString(L"TLSCallbackProcess wait failed.");
+		else if (waitStatus == WAIT_ABANDONED)
+			OutputDebugString(L"TLSCallbackProcess wait abandoned.");
+		else
+			OutputDebugString(L"TLSCallbackProcess timeout on event wait.");
+		return TRUE;
+	}
+
+	if (tls_callback_process_data != 0xDEADBEEF)
+		OutputDebugString(L"TLSCallbackProcess data did not match.");
+	else
+		OutputDebugString(L"All seems fine for TLSCallbackProcess.");
+
+	return tls_callback_process_data == 0xDEADBEEF ? FALSE : TRUE;
+}
+
+#ifdef _WIN64
+	#pragma comment (linker, "/INCLUDE:_tls_used")
+	#pragma comment (linker, "/INCLUDE:tls_callback_func")
+#else
+	#pragma comment (linker, "/INCLUDE:__tls_used")
+	#pragma comment (linker, "/INCLUDE:_tls_callback_func")
+#endif
+
+
+#ifdef _WIN64
+	#pragma const_seg(".CRT$XLF")
+	EXTERN_C const
+#else
+	#pragma data_seg(".CRT$XLF")
+	EXTERN_C
+#endif
+
+PIMAGE_TLS_CALLBACK tls_callback_func = tls_callback;
+
+#ifdef _WIN64
+	#pragma const_seg()
+#else
+	#pragma data_seg()
+#endif //_WIN64
diff --git a/al-khaser/al-khaser/AntiDebug/TLS_callbacks.h b/al-khaser/al-khaser/AntiDebug/TLS_callbacks.h
new file mode 100644
index 0000000000000000000000000000000000000000..0575d201031fa65af34553fc8e268993dca91095
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/TLS_callbacks.h
@@ -0,0 +1,10 @@
+#pragma once
+
+static volatile HANDLE tls_callback_thread_event = 0;
+static volatile HANDLE tls_callback_process_event = 0;
+static volatile UINT32 tls_callback_thread_data = 0;
+static volatile UINT32 tls_callback_process_data = 0;
+
+VOID WINAPI tls_callback(PVOID hModule, DWORD dwReason, PVOID pContext);
+BOOL TLSCallbackThread();
+BOOL TLSCallbackProcess();
diff --git a/al-khaser/al-khaser/AntiDebug/TrapFlag.cpp b/al-khaser/al-khaser/AntiDebug/TrapFlag.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6eddf650133b5ae8b701ff4114a2b5197ce6e85c
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/TrapFlag.cpp
@@ -0,0 +1,51 @@
+#include "pch.h"
+
+#include "TrapFlag.h"
+
+/*
+	This technique is similar to exceptions based debugger detections.
+	You enable the trap flag in the current process and check whether
+	an exception is raised or not. If an exception is not raised, you
+	can assume that a debugger has “swallowed” the exception for us,
+	and that the program is being traced. The beauty of this approach
+	is that it detects every debugger, user mode or kernel mode,
+	because they all use the trap flag for tracing a program.
+
+	Vectored Exception Handling is used here because SEH is an
+	anti-debug trick in itself.
+*/
+
+static BOOL SwallowedException = TRUE;
+
+static LONG CALLBACK VectoredHandler(
+	_In_ PEXCEPTION_POINTERS ExceptionInfo
+)
+{
+	SwallowedException = FALSE;
+	
+	if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
+		return EXCEPTION_CONTINUE_EXECUTION;
+		
+	return EXCEPTION_CONTINUE_SEARCH;
+}
+
+
+
+BOOL TrapFlag()
+{
+	PVOID Handle = AddVectoredExceptionHandler(1, VectoredHandler);
+	SwallowedException = TRUE;
+
+#ifdef _WIN64
+	UINT64 eflags = __readeflags();
+#else
+	UINT eflags = __readeflags();
+#endif
+
+	//  Set the trap flag
+	eflags |= 0x100;
+	__writeeflags(eflags);
+
+	RemoveVectoredExceptionHandler(Handle);
+	return SwallowedException;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/TrapFlag.h b/al-khaser/al-khaser/AntiDebug/TrapFlag.h
new file mode 100644
index 0000000000000000000000000000000000000000..d36c23aaa82f13fcaf062e719e3ff6ef349c8320
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/TrapFlag.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL TrapFlag();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/UnhandledExceptionFilter_Handler.cpp b/al-khaser/al-khaser/AntiDebug/UnhandledExceptionFilter_Handler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bbcee11a22b4e6e0df9dfc949ff4d7c8467ff600
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/UnhandledExceptionFilter_Handler.cpp
@@ -0,0 +1,27 @@
+#include "pch.h"
+#include "UnhandledExceptionFilter_Handler.h"
+
+
+/*
+When an exception occurs, and no registered Exception Handlers exist (neither Structured nor
+Vectored), or if none of the registered handlers handles the exception, then the kernel32
+UnhandledExceptionFilter() function will be called as a last resort. 
+*/
+
+BOOL bIsBeinDbg = TRUE;
+
+LONG WINAPI UnhandledExcepFilter(PEXCEPTION_POINTERS pExcepPointers)
+{
+	// If a debugger is present, then this function will not be reached.
+	bIsBeinDbg = FALSE;
+    return EXCEPTION_CONTINUE_EXECUTION;
+}
+
+
+BOOL UnhandledExcepFilterTest ()
+{
+	LPTOP_LEVEL_EXCEPTION_FILTER Top = SetUnhandledExceptionFilter(UnhandledExcepFilter);
+	RaiseException(EXCEPTION_FLT_DIVIDE_BY_ZERO, 0, 0, NULL);
+	SetUnhandledExceptionFilter(Top);
+	return bIsBeinDbg;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/UnhandledExceptionFilter_Handler.h b/al-khaser/al-khaser/AntiDebug/UnhandledExceptionFilter_Handler.h
new file mode 100644
index 0000000000000000000000000000000000000000..97a76d7aa3906816792a6e40f6e0a2e8808008c7
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/UnhandledExceptionFilter_Handler.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL UnhandledExcepFilterTest();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/WUDF_IsDebuggerPresent.cpp b/al-khaser/al-khaser/AntiDebug/WUDF_IsDebuggerPresent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3a8e24b125c7891e0a24ed99e179362fa089d3ef
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/WUDF_IsDebuggerPresent.cpp
@@ -0,0 +1,35 @@
+#include "pch.h"
+#include "WUDF_IsDebuggerPresent.h"
+
+BOOL WUDF_IsAnyDebuggerPresent()
+{
+	if (API::IsAvailable(API_IDENTIFIER::API_WudfIsAnyDebuggerPresent))
+	{
+		auto WudfIsAnyDebuggerPresent = static_cast<pWudfIsAnyDebuggerPresent>(API::GetAPI(API_IDENTIFIER::API_WudfIsAnyDebuggerPresent));
+		return WudfIsAnyDebuggerPresent() == 0 ? FALSE : TRUE;
+	}
+	else
+		return FALSE;
+}
+
+BOOL WUDF_IsKernelDebuggerPresent()
+{
+	if (API::IsAvailable(API_IDENTIFIER::API_WudfIsKernelDebuggerPresent))
+	{
+		auto WudfIsKernelDebuggerPresent = static_cast<pWudfIsKernelDebuggerPresent>(API::GetAPI(API_IDENTIFIER::API_WudfIsKernelDebuggerPresent));
+		return WudfIsKernelDebuggerPresent() == 0 ? FALSE : TRUE;
+	}
+	else
+		return FALSE;
+}
+
+BOOL WUDF_IsUserDebuggerPresent()
+{
+	if (API::IsAvailable(API_IDENTIFIER::API_WudfIsUserDebuggerPresent))
+	{
+		auto WudfIsUserDebuggerPresent = static_cast<pWudfIsKernelDebuggerPresent>(API::GetAPI(API_IDENTIFIER::API_WudfIsUserDebuggerPresent));
+		return WudfIsUserDebuggerPresent() == 0 ? FALSE : TRUE;
+	}
+	else
+		return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/WUDF_IsDebuggerPresent.h b/al-khaser/al-khaser/AntiDebug/WUDF_IsDebuggerPresent.h
new file mode 100644
index 0000000000000000000000000000000000000000..8f6e96e96ecb0e20f65a012c23886b870656ad0b
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/WUDF_IsDebuggerPresent.h
@@ -0,0 +1,3 @@
+BOOL WUDF_IsAnyDebuggerPresent();
+BOOL WUDF_IsKernelDebuggerPresent();
+BOOL WUDF_IsUserDebuggerPresent();
diff --git a/al-khaser/al-khaser/AntiDebug/WriteWatch.cpp b/al-khaser/al-khaser/AntiDebug/WriteWatch.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0a12d52d6446db82b2bc7b42c31d1a1e1766ef17
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/WriteWatch.cpp
@@ -0,0 +1,296 @@
+#include "pch.h"
+#include "WriteWatch.h"
+
+/*
+ * This check uses the MEM_WRITE_WATCH feature of VirtualAlloc to test for additional memory writes by debuggers, sandboxing, etc.
+ * There are a few ways that we can exploit this:
+ *  (1) Allocate a buffer, write it once, get the count, see if it's >1
+ *  (2) Allocate a buffer, pass it to an API where we know the buffer isn't touched (e.g. call with invalid parameter) and see if the count is >0
+ *  (3) Allocate a buffer, use it to store a result of a call we care about (e.g. IsDebuggerPresent) and see if the memory was hit exactly once
+ *  (4) Allocate an executable buffer, copy a debug check routine to it, run the check, see if any writes were performed after ours.
+ *
+ * Reference: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366887.aspx
+ * GetWriteWatch: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366573.aspx
+ * 
+ */
+
+BOOL VirtualAlloc_WriteWatch_BufferOnly()
+{
+	ULONG_PTR hitCount;
+	DWORD granularity;
+	BOOL result = FALSE;
+
+	PVOID* addresses = static_cast<PVOID*>(VirtualAlloc(NULL, 4096 * sizeof(PVOID), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
+	if (addresses == NULL) {
+		printf("VirtualAlloc failed. Last error: %u\n", GetLastError());
+		return result;
+	}
+
+	int* buffer = static_cast<int*>(VirtualAlloc(NULL, 4096 * 4096, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE));
+	if (buffer == NULL) {
+		VirtualFree(addresses, 0, MEM_RELEASE);
+		printf("VirtualAlloc failed. Last error: %u\n", GetLastError());
+		return result;
+	}
+
+	// read the buffer once
+	buffer[0] = 1234;
+	
+	hitCount = 4096;
+	if (GetWriteWatch(0, buffer, 4096, addresses, &hitCount, &granularity) != 0)
+	{
+		printf("GetWriteWatch failed. Last error: %u\n", GetLastError());
+		result = FALSE;
+	}
+	else
+	{
+		// should only have one read here
+		result = hitCount != 1;
+	}
+
+	VirtualFree(addresses, 0, MEM_RELEASE);
+	VirtualFree(buffer, 0, MEM_RELEASE);
+
+	return result;
+}
+
+BOOL VirtualAlloc_WriteWatch_APICalls()
+{
+	ULONG_PTR hitCount;
+	DWORD granularity;
+	BOOL result = FALSE, error = FALSE;
+
+	PVOID* addresses = static_cast<PVOID*>(VirtualAlloc(NULL, 4096 * sizeof(PVOID), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
+	if (addresses == NULL) {
+		printf("VirtualAlloc failed. Last error: %u\n", GetLastError());
+		return result;
+	}
+
+	int* buffer = static_cast<int*>(VirtualAlloc(NULL, 4096 * 4096, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE));
+	if (buffer == NULL) {
+		VirtualFree(addresses, 0, MEM_RELEASE);
+		printf("VirtualAlloc failed. Last error: %u\n", GetLastError());
+		return result;
+	}
+
+	// make a bunch of calls where buffer *can* be written to, but isn't actually touched due to invalid parameters.
+	// this can catch out API hooks whose return-by-parameter behaviour is different to that of regular APIs
+
+	if (GlobalGetAtomName(INVALID_ATOM, (LPTSTR)buffer, 1) != FALSE)
+	{
+		printf("GlobalGetAtomName succeeded when it should've failed... not sure what happened!\n");
+		result = FALSE;
+		error = TRUE;
+	}
+	if (GetEnvironmentVariable(L"%ThisIsAnInvalidEnvironmentVariableName?[]<>@\\;*!-{}#:/~%", (LPWSTR)buffer, 4096*4096) != FALSE)
+	{
+		printf("GetEnvironmentVariable succeeded when it should've failed... not sure what happened!\n");
+		result = FALSE;
+		error = TRUE;
+	}
+	if (GetBinaryType(L"%ThisIsAnInvalidFileName?[]<>@\\;*!-{}#:/~%", (LPDWORD)buffer) != FALSE)
+	{
+		printf("GetBinaryType succeeded when it should've failed... not sure what happened!\n");
+		result = FALSE;
+		error = TRUE;
+	}
+	if (HeapQueryInformation(0, (HEAP_INFORMATION_CLASS)69, buffer, 4096, NULL) != FALSE)
+	{
+		printf("HeapQueryInformation succeeded when it should've failed... not sure what happened!\n");
+		result = FALSE;
+		error = TRUE;
+	}
+	if (ReadProcessMemory(INVALID_HANDLE_VALUE, (LPCVOID)0x69696969, buffer, 4096, NULL) != FALSE)
+	{
+		printf("ReadProcessMemory succeeded when it should've failed... not sure what happened!\n");
+		result = FALSE;
+		error = TRUE;
+	}
+	if (GetThreadContext(INVALID_HANDLE_VALUE, (LPCONTEXT)buffer) != FALSE)
+	{
+		printf("GetThreadContext succeeded when it should've failed... not sure what happened!\n");
+		result = FALSE;
+		error = TRUE;
+	}
+	if (GetWriteWatch(0, &VirtualAlloc_WriteWatch_APICalls, 0, NULL, NULL, (PULONG)buffer) == 0)
+	{
+		printf("GetWriteWatch succeeded when it should've failed... not sure what happened!\n");
+		result = FALSE;
+		error = TRUE;
+	}
+
+	if (error == FALSE)
+	{
+		// APIs failed as they should have! :)
+
+		hitCount = 4096;
+		if (GetWriteWatch(0, buffer, 4096, addresses, &hitCount, &granularity) != 0)
+		{
+			printf("GetWriteWatch failed. Last error: %u\n", GetLastError());
+			result = FALSE;
+		}
+		else
+		{
+			// should have zero reads here because GlobalGetAtomName doesn't probe the buffer until other checks have succeeded
+			// if there's an API hook or debugger in here it'll probably try to probe the buffer, which will be caught here
+			result = hitCount != 0;
+		}
+	}
+	else
+	{
+		printf("Write watch API check skipped, ignore the result as it is inconclusive.\n");
+	}
+
+	VirtualFree(addresses, 0, MEM_RELEASE);
+	VirtualFree(buffer, 0, MEM_RELEASE);
+
+	return result;
+}
+
+BOOL VirtualAlloc_WriteWatch_IsDebuggerPresent()
+{
+	ULONG_PTR hitCount;
+	DWORD granularity;
+	BOOL result = FALSE;
+
+	PVOID* addresses = static_cast<PVOID*>(VirtualAlloc(NULL, 4096 * sizeof(PVOID), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
+	if (addresses == NULL) {
+		printf("VirtualAlloc failed. Last error: %u\n", GetLastError());
+		return result;
+	}
+
+	int* buffer = static_cast<int*>(VirtualAlloc(NULL, 4096 * 4096, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE));
+	if (buffer == NULL) {
+		VirtualFree(addresses, 0, MEM_RELEASE);
+		printf("VirtualAlloc failed. Last error: %u\n", GetLastError());
+		return result;
+	}
+
+	buffer[0] = IsDebuggerPresent();
+
+	hitCount = 4096;
+	if (GetWriteWatch(0, buffer, 4096, addresses, &hitCount, &granularity) != 0)
+	{
+		printf("GetWriteWatch failed. Last error: %u\n", GetLastError());
+		result = FALSE;
+	}
+	else
+	{
+		// should only have one write here
+		result = (hitCount != 1) | (buffer[0] == TRUE);
+	}
+
+	VirtualFree(addresses, 0, MEM_RELEASE);
+	VirtualFree(buffer, 0, MEM_RELEASE);
+
+	return result;
+}
+
+BOOL VirtualAlloc_WriteWatch_CodeWrite()
+{
+	ULONG_PTR hitCount;
+	DWORD granularity;
+	BOOL result = FALSE;
+
+	PVOID* addresses = static_cast<PVOID*>(VirtualAlloc(NULL, 4096 * sizeof(PVOID), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
+	if (addresses == NULL) {
+		printf("VirtualAlloc failed. Last error: %u\n", GetLastError());
+		return result;
+	}
+
+	byte* buffer = static_cast<byte*>(VirtualAlloc(NULL, 4096 * 4096, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_EXECUTE_READWRITE));
+	if (buffer == NULL) {
+		VirtualFree(addresses, 0, MEM_RELEASE);
+		printf("VirtualAlloc failed. Last error: %u\n", GetLastError());
+		return result;
+	}
+	
+	// construct a call to isDebuggerPresent in assembly
+	ULONG_PTR isDebuggerPresentAddr = (ULONG_PTR)&IsDebuggerPresent;
+
+#ifndef _WIN32
+#ifndef _WIN64
+#error Architecture must be WIN32 or WIN64
+#endif
+#endif
+
+
+#if _WIN64
+	/*
+	 * 64-bit
+	 *
+		0:  51                              push   rcx
+		1:  48 b9 ef cd ab 90 78 56 34 12   movabs rcx, 0x1234567890abcdef
+		b:  ff d1                           call   rcx
+		d:  59                              pop    rcx
+	    e:  c3                              ret
+	 */
+	int pos = 0;
+	buffer[pos++] = 0x51; // push rcx
+	buffer[pos++] = 0x48; // movabs rcx, ...
+	buffer[pos++] = 0xB9; // ^ ...
+	int offset = 0;
+	for (int n = 0; n < 8; n++)
+	{
+		buffer[pos++] = (isDebuggerPresentAddr >> offset) & 0xFF;
+		offset += 8;
+	}
+	buffer[pos++] = 0xFF; // call rcx
+	buffer[pos++] = 0xD1; // ^
+	buffer[pos++] = 0x59; // pop rcx
+	buffer[pos  ] = 0xC3; // ret
+
+#else
+	/*
+	 * 32-bit
+	 *
+	0:  51                      push   ecx
+	1:  b9 78 56 34 12          mov    ecx, 0x12345678
+	6:  ff d1                   call   ecx
+	8:  59                      pop    ecx
+	9:  c3                      ret
+	*/
+	int pos = 0;
+	buffer[pos++] = 0x51; // push ecx
+	buffer[pos++] = 0xB9; // mov ecx, ...
+	int offset = 0;
+	for (int n = 0; n < 4; n++)
+	{
+		buffer[pos++] = (isDebuggerPresentAddr >> offset) & 0xFF;
+		offset += 8;
+	}
+	buffer[pos++] = 0xFF; // call ecx
+	buffer[pos++] = 0xD1; // ^
+	buffer[pos++] = 0x59; // pop ecx
+	buffer[pos] = 0xC3; // ret
+
+#endif
+
+	ResetWriteWatch(buffer, 4096 * 4096);
+
+	// cool, now exec the code
+	BOOL(*foo)(VOID) = (BOOL(*)(VOID))buffer;
+	if (foo() == TRUE)
+	{
+		result = TRUE;
+	}
+	
+	if (result == FALSE)
+	{
+		hitCount = 4096;
+		if (GetWriteWatch(0, buffer, 4096, addresses, &hitCount, &granularity) != 0)
+		{
+			printf("GetWriteWatch failed. Last error: %u\n", GetLastError());
+			result = FALSE;
+		}
+		else
+		{
+			result = hitCount != 0;
+		}
+	}
+
+	VirtualFree(addresses, 0, MEM_RELEASE);
+	VirtualFree(buffer, 0, MEM_RELEASE);
+
+	return result;
+}
diff --git a/al-khaser/al-khaser/AntiDebug/WriteWatch.h b/al-khaser/al-khaser/AntiDebug/WriteWatch.h
new file mode 100644
index 0000000000000000000000000000000000000000..28f4a93cc69db5634e6002307a445927c563831d
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/WriteWatch.h
@@ -0,0 +1,6 @@
+#pragma once
+
+BOOL VirtualAlloc_WriteWatch_BufferOnly();
+BOOL VirtualAlloc_WriteWatch_APICalls();
+BOOL VirtualAlloc_WriteWatch_IsDebuggerPresent();
+BOOL VirtualAlloc_WriteWatch_CodeWrite();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDebug/int2d_x64.asm b/al-khaser/al-khaser/AntiDebug/int2d_x64.asm
new file mode 100644
index 0000000000000000000000000000000000000000..daf13773c311c382bdca4b2565d55febde0b439d
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/int2d_x64.asm
@@ -0,0 +1,10 @@
+.code 
+
+__int2d proc
+    mov rax, 0
+    int 2dh
+    nop
+    ret
+__int2d endp
+
+end
diff --git a/al-khaser/al-khaser/AntiDebug/int2d_x86.asm b/al-khaser/al-khaser/AntiDebug/int2d_x86.asm
new file mode 100644
index 0000000000000000000000000000000000000000..bed0cd0c94840c20459f985ab064ab52f72469de
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/int2d_x86.asm
@@ -0,0 +1,11 @@
+.model flat
+.code 
+
+___int2d proc
+    mov eax, 0
+    int 2dh
+    nop
+    ret
+___int2d endp
+
+end
diff --git a/al-khaser/al-khaser/AntiDebug/pch.h b/al-khaser/al-khaser/AntiDebug/pch.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7df92d774ff3829efea501cff3b5b40e5b16f4b
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDebug/pch.h
@@ -0,0 +1 @@
+#include "../pch.h"
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDisassm/AntiDisassm.cpp b/al-khaser/al-khaser/AntiDisassm/AntiDisassm.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ffd88846687a454046b63dcc4b0ced9fb736ffa6
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDisassm/AntiDisassm.cpp
@@ -0,0 +1,74 @@
+#include "pch.h"
+
+#include "AntiDisassm.h"
+
+
+extern "C" void __AsmConstantCondition();
+extern "C" void __AsmJmpSameTarget();
+extern "C" void __AsmImpossibleDisassm();
+extern "C" void __AsmFunctionPointer(DWORD);
+extern "C" void __AsmReturnPointerAbuse(DWORD64);
+#ifndef _WIN64
+extern "C" void __AsmSEHMisuse();
+#endif
+
+/*
+	This technique is composed of a single conditional jump instruction placed where the condition
+	will always be the same.
+*/
+VOID AntiDisassmConstantCondition()
+{
+	__AsmConstantCondition();
+}
+
+/*
+	The most common anti-disassembly technique seen in the wild is two back-to back
+	conditional jump instructions that both point to the same target. For example,
+	if a jz XYZ is followed by jnz XYZ, the location XYZ will always be jumped to
+*/
+VOID AntiDisassmAsmJmpSameTarget()
+{
+	__AsmJmpSameTarget();
+}
+
+
+/*
+	By using a data byte placed strategically after a conditional jump instruction
+	with the idea that disassembly starting at this byte will prevent the real instruction
+	that follows from being disassembled because the byte that inserted is the opcode for
+	a multibyte instruction.
+
+*/
+VOID AntiDisassmImpossibleDiasassm()
+{
+	__AsmImpossibleDisassm();
+}
+
+
+/*
+	If function pointers are used in handwritten assembly or crafted in a nonstandard way
+	in source code, the results can be difficult to reverse engineer without dynamic analysis.
+*/
+VOID AntiDisassmFunctionPointer()
+{
+
+	DWORD Number = 2;
+	__AsmFunctionPointer(Number);
+}
+
+
+/*
+	The most obvious result of this technique is that the disassembler doesn�t show any
+	code cross - reference to the target being jumped to.
+*/
+VOID AntiDisassmReturnPointerAbuse()
+{
+	__AsmReturnPointerAbuse(666);
+}
+
+#ifndef _WIN64
+VOID AntiDisassmSEHMisuse()
+{
+	__AsmSEHMisuse();
+}
+#endif
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDisassm/AntiDisassm.h b/al-khaser/al-khaser/AntiDisassm/AntiDisassm.h
new file mode 100644
index 0000000000000000000000000000000000000000..99f02d14bb19701ee38af87eab6417abd107e63d
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDisassm/AntiDisassm.h
@@ -0,0 +1,8 @@
+#pragma once
+
+VOID AntiDisassmConstantCondition();
+VOID AntiDisassmAsmJmpSameTarget();
+VOID AntiDisassmImpossibleDiasassm();
+VOID AntiDisassmFunctionPointer();
+VOID AntiDisassmReturnPointerAbuse();
+VOID AntiDisassmSEHMisuse();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDisassm/AntiDisassm_x64.asm b/al-khaser/al-khaser/AntiDisassm/AntiDisassm_x64.asm
new file mode 100644
index 0000000000000000000000000000000000000000..4d20ecd3fbbff0e461dcee63999bf34f707520a7
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDisassm/AntiDisassm_x64.asm
@@ -0,0 +1,75 @@
+
+.code 
+
+__AsmConstantCondition proc
+    xor rax, rax
+	jz L_END
+	db 0e8h
+L_END:
+	nop
+    ret
+__AsmConstantCondition endp
+
+
+__AsmJmpSameTarget proc
+	jz L_END
+	jnz L_END
+	db 0e8h
+L_END:
+	nop
+	ret
+__AsmJmpSameTarget endp
+
+
+__AsmImpossibleDisassm proc
+	push rax
+
+	mov ax, 05EBh	; db 066h, 0B8h, 0EBh, 005h
+	xor eax, eax	; db 033h, 0C0h
+	db 074h, 0fah
+	db 0e8h			; call
+
+	pop rax
+	ret
+__AsmImpossibleDisassm endp
+
+; a dummy function
+func2 proc
+	mov rax, r8
+	shl rax, 2
+	ret
+ func2 endp
+
+
+__AsmFunctionPointer proc
+	push rax
+	push rcx
+	push rsi
+	mov rcx, offset func2
+	mov r8, 02h
+	call rcx
+	mov rsi, rax
+	mov r8, 03h
+	call rcx
+	lea rax, [rsi+rax+1]
+	pop rsi
+	pop rcx
+	pop rax
+	ret
+__AsmFunctionPointer endp
+
+
+__AsmReturnPointerAbuse proc
+	call $+5
+	add qword ptr[rsp], 6
+	ret
+
+	push rax
+	mov rax, rcx
+	imul rax, 40h
+	pop rax
+	ret
+__AsmReturnPointerAbuse endp
+
+
+end
diff --git a/al-khaser/al-khaser/AntiDisassm/AntiDisassm_x86.asm b/al-khaser/al-khaser/AntiDisassm/AntiDisassm_x86.asm
new file mode 100644
index 0000000000000000000000000000000000000000..327f1820ac656bffe980a2d3dfd8fb8e3fdcd042
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDisassm/AntiDisassm_x86.asm
@@ -0,0 +1,111 @@
+.model flat, c
+
+.code 
+
+__AsmConstantCondition proc
+    xor eax, eax
+	jz L_END
+	db 0e8h
+L_END:
+	nop
+    ret
+__AsmConstantCondition endp
+
+
+__AsmJmpSameTarget proc
+	jz L_END
+	jnz L_END
+	db 0e8h
+L_END:
+	nop
+	ret
+__AsmJmpSameTarget endp
+
+
+__AsmImpossibleDisassm proc
+	push eax
+
+	mov ax, 05EBh	; db 066h, 0B8h, 0EBh, 005h
+	xor eax, eax	; db 033h, 0C0h
+	db 074h, 0fah
+	db 0e8h			; call
+
+	pop eax
+	ret
+__AsmImpossibleDisassm endp
+
+; a dummy function
+func2 proc arg_0:DWORD
+	 mov eax, [arg_0]
+	 shl eax, 2
+	 pop ebp
+	 retn
+ func2 endp
+
+
+__AsmFunctionPointer proc arg_0:DWORD
+
+	LOCAL var_4:DWORD
+
+	push ecx
+	push esi
+	mov [var_4], offset func2
+	push 03h
+	call [var_4]
+	add esp, 4
+	mov esi, eax
+	mov eax, [arg_0]
+	push eax
+	call [var_4]
+	add esp, 4
+	lea eax, [esi+eax+1]
+	pop esi
+	mov esp, ebp
+	pop ebp
+	retn
+__AsmFunctionPointer endp
+
+__AsmReturnPointerAbuse proc
+
+	call $+5
+	add dword ptr[esp], 5
+	retn
+
+	push eax
+	mov eax, [ebp+8]
+	imul eax, 40h
+	pop eax
+	retn
+__AsmReturnPointerAbuse endp
+
+; another dummy function
+func3 proc 
+	mov esp, [esp+8]
+	ASSUME FS:NOTHING
+	mov eax, dword ptr fs:[0]
+	ASSUME FS:ERROR
+	mov eax, [eax]
+	mov eax, [eax]
+	ASSUME FS:NOTHING
+	mov dword ptr fs:[0], eax
+	ASSUME FS:ERROR
+	add esp, 8
+	pop ebp
+	retn
+ func3 endp
+
+__AsmSEHMisuse proc
+	push ebp
+	mov eax, offset func3
+	push eax
+	ASSUME FS:NOTHING
+	push dword ptr fs:[0]
+	mov dword ptr fs:[0], esp
+	ASSUME FS:ERROR
+	xor ecx, ecx
+	div ecx
+	call func2
+	retn
+__AsmSEHMisuse endp
+
+end
diff --git a/al-khaser/al-khaser/AntiDisassm/pch.h b/al-khaser/al-khaser/AntiDisassm/pch.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7df92d774ff3829efea501cff3b5b40e5b16f4b
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDisassm/pch.h
@@ -0,0 +1 @@
+#include "../pch.h"
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDump/ErasePEHeaderFromMemory.cpp b/al-khaser/al-khaser/AntiDump/ErasePEHeaderFromMemory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bbdd1ddd586480b4a8e20da359df672508885d31
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDump/ErasePEHeaderFromMemory.cpp
@@ -0,0 +1,25 @@
+#include "pch.h"
+
+#include "ErasePEHeaderFromMemory.h"
+
+/* This function will erase the current images PE header from memory preventing a successful image if dumped */
+
+
+VOID ErasePEHeaderFromMemory()
+{
+	_tprintf(_T("[*] Erasing PE header from memory\n"));
+	DWORD OldProtect = 0;
+
+	// Get base address of module
+	char *pBaseAddr = (char*)GetModuleHandle(NULL);
+
+	// Change memory protection
+	VirtualProtect(pBaseAddr, 4096, // Assume x86 page size
+		PAGE_READWRITE, &OldProtect);
+
+	// Erase the header
+	SecureZeroMemory(pBaseAddr, 4096);
+}
+
+
+
diff --git a/al-khaser/al-khaser/AntiDump/ErasePEHeaderFromMemory.h b/al-khaser/al-khaser/AntiDump/ErasePEHeaderFromMemory.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f9af23eaca1cfa3730c126cb738c52f8eaadff4
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDump/ErasePEHeaderFromMemory.h
@@ -0,0 +1,3 @@
+#pragma once
+
+VOID ErasePEHeaderFromMemory();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDump/SizeOfImage.cpp b/al-khaser/al-khaser/AntiDump/SizeOfImage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3881b8ac029c6952ad3ca4fa33abff388d582c9b
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDump/SizeOfImage.cpp
@@ -0,0 +1,23 @@
+#include "pch.h"
+
+#include "SizeOfImage.h"
+
+// Any unreasonably large value will work say for example 0x100000 or 100,000h
+
+VOID SizeOfImage()
+{
+
+#if defined (ENV64BIT)
+	PPEB pPeb = (PPEB)__readgsqword(0x60);
+#elif defined(ENV32BIT)
+	PPEB pPeb = (PPEB)__readfsdword(0x30);
+#endif
+
+	_tprintf(_T("[*] Increasing SizeOfImage in PE Header to: 0x100000\n"));
+
+	// The following pointer hackery is because winternl.h defines incomplete PEB types
+	PLIST_ENTRY InLoadOrderModuleList = (PLIST_ENTRY)pPeb->Ldr->Reserved2[1]; // pPeb->Ldr->InLoadOrderModuleList
+	PLDR_DATA_TABLE_ENTRY tableEntry = CONTAINING_RECORD(InLoadOrderModuleList, LDR_DATA_TABLE_ENTRY, Reserved1[0] /*InLoadOrderLinks*/);
+	PULONG pEntrySizeOfImage = (PULONG)&tableEntry->Reserved3[1]; // &tableEntry->SizeOfImage
+	*pEntrySizeOfImage = (ULONG)((INT_PTR)tableEntry->DllBase + 0x100000);
+}
diff --git a/al-khaser/al-khaser/AntiDump/SizeOfImage.h b/al-khaser/al-khaser/AntiDump/SizeOfImage.h
new file mode 100644
index 0000000000000000000000000000000000000000..336bdb1ff2bcf31d82c51b0eab086afe986e7d9a
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDump/SizeOfImage.h
@@ -0,0 +1,3 @@
+#pragma once
+
+VOID SizeOfImage();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiDump/pch.h b/al-khaser/al-khaser/AntiDump/pch.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7df92d774ff3829efea501cff3b5b40e5b16f4b
--- /dev/null
+++ b/al-khaser/al-khaser/AntiDump/pch.h
@@ -0,0 +1 @@
+#include "../pch.h"
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiVM/Generic.cpp b/al-khaser/al-khaser/AntiVM/Generic.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..fb9937d4bc82097f4cd99e676ba6b56d5e0567e9
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/Generic.cpp
@@ -0,0 +1,2046 @@
+#include "pch.h"
+
+#include "Generic.h"
+
+/*
+Check if the DLL is loaded in the context of the process
+*/
+VOID loaded_dlls()
+{
+	/* Some vars */
+	HMODULE hDll;
+
+	/* Array of strings of blacklisted dlls */
+	CONST TCHAR* szDlls[] = {
+		_T("avghookx.dll"),		// AVG
+		_T("avghooka.dll"),		// AVG
+		_T("snxhk.dll"),		// Avast
+		_T("sbiedll.dll"),		// Sandboxie
+		_T("dbghelp.dll"),		// WindBG
+		_T("api_log.dll"),		// iDefense Lab
+		_T("dir_watch.dll"),	// iDefense Lab
+		_T("pstorec.dll"),		// SunBelt Sandbox
+		_T("vmcheck.dll"),		// Virtual PC
+		_T("wpespy.dll"),		// WPE Pro
+		_T("cmdvrt64.dll"),		// Comodo Container
+		_T("cmdvrt32.dll"),		// Comodo Container
+
+	};
+
+	WORD dwlength = sizeof(szDlls) / sizeof(szDlls[0]);
+	for (int i = 0; i < dwlength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking if process loaded modules contains: %s "), szDlls[i]);
+
+		/* Check if process loaded modules contains the blacklisted dll */
+		hDll = GetModuleHandle(szDlls[i]);
+		if (hDll == NULL)
+			print_results(FALSE, msg);
+		else
+			print_results(TRUE, msg);
+	}
+}
+
+/*
+Check if the file name contains any of the following strings.
+This is likely an automated malware sandbox.
+*/
+VOID known_file_names() {
+
+	/* Array of strings of filenames seen in sandboxes */
+	CONST TCHAR* szFilenames[] = {
+		_T("sample.exe"),
+		_T("bot.exe"),		
+		_T("sandbox.exe"),		
+		_T("malware.exe"),	
+		_T("test.exe"),	
+		_T("klavme.exe"),		
+		_T("myapp.exe"),
+		_T("testapp.exe"),
+
+	};
+
+#if defined (ENV64BIT)
+	PPEB pPeb = (PPEB)__readgsqword(0x60);
+
+#elif defined(ENV32BIT)
+	PPEB pPeb = (PPEB)__readfsdword(0x30);
+#endif
+
+	if (!pPeb->ProcessParameters->ImagePathName.Buffer) {
+		return;
+	}
+
+	// Get the file name from path/
+	WCHAR* szFileName = PathFindFileNameW(pPeb->ProcessParameters->ImagePathName.Buffer);
+	
+	TCHAR msg[256] = _T("");
+	WORD dwlength = sizeof(szFilenames) / sizeof(szFilenames[0]);
+	for (int i = 0; i < dwlength; i++)
+	{
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking if process file name contains: %s "), szFilenames[i]);
+
+		/* Check if file name matches any blacklisted filenames */
+		if (StrCmpIW(szFilenames[i], szFileName) != 0)
+			print_results(FALSE, msg);
+		else
+			print_results(TRUE, msg);
+	}
+
+	// Some malware do check if the file name is a known hash (like md5 or sha1)
+	PathRemoveExtensionW(szFileName);
+	_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking if process file name looks like a hash: %s "), szFileName);
+	if ( (wcslen(szFileName) == 32 || wcslen(szFileName) == 40 || wcslen(szFileName) == 64) && IsHexString(szFileName))
+		print_results(TRUE, msg);
+	else 
+		print_results(FALSE, msg);
+}
+
+static TCHAR * get_username() {
+	TCHAR *username;
+	DWORD nSize = (UNLEN + 1);
+
+	username = (TCHAR *) malloc(nSize * sizeof(TCHAR));
+	if (!username) {
+		return NULL;
+	}
+	if (0 == GetUserName(username, &nSize)) {
+		free(username);
+		return NULL;
+	}
+	return username;
+}
+
+/*
+Check for usernames associated with sandboxes
+*/
+VOID known_usernames() {
+
+	/* Array of strings of usernames seen in sandboxes */
+	CONST TCHAR* szUsernames[] = {
+		/* Checked for by Gootkit
+		 * https://www.sentinelone.com/blog/gootkit-banking-trojan-deep-dive-anti-analysis-features/ */
+		_T("CurrentUser"),
+		_T("Sandbox"),
+
+		/* Checked for by ostap
+		 * https://www.bromium.com/deobfuscating-ostap-trickbots-javascript-downloader/ */
+		_T("Emily"),
+		_T("HAPUBWS"),
+		_T("Hong Lee"),
+		_T("IT-ADMIN"),
+		_T("Johnson"), /* Lastline Sandbox */
+		_T("Miller"), /* Lastline Sandbox */
+		_T("milozs"),
+		_T("Peter Wilson"),
+		_T("timmy"),
+		_T("user"),
+
+		/* Checked for by Betabot (not including ones from above)
+		 * https://www.bromium.com/deobfuscating-ostap-trickbots-javascript-downloader/ */
+		_T("sand box"),
+		_T("malware"),
+		_T("maltest"),
+		_T("test user"),
+
+		/* Checked for by Satan (not including ones from above)
+		 * https://cofense.com/satan/ */
+		_T("virus"),
+
+		/* Checked for by Emotet (not including ones from above)
+		 * https://blog.trendmicro.com/trendlabs-security-intelligence/new-emotet-hijacks-windows-api-evades-sandbox-analysis/ */
+		_T("John Doe"), /* VirusTotal Cuckoofork Sandbox */
+	};
+	TCHAR *username;
+
+	if (NULL == (username = get_username())) {
+		return;
+	}
+
+	TCHAR msg[256];
+	WORD dwlength = sizeof(szUsernames) / sizeof(szUsernames[0]);
+	for (int i = 0; i < dwlength; i++) {
+
+		_stprintf_s(msg, sizeof(msg) / sizeof(msg[0]), _T("Checking if username matches : %s "), szUsernames[i]);
+
+		/* Do a case-insensitive search for all entries in szHostnames */
+		BOOL matched = FALSE;
+		if (0 == _tcsicmp(szUsernames[i], username)) {
+			matched = TRUE;
+		}
+
+		print_results(matched, msg);
+	}
+
+	free(username);
+}
+
+static TCHAR * get_netbios_hostname() {
+	TCHAR *hostname;
+	DWORD nSize = (MAX_COMPUTERNAME_LENGTH + 1);
+
+	hostname = (TCHAR *) malloc(nSize * sizeof(TCHAR));
+	if (!hostname) {
+		return NULL;
+	}
+	if (0 == GetComputerName(hostname, &nSize)) {
+		free(hostname);
+		return NULL;
+	}
+	return hostname;
+}
+
+static TCHAR * get_dns_hostname() {
+	TCHAR *hostname;
+	DWORD nSize = 0;
+
+	GetComputerNameEx(ComputerNameDnsHostname, NULL, &nSize);
+	hostname = (TCHAR *) malloc((nSize + 1) * sizeof(TCHAR));
+	if (!hostname) {
+		return NULL;
+	}
+	if (0 == GetComputerNameEx(ComputerNameDnsHostname, hostname, &nSize)) {
+		free(hostname);
+		return NULL;
+	}
+	return hostname;
+}
+
+/*
+Check for hostnames associated with sandboxes
+*/
+VOID known_hostnames() {
+
+	/* Array of strings of hostnames seen in sandboxes */
+	CONST TCHAR* szHostnames[] = {
+		/* Checked for by Gootkit
+		 * https://www.sentinelone.com/blog/gootkit-banking-trojan-deep-dive-anti-analysis-features/ */
+		_T("SANDBOX"),
+		_T("7SILVIA"),
+
+		/* Checked for by ostap
+		 * https://www.bromium.com/deobfuscating-ostap-trickbots-javascript-downloader/ */
+		_T("HANSPETER-PC"),
+		_T("JOHN-PC"),
+		_T("MUELLER-PC"),
+		_T("WIN7-TRAPS"),
+
+		/* Checked for by Shifu (not including ones from above)
+		 * https://www.mcafee.com/blogs/other-blogs/mcafee-labs/japanese-banking-trojan-shifu-combines-malware-tools */
+		_T("FORTINET"),
+
+		/* Checked for by Emotet (not including ones from above)
+		 * https://blog.trendmicro.com/trendlabs-security-intelligence/new-emotet-hijacks-windows-api-evades-sandbox-analysis/ */
+		_T("TEQUILABOOMBOOM"), /* VirusTotal Cuckoofork Sandbox */
+	};
+	TCHAR *NetBIOSHostName;
+	TCHAR *DNSHostName;
+
+	if (NULL == (NetBIOSHostName = get_netbios_hostname())) {
+		return;
+	}
+
+	if (NULL == (DNSHostName = get_dns_hostname())) {
+		free(NetBIOSHostName);
+		return;
+	}
+
+	TCHAR msg[256];
+	WORD dwlength = sizeof(szHostnames) / sizeof(szHostnames[0]);
+	for (int i = 0; i < dwlength; i++) {
+
+		_stprintf_s(msg, sizeof(msg) / sizeof(msg[0]), _T("Checking if hostname matches : %s "), szHostnames[i]);
+
+		/* Do a case-insensitive search for all entries in szHostnames */
+		BOOL matched = FALSE;
+		if (0 == _tcsicmp(szHostnames[i], NetBIOSHostName)) {
+			matched = TRUE;
+		}
+		else if (0 == _tcsicmp(szHostnames[i], DNSHostName)) {
+			matched = TRUE;
+		}
+
+		print_results(matched, msg);
+	}
+
+	free(NetBIOSHostName);
+	free(DNSHostName);
+}
+
+/*
+Check for a combination of environmental conditions, replicating what malware
+could/has used to detect that it's running in a sandbox. */
+VOID other_known_sandbox_environment_checks() {
+	TCHAR *NetBIOSHostName;
+	TCHAR *DNSHostName;
+	TCHAR *username;
+	BOOL matched;
+
+	if (NULL == (username = get_username())) {
+		return;
+	}
+	if (NULL == (NetBIOSHostName = get_netbios_hostname())) {
+		free(username);
+		return;
+	}
+
+	if (NULL == (DNSHostName = get_dns_hostname())) {
+		free(username);
+		free(NetBIOSHostName);
+		return;
+	}
+	/* From Emotet
+	 * https://blog.trendmicro.com/trendlabs-security-intelligence/new-emotet-hijacks-windows-api-evades-sandbox-analysis/ */
+
+	matched = FALSE;
+	if ((0 == StrCmp(username, _T("Wilber"))) &&
+		((0 == StrCmpNI(NetBIOSHostName, _T("SC"), 2)) ||
+	     (0 == StrCmpNI(NetBIOSHostName, _T("SW"), 2)))) {
+		matched = TRUE;
+	}
+	print_results(matched, (TCHAR *)_T("Checking whether username is 'Wilber' and NetBIOS name starts with 'SC' or 'SW' "));
+
+	matched = FALSE;
+	if ((0 == StrCmp(username, _T("admin"))) && (0 == StrCmp(NetBIOSHostName, _T("SystemIT")))) {
+		matched = TRUE;
+	}
+	print_results(matched, (TCHAR *)_T("Checking whether username is 'admin' and NetBIOS name is 'SystemIT' "));
+
+	matched = FALSE;
+	if ((0 == StrCmp(username, _T("admin"))) && (0 == StrCmp(DNSHostName, _T("KLONE_X64-PC")))) {
+		matched = TRUE;
+	}
+	print_results(matched, (TCHAR *) _T("Checking whether username is 'admin' and DNS hostname is 'KLONE_X64-PC' "));
+
+	matched = FALSE;
+	if ((0 == StrCmp(username, _T("John"))) &&
+		(is_FileExists((TCHAR *)_T("C:\\take_screenshot.ps1"))) &&
+		(is_FileExists((TCHAR *)_T("C:\\loaddll.exe")))) {
+		matched = TRUE;
+	}
+	print_results(matched, (TCHAR *)_T("Checking whether username is 'John' and two sandbox files exist "));
+
+	matched = FALSE;
+	if ((is_FileExists((TCHAR *)_T("C:\\email.doc"))) &&
+		(is_FileExists((TCHAR *)_T("C:\\email.htm"))) &&
+		(is_FileExists((TCHAR *)_T("C:\\123\\email.doc"))) &&
+		(is_FileExists((TCHAR *)_T("C:\\123\\email.docx")))) {
+		matched = TRUE;
+	}
+	print_results(matched, (TCHAR *)_T("Checking whether four known sandbox 'email' file paths exist "));
+
+	matched = FALSE;
+	if ((is_FileExists((TCHAR *)_T("C:\\a\\foobar.bmp"))) &&
+		(is_FileExists((TCHAR *)_T("C:\\a\\foobar.doc"))) &&
+		(is_FileExists((TCHAR *)_T("C:\\a\\foobar.gif")))) {
+		matched = TRUE;
+	}
+	print_results(matched, (TCHAR *)_T("Checking whether three known sandbox 'foobar' files exist "));
+
+	free(username);
+	free(NetBIOSHostName);
+	free(DNSHostName);
+}
+
+/*
+Detect Hybrid Analysis with mac vendor
+*/
+BOOL hybridanalysismacdetect()
+{
+	return check_mac_addr(_T("\x0A\x00\x27"));
+}
+
+/*
+Number of Processors in VM
+*/
+
+BOOL NumberOfProcessors()
+{
+#if defined (ENV64BIT)
+	PULONG ulNumberProcessors = (PULONG)(__readgsqword(0x60) + 0xB8);
+
+#elif defined(ENV32BIT)
+	PULONG ulNumberProcessors = (PULONG)(__readfsdword(0x30) + 0x64);
+
+#endif
+
+	if (*ulNumberProcessors < 2)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+
+/*
+This trick  involves looking at pointers to critical operating system tables
+that are typically relocated on a virtual machine. One such table is the
+Interrupt Descriptor Table (IDT), which tells the system where various operating
+system interrupt handlers are located in memory. On real machines, the IDT is
+located lower in memory than it is on guest (i.e., virtual) machines
+PS: Does not seem to work on newer version of VMWare Workstation (Tested on v12)
+*/
+BOOL idt_trick()
+{
+	UINT idt_base = get_idt_base();
+	if ((idt_base >> 24) == 0xff)
+		return TRUE;
+
+	else
+		return FALSE;
+}
+
+/*
+Same for Local Descriptor Table (LDT)
+*/
+BOOL ldt_trick()
+{
+	UINT ldt_base = get_ldt_base();
+
+	if (ldt_base == 0xdead0000)
+		return FALSE;
+	else
+		return TRUE; // VMWare detected	
+}
+
+
+/*
+Same for Global Descriptor Table (GDT)
+*/
+BOOL gdt_trick()
+{
+	UINT gdt_base = get_gdt_base();
+
+	if ((gdt_base >> 24) == 0xff)
+		return TRUE; // VMWare detected	
+
+	else
+		return FALSE;
+}
+
+
+/*
+The instruction STR (Store Task Register) stores the selector segment of the TR
+register (Task Register) in the specified operand (memory or other general purpose register).
+All x86 processors can manage tasks in the same way as an operating system would do it.
+That is, keeping the task state and recovering it when that task is executed again. All
+the states of a task are kept in its TSS; there is one TSS per task. How can we know which
+is the TSS associated to the execution task? Using STR instruction, due to the fact that
+the selector segment that was brought back points into the TSS of the present task.
+In all the tests that were done, the value brought back by STR from within a virtual machine
+was different to the obtained from a native system, so apparently, it can be used as a another
+mechanism of a unique instruction in assembler to detect virtual machines.
+*/
+BOOL str_trick()
+{
+	UCHAR mem[4] = { 0, 0, 0, 0 };
+
+#if defined (ENV32BIT)
+	__asm str mem;
+#endif
+
+	if ((mem[0] == 0x00) && (mem[1] == 0x40))
+		return TRUE; // VMWare detected	
+	else
+		return FALSE;
+}
+
+
+/*
+Check number of cores using WMI
+*/
+BOOL number_cores_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_Processor"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			// Iterate over our enumator
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("NumberOfCores"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+					if (V_VT(&vtProp) != VT_NULL) {
+
+						// Do our comparaison
+						if (vtProp.uintVal < 2) {
+							bFound = TRUE;
+						}
+
+						// release the current result object
+						VariantClear(&vtProp);
+					}
+				}
+
+				// release class object
+				pclsObj->Release();
+
+				// break from while
+				if (bFound)
+					break;
+			}
+
+			// Cleanup
+			pEnumerator->Release();
+			pSvc->Release();
+			pLoc->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+/*
+Filter for removable disk, CD-ROM, network drive or RAM disk
+*/
+BOOL checkDriveType(IWbemClassObject* pclsObj)
+{
+	if (!pclsObj)
+		return FALSE;
+
+	BOOL res = FALSE;
+	VARIANT vtDriveType;
+	HRESULT hResDriveType;
+
+	hResDriveType = pclsObj->Get(_T("DriveType"), 0, &vtDriveType, NULL, 0);
+	if (SUCCEEDED(hResDriveType) && V_VT(&vtDriveType) != VT_NULL)
+	{
+		if (vtDriveType.uintVal == 2 // removable disk (USB)
+			|| vtDriveType.uintVal == 4 // network drive
+			|| vtDriveType.uintVal == 5 // CD-ROM
+			|| vtDriveType.uintVal == 6 // RAM disk
+			)
+		{
+			res = TRUE;
+		}
+		VariantClear(&vtDriveType);
+	}
+	return res;
+}
+
+/*
+Check hard disk size using WMI
+*/
+BOOL disk_size_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+	UINT64 minHardDiskSize = (80ULL * (1024ULL * (1024ULL * (1024ULL))));
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_LogicalDisk"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			// Iterate over our enumator
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+				
+				// Don`t check removable disk, network drive CD-ROM and RAM disk
+				if (checkDriveType(pclsObj)) {
+					pclsObj->Release();
+					continue;
+				}
+				
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("Size"), 0, &vtProp, NULL, 0);
+				if (SUCCEEDED(hRes)) {
+					if (V_VT(&vtProp) != VT_NULL)
+					{
+						// convert disk size string to bytes
+						errno = 0;
+						unsigned long long diskSizeBytes = _tcstoui64_l(vtProp.bstrVal, NULL, 10, _get_current_locale());
+						// do the check only if we successfuly got the disk size
+						if (errno == 0)
+						{
+							// Do our comparison
+							if (diskSizeBytes < minHardDiskSize) { // Less than 80GB
+								bFound = TRUE;
+							}
+						}	
+						// release the current result object
+						VariantClear(&vtProp);
+					}
+				}
+
+				// release class object
+				pclsObj->Release();
+
+				// break from while
+				if (bFound)
+					break;
+			}
+
+			// Cleanup
+			pEnumerator->Release();
+			pSvc->Release();
+			pLoc->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+
+/*
+DeviceIoControl works with disks directly rather than partitions (GetDiskFreeSpaceEx)
+We can send IOCTL_DISK_GET_LENGTH_INFO code to get the raw byte size of the physical disk
+*/
+BOOL dizk_size_deviceiocontrol()
+{
+	HANDLE hDevice = INVALID_HANDLE_VALUE;
+	BOOL bResult = FALSE;
+	GET_LENGTH_INFORMATION size = { 0 };
+	DWORD lpBytesReturned = 0;
+	LONGLONG minHardDiskSize = (80LL * (1024LL * (1024LL * (1024LL))));
+	LARGE_INTEGER totalDiskSize;
+	totalDiskSize.QuadPart = 0LL;
+
+	// This technique requires admin priviliege starting from Windows Vista
+	if (!IsElevated() && IsWindowsVistaOrGreater())
+		return FALSE;
+
+	// This code tries to get the physical disk(s) associated with the drive that Windows is on.
+	// This is not always C:\ or PhysicalDrive0 so we need to do some work to account for multi-disk volumes.
+	// By default we fall back to PhysicalDrive0 if any of this fails.
+
+	bool defaultToDrive0 = true;
+
+	// get the Windows system directory
+	wchar_t winDirBuffer[MAX_PATH];
+	SecureZeroMemory(winDirBuffer, MAX_PATH);
+	UINT winDirLen = GetSystemWindowsDirectory(winDirBuffer, MAX_PATH);
+
+	if (winDirLen)
+	{
+		// get the drive number (0-25 for A-Z) associated with the directory
+		int driveNumber = PathGetDriveNumber(winDirBuffer);
+		if (driveNumber >= 0)
+		{
+			// convert the drive number to a root path (e.g. C:\)
+			wchar_t driveRootPathBuffer[MAX_PATH];
+			SecureZeroMemory(driveRootPathBuffer, MAX_PATH);
+
+			wnsprintf(driveRootPathBuffer, MAX_PATH, _T("\\\\.\\%C:"), _T('A') + driveNumber);
+
+			// open a handle to the volume
+			HANDLE hVolume = CreateFile(
+				driveRootPathBuffer,
+				GENERIC_READ,
+				FILE_SHARE_READ | FILE_SHARE_WRITE,
+				NULL,
+				OPEN_EXISTING,
+				FILE_FLAG_BACKUP_SEMANTICS,
+				NULL);
+
+			if (hVolume != INVALID_HANDLE_VALUE)
+			{
+				DWORD extentSize = 8192; //256 VOLUME_DISK_EXTENTS entries
+				PVOLUME_DISK_EXTENTS diskExtents = NULL;
+
+				diskExtents = static_cast<PVOLUME_DISK_EXTENTS>(LocalAlloc(LPTR, extentSize));
+				if (diskExtents) {
+
+					DWORD dummy = 0;
+					BOOL extentsIoctlOK = DeviceIoControl(hVolume, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, diskExtents, extentSize, &dummy, NULL);
+
+					if (extentsIoctlOK && diskExtents->NumberOfDiskExtents > 0)
+					{
+						// loop through disks associated with this drive
+						// we want to sum the disk
+						wchar_t physicalPathBuffer[MAX_PATH];
+
+						for (DWORD i = 0; i < diskExtents->NumberOfDiskExtents; i++)
+						{
+							if (wnsprintf(physicalPathBuffer, MAX_PATH, _T("\\\\.\\PhysicalDrive%u"), diskExtents->Extents[i].DiskNumber) > 0)
+							{
+								// open the physical disk
+								hDevice = CreateFile(
+									physicalPathBuffer,
+									GENERIC_READ,
+									FILE_SHARE_READ,
+									NULL,
+									OPEN_EXISTING,
+									0,
+									NULL);
+
+								if (hDevice != INVALID_HANDLE_VALUE)
+								{
+									// fetch the size info
+									bResult = DeviceIoControl(
+										hDevice,					// device to be queried
+										IOCTL_DISK_GET_LENGTH_INFO, // operation to perform
+										NULL, 0,					// no input buffer
+										&size, sizeof(GET_LENGTH_INFORMATION),
+										&lpBytesReturned,			// bytes returned
+										(LPOVERLAPPED)NULL);		// synchronous I/O
+
+									if (bResult)
+									{
+										// add size :)
+										totalDiskSize.QuadPart += size.Length.QuadPart;
+										// we've been successful so far, so let's say it's fine
+										defaultToDrive0 = false;
+									}
+									else
+									{
+										// failed IOCTL call
+										defaultToDrive0 = true;
+									}
+
+									CloseHandle(hDevice);
+
+									if (!bResult)
+										break;
+								}
+								else
+								{
+									// failed to open the drive
+									defaultToDrive0 = true;
+									break;
+								}
+							}
+							else
+							{
+								// failed to construct the path string for some reason
+								defaultToDrive0 = true;
+								break;
+							}
+						}
+					}
+
+					LocalFree(diskExtents);
+				}
+
+				CloseHandle(hVolume);
+			}
+		}
+	}
+
+	// for some reason we couldn't enumerate the disks associated with the system drive
+	// so we'll just check PhysicalDrive0 as a backup
+	if (defaultToDrive0)
+	{
+		hDevice = CreateFile(_T("\\\\.\\PhysicalDrive0"),
+			GENERIC_READ,               // no access to the drive
+			FILE_SHARE_READ, 			// share mode
+			NULL,						// default security attributes
+			OPEN_EXISTING,				// disposition
+			0,							// file attributes
+			NULL);						// do not copy file attributes
+
+		if (hDevice != INVALID_HANDLE_VALUE) {
+
+			if (DeviceIoControl(
+				hDevice,					// device to be queried
+				IOCTL_DISK_GET_LENGTH_INFO, // operation to perform
+				NULL, 0,					// no input buffer
+				&size, sizeof(GET_LENGTH_INFORMATION),
+				&lpBytesReturned,			// bytes returned
+				(LPOVERLAPPED)NULL))		// synchronous I/O
+			{
+				totalDiskSize.QuadPart = size.Length.QuadPart;
+			}
+			CloseHandle(hDevice);
+		}
+	}
+
+	if (totalDiskSize.QuadPart < minHardDiskSize) // 80GB
+		bResult = TRUE;
+	else
+		bResult = FALSE;
+
+	return bResult;
+}
+
+
+BOOL setupdi_diskdrive()
+{
+	HDEVINFO hDevInfo;
+	SP_DEVINFO_DATA DeviceInfoData;
+	DWORD i;
+	BOOL bFound = FALSE;
+
+	// Create a HDEVINFO with all present devices.
+	hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_DEVCLASS_DISKDRIVE,
+		0, // Enumerator
+		0,
+		DIGCF_PRESENT);
+
+	if (hDevInfo == INVALID_HANDLE_VALUE)
+		return FALSE;
+
+	// Enumerate through all devices in Set.
+	DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+
+	/* Init some vars */
+	DWORD dwPropertyRegDataType;
+	LPTSTR buffer = NULL;
+	DWORD dwSize = 0;
+
+	for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++)
+	{
+		while (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_HARDWAREID,
+			&dwPropertyRegDataType, (PBYTE)buffer, dwSize, &dwSize))
+		{
+			if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+				// Change the buffer size.
+				if (buffer)LocalFree(buffer);
+				// Double the size to avoid problems on 
+				// W2k MBCS systems per KB 888609. 
+				buffer = (LPTSTR)LocalAlloc(LPTR, dwSize * 2);
+				if (buffer == NULL)
+					break;
+			}
+			else
+				break;
+
+		}
+
+		if (buffer) {
+			// Do our comparison
+			if ((StrStrI(buffer, _T("vbox")) != NULL) ||
+				(StrStrI(buffer, _T("vmware")) != NULL) ||
+				(StrStrI(buffer, _T("qemu")) != NULL) ||
+				(StrStrI(buffer, _T("virtual")) != NULL))
+			{
+				bFound = TRUE;
+				break;
+			}
+		}
+	}
+
+	if (buffer)
+		LocalFree(buffer);
+
+	//  Cleanup
+	SetupDiDestroyDeviceInfoList(hDevInfo);
+
+	if (GetLastError() != NO_ERROR && GetLastError() != ERROR_NO_MORE_ITEMS)
+		return FALSE;
+
+	return bFound;
+}
+
+
+/*
+Check if there is any mouse movement in the sandbox.
+*/
+BOOL mouse_movement() {
+
+	POINT positionA = {};
+	POINT positionB = {};
+
+	/* Retrieve the position of the mouse cursor, in screen coordinates */
+	GetCursorPos(&positionA);
+
+	/* Wait a moment */
+	Sleep(5000);
+
+	/* Retrieve the poition gain */
+	GetCursorPos(&positionB);
+
+	if ((positionA.x == positionB.x) && (positionA.y == positionB.y))
+		/* Probably a sandbox, because mouse position did not change. */
+		return TRUE;
+
+	else
+		return FALSE;
+}
+
+
+/*
+Check for the lack of user input.
+This version is slightly different from the original:
+https://www.lastline.com/labsblog/malware-evasion-techniques/
+It does not run inside an infinite loop (preventing al-khaser to get stuck)
+*/
+BOOL lack_user_input() {
+	int correct_idle_time_counter = 0;
+	DWORD current_tick_count = 0, idle_time = 0;
+	LASTINPUTINFO last_input_info; // Contains the time of the last input
+	last_input_info.cbSize = sizeof(LASTINPUTINFO);
+
+	for (int i = 0; i < 128; ++i) {
+		Sleep(0xb);
+		// Retrieves the time of the last input event
+		if (GetLastInputInfo(&last_input_info)) {
+			current_tick_count = GetTickCount();
+			if (current_tick_count < last_input_info.dwTime)
+				// impossible case unless GetTickCount is manipulated
+				return TRUE;
+			if (current_tick_count - last_input_info.dwTime < 100) {
+				correct_idle_time_counter++;
+				if (correct_idle_time_counter >= 10)
+					return FALSE;
+			}
+		}
+		else  // GetLastInputInfo must not fail
+			return TRUE;
+	}
+	return TRUE;
+}
+
+
+/*
+Check if the machine have enough memory space, usually VM get a small ammount,
+one reason if because several VMs are running on the same servers so they can run
+more tasks at the same time.
+*/
+BOOL memory_space()
+{
+	DWORDLONG ullMinRam = (1024LL * (1024LL * (1024LL * 1LL))); // 1GB
+	MEMORYSTATUSEX statex = { 0 };
+
+	statex.dwLength = sizeof(statex);
+	GlobalMemoryStatusEx(&statex);
+
+	return (statex.ullTotalPhys < ullMinRam) ? TRUE : FALSE;
+}
+
+/*
+This trick consists of getting information about total amount of space.
+This can be used to expose a sandbox.
+*/
+BOOL disk_size_getdiskfreespace()
+{
+	ULONGLONG minHardDiskSize = (80ULL * (1024ULL * (1024ULL * (1024ULL))));
+	LPCWSTR pszDrive = NULL;
+	BOOL bStatus = FALSE;
+
+	// 64 bits integer, low and high bytes
+	ULARGE_INTEGER totalNumberOfBytes;
+
+	// If the function succeeds, the return value is nonzero. If the function fails, the return value is 0 (zero).
+	bStatus = GetDiskFreeSpaceEx(pszDrive, NULL, &totalNumberOfBytes, NULL);
+	if (bStatus) {
+		if (totalNumberOfBytes.QuadPart < minHardDiskSize)  // 80GB
+			return TRUE;
+	}
+
+	return FALSE;;
+}
+
+/*
+Sleep and check if time have been accelerated
+*/
+BOOL accelerated_sleep()
+{
+	DWORD dwStart = 0, dwEnd = 0, dwDiff = 0;
+	DWORD dwMillisecondsToSleep = 60 * 1000;
+
+	/* Retrieves the number of milliseconds that have elapsed since the system was started */
+	dwStart = GetTickCount();
+
+	/* Let's sleep 1 minute so Sandbox is interested to patch that */
+	Sleep(dwMillisecondsToSleep);
+
+	/* Do it again */
+	dwEnd = GetTickCount();
+
+	/* If the Sleep function was patched*/
+	dwDiff = dwEnd - dwStart;
+	if (dwDiff > dwMillisecondsToSleep - 1000) // substracted 1s just to be sure
+		return FALSE;
+	else
+		return TRUE;
+}
+
+/*
+The CPUID instruction is a processor supplementary instruction (its name derived from
+CPU IDentification) for the x86 architecture allowing software to discover details of
+the processor. By calling CPUID with EAX =1, The 31bit of ECX register if set will
+reveal the precense of a hypervisor.
+*/
+BOOL cpuid_is_hypervisor()
+{
+	INT CPUInfo[4] = { -1 };
+
+	/* Query hypervisor precense using CPUID (EAX=1), BIT 31 in ECX */
+	__cpuid(CPUInfo, 1);
+	if ((CPUInfo[2] >> 31) & 1)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+
+/*
+If HV presence confirmed then it is good to know which type of hypervisor we have
+When CPUID is called with EAX=0x40000000, cpuid return the hypervisor signature.
+*/
+BOOL cpuid_hypervisor_vendor()
+{
+	INT CPUInfo[4] = { -1 };
+	CHAR szHypervisorVendor[0x40];
+	WCHAR *pwszConverted;
+
+	BOOL bResult = FALSE;
+
+	const TCHAR* szBlacklistedHypervisors[] = {
+		_T("KVMKVMKVM\0\0\0"),	/* KVM */
+		_T("Microsoft Hv"),		/* Microsoft Hyper-V or Windows Virtual PC */
+		_T("VMwareVMware"),		/* VMware */
+		_T("XenVMMXenVMM"),		/* Xen */
+		_T("prl hyperv  "),		/* Parallels */
+		_T("VBoxVBoxVBox"),		/* VirtualBox */
+	};
+	WORD dwlength = sizeof(szBlacklistedHypervisors) / sizeof(szBlacklistedHypervisors[0]);
+
+	// __cpuid with an InfoType argument of 0 returns the number of
+	// valid Ids in CPUInfo[0] and the CPU identification string in
+	// the other three array elements. The CPU identification string is
+	// not in linear order. The code below arranges the information 
+	// in a human readable form.
+	__cpuid(CPUInfo, 0x40000000);
+	memset(szHypervisorVendor, 0, sizeof(szHypervisorVendor));
+	memcpy(szHypervisorVendor, CPUInfo + 1, 12);
+
+	for (int i = 0; i < dwlength; i++)
+	{
+		pwszConverted = ascii_to_wide_str(szHypervisorVendor);
+		if (pwszConverted) {
+
+			bResult = (_tcscmp(pwszConverted, szBlacklistedHypervisors[i]) == 0);
+
+			free(pwszConverted);
+
+			if (bResult)
+				return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+
+/*
+Check SerialNumber devices using WMI
+*/
+BOOL serial_number_bios_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_BIOS"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("SerialNumber"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+					if (vtProp.vt == VT_BSTR) {
+
+						// Do our comparison
+						if (
+							(StrStrI(vtProp.bstrVal, _T("VMWare")) != 0) ||
+							(wcscmp(vtProp.bstrVal, _T("0")) == 0) || // VBox (serial is just "0")
+							(StrStrI(vtProp.bstrVal, _T("Xen")) != 0) ||
+							(StrStrI(vtProp.bstrVal, _T("Virtual")) != 0) ||
+							(StrStrI(vtProp.bstrVal, _T("A M I")) != 0)
+							)
+						{
+							VariantClear(&vtProp);
+							pclsObj->Release();
+							bFound = TRUE;
+							break;
+						}
+					}
+					VariantClear(&vtProp);
+				}
+
+				// release the current result object
+				pclsObj->Release();
+			}
+
+			// Cleanup
+			pSvc->Release();
+			pLoc->Release();
+			pEnumerator->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+
+/*
+Check Model from ComputerSystem using WMI
+*/
+BOOL model_computer_system_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_ComputerSystem"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("Model"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+					if (vtProp.vt == VT_BSTR) {
+
+						// Do our comparison
+						if (
+							(StrStrI(vtProp.bstrVal, _T("VirtualBox")) != 0) ||
+							(StrStrI(vtProp.bstrVal, _T("HVM domU")) != 0) || //Xen
+							(StrStrI(vtProp.bstrVal, _T("VMWare")) != 0)
+							)
+						{
+							VariantClear(&vtProp);
+							pclsObj->Release();
+							bFound = TRUE;
+							break;
+						}
+					}
+					VariantClear(&vtProp);
+				}
+
+				// release the current result object
+				pclsObj->Release();
+			}
+
+			// Cleanup
+			pSvc->Release();
+			pLoc->Release();
+			pEnumerator->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+
+/*
+Check Manufacturer from ComputerSystem using WMI
+*/
+BOOL manufacturer_computer_system_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_ComputerSystem"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("Manufacturer"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+					if (vtProp.vt == VT_BSTR) {
+
+						// Do our comparison
+						if (
+							(StrStrI(vtProp.bstrVal, _T("VMWare")) != 0) ||
+							(StrStrI(vtProp.bstrVal, _T("Xen")) != 0) ||
+							(StrStrI(vtProp.bstrVal, _T("innotek GmbH")) != 0) || // Vbox
+							(StrStrI(vtProp.bstrVal, _T("QEMU")) != 0)
+							)
+						{
+							VariantClear(&vtProp);
+							pclsObj->Release();
+							bFound = TRUE;
+							break;
+						}
+					}
+					VariantClear(&vtProp);
+				}
+				// release the current result object
+				pclsObj->Release();
+			}
+
+			// Cleanup
+			pSvc->Release();
+			pLoc->Release();
+			pEnumerator->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+
+/*
+Check Current Temperature using WMI, this requires admin privileges
+In my tests, it works against vbox, vmware, kvm and xen.
+*/
+BOOL current_temperature_acpi_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// This technique required admin priviliege
+	if (!IsElevated())
+		return FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("root\\WMI"));
+
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM MSAcpi_ThermalZoneTemperature"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn) {
+					bFound = TRUE;
+					break;
+				}
+
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("CurrentTemperature"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+					VariantClear(&vtProp);
+					pclsObj->Release();
+					break;
+				}
+
+				// release the current result object
+				VariantClear(&vtProp);
+				pclsObj->Release();
+			}
+
+			// Cleanup
+			pSvc->Release();
+			pLoc->Release();
+			pEnumerator->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+/*
+Check ProcessId from Win32_Processor using WMI
+KVM, XEN anv VMWare seems to return something, VBOX return NULL
+*/
+BOOL process_id_processor_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_Processor"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("ProcessorId"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+
+					// Do our comparison
+					if (vtProp.bstrVal == NULL)
+					{
+						bFound = TRUE;
+					}
+				}
+				// release the current result object
+				VariantClear(&vtProp);
+				pclsObj->Release();
+
+				// break from while
+				if (bFound)
+					break;
+			}
+
+			// Cleanup
+			pSvc->Release();
+			pLoc->Release();
+			pEnumerator->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+/*
+Check what power states are enabled.
+Most VMs don't support S1-S4 power states whereas most hardware does, and thermal control is usually not found either.
+This has been tested on VirtualBox and Hyper-V, as well as a physical desktop and laptop.
+*/
+BOOL power_capabilities()
+{
+	SYSTEM_POWER_CAPABILITIES powerCaps;
+	BOOL bFound = FALSE;
+	if (GetPwrCapabilities(&powerCaps) == TRUE)
+	{
+		if ((powerCaps.SystemS1 | powerCaps.SystemS2 | powerCaps.SystemS3 | powerCaps.SystemS4) == FALSE)
+		{
+			bFound = (powerCaps.ThermalControl == FALSE);
+		}
+	}
+
+	return bFound;
+}
+
+
+/*
+According to MSDN, this query should return a class that provides statistics on the CPU fan.
+Win32/OilRig checks to see if the result of this query returned a class with more than 0 elements,
+which would most likely be true in a non-virtual environment.
+*/
+BOOL cpu_fan_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+	ULONG uObjCount = 0;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_Fan"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn) {
+					break;
+				}
+				else {
+					uObjCount++;
+					pclsObj->Release();
+				}
+			}
+
+			// Cleanup
+			pSvc->Release();
+			pLoc->Release();
+			pEnumerator->Release();
+			CoUninitialize();
+		}
+	}
+
+	if (uObjCount == 0)
+		bFound = TRUE;
+	return bFound;
+}
+
+
+/*
+Check Caption from VideoController using WMI
+*/
+BOOL caption_video_controller_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_VideoController"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("Caption"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+					if (vtProp.vt == VT_BSTR) {
+
+						// Do our comparison
+						if (
+							(StrStrI(vtProp.bstrVal, _T("Hyper-V")) != 0) ||
+							(StrStrI(vtProp.bstrVal, _T("VMWare")) != 0)
+							)
+						{
+							VariantClear(&vtProp);
+							pclsObj->Release();
+							bFound = TRUE;
+							break;
+						}
+					}
+					VariantClear(&vtProp);
+				}
+
+				// release the current result object
+				pclsObj->Release();
+			}
+
+			// Cleanup
+			pSvc->Release();
+			pLoc->Release();
+			pEnumerator->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+/*
+Detect Virtual machine by calling NtQueryLicenseValue with Kernel-VMDetection-Private as license value.
+This detection works on Windows 7 and does not detect Microsoft Hypervisor.
+*/
+BOOL query_license_value()
+{
+	auto RtlInitUnicodeString = static_cast<pRtlInitUnicodeString>(API::GetAPI(API_IDENTIFIER::API_RtlInitUnicodeString));
+	auto NtQueryLicenseValue = static_cast<pNtQueryLicenseValue>(API::GetAPI(API_IDENTIFIER::API_NtQueryLicenseValue));
+
+	if (RtlInitUnicodeString == nullptr || NtQueryLicenseValue == nullptr)
+		return FALSE;
+
+	UNICODE_STRING LicenseValue;
+	RtlInitUnicodeString(&LicenseValue, L"Kernel-VMDetection-Private");
+
+	ULONG Result = 0, ReturnLength;
+
+	NTSTATUS Status = NtQueryLicenseValue(&LicenseValue, NULL, reinterpret_cast<PVOID>(&Result), sizeof(ULONG), &ReturnLength);
+
+	if (NT_SUCCESS(Status)) {
+		return (Result != 0);
+	}
+
+	return FALSE;
+}
+
+int wmi_query_count(const _TCHAR* query)
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+
+	int count = 0;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, query);
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+
+			// Iterate over our enumator
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				count++;
+
+				pclsObj->Release();
+			}
+
+			// Cleanup
+			pEnumerator->Release();
+			pSvc->Release();
+			pLoc->Release();
+			CoUninitialize();
+		}
+		else
+		{
+			pSvc->Release();
+			pLoc->Release();
+			CoUninitialize();
+		}
+	}
+	else return -1;
+
+	return count;
+}
+
+/*
+Check Win32_CacheMemory for entries
+*/
+BOOL cachememory_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM Win32_CacheMemory"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check Win32_PhysicalMemory for entries
+*/
+BOOL physicalmemory_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM Win32_PhysicalMemory"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check Win32_MemoryDevice for entries
+*/
+BOOL memorydevice_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM Win32_MemoryDevice"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check Win32_MemoryArray for entries
+*/
+BOOL memoryarray_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM Win32_MemoryArray"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check Win32_VoltageProbe for entries
+*/
+BOOL voltageprobe_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM Win32_VoltageProbe"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check Win32_PortConnector for entries
+*/
+BOOL portconnector_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM Win32_PortConnector"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check Win32_SMBIOSMemory for entries
+*/
+BOOL smbiosmemory_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM Win32_SMBIOSMemory"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check Win32_PerfFormattedData_Counters_ThermalZoneInformation for entries
+*/
+BOOL perfctrs_thermalzoneinfo_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM Win32_PerfFormattedData_Counters_ThermalZoneInformation"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check CIM_Memory for entries
+*/
+BOOL cim_memory_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM CIM_Memory"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check CIM_NumericSensor for entries
+*/
+BOOL cim_numericsensor_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM CIM_NumericSensor"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check CIM_PhysicalConnector for entries
+*/
+BOOL cim_physicalconnector_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM CIM_PhysicalConnector"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check CIM_Sensor for entries
+*/
+BOOL cim_sensor_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM CIM_Sensor"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check CIM_Slot for entries
+*/
+BOOL cim_slot_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM CIM_Slot"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check CIM_TemperatureSensor for entries
+*/
+BOOL cim_temperaturesensor_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM CIM_TemperatureSensor"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check CIM_VoltageSensor for entries
+*/
+BOOL cim_voltagesensor_wmi()
+{
+	int count = wmi_query_count(_T("SELECT * FROM CIM_VoltageSensor"));
+	if (count == 0)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Checks whether the specified application is a genuine Windows installation.
+
+*/
+
+#define WINDOWS_SLID                                                \
+            { 0x55c92734,                                           \
+              0xd682,                                               \
+              0x4d71,                                               \
+              { 0x98, 0x3e, 0xd6, 0xec, 0x3f, 0x16, 0x05, 0x9f }    \
+            }
+
+BOOL pirated_windows()
+{
+	CONST SLID AppId = WINDOWS_SLID;
+	SL_GENUINE_STATE GenuineState;
+	HRESULT hResult;
+
+	hResult = SLIsGenuineLocal(&AppId, &GenuineState, NULL);
+
+	if (hResult == S_OK) {
+		if (GenuineState != SL_GEN_STATE_IS_GENUINE) {
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+/* Check HKLM\System\CurrentControlSet\Services\Disk\Enum for values related
+ * to virtual machines. */
+BOOL registry_services_disk_enum()
+{
+	HKEY hkResult = NULL;
+	const TCHAR* diskEnumKey = _T("System\\CurrentControlSet\\Services\\Disk\\Enum");
+	DWORD diskCount = 0;
+	DWORD cbData = sizeof(diskCount);
+	const TCHAR* szChecks[] = {
+		/* Checked for by Smokeloader
+		 * https://research.checkpoint.com/2019-resurgence-of-smokeloader/*/
+		 _T("qemu"),
+		 _T("virtio"),
+		 _T("vmware"),
+		 _T("vbox"),
+		 _T("xen"),
+
+		 /* Checked for by Kutaki (not including ones from above)
+		 * https://cofense.com/kutaki-malware-bypasses-gateways-steal-users-credentials/ */
+		_T("VMW"),
+		_T("Virtual"),
+
+	};
+	WORD dwChecksLength = sizeof(szChecks) / sizeof(szChecks[0]);
+	BOOL bFound = FALSE;
+
+	/* Each disk has a corresponding value where the value name starts at '0' for
+	 * the first disk and increases by 1 for each subsequent disk.  The 'Count'
+	 * value appears to store the total number of disk entries.*/
+
+	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, diskEnumKey, NULL, KEY_READ, &hkResult) == ERROR_SUCCESS)
+	{
+		if (RegQueryValueEx(hkResult, _T("Count"), NULL, NULL, (LPBYTE)&diskCount, &cbData) != ERROR_SUCCESS)
+		{
+			RegCloseKey(hkResult);
+			return bFound;
+		}
+		RegCloseKey(hkResult);
+	}
+
+	for (unsigned int i = 0; i < diskCount; i++) {
+		TCHAR subkey[11];
+
+		_stprintf_s(subkey, sizeof(subkey) / sizeof(subkey[0]), _T("%d"), i);
+
+		for (unsigned int j = 0; j < dwChecksLength; j++) {
+			//_tprintf(_T("Checking %s %s for %s (%d)\n"), diskEnumKey, subkey, szChecks[j], diskCount);
+			if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, diskEnumKey, subkey, szChecks[j])) {
+				bFound = TRUE;
+				break;
+			}
+		}
+		if (bFound) {
+			break;
+		}
+	}
+	return bFound;
+}
+
+BOOL registry_disk_enum()
+{
+	HKEY hkResult = NULL;
+	const TCHAR* szEntries[] = {
+		_T("System\\CurrentControlSet\\Enum\\IDE"),
+		_T("System\\CurrentControlSet\\Enum\\SCSI"),
+	};
+	const TCHAR* szChecks[] = {
+		/* Checked for by Smokeloader
+		 * https://research.checkpoint.com/2019-resurgence-of-smokeloader/*/
+		 _T("qemu"),
+		 _T("virtio"),
+		 _T("vmware"),
+		 _T("vbox"),
+		 _T("xen"),
+
+		 /* Checked for by Kutaki (not including ones from above)
+		 * https://cofense.com/kutaki-malware-bypasses-gateways-steal-users-credentials/ */
+		_T("VMW"),
+		_T("Virtual"),
+
+	};
+	WORD dwEntriesLength = sizeof(szEntries) / sizeof(szEntries[0]);
+	WORD dwChecksLength = sizeof(szChecks) / sizeof(szChecks[0]);
+	BOOL bFound = FALSE;
+
+	for (unsigned int i = 0; i < dwEntriesLength; i++) {
+		DWORD cSubKeys = 0;
+		DWORD cbMaxSubKeyLen = 0;
+		if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szEntries[i], NULL, KEY_READ, &hkResult) != ERROR_SUCCESS) {
+			continue;
+		}
+
+		if (RegQueryInfoKey(hkResult, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
+			RegCloseKey(hkResult);
+			continue;
+		}
+
+		DWORD subKeyBufferLen = (cbMaxSubKeyLen + 1) * sizeof(TCHAR);
+		TCHAR* subKeyBuffer = (TCHAR *)malloc(subKeyBufferLen);
+		if (!subKeyBuffer) {
+			RegCloseKey(hkResult);
+			continue;
+		}
+
+		for (unsigned int j = 0; j < cSubKeys; j++) {
+			DWORD cchName = subKeyBufferLen;
+			if (RegEnumKeyEx(hkResult, j, subKeyBuffer, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
+				continue;
+			}
+			for (unsigned int k = 0; k < dwChecksLength; k++) {
+				//_tprintf(_T("Checking %s %s for %s (%d)\n"), szEntries[i], subKeyBuffer, szChecks[k], cSubKeys);
+				if (StrStrI(subKeyBuffer, szChecks[k]) != NULL) {
+					bFound = TRUE;
+					break;
+				}
+			}
+			if (bFound) {
+				break;
+			}
+		}
+
+		free(subKeyBuffer);
+		RegCloseKey(hkResult);
+
+		if (bFound) {
+			break;
+		}
+	}
+	return bFound;
+}
+
+BOOL handle_one_table(BYTE* currentPosition, UINT& bias, BYTE* smBiosTableBoundary)
+{
+	struct SmbiosTableHeader
+	{
+		BYTE type;       // Table type
+		BYTE length;     // Length of the table
+		WORD handle;     // Handle of the table
+	};
+
+	SmbiosTableHeader* tableHeader = reinterpret_cast<SmbiosTableHeader*>(currentPosition);
+	SmbiosTableHeader* tableBoundary = reinterpret_cast<SmbiosTableHeader*>(smBiosTableBoundary);
+
+	const BYTE lastEntry = 127;
+	if (tableHeader->type == lastEntry) {
+		// End of tables reached
+		return TRUE;
+	}
+
+	currentPosition += tableHeader->length;
+	UINT i = 0;
+	// Find the end of the table
+	while (!(currentPosition[i] == 0 && currentPosition[i + 1] == 0)
+		&& (currentPosition + i + 1 < smBiosTableBoundary))
+	{
+		i++;
+	}
+	//pair of terminal zeros
+	i += 2;
+	bias = i + tableHeader->length;
+
+	return FALSE;
+}
+
+BOOL check_tables_number(const PBYTE smbios)
+{
+	struct RawSMBIOSData
+	{
+		BYTE    method;           // Access method(obsolete)
+		BYTE    mjVer;            // Major part of the SMB version(major)
+		BYTE    mnVer;            // Minor part of the SMB version(minor)
+		BYTE    dmiRev;           // DMI version(obsolete)
+		DWORD   length;           // Data table size
+		BYTE    tableData[];      // Table data
+	};
+
+	RawSMBIOSData* smBiosData = reinterpret_cast<RawSMBIOSData*>(smbios);
+	BYTE* smBiosTableBoundary = smBiosData->tableData + smBiosData->length;
+	BYTE* currentPosition = smBiosData->tableData;
+	UINT tableNumber = 0;
+
+	while (currentPosition < smBiosTableBoundary) {
+		UINT biasNewTable = 0;
+		tableNumber++;
+		if (handle_one_table(currentPosition, biasNewTable, smBiosTableBoundary))
+		{
+			break;
+		}
+		currentPosition += biasNewTable;
+	}
+
+	const UINT tableMinReal = 40;
+	if (tableNumber <= tableMinReal)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+Check for SMBIOS tables number
+*/
+BOOL number_SMBIOS_tables()
+{
+	BOOL result = FALSE;
+
+	DWORD smbiosSize = 0;
+	PBYTE smbios = get_system_firmware(static_cast<DWORD>('RSMB'), 0x0000, &smbiosSize);
+	if (smbios != NULL)
+	{
+		result = check_tables_number(smbios);
+		free(smbios);
+	}
+	return result;
+}
diff --git a/al-khaser/al-khaser/AntiVM/Generic.h b/al-khaser/al-khaser/AntiVM/Generic.h
new file mode 100755
index 0000000000000000000000000000000000000000..3d9c4d946f44c98f2610132c587f6e61b23726fb
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/Generic.h
@@ -0,0 +1,52 @@
+#pragma once
+
+VOID loaded_dlls();
+VOID known_file_names();
+VOID known_usernames();
+VOID known_hostnames();
+VOID other_known_sandbox_environment_checks();
+BOOL NumberOfProcessors();
+BOOL idt_trick();
+BOOL ldt_trick();
+BOOL gdt_trick();
+BOOL str_trick();
+BOOL number_cores_wmi();
+BOOL disk_size_wmi();
+BOOL setupdi_diskdrive();
+BOOL mouse_movement();
+BOOL lack_user_input();
+BOOL memory_space();
+BOOL dizk_size_deviceiocontrol();
+BOOL disk_size_getdiskfreespace();
+BOOL accelerated_sleep();
+BOOL cpuid_is_hypervisor();
+BOOL cpuid_hypervisor_vendor();
+BOOL serial_number_bios_wmi();
+BOOL model_computer_system_wmi();
+BOOL manufacturer_computer_system_wmi();
+BOOL current_temperature_acpi_wmi();
+BOOL process_id_processor_wmi();
+BOOL power_capabilities();
+BOOL hybridanalysismacdetect();
+BOOL cpu_fan_wmi();
+BOOL caption_video_controller_wmi();
+BOOL query_license_value();
+BOOL cachememory_wmi();
+BOOL physicalmemory_wmi();
+BOOL memorydevice_wmi();
+BOOL memoryarray_wmi();
+BOOL voltageprobe_wmi();
+BOOL portconnector_wmi();
+BOOL smbiosmemory_wmi();
+BOOL perfctrs_thermalzoneinfo_wmi();
+BOOL cim_memory_wmi();
+BOOL cim_numericsensor_wmi();
+BOOL cim_physicalconnector_wmi();
+BOOL cim_sensor_wmi();
+BOOL cim_slot_wmi();
+BOOL cim_temperaturesensor_wmi();
+BOOL cim_voltagesensor_wmi();
+BOOL pirated_windows();
+BOOL registry_services_disk_enum();
+BOOL registry_disk_enum();
+BOOL number_SMBIOS_tables();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiVM/HyperV.cpp b/al-khaser/al-khaser/AntiVM/HyperV.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..be1b7e34b374fec1f4a1b99676a762d541acc692
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/HyperV.cpp
@@ -0,0 +1,70 @@
+#include "pch.h"
+#include "HyperV.h"
+
+
+BOOL check_hyperv_driver_objects()
+{
+	auto driverList = enumerate_object_directory(L"\\Driver");
+	if (driverList == nullptr)
+	{
+		return FALSE;
+	}
+	for (wchar_t* driver : *driverList)
+	{
+		if (StrCmpCW(driver, L"VMBusHID") == 0)
+		{
+			return TRUE;
+		}
+		if (StrCmpCW(driver, L"vmbus") == 0)
+		{
+			return TRUE;
+		}
+		if (StrCmpCW(driver, L"vmgid") == 0)
+		{
+			return TRUE;
+		}
+		if (StrCmpCW(driver, L"IndirectKmd") == 0)
+		{
+			return TRUE;
+		}
+		if (StrCmpCW(driver, L"HyperVideo") == 0)
+		{
+			return TRUE;
+		}
+		if (StrCmpCW(driver, L"hyperkbd") == 0)
+		{
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+
+BOOL check_hyperv_global_objects()
+{
+	auto globalObjs = enumerate_object_directory(L"\\GLOBAL??");
+	if (globalObjs == nullptr)
+	{
+		return FALSE;
+	}
+	for (wchar_t* globalObj : *globalObjs)
+	{
+		if (StrStrW(globalObj, L"VMBUS#") != NULL)
+		{
+			return TRUE;
+		}
+		if (StrCmpCW(globalObj, L"VDRVROOT") == 0)
+		{
+			return TRUE;
+		}
+		if (StrCmpCW(globalObj, L"VmGenerationCounter") == 0)
+		{
+			return TRUE;
+		}
+		if (StrCmpCW(globalObj, L"VmGid") == 0)
+		{
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiVM/HyperV.h b/al-khaser/al-khaser/AntiVM/HyperV.h
new file mode 100644
index 0000000000000000000000000000000000000000..d099a7075f1f3ad4201de82273906b9ecaa30827
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/HyperV.h
@@ -0,0 +1,4 @@
+#pragma once
+
+BOOL check_hyperv_driver_objects();
+BOOL check_hyperv_global_objects();
diff --git a/al-khaser/al-khaser/AntiVM/KVM.cpp b/al-khaser/al-khaser/AntiVM/KVM.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4ecae99b45b8e98c31c4a845ee0518711ba7e858
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/KVM.cpp
@@ -0,0 +1,99 @@
+#include "pch.h"
+
+
+/*
+Check against kvm registry keys
+*/
+VOID kvm_reg_keys()
+{
+	/* Array of strings of blacklisted registry keys */
+	const TCHAR* szKeys[] = {
+		_T("SYSTEM\\ControlSet001\\Services\\vioscsi"),
+		_T("SYSTEM\\ControlSet001\\Services\\viostor"),
+		_T("SYSTEM\\ControlSet001\\Services\\VirtIO-FS Service"),
+		_T("SYSTEM\\ControlSet001\\Services\\VirtioSerial"),
+		_T("SYSTEM\\ControlSet001\\Services\\BALLOON"),
+		_T("SYSTEM\\ControlSet001\\Services\\BalloonService"),
+		_T("SYSTEM\\ControlSet001\\Services\\netkvm"),
+	};
+
+	WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]);
+
+	/* Check one by one */
+	for (int i = 0; i < dwlength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]);
+		if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+/*
+Check against kvm blacklisted files
+*/
+VOID kvm_files()
+{
+	/* Array of strings of blacklisted paths */
+	const TCHAR* szPaths[] = {
+		_T("System32\\drivers\\balloon.sys"), 
+		_T("System32\\drivers\\netkvm.sys"),
+		_T("System32\\drivers\\pvpanic.sys"),
+		_T("System32\\drivers\\viofs.sys"),
+		_T("System32\\drivers\\viogpudo.sys"),
+		_T("System32\\drivers\\vioinput.sys"),
+		_T("System32\\drivers\\viorng.sys"),
+		_T("System32\\drivers\\vioscsi.sys"),
+		_T("System32\\drivers\\vioser.sys"),
+		_T("System32\\drivers\\viostor.sys"),
+	
+	};
+
+	/* Getting Windows Directory */
+	WORD dwlength = sizeof(szPaths) / sizeof(szPaths[0]);
+	TCHAR szWinDir[MAX_PATH] = _T("");
+	TCHAR szPath[MAX_PATH] = _T("");
+	PVOID OldValue = NULL;
+
+	GetWindowsDirectory(szWinDir, MAX_PATH);
+
+	if (IsWoW64()) {
+		Wow64DisableWow64FsRedirection(&OldValue);
+	}
+
+	/* Check one by one */
+	for (int i = 0; i < dwlength; i++)
+	{
+		PathCombine(szPath, szWinDir, szPaths[i]);
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking file %s "), szPath);
+		if (is_FileExists(szPath))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+
+	if (IsWoW64()) {
+		Wow64RevertWow64FsRedirection(&OldValue);
+	}
+}
+
+/*
+Check against kvm blacklisted directories
+*/
+BOOL kvm_dir()
+{
+	TCHAR szProgramFile[MAX_PATH];
+	TCHAR szPath[MAX_PATH] = _T("");
+	TCHAR szTarget[MAX_PATH] = _T("Virtio-Win\\");
+
+	if (IsWoW64())
+		ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile));
+	else
+		SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE);
+
+	PathCombine(szPath, szProgramFile, szTarget);
+	return is_DirectoryExists(szPath);
+}
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiVM/KVM.h b/al-khaser/al-khaser/AntiVM/KVM.h
new file mode 100644
index 0000000000000000000000000000000000000000..b92b0dadd7ef509f72f13acc9c7c05bbdbec66d9
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/KVM.h
@@ -0,0 +1,5 @@
+#pragma once
+
+VOID kvm_reg_keys();
+VOID kvm_files();
+BOOL kvm_dir();
diff --git a/al-khaser/al-khaser/AntiVM/Parallels.cpp b/al-khaser/al-khaser/AntiVM/Parallels.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9b14b554478a9280c7a51627946733d75d1233e5
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/Parallels.cpp
@@ -0,0 +1,36 @@
+#include "pch.h"
+
+#include "Parallels.h"
+
+/*
+Check for process list
+*/
+
+VOID parallels_process()
+{
+	const TCHAR *szProcesses[] = {
+		_T("prl_cc.exe"),
+		_T("prl_tools.exe"),
+	};
+
+	WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]);
+	for (int i = 0; i < iLength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking Parallels processes: %s"), szProcesses[i]);
+		if (GetProcessIdFromName(szProcesses[i]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+/*
+Check Parallels NIC MAC address
+*/
+BOOL parallels_check_mac()
+{
+	// Parallels, Inc. 
+	return check_mac_addr(_T("\x00\x1C\x42"));
+}
diff --git a/al-khaser/al-khaser/AntiVM/Parallels.h b/al-khaser/al-khaser/AntiVM/Parallels.h
new file mode 100644
index 0000000000000000000000000000000000000000..34036c15177463c5339a1872def0edea6415dae3
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/Parallels.h
@@ -0,0 +1,4 @@
+#pragma once
+
+VOID parallels_process();
+BOOL parallels_check_mac();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiVM/Qemu.cpp b/al-khaser/al-khaser/AntiVM/Qemu.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..143d3921fe491752e4a89b4a6cf758982c6a7987
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/Qemu.cpp
@@ -0,0 +1,167 @@
+#include "pch.h"
+
+#include "Qemu.h"
+
+/*
+Registry key values
+*/
+
+VOID qemu_reg_key_value()
+{
+	/* Array of strings of blacklisted registry key values */
+	const TCHAR *szEntries[][3] = {
+		{ _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("QEMU") },
+		{ _T("HARDWARE\\Description\\System"), _T("SystemBiosVersion"), _T("QEMU") },
+	};
+
+	WORD dwLength = sizeof(szEntries) / sizeof(szEntries[0]);
+
+	for (int i = 0; i < dwLength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szEntries[i][0]);
+		if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, szEntries[i][0], szEntries[i][1], szEntries[i][2]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+
+/*
+Check for process list
+*/
+
+VOID qemu_processes()
+{
+	const TCHAR *szProcesses[] = {
+		_T("qemu-ga.exe"),		// QEMU guest agent.
+		_T("vdagent.exe"),		// SPICE guest tools.
+		_T("vdservice.exe"),	// SPICE guest tools.
+	};
+
+	WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]);
+	for (int i = 0; i < iLength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking qemu processes %s "), szProcesses[i]);
+		if (GetProcessIdFromName(szProcesses[i]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+/*
+Check against blacklisted directories.
+*/
+VOID qemu_dir()
+{
+	TCHAR szProgramFile[MAX_PATH];
+	TCHAR szPath[MAX_PATH] = _T("");
+
+	const TCHAR* szDirectories[] = {
+	_T("qemu-ga"),	// QEMU guest agent.
+	_T("SPICE Guest Tools"), // SPICE guest tools.
+	};
+
+	WORD iLength = sizeof(szDirectories) / sizeof(szDirectories[0]);
+	for (int i = 0; i < iLength; i++)
+	{
+		TCHAR msg[256] = _T("");
+
+		if (IsWoW64())
+			ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile));
+		else
+			SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE);
+
+		PathCombine(szPath, szProgramFile, szDirectories[i]);
+
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking QEMU directory %s "), szPath);
+		if (is_DirectoryExists(szPath))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+/*
+Check for SMBIOS firmware 
+*/
+BOOL qemu_firmware_SMBIOS()
+{
+	BOOL result = FALSE;
+
+	DWORD smbiosSize = 0;
+	PBYTE smbios = get_system_firmware(static_cast<DWORD>('RSMB'), 0x0000, &smbiosSize);
+	if (smbios != NULL)
+	{
+		PBYTE qemuString1 = (PBYTE)"qemu";
+		size_t StringLen = 4;
+		PBYTE qemuString2 = (PBYTE)"QEMU";
+
+		if (find_str_in_data(qemuString1, StringLen, smbios, smbiosSize) ||
+			find_str_in_data(qemuString2, StringLen, smbios, smbiosSize))
+		{
+			result = TRUE;
+		}
+
+		free(smbios);
+	}
+
+	return result;
+}
+
+
+/*
+Check for ACPI firmware
+*/
+BOOL qemu_firmware_ACPI()
+{
+	BOOL result = FALSE;
+
+	PDWORD tableNames = static_cast<PDWORD>(malloc(4096));
+	
+	if (tableNames) {
+		SecureZeroMemory(tableNames, 4096);
+		DWORD tableSize = enum_system_firmware_tables(static_cast<DWORD>('ACPI'), tableNames, 4096);
+
+		// API not available
+		if (tableSize == -1)
+			return FALSE;
+
+		DWORD tableCount = tableSize / 4;
+		if (tableSize < 4 || tableCount == 0)
+		{
+			result = TRUE;
+		}
+		else
+		{
+			for (DWORD i = 0; i < tableCount; i++)
+			{
+				DWORD tableSize = 0;
+				PBYTE table = get_system_firmware(static_cast<DWORD>('ACPI'), tableNames[i], &tableSize);
+
+				if (table) {
+
+					PBYTE qemuString1 = (PBYTE)"BOCHS";
+					size_t StringLen = 4;
+					PBYTE qemuString2 = (PBYTE)"BXPC";
+
+					if (find_str_in_data(qemuString1, StringLen, table, tableSize) ||
+						find_str_in_data(qemuString2, StringLen, table, tableSize))
+					{
+						result = TRUE;
+					}
+
+					free(table);
+				}
+			}
+		}
+
+		free(tableNames);
+	}
+	return result;
+}
diff --git a/al-khaser/al-khaser/AntiVM/Qemu.h b/al-khaser/al-khaser/AntiVM/Qemu.h
new file mode 100644
index 0000000000000000000000000000000000000000..6a632ddca3656f32c6671cfcd809292b63884ae3
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/Qemu.h
@@ -0,0 +1,7 @@
+#pragma once
+
+VOID qemu_reg_key_value();
+VOID qemu_processes();
+VOID qemu_dir();
+BOOL qemu_firmware_ACPI();
+BOOL qemu_firmware_SMBIOS();
diff --git a/al-khaser/al-khaser/AntiVM/Services.cpp b/al-khaser/al-khaser/AntiVM/Services.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..33686e80251fe51aaa59a679e60b2e20bc4aa451
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/Services.cpp
@@ -0,0 +1,117 @@
+#include "pch.h"
+
+#include "Services.h"
+
+BOOL VMDriverServices()
+{
+	const int KnownServiceCount = 13;
+	const TCHAR* KnownVMServices[KnownServiceCount] = {
+		L"VBoxWddm",
+		L"VBoxSF", //VirtualBox Shared Folders
+		L"VBoxMouse", //VirtualBox Guest Mouse
+		L"VBoxGuest", //VirtualBox Guest Driver
+		L"vmci", //VMWare VMCI Bus Driver
+		L"vmhgfs", //VMWare Host Guest Control Redirector
+		L"vmmouse",
+		L"vmmemctl", //VMWare Guest Memory Controller Driver
+		L"vmusb",
+		L"vmusbmouse",
+		L"vmx_svga",
+		L"vmxnet",
+		L"vmx86"
+	};
+
+	SC_HANDLE hSCM = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
+	if (hSCM != NULL)
+	{
+		ENUM_SERVICE_STATUS_PROCESS* services = NULL;
+		DWORD serviceCount = 0;
+		if (get_services(hSCM, SERVICE_DRIVER, &services, &serviceCount))
+		{
+			bool ok = true;
+
+			for (DWORD i = 0; i < serviceCount; i++)
+			{
+				for (int s = 0; s < KnownServiceCount; s++)
+				{
+					if (StrCmpIW(services[i].lpServiceName, KnownVMServices[s]) == 0)
+					{
+						ok = false;
+						break;
+					}
+				}
+			}
+
+			free(services);
+
+			if (ok)
+			{
+				CloseServiceHandle(hSCM);
+				return FALSE;
+			}
+			
+		}
+		else
+		{
+			printf("Failed to get services list.\n");
+		}
+		CloseServiceHandle(hSCM);
+	}
+	else
+	{
+		printf("Failed to get SCM handle.\n");
+	}
+
+	return TRUE;
+}
+
+BOOL get_services(_In_ SC_HANDLE hServiceManager, _In_ DWORD serviceType, _Out_ ENUM_SERVICE_STATUS_PROCESS** servicesBuffer, _Out_ DWORD* serviceCount)
+{
+	DWORD serviceBufferSize = 1024 * sizeof(ENUM_SERVICE_STATUS_PROCESS);
+	ENUM_SERVICE_STATUS_PROCESS* services = static_cast<ENUM_SERVICE_STATUS_PROCESS*>(malloc(serviceBufferSize));
+
+	if (serviceCount) //assume failure
+		*serviceCount = 0;
+
+	if (services) {
+
+		SecureZeroMemory(services, serviceBufferSize);
+
+		DWORD remainderBufferSize = 0;
+		DWORD resumeHandle = 0;
+		if (EnumServicesStatusEx(hServiceManager, SC_ENUM_PROCESS_INFO, serviceType, SERVICE_STATE_ALL, (LPBYTE)services, serviceBufferSize, &remainderBufferSize, serviceCount, &resumeHandle, NULL) != 0)
+		{
+			// success and we enumerated all the services
+			*servicesBuffer = services;
+			return TRUE;
+		}
+
+		DWORD lastError = GetLastError();
+		if (lastError == ERROR_MORE_DATA)
+		{
+			// we didn't get all the services, so we'll just re-enumerate all to make things easy
+			serviceBufferSize += remainderBufferSize;
+
+			ENUM_SERVICE_STATUS_PROCESS* tmp;
+
+			tmp = static_cast<ENUM_SERVICE_STATUS_PROCESS*>(realloc(services, serviceBufferSize));
+			if (tmp) {
+				services = tmp;
+				SecureZeroMemory(services, serviceBufferSize);
+				if (EnumServicesStatusEx(hServiceManager, SC_ENUM_PROCESS_INFO, serviceType, SERVICE_STATE_ALL, (LPBYTE)services, serviceBufferSize, &remainderBufferSize, serviceCount, NULL, NULL) != 0)
+				{
+					*servicesBuffer = services;
+					return TRUE;
+				}
+			}
+		}
+		else
+		{
+			printf("ERROR: %u\n", lastError);
+		}
+		
+		free(services);
+
+	}
+	return FALSE;
+}
diff --git a/al-khaser/al-khaser/AntiVM/Services.h b/al-khaser/al-khaser/AntiVM/Services.h
new file mode 100644
index 0000000000000000000000000000000000000000..d3f42255341dac4b09a3859f6fe4b7b33369561f
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/Services.h
@@ -0,0 +1,4 @@
+#pragma once
+
+BOOL VMDriverServices();
+BOOL get_services(_In_ SC_HANDLE hServiceManager, _In_ DWORD serviceType, _Out_ ENUM_SERVICE_STATUS_PROCESS** servicesBuffer, _Out_ DWORD* serviceCount);
diff --git a/al-khaser/al-khaser/AntiVM/VMWare.cpp b/al-khaser/al-khaser/AntiVM/VMWare.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e7c3e2b637fa7bdd6f9fce8a9e049b0615b8cd21
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/VMWare.cpp
@@ -0,0 +1,297 @@
+#include "pch.h"
+
+#include "VMWare.h"
+
+/*
+Check against VMWare registry key values
+*/
+VOID vmware_reg_key_value()
+{
+	/* Array of strings of blacklisted registry key values */
+	const TCHAR *szEntries[][3] = {
+		{ _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("VMWARE") },
+		{ _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("VMWARE") },
+		{ _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 2\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("VMWARE") },
+		{ _T("SYSTEM\\ControlSet001\\Control\\SystemInformation"), _T("SystemManufacturer"), _T("VMWARE") },
+		{ _T("SYSTEM\\ControlSet001\\Control\\SystemInformation"), _T("SystemProductName"), _T("VMWARE") },
+	};
+
+	WORD dwLength = sizeof(szEntries) / sizeof(szEntries[0]);
+
+	for (int i = 0; i < dwLength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s"), szEntries[i][0]);
+		if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, szEntries[i][0], szEntries[i][1], szEntries[i][2]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+
+/*
+Check against VMWare registry keys
+*/
+VOID vmware_reg_keys()
+{
+	/* Array of strings of blacklisted registry keys */
+	const TCHAR* szKeys[] = {
+		_T("SOFTWARE\\VMware, Inc.\\VMware Tools"),
+	};
+
+	WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]);
+
+	/* Check one by one */
+	for (int i = 0; i < dwlength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]);
+		if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+/*
+Check against VMWare blacklisted files
+*/
+VOID vmware_files()
+{
+	/* Array of strings of blacklisted paths */
+	const TCHAR* szPaths[] = {
+		_T("System32\\drivers\\vmnet.sys"),
+		_T("System32\\drivers\\vmmouse.sys"),
+		_T("System32\\drivers\\vmusb.sys"),
+		_T("System32\\drivers\\vm3dmp.sys"),
+		_T("System32\\drivers\\vmci.sys"),
+		_T("System32\\drivers\\vmhgfs.sys"),
+		_T("System32\\drivers\\vmmemctl.sys"),
+		_T("System32\\drivers\\vmx86.sys"),
+		_T("System32\\drivers\\vmrawdsk.sys"),
+		_T("System32\\drivers\\vmusbmouse.sys"),
+		_T("System32\\drivers\\vmkdb.sys"),
+		_T("System32\\drivers\\vmnetuserif.sys"),
+		_T("System32\\drivers\\vmnetadapter.sys"),
+	};
+
+	/* Getting Windows Directory */
+	WORD dwlength = sizeof(szPaths) / sizeof(szPaths[0]);
+	TCHAR szWinDir[MAX_PATH] = _T("");
+	TCHAR szPath[MAX_PATH] = _T("");
+	PVOID OldValue = NULL;
+
+	GetWindowsDirectory(szWinDir, MAX_PATH);
+
+	if (IsWoW64()) {
+		Wow64DisableWow64FsRedirection(&OldValue);
+	}
+	
+	/* Check one by one */
+	for (int i = 0; i < dwlength; i++)
+	{
+		PathCombine(szPath, szWinDir, szPaths[i]);
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking file %s "), szPath);
+		if (is_FileExists(szPath))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+
+	if (IsWoW64()) {
+		Wow64RevertWow64FsRedirection(&OldValue);
+	}
+	
+}
+
+/*
+Check against VMWare blacklisted directories
+*/
+BOOL vmware_dir()
+{
+	TCHAR szProgramFile[MAX_PATH];
+	TCHAR szPath[MAX_PATH] = _T("");
+	TCHAR szTarget[MAX_PATH] = _T("VMWare\\");
+
+	if (IsWoW64())
+		ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile));
+	else
+		SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE);
+
+	PathCombine(szPath, szProgramFile, szTarget);
+	return is_DirectoryExists(szPath);
+}
+
+
+/*
+Check VMWare NIC MAC addresses
+*/
+VOID vmware_mac()
+{
+	/* VMWre blacklisted mac adr */
+	const TCHAR *szMac[][2] = {
+		{ _T("\x00\x05\x69"), _T("00:05:69") }, // VMWare, Inc.
+		{ _T("\x00\x0C\x29"), _T("00:0c:29") }, // VMWare, Inc.
+		{ _T("\x00\x1C\x14"), _T("00:1C:14") }, // VMWare, Inc.
+		{ _T("\x00\x50\x56"), _T("00:50:56") },	// VMWare, Inc.
+	};
+
+	WORD dwLength = sizeof(szMac) / sizeof(szMac[0]);
+
+	/* Check one by one */
+	for (int i = 0; i < dwLength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking MAC starting with %s"), szMac[i][1]);
+		if (check_mac_addr(szMac[i][0]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+/*
+Check against VMWare adapter name
+*/
+BOOL vmware_adapter_name()
+{
+	const TCHAR* szAdapterName = _T("VMWare");
+	if (check_adapter_name(szAdapterName))
+		return TRUE;
+	else
+		return FALSE;
+}
+
+
+/*
+Check against VMWare pseaudo-devices
+*/
+VOID vmware_devices()
+{
+	const TCHAR *devices[] = {
+		_T("\\\\.\\HGFS"),
+		_T("\\\\.\\vmci"),
+	};
+
+	WORD iLength = sizeof(devices) / sizeof(devices[0]);
+	for (int i = 0; i < iLength; i++)
+	{
+		HANDLE hFile = CreateFile(devices[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking device %s "), devices[i]);
+		
+		if (hFile != INVALID_HANDLE_VALUE) {
+			CloseHandle(hFile);
+			print_results(TRUE, msg);
+		}
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+/*
+Check for process list
+*/
+
+VOID vmware_processes()
+{
+	const TCHAR *szProcesses[] = {
+		_T("vmtoolsd.exe"),
+		_T("vmwaretray.exe"),
+		_T("vmwareuser.exe"),
+		_T("VGAuthService.exe"),
+		_T("vmacthlp.exe"),
+	};
+
+	WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]);
+	for (int i = 0; i < iLength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking VWware process %s "), szProcesses[i]);
+		if (GetProcessIdFromName(szProcesses[i]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+/*
+Check for SMBIOS firmware
+*/
+BOOL vmware_firmware_SMBIOS()
+{
+	BOOL result = FALSE;
+	const DWORD Signature = static_cast<DWORD>('RSMB');
+
+	DWORD smbiosSize = 0;
+	PBYTE smbios = get_system_firmware(static_cast<DWORD>('RSMB'), 0x0000, &smbiosSize);
+	if (smbios != NULL)
+	{
+		PBYTE vmwareString = (PBYTE)"VMware";
+		size_t vmwwareStringLen = 6;
+
+		if (find_str_in_data(vmwareString, vmwwareStringLen, smbios, smbiosSize))
+		{
+			result = TRUE;
+		}
+
+		free(smbios);
+	}
+
+	return result;
+}
+
+/*
+Check for ACPI firmware
+*/
+BOOL vmware_firmware_ACPI()
+{
+	BOOL result = FALSE;
+
+	PDWORD tableNames = static_cast<PDWORD>(malloc(4096));
+
+	if (tableNames == NULL)
+		return FALSE;
+
+	SecureZeroMemory(tableNames, 4096);
+	DWORD tableSize = enum_system_firmware_tables(static_cast<DWORD>('ACPI'), tableNames, 4096);
+
+	// API not available
+	if (tableSize == -1)
+		return FALSE;
+
+	DWORD tableCount = tableSize / 4;
+	if (tableSize < 4 || tableCount == 0)
+	{
+		result = TRUE;
+	}
+	else
+	{
+		for (DWORD i = 0; i < tableCount; i++) {
+			DWORD tableSize = 0;
+			PBYTE table = get_system_firmware(static_cast<DWORD>('ACPI'), tableNames[i], &tableSize);
+
+			if (table) {
+
+				PBYTE vmwareString = (PBYTE)"VMWARE";
+				size_t vmwwareStringLen = 6;
+
+				if (find_str_in_data(vmwareString, vmwwareStringLen, table, tableSize)) {
+					result = TRUE;
+				}
+
+				free(table);
+			}
+		}
+	}
+
+	free(tableNames);
+	return result;
+}
+
diff --git a/al-khaser/al-khaser/AntiVM/VMWare.h b/al-khaser/al-khaser/AntiVM/VMWare.h
new file mode 100644
index 0000000000000000000000000000000000000000..c9205def4040c593b3b7f9b785bb32ed9e899a0a
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/VMWare.h
@@ -0,0 +1,12 @@
+#pragma once
+
+VOID vmware_reg_key_value();
+VOID vmware_reg_keys();
+VOID vmware_files();
+BOOL vmware_dir();
+VOID vmware_mac();
+BOOL vmware_adapter_name();
+VOID vmware_devices();
+VOID vmware_processes();
+BOOL vmware_firmware_SMBIOS();
+BOOL vmware_firmware_ACPI();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiVM/VirtualBox.cpp b/al-khaser/al-khaser/AntiVM/VirtualBox.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c71fdba1c3ac64283d3e2891f888134dfe5e919e
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/VirtualBox.cpp
@@ -0,0 +1,920 @@
+#include "pch.h"
+
+#include "VirtualBox.h"
+
+/*
+Registry key values
+*/
+VOID vbox_reg_key_value()
+{
+	/* Array of strings of blacklisted registry key values */
+	const TCHAR *szEntries[][3] = {
+		{ _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("VBOX") },
+		{ _T("HARDWARE\\Description\\System"), _T("SystemBiosVersion"), _T("VBOX") },
+		{ _T("HARDWARE\\Description\\System"), _T("VideoBiosVersion"), _T("VIRTUALBOX") },
+		{ _T("HARDWARE\\Description\\System"), _T("SystemBiosDate"), _T("06/23/99") },
+	};
+
+	WORD dwLength = sizeof(szEntries) / sizeof(szEntries[0]);
+
+	for (int i = 0; i < dwLength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key HARDWARE\\Description\\System - %s is set to %s"), szEntries[i][1], szEntries[i][2]);
+		if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, szEntries[i][0], szEntries[i][1], szEntries[i][2]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+/*
+Check against virtualbox registry keys
+*/
+VOID vbox_reg_keys()
+{
+	/* Array of strings of blacklisted registry keys */
+	const TCHAR* szKeys[] = {
+		_T("HARDWARE\\ACPI\\DSDT\\VBOX__"),
+		_T("HARDWARE\\ACPI\\FADT\\VBOX__"),
+		_T("HARDWARE\\ACPI\\RSDT\\VBOX__"),
+		_T("SOFTWARE\\Oracle\\VirtualBox Guest Additions"),
+		_T("SYSTEM\\ControlSet001\\Services\\VBoxGuest"),
+		_T("SYSTEM\\ControlSet001\\Services\\VBoxMouse"),
+		_T("SYSTEM\\ControlSet001\\Services\\VBoxService"),
+		_T("SYSTEM\\ControlSet001\\Services\\VBoxSF"),
+		_T("SYSTEM\\ControlSet001\\Services\\VBoxVideo")
+	};
+
+	WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]);
+
+	/* Check one by one */
+	for (int i = 0; i < dwlength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]);
+		if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+/*
+Check against virtualbox blacklisted files
+*/
+VOID vbox_files()
+{
+	/* Array of strings of blacklisted paths */
+	const TCHAR* szPaths[] = {
+		_T("System32\\drivers\\VBoxMouse.sys"),
+		_T("System32\\drivers\\VBoxGuest.sys"),
+		_T("System32\\drivers\\VBoxSF.sys"),
+		_T("System32\\drivers\\VBoxVideo.sys"),
+		_T("System32\\vboxdisp.dll"),
+		_T("System32\\vboxhook.dll"),
+		_T("System32\\vboxmrxnp.dll"),
+		_T("System32\\vboxogl.dll"),
+		_T("System32\\vboxoglarrayspu.dll"),
+		_T("System32\\vboxoglcrutil.dll"),
+		_T("System32\\vboxoglerrorspu.dll"),
+		_T("System32\\vboxoglfeedbackspu.dll"),
+		_T("System32\\vboxoglpackspu.dll"),
+		_T("System32\\vboxoglpassthroughspu.dll"),
+		_T("System32\\vboxservice.exe"),
+		_T("System32\\vboxtray.exe"),
+		_T("System32\\VBoxControl.exe"),
+	};
+
+	/* Getting Windows Directory */
+	WORD dwlength = sizeof(szPaths) / sizeof(szPaths[0]);
+	TCHAR szWinDir[MAX_PATH] = _T("");
+	TCHAR szPath[MAX_PATH] = _T("");
+	PVOID OldValue = NULL;
+
+	GetWindowsDirectory(szWinDir, MAX_PATH);
+
+	if (IsWoW64()) {
+		Wow64DisableWow64FsRedirection(&OldValue);
+	}
+
+	/* Check one by one */
+	for (int i = 0; i < dwlength; i++)
+	{
+		PathCombine(szPath, szWinDir, szPaths[i]);
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking file %s "), szPath);
+		if (is_FileExists(szPath))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+
+	if (IsWoW64()) {
+		Wow64RevertWow64FsRedirection(&OldValue);
+	}
+}
+
+
+/*
+Check against virtualbox blacklisted directories
+*/
+BOOL vbox_dir()
+{
+	TCHAR szProgramFile[MAX_PATH];
+	TCHAR szPath[MAX_PATH] = _T("");
+	TCHAR szTarget[MAX_PATH] = _T("oracle\\virtualbox guest additions\\");
+
+	if (IsWoW64())
+		ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile));
+	else
+		SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE);
+
+	PathCombine(szPath, szProgramFile, szTarget);
+	return is_DirectoryExists(szPath);
+}
+
+
+/*
+Check virtualbox NIC MAC address
+*/
+BOOL vbox_check_mac()
+{
+	// PCS Systemtechnik CmbH (VirtualBox)
+	return check_mac_addr(_T("\x08\x00\x27"));
+}
+
+
+/*
+Check against pseaudo-devices
+*/
+VOID vbox_devices()
+{
+	const TCHAR *devices[] = {
+		_T("\\\\.\\VBoxMiniRdrDN"),
+		_T("\\\\.\\VBoxGuest"),
+		_T("\\\\.\\pipe\\VBoxMiniRdDN"),
+		_T("\\\\.\\VBoxTrayIPC"),
+		_T("\\\\.\\pipe\\VBoxTrayIPC")
+	};
+
+	WORD iLength = sizeof(devices) / sizeof(devices[0]);
+	for (int i = 0; i < iLength; i++)
+	{
+		HANDLE hFile = CreateFile(devices[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking device %s "), devices[i]);
+		if (hFile != INVALID_HANDLE_VALUE) {
+			CloseHandle(hFile);
+			print_results(TRUE, msg);
+		}
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+/*
+Check for Window class
+*/
+BOOL vbox_window_class()
+{
+	HWND hClass = FindWindow(_T("VBoxTrayToolWndClass"), NULL);
+	HWND hWindow = FindWindow(NULL, _T("VBoxTrayToolWnd"));
+
+	if (hClass || hWindow)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+
+/*
+Check for shared folders network profider
+*/
+BOOL vbox_network_share()
+{
+	TCHAR szProviderName[MAX_PATH] = _T("");
+	DWORD lpBufferSize = MAX_PATH;
+
+	if (WNetGetProviderName(WNNC_NET_RDR2SAMPLE, szProviderName, &lpBufferSize) == NO_ERROR)
+	{
+		if (StrCmpI(szProviderName, _T("VirtualBox Shared Folders")) == 0)
+			return TRUE;
+		else
+			return FALSE;
+	}
+	return FALSE;
+}
+
+
+/*
+Check for process list
+*/
+VOID vbox_processes()
+{
+	const TCHAR *szProcesses[] = {
+		_T("vboxservice.exe"),
+		_T("vboxtray.exe")
+	};
+
+	WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]);
+	for (int i = 0; i < iLength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking VirtualBox process %s "), szProcesses[i]);
+		if (GetProcessIdFromName(szProcesses[i]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+/*
+Check vbox mac @ using WMI
+*/
+BOOL vbox_mac_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_NetworkAdapterConfiguration"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			// Iterate over our enumator
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("MACAddress"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+
+					if (V_VT(&vtProp) != VT_NULL) {
+
+						if ((vtProp.vt & VT_BSTR) == VT_BSTR)
+						{
+							// Do our comparison
+							if (_tcsstr(vtProp.bstrVal, _T("08:00:27")) != 0) {
+								bFound = TRUE;
+							}
+						}
+
+						// release the current result object
+						VariantClear(&vtProp);					
+					}
+				}
+				pclsObj->Release();
+
+				// break from while
+				if (bFound)
+					break;
+			}
+
+			// Cleanup
+			pEnumerator->Release();
+			pSvc->Release();
+			pLoc->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+
+/*
+Check vbox event log using WMI
+*/
+BOOL vbox_eventlogfile_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	const TCHAR *szVBoxSources[] = {
+		_T("vboxvideo"),
+		_T("VBoxVideoW8"),
+		_T("VBoxWddm")
+	};
+
+	USHORT MaxVBoxSources = _countof(szVBoxSources);
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_NTEventlogFile"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			// Iterate over our enumator
+			while (pEnumerator && !bFound)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				// Get the value of the FileName property
+				hRes = pclsObj->Get(_T("FileName"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes) && (V_VT(&vtProp) != VT_NULL)) {
+
+					if ((vtProp.vt & VT_BSTR) == VT_BSTR)
+					{
+						// Do our comparaison
+						if (StrCmpI(vtProp.bstrVal, _T("System")) == 0) {
+
+							// Now, grab the Source property
+							VariantClear(&vtProp);
+							hRes = pclsObj->Get(_T("Sources"), 0, &vtProp, 0, 0);
+
+							// Get the number of elements of our SAFEARRAY
+							SAFEARRAY* saSources = vtProp.parray;
+							LONG* pVals;
+							HRESULT hr = SafeArrayAccessData(saSources, (VOID**)&pVals); // direct access to SA memory
+							if (SUCCEEDED(hr)) {
+								LONG lowerBound, upperBound;
+								SafeArrayGetLBound(saSources, 1, &lowerBound);
+								SafeArrayGetUBound(saSources, 1, &upperBound);
+								LONG iLength = upperBound - lowerBound + 1;
+
+								// Iteare over our array of BTSR
+								TCHAR* bstrItem;
+								for (LONG ix = 0; ix < iLength; ix++) {
+									SafeArrayGetElement(saSources, &ix, (void *)&bstrItem);
+
+									for (UINT id = 0; id < MaxVBoxSources; id++) {
+										if (_tcsicmp(bstrItem, szVBoxSources[id]) == 0)
+										{
+											bFound = TRUE;
+											break;
+										}
+									}
+									// break from upper level "for" on detection success
+									if (bFound)
+										break;
+								}
+								//unlock data
+								SafeArrayUnaccessData(saSources);
+							}
+						}
+					}
+					
+					// release the current result object
+					VariantClear(&vtProp);
+				}
+				pclsObj->Release();
+			}
+
+			// Cleanup
+			pEnumerator->Release();
+			pSvc->Release();
+			pLoc->Release();
+			CoUninitialize();
+
+		}
+	}
+
+	return bFound;
+}
+
+
+BOOL vbox_firmware_SMBIOS()
+{
+	BOOL result = FALSE;
+
+	DWORD smbiosSize = 0;
+	PBYTE smbios = get_system_firmware(static_cast<DWORD>('RSMB'), 0x0000, &smbiosSize);
+	if (smbios != NULL)
+	{
+		PBYTE virtualBoxString = (PBYTE)"VirtualBox";
+		size_t virtualBoxStringLen = 10;
+		PBYTE vboxLowerString = (PBYTE)"vbox";
+		size_t vboxLowerStringLen = 4;
+		PBYTE vboxUpperString = (PBYTE)"VBOX";
+		size_t vboxUpperStringLen = 4;
+
+		if (find_str_in_data(virtualBoxString, virtualBoxStringLen, smbios, smbiosSize) ||
+			find_str_in_data(vboxLowerString, vboxLowerStringLen, smbios, smbiosSize) ||
+			find_str_in_data(vboxUpperString, vboxUpperStringLen, smbios, smbiosSize))
+		{
+			result = TRUE;
+		}
+
+		free(smbios);
+	}
+
+	return result;
+}
+
+
+BOOL vbox_firmware_ACPI()
+{
+	BOOL result = FALSE;
+
+	PDWORD tableNames = static_cast<PDWORD>(malloc(4096));
+
+	if (tableNames == NULL)
+		return FALSE;
+
+	SecureZeroMemory(tableNames, 4096);
+	DWORD tableSize = enum_system_firmware_tables(static_cast<DWORD>('ACPI'), tableNames, 4096);
+
+	// API not available
+	if (tableSize == -1)
+		return FALSE;
+
+	DWORD tableCount = tableSize / 4;
+
+	if (tableSize < 4 || tableCount == 0)
+	{
+		result = TRUE;
+	}
+	else
+	{
+		for (DWORD i = 0; i < tableCount; i++)
+		{
+			DWORD tableSize = 0;
+			PBYTE table = get_system_firmware(static_cast<DWORD>('ACPI'), tableNames[i], &tableSize);
+
+			if (table) {
+
+				PBYTE virtualBoxString = (PBYTE)"VirtualBox";
+				size_t virtualBoxStringLen = 10;
+				PBYTE vboxLowerString = (PBYTE)"vbox";
+				size_t vboxLowerStringLen = 4;
+				PBYTE vboxUpperString = (PBYTE)"VBOX";
+				size_t vboxUpperStringLen = 4;
+
+				if (find_str_in_data(virtualBoxString, virtualBoxStringLen, table, tableSize) ||
+					find_str_in_data(vboxLowerString, vboxLowerStringLen, table, tableSize) ||
+					find_str_in_data(vboxUpperString, vboxUpperStringLen, table, tableSize))
+				{
+					result = TRUE;
+				}
+
+				free(table);
+			}
+		}
+	}
+
+	free(tableNames);
+	return result;
+}
+
+
+/*
+Check vbox devices using WMI
+*/
+BOOL vbox_pnpentity_pcideviceid_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_PnPEntity"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("DeviceId"), 0, &vtProp, 0, 0);
+
+				if (SUCCEEDED(hRes)) {
+					if (vtProp.vt == VT_BSTR) {
+
+						// Do our comparaison
+						if (_tcsstr(vtProp.bstrVal, _T("PCI\\VEN_80EE&DEV_CAFE")) != 0)
+						{
+							bFound = TRUE;
+						}
+					}
+					VariantClear(&vtProp);
+				}
+
+				// release the current result object				
+				pclsObj->Release();
+
+				if (bFound)
+					break;
+			}
+
+			// Cleanup
+			pSvc->Release();
+			pLoc->Release();
+			pEnumerator->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+
+/*
+Check Win32_PnPEntity for known VirtualBox hardware
+*/
+BOOL vbox_pnpentity_controllers_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_PnPEntity"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			int findCount = 0;
+			const int findThreshold = 3;
+
+			// Iterate over our enumator
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("Name"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+
+					if (V_VT(&vtProp) != VT_NULL) {
+
+						if ((vtProp.vt & VT_BSTR) == VT_BSTR)
+						{
+							// increment the find counter if this instance matches any of the known VBox hardware
+							if (_tcsstr(vtProp.bstrVal, _T("82801FB")) != 0) {
+								findCount++;
+							}
+							else if (_tcsstr(vtProp.bstrVal, _T("82441FX")) != 0) {
+								findCount++;
+							}
+							else if (_tcsstr(vtProp.bstrVal, _T("82371SB")) != 0) {
+								findCount++;
+							}
+							else if (_tcsstr(vtProp.bstrVal, _T("OpenHCD")) != 0) {
+								findCount++;
+							}
+						}
+
+						// release the current result object
+						VariantClear(&vtProp);
+					}
+				}
+				pclsObj->Release();
+			}
+
+			if (findCount >= findThreshold)
+			{
+				bFound = TRUE;
+			}
+
+			// Cleanup
+			pEnumerator->Release();
+			pSvc->Release();
+			pLoc->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+
+/*
+Check Win32_Bus to see if only ACPIBus_BUS_0, PCI_BUS_0, PNP_BUS_0 are present
+*/
+BOOL vbox_bus_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_Bus"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+			
+			int count = 0;
+			int findCount = 0;
+			const int findThreshold = 3;
+
+			// Iterate over our enumator
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				count++;
+
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("Name"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+
+					if (V_VT(&vtProp) != VT_NULL)
+					{
+						if ((vtProp.vt & VT_BSTR) == VT_BSTR)
+						{
+							// increment the find counter if this is 
+							if (_tcsstr(vtProp.bstrVal, _T("ACPIBus_BUS_0")) != 0) {
+								findCount++;
+							}
+							else if (_tcsstr(vtProp.bstrVal, _T("PCI_BUS_0")) != 0) {
+								findCount++;
+							}
+							else if (_tcsstr(vtProp.bstrVal, _T("PNP_BUS_0")) != 0) {
+								findCount++;
+							}
+						}
+
+						// release the current result object
+						VariantClear(&vtProp);
+					}
+				}
+				pclsObj->Release();
+			}
+
+			// check that there are 3 instances and they match the strings above
+			if (count == findThreshold &&
+				findCount == findThreshold)
+			{
+				bFound = TRUE;
+			}
+
+			// Cleanup
+			pEnumerator->Release();
+			pSvc->Release();
+			pLoc->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+
+/*
+Check Win32_BaseBoard
+*/
+BOOL vbox_baseboard_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_BaseBoard"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp = { 0 };
+
+			// Iterate over our enumator
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				// Get the value of the Product property
+				hRes = pclsObj->Get(_T("Product"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+
+					if (V_VT(&vtProp) != VT_NULL) {
+
+						if ((vtProp.vt & VT_BSTR) == VT_BSTR)
+						{
+							// Do our comparison
+							if (_tcsstr(vtProp.bstrVal, _T("VirtualBox")) != 0) {
+								bFound = TRUE;
+							}
+						}
+
+						// release the current result object
+						VariantClear(&vtProp);
+					}
+				}
+
+				vtProp = { 0 };
+
+				// Get the value of the Manufacturer property
+				hRes = pclsObj->Get(_T("Manufacturer"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+
+					if (V_VT(&vtProp) != VT_NULL) {
+
+						if ((vtProp.vt & VT_BSTR) == VT_BSTR)
+						{
+							// Do our comparison
+							if (_tcsstr(vtProp.bstrVal, _T("Oracle Corporation")) != 0) {
+								bFound = TRUE;
+							}
+						}
+
+						// release the current result object
+						VariantClear(&vtProp);
+					}
+				}
+
+				pclsObj->Release();
+
+				// break from while
+				if (bFound)
+					break;
+			}
+
+			// Cleanup
+			pEnumerator->Release();
+			pSvc->Release();
+			pLoc->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
+
+
+/*
+Check Win32_PnPDevice for VBOX entries
+*/
+BOOL vbox_pnpentity_vboxname_wmi()
+{
+	IWbemServices *pSvc = NULL;
+	IWbemLocator *pLoc = NULL;
+	IEnumWbemClassObject* pEnumerator = NULL;
+	BOOL bStatus = FALSE;
+	HRESULT hRes;
+	BOOL bFound = FALSE;
+
+	// Init WMI
+	bStatus = InitWMI(&pSvc, &pLoc, _T("ROOT\\CIMV2"));
+	if (bStatus)
+	{
+		// If success, execute the desired query
+		bStatus = ExecWMIQuery(&pSvc, &pLoc, &pEnumerator, _T("SELECT * FROM Win32_PnPDevice"));
+		if (bStatus)
+		{
+			// Get the data from the query
+			IWbemClassObject *pclsObj = NULL;
+			ULONG uReturn = 0;
+			VARIANT vtProp;
+
+			// Iterate over our enumator
+			while (pEnumerator)
+			{
+				hRes = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
+				if (0 == uReturn)
+					break;
+
+				// Get the value of the Name property
+				hRes = pclsObj->Get(_T("Name"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+
+					if (V_VT(&vtProp) != VT_NULL) {
+
+						if ((vtProp.vt & VT_BSTR) == VT_BSTR)
+						{
+							// Do our comparison
+							if (_tcsstr(vtProp.bstrVal, _T("VBOX")) != 0) {
+								bFound = TRUE;
+							}
+						}
+
+						// release the current result object
+						VariantClear(&vtProp);
+					}
+				}
+
+				// Get the value of the Caption property
+				hRes = pclsObj->Get(_T("Caption"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+
+					if (V_VT(&vtProp) != VT_NULL) {
+
+						if ((vtProp.vt & VT_BSTR) == VT_BSTR)
+						{
+							// Do our comparison
+							if (_tcsstr(vtProp.bstrVal, _T("VBOX")) != 0) {
+								bFound = TRUE;
+							}
+						}
+
+						// release the current result object
+						VariantClear(&vtProp);
+					}
+				}
+
+				// Get the value of the PNPDeviceID property
+				hRes = pclsObj->Get(_T("PNPDeviceID"), 0, &vtProp, 0, 0);
+				if (SUCCEEDED(hRes)) {
+
+					if (V_VT(&vtProp) != VT_NULL) {
+
+						if ((vtProp.vt & VT_BSTR) == VT_BSTR)
+						{
+							// Do our comparison
+							if (_tcsstr(vtProp.bstrVal, _T("VEN_VBOX")) != 0) {
+								bFound = TRUE;
+							}
+						}
+
+						// release the current result object
+						VariantClear(&vtProp);
+					}
+				}
+
+				pclsObj->Release();
+
+				// break from while
+				if (bFound)
+					break;
+			}
+
+			// Cleanup
+			pEnumerator->Release();
+			pSvc->Release();
+			pLoc->Release();
+			CoUninitialize();
+		}
+	}
+
+	return bFound;
+}
diff --git a/al-khaser/al-khaser/AntiVM/VirtualBox.h b/al-khaser/al-khaser/AntiVM/VirtualBox.h
new file mode 100644
index 0000000000000000000000000000000000000000..0d34654feca3b7073bae62bccb44b7cd34160d38
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/VirtualBox.h
@@ -0,0 +1,21 @@
+#pragma once
+
+VOID vbox_reg_key_value();
+VOID vbox_reg_keys();
+VOID vbox_files();
+BOOL vbox_dir();
+
+BOOL vbox_check_mac();
+VOID vbox_devices();
+BOOL vbox_window_class();
+BOOL vbox_network_share();
+VOID vbox_processes();
+BOOL vbox_mac_wmi();
+BOOL vbox_eventlogfile_wmi();
+BOOL vbox_firmware_SMBIOS();
+BOOL vbox_firmware_ACPI();
+BOOL vbox_bus_wmi();
+BOOL vbox_baseboard_wmi();
+BOOL vbox_pnpentity_pcideviceid_wmi();
+BOOL vbox_pnpentity_controllers_wmi();
+BOOL vbox_pnpentity_vboxname_wmi();
diff --git a/al-khaser/al-khaser/AntiVM/VirtualPC.cpp b/al-khaser/al-khaser/AntiVM/VirtualPC.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d77d9dd8363da72649f7eb103755f087aed0c599
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/VirtualPC.cpp
@@ -0,0 +1,49 @@
+#include "pch.h"
+
+#include "VirtualPC.h"
+
+/*
+Check for process list
+*/
+
+VOID virtual_pc_process()
+{
+	const TCHAR *szProcesses[] = {
+		_T("VMSrvc.exe"),
+		_T("VMUSrvc.exe"),
+	};
+
+	WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]);
+	for (int i = 0; i < iLength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking Virtual PC processes %s "), szProcesses[i]);
+		if (GetProcessIdFromName(szProcesses[i]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+
+VOID virtual_pc_reg_keys()
+{
+	/* Array of strings of blacklisted registry keys */
+	const TCHAR* szKeys[] = {
+		_T("SOFTWARE\\Microsoft\\Virtual Machine\\Guest\\Parameters"),
+	};
+
+	WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]);
+
+	/* Check one by one */
+	for (int i = 0; i < dwlength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]);
+		if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
diff --git a/al-khaser/al-khaser/AntiVM/VirtualPC.h b/al-khaser/al-khaser/AntiVM/VirtualPC.h
new file mode 100644
index 0000000000000000000000000000000000000000..53b9d57e445414f1d741009d20fdc892267b43ea
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/VirtualPC.h
@@ -0,0 +1,5 @@
+#pragma once
+
+
+VOID virtual_pc_process();
+VOID virtual_pc_reg_keys();
diff --git a/al-khaser/al-khaser/AntiVM/Wine.cpp b/al-khaser/al-khaser/AntiVM/Wine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..05658a810d54762deb8574b301704e9397c3e555
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/Wine.cpp
@@ -0,0 +1,49 @@
+#include "pch.h"
+
+#include "Wine.h"
+
+/*
+Check against Wine export dlls
+*/
+BOOL wine_exports()
+{
+	/* Some vars */
+	HMODULE hKernel32;
+
+	/* Get kernel32 module handle */
+	hKernel32 = GetModuleHandle(_T("kernel32.dll"));
+	if (hKernel32 == NULL) {
+		print_last_error(_T("GetModuleHandle"));
+		return FALSE;
+	}
+
+	/* Check if wine_get_unix_file_name is exported by this dll */
+	if (GetProcAddress(hKernel32, "wine_get_unix_file_name") == NULL)
+		return FALSE;
+	else
+		return TRUE;
+}
+
+/*
+Check against Wine registry keys
+*/
+VOID wine_reg_keys()
+{
+	/* Array of strings of blacklisted registry keys */
+	const TCHAR* szKeys[] = {
+		_T("SOFTWARE\\Wine")
+	};
+
+	WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]);
+
+	/* Check one by one */
+	for (int i = 0; i < dwlength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]);
+		if (Is_RegKeyExists(HKEY_CURRENT_USER, szKeys[i]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
diff --git a/al-khaser/al-khaser/AntiVM/Wine.h b/al-khaser/al-khaser/AntiVM/Wine.h
new file mode 100644
index 0000000000000000000000000000000000000000..832d9c2297513f63ad3547c54445e7e9715222ae
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/Wine.h
@@ -0,0 +1,4 @@
+#pragma once
+
+BOOL wine_exports();
+VOID wine_reg_keys();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiVM/Xen.cpp b/al-khaser/al-khaser/AntiVM/Xen.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..baadb4361e56d77fab18bede2797938dc728647a
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/Xen.cpp
@@ -0,0 +1,36 @@
+#include "pch.h"
+
+#include "Xen.h"
+
+/*
+Check for process list
+*/
+
+VOID xen_process()
+{
+	const TCHAR *szProcesses[] = {
+		_T("xenservice.exe"),
+	};
+
+	WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]);
+	for (int i = 0; i < iLength; i++)
+	{
+		TCHAR msg[256] = _T("");
+		_stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking Citrix Xen process %s"), szProcesses[i]);
+		if (GetProcessIdFromName(szProcesses[i]))
+			print_results(TRUE, msg);
+		else
+			print_results(FALSE, msg);
+	}
+}
+
+
+
+/*
+Check Xen NIC MAC address
+*/
+BOOL xen_check_mac()
+{
+	// Xensource, Inc. 
+	return check_mac_addr(_T("\x00\x16\x3E"));
+}
diff --git a/al-khaser/al-khaser/AntiVM/Xen.h b/al-khaser/al-khaser/AntiVM/Xen.h
new file mode 100644
index 0000000000000000000000000000000000000000..9f1b8d846af37b4983e6f73dcb62f8774373582b
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/Xen.h
@@ -0,0 +1,4 @@
+#pragma once
+
+VOID xen_process();
+BOOL xen_check_mac();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/AntiVM/pch.h b/al-khaser/al-khaser/AntiVM/pch.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7df92d774ff3829efea501cff3b5b40e5b16f4b
--- /dev/null
+++ b/al-khaser/al-khaser/AntiVM/pch.h
@@ -0,0 +1 @@
+#include "../pch.h"
\ No newline at end of file
diff --git a/al-khaser/al-khaser/CodeInjection/CreateRemoteThread.cpp b/al-khaser/al-khaser/CodeInjection/CreateRemoteThread.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..20a773a0f1ee54e302cdbee991f739e1831ebe45
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/CreateRemoteThread.cpp
@@ -0,0 +1,97 @@
+#include "pch.h"
+
+#include "CreateRemoteThread.h"
+
+BOOL CreateRemoteThread_Injection()
+{
+	/* Some vars */
+	DWORD dwProcessId;
+	HANDLE hProcess = NULL, hRemoteThread = NULL;
+	HMODULE hKernel32;
+	FARPROC LoadLibraryAddress;
+	LPVOID lpBaseAddress = NULL;
+	TCHAR lpDllName[] = _T("InjectedDLL.dll");
+	TCHAR lpDllPath[MAX_PATH];
+	SIZE_T dwSize;
+	BOOL bStatus = FALSE, bDebugPrivilegeEnabled;
+	
+	/* Get Process ID from Process name */
+	dwProcessId = GetProcessIdFromName(_T("notepad.exe"));
+	if (dwProcessId == NULL)
+		return FALSE;
+	_tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId);
+
+	/* Set Debug privilege */
+	bDebugPrivilegeEnabled = SetDebugPrivileges();
+	_tprintf(_T("\t[+] Setting Debug Privileges [%d]\n"), bDebugPrivilegeEnabled);
+	if (!bDebugPrivilegeEnabled)
+		return FALSE;
+
+	/* Obtain a handle the process */
+	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
+	if (hProcess == NULL) {
+		print_last_error(_T("OpenProcess"));
+		goto Cleanup;
+	}
+
+	/* Obtain a handle to kernel32 */
+	hKernel32 = GetModuleHandle(_T("kernel32.dll"));
+	if (hKernel32 == NULL) {
+		print_last_error(_T("GetModuleHandle"));
+		goto Cleanup;
+	}
+
+	/* Get LoadLibrary address */
+	_tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n"));
+	LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW");
+	if (LoadLibraryAddress == NULL) {
+		print_last_error(_T("GetProcAddress"));
+		goto Cleanup;
+	}
+	_tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress);
+
+	/* Get the full path of the dll */
+	GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL);
+	_tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath);
+
+	/* Calculate the number of bytes needed for the DLL's pathname */
+	dwSize = _tcslen(lpDllPath) * sizeof(TCHAR);
+
+	/* Allocate memory into the remote process */
+	_tprintf(_T("\t[+] Allocating space for the path of the DLL\n"));
+	lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+	if (lpBaseAddress == NULL) {       
+		print_last_error(_T("VirtualAllocEx"));
+		goto Cleanup;
+	}
+
+	/* Write to the remote process */
+	printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress);
+	if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, dwSize, NULL)) {
+		print_last_error(_T("WriteProcessMemory"));
+		goto Cleanup;
+	}
+
+	/* Create the more thread */
+	hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryAddress, lpBaseAddress, NULL, 0);
+	if (hRemoteThread == NULL) {
+		print_last_error(_T("CreateRemoteThread"));
+	}
+	else {
+		_tprintf(_T("Remote thread has been created successfully ...\n"));
+		WaitForSingleObject(hRemoteThread, INFINITE);
+		CloseHandle(hRemoteThread);
+		
+		/* assign function success return result */
+		bStatus = TRUE;
+	}
+
+Cleanup:
+	/* If lpBaseAddress initialized then hProcess is initialized too because of upper check. */
+	if (lpBaseAddress) {
+		VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE);
+	}
+	if (hProcess) CloseHandle(hProcess);
+
+	return bStatus;
+}
diff --git a/al-khaser/al-khaser/CodeInjection/CreateRemoteThread.h b/al-khaser/al-khaser/CodeInjection/CreateRemoteThread.h
new file mode 100644
index 0000000000000000000000000000000000000000..6721e5d04a35c9bc1a2ae75b75c4acdf012f6019
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/CreateRemoteThread.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL CreateRemoteThread_Injection();
\ No newline at end of file
diff --git a/al-khaser/al-khaser/CodeInjection/GetSetThreadContext.cpp b/al-khaser/al-khaser/CodeInjection/GetSetThreadContext.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a9fca1a85f7d3eb5e8c1a42a0315e1e07f4974e8
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/GetSetThreadContext.cpp
@@ -0,0 +1,132 @@
+#include "pch.h"
+
+#include "GetSetThreadContext.h"
+
+BOOL GetSetThreadContext_Injection()
+{
+#ifdef _WIN64
+	return TRUE; //TODO implement this on x64
+#else
+	TCHAR lpApplicationName[] = _T("C:\\Windows\\System32\\svchost.exe");
+	TCHAR lpApplicationName2[] = _T("C:\\masm32\\examples\\dialogs_later\\basic\\basicdlg.exe");
+	BOOL bResult = FALSE;
+
+	STARTUPINFO StartupInfo;
+	PROCESS_INFORMATION ProcessInfo;
+
+	PCONTEXT pContext = NULL;
+	HANDLE hFile = INVALID_HANDLE_VALUE;
+
+	SecureZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
+	SecureZeroMemory(&ProcessInfo, sizeof(PPROCESS_INFORMATION));
+
+	do { /* not a loop */
+
+		// Create the hollowed process in suspended mode
+		if (!CreateProcess(lpApplicationName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInfo)) {
+			print_last_error(_T("CreateProcess"));
+			break;
+		}
+
+		// Allocate space for context structure	
+		LPVOID pTargetImageBase = NULL;
+
+		pContext = PCONTEXT(VirtualAlloc(NULL, sizeof(CONTEXT), MEM_COMMIT, PAGE_READWRITE));
+		if (pContext == NULL) {
+			print_last_error(_T("VirtualAlloc"));
+			break;
+		}
+
+		// Get the thread context of target
+		pContext->ContextFlags = CONTEXT_FULL;
+		if (!GetThreadContext(ProcessInfo.hThread, pContext)) {
+			print_last_error(_T("GetThreadContext"));	
+			break;
+		}
+
+		// Read the image base address of target
+		ReadProcessMemory(ProcessInfo.hProcess, LPCVOID(pContext->Ebx + 8), pTargetImageBase, 4, NULL);
+
+		// Opening source image
+		hFile = CreateFile(lpApplicationName2, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, NULL, NULL);
+		if (hFile == INVALID_HANDLE_VALUE)
+		{
+			print_last_error(_T("CreateFile"));
+			break;
+		}
+
+		// Reading the file
+		DWORD dwSize = GetFileSize(hFile, 0);
+		DWORD dwBytesRead;
+		PBYTE pBuffer = static_cast<PBYTE>(MALLOC(dwSize));
+
+		if (pBuffer == NULL) {
+			print_last_error(_T("HeapAlloc"));
+			break;
+		}
+		else {
+
+			SecureZeroMemory(pBuffer, dwSize);
+
+			ReadFile(hFile, pBuffer, dwSize, &dwBytesRead, 0);
+			PIMAGE_SECTION_HEADER pImageSectionHeader;
+
+			PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBuffer;
+			if (pDosHeader->e_magic == IMAGE_DOS_SIGNATURE)
+			{
+				PIMAGE_NT_HEADERS32 pNTHeaders = PIMAGE_NT_HEADERS(DWORD(pBuffer) + pDosHeader->e_lfanew);
+				if (pNTHeaders->Signature == IMAGE_NT_SIGNATURE)
+				{
+
+					if (DWORD(pTargetImageBase) == pNTHeaders->OptionalHeader.ImageBase)
+					{
+						pNtUnmapViewOfSection NtUnmapViewOfSection;
+						NtUnmapViewOfSection = (pNtUnmapViewOfSection)(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection"));
+						NtUnmapViewOfSection(ProcessInfo.hProcess, pTargetImageBase);
+					}
+
+					LPVOID pImageBase;
+
+					pImageBase = VirtualAllocEx(ProcessInfo.hProcess, LPVOID(pNTHeaders->OptionalHeader.ImageBase),
+						pNTHeaders->OptionalHeader.SizeOfImage,
+						MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+
+					if (pImageBase == NULL) {
+						print_last_error(_T("VirtualAllocEx"));
+						break;
+					}
+					else {
+
+						WriteProcessMemory(ProcessInfo.hProcess, pImageBase, pBuffer, pNTHeaders->OptionalHeader.SizeOfHeaders, NULL);
+						for (int Count = 0; Count < pNTHeaders->FileHeader.NumberOfSections; Count++)
+						{
+							pImageSectionHeader = PIMAGE_SECTION_HEADER(DWORD(pBuffer) + pDosHeader->e_lfanew + 248 + (Count * 40));
+							WriteProcessMemory(ProcessInfo.hProcess, LPVOID(DWORD(pImageBase) + pImageSectionHeader->VirtualAddress),
+								LPVOID(DWORD(pBuffer) + pImageSectionHeader->PointerToRawData), pImageSectionHeader->SizeOfRawData, NULL);
+						}
+						WriteProcessMemory(ProcessInfo.hProcess, LPVOID(pContext->Ebx + 8), LPVOID(&pNTHeaders->OptionalHeader.ImageBase), 4, NULL);
+						pContext->Eax = DWORD(pImageBase) + pNTHeaders->OptionalHeader.AddressOfEntryPoint;
+						SetThreadContext(ProcessInfo.hThread, LPCONTEXT(pContext));
+
+						LONG dwRet;
+
+						dwRet = ResumeThread(ProcessInfo.hThread);
+						bResult = (dwRet != -1);
+					}
+				}
+			}
+
+			FREE(pBuffer);
+		}
+
+	} while (FALSE); /* not a loop */
+
+	/* Cleanup */
+	if (ProcessInfo.hThread) CloseHandle(ProcessInfo.hThread);
+	if (ProcessInfo.hProcess) CloseHandle(ProcessInfo.hProcess);
+	if (pContext) VirtualFree(pContext, 0, MEM_RELEASE);
+	if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
+
+	return bResult;
+#endif
+}
diff --git a/al-khaser/al-khaser/CodeInjection/GetSetThreadContext.h b/al-khaser/al-khaser/CodeInjection/GetSetThreadContext.h
new file mode 100644
index 0000000000000000000000000000000000000000..c83e69638cd7131adfcb6ee546663410cbf450bf
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/GetSetThreadContext.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL GetSetThreadContext_Injection();
diff --git a/al-khaser/al-khaser/CodeInjection/InjectedDLL/InjectedDLL.cpp b/al-khaser/al-khaser/CodeInjection/InjectedDLL/InjectedDLL.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..322e7816a6a29de1be0d7a46023a26cb4f284089
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/InjectedDLL/InjectedDLL.cpp
@@ -0,0 +1,39 @@
+#include "stdafx.h"
+#include "InjectedDLL.h"
+
+LRESULT CALLBACK MyProc(INT code, WPARAM wParam, LPARAM lParam);
+
+LRESULT CALLBACK MyProc(INT code, WPARAM wParam, LPARAM lParam)
+{
+	//here goes our code
+	TCHAR str[MAX_PATH] = _T("");
+	_stprintf(str, _T("[Al-khaser] - Injected from process: %d"), GetCurrentProcessId());
+	OutputDebugString(str);
+	return CallNextHookEx(NULL, code, wParam, lParam);  //this is needed to let other applications set other hooks on this target
+}
+
+
+BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
+{
+	switch (dwReason)
+	{
+		case DLL_PROCESS_ATTACH:
+			OutputDebugString(_T("[Al-khaser] - DLL is attached"));
+			break;
+
+		case DLL_PROCESS_DETACH:
+			OutputDebugString(_T("[Al-khaser] - DLL is detached"));
+			break;
+
+		case DLL_THREAD_ATTACH:
+			OutputDebugString(_T("[Al-khaser] - Thread is atached"));
+			break;
+
+		case DLL_THREAD_DETACH:
+			OutputDebugString(_T("[Al-khaser] - Thread is detached"));
+			break;
+		}
+
+	/* Returns TRUE on success, FALSE on failure */
+	return TRUE;
+}
diff --git a/al-khaser/al-khaser/CodeInjection/InjectedDLL/InjectedDLL.h b/al-khaser/al-khaser/CodeInjection/InjectedDLL/InjectedDLL.h
new file mode 100644
index 0000000000000000000000000000000000000000..b9c272d2cc88bd8894ec285421b14e539a685626
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/InjectedDLL/InjectedDLL.h
@@ -0,0 +1,2 @@
+#include <Windows.h>
+#include <tchar.h>
\ No newline at end of file
diff --git a/al-khaser/al-khaser/CodeInjection/InjectedDLL/InjectedDLL.vcxproj b/al-khaser/al-khaser/CodeInjection/InjectedDLL/InjectedDLL.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..a27f9d7ba6a09a13599b4b971dbf510625570744
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/InjectedDLL/InjectedDLL.vcxproj
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{BFB018FC-33D1-4351-B6EA-1CA77336A0E4}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>InjectedDLL</RootNamespace>
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140_xp</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140_xp</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;INJECTEDDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ModuleDefinitionFile>definitions.def</ModuleDefinitionFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;INJECTEDDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ModuleDefinitionFile>definitions.def</ModuleDefinitionFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;INJECTEDDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ModuleDefinitionFile>definitions.def</ModuleDefinitionFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;INJECTEDDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ModuleDefinitionFile>definitions.def</ModuleDefinitionFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="InjectedDLL.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="InjectedDLL.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="definitions.def" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/al-khaser/al-khaser/CodeInjection/InjectedDLL/InjectedDLL.vcxproj.filters b/al-khaser/al-khaser/CodeInjection/InjectedDLL/InjectedDLL.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..2cd6a14be1687f1db9f972ebb08430943269683d
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/InjectedDLL/InjectedDLL.vcxproj.filters
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="InjectedDLL.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="InjectedDLL.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="definitions.def">
+      <Filter>Source Files</Filter>
+    </None>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/al-khaser/al-khaser/CodeInjection/InjectedDLL/definitions.def b/al-khaser/al-khaser/CodeInjection/InjectedDLL/definitions.def
new file mode 100644
index 0000000000000000000000000000000000000000..ed7fcca087d9ada64a5fb0d77b457d59b4a0a106
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/InjectedDLL/definitions.def
@@ -0,0 +1,3 @@
+LIBRARY
+EXPORTS
+  MyProc
\ No newline at end of file
diff --git a/al-khaser/al-khaser/CodeInjection/NtCreateThreadEx.cpp b/al-khaser/al-khaser/CodeInjection/NtCreateThreadEx.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b466e2e03ba96707cace5de109d552b829740d81
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/NtCreateThreadEx.cpp
@@ -0,0 +1,141 @@
+#include "pch.h"
+
+#include "NtCreateThreadEx.h"
+
+BOOL NtCreateThreadEx_Injection()
+{
+	// some vars
+	HMODULE hNtdll;
+	DWORD dwProcessId;
+	HANDLE hProcess = NULL;
+	TCHAR lpDllName[] = _T("InjectedDLL.dll");
+	TCHAR lpDllPath[MAX_PATH];
+	LPVOID lpBaseAddress = NULL;
+	BOOL bStatus = FALSE;
+	HMODULE hKernel32;
+	FARPROC LoadLibraryAddress;
+	HANDLE  hRemoteThread = NULL;
+	NTSTATUS Status;
+	SIZE_T dwSize;
+	CLIENT_ID ClientId;
+	PS_ATTRIBUTE_LIST PsAttrList;
+
+	// we have to import our function
+	pNtCreateThreadEx NtCreateThreadEx = NULL;
+
+	/*
+		GetLastError cannot be used with NtCreateThreadEx because this service does not set Win32 LastError value.
+		Native status code must be translated to Win32 error code and set manually.
+	*/
+	pRtlNtStatusToDosError RtlNtStatusToDosErrorPtr = NULL;
+
+	/* Get Process ID from Process name */
+	dwProcessId = GetProcessIdFromName(_T("notepad.exe"));
+	if (dwProcessId == 0)
+		return FALSE;
+	_tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId);
+
+	/* Obtain a handle the process */
+	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
+	if (hProcess == NULL) {
+		print_last_error(_T("OpenProcess"));
+		goto Cleanup;
+	}
+
+	/* Get module handle of ntdll */
+	hNtdll = GetModuleHandle(_T("ntdll.dll"));
+	if (hNtdll == NULL) {
+		print_last_error(_T("GetModuleHandle"));
+		goto Cleanup;
+	}
+
+	/* Obtain a handle to kernel32 */
+	hKernel32 = GetModuleHandle(_T("kernel32.dll"));
+	if (hKernel32 == NULL) {
+		print_last_error(_T("GetModuleHandle"));
+		goto Cleanup;
+	}
+
+	/* Get routine pointer, failure is not critical */
+	RtlNtStatusToDosErrorPtr = (pRtlNtStatusToDosError)GetProcAddress(hNtdll, "RtlNtStatusToDosError");
+
+	// Get the address NtCreateThreadEx
+	_tprintf(_T("\t[+] Looking for NtCreateThreadEx in ntdll\n"));
+	NtCreateThreadEx = (pNtCreateThreadEx)GetProcAddress(hNtdll, "NtCreateThreadEx");
+	if (NtCreateThreadEx == NULL) {
+		print_last_error(_T("GetProcAddress"));
+		goto Cleanup;
+	}
+	_tprintf(_T("\t[+] Found at 0x%p\n"), NtCreateThreadEx);
+
+	/* Get LoadLibrary address */
+	_tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n"));
+	LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW");
+	if (LoadLibraryAddress == NULL) {
+		print_last_error(_T("GetProcAddress"));
+		goto Cleanup;
+	}
+	_tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress);
+
+	/* Get the full path of the dll */
+	GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL);
+	_tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath);
+
+	/* Calculate the number of bytes needed for the DLL's pathname */
+	dwSize = _tcslen(lpDllPath) * sizeof(TCHAR);
+
+	/* Allocate memory into the remote process */
+	_tprintf(_T("\t[+] Allocating space for the path of the DLL\n"));
+	lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+	if (lpBaseAddress == NULL) {
+		print_last_error(_T("VirtualAllocEx"));
+		goto Cleanup;
+	}
+
+	/* Write to the remote process */
+	printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress);
+	if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, dwSize, NULL)) {
+		print_last_error(_T("WriteProcessMemory"));
+		goto Cleanup;
+	}
+
+	/* Create the more thread */
+	SecureZeroMemory(&PsAttrList, sizeof(PsAttrList));
+
+	/* Setup attributes entry */
+	PsAttrList.TotalLength = sizeof(PS_ATTRIBUTE_LIST);
+	PsAttrList.Attributes[0].Attribute = PS_ATTRIBUTE_CLIENT_ID;
+	PsAttrList.Attributes[0].Size = sizeof(CLIENT_ID);
+	PsAttrList.Attributes[0].u1.ValuePtr = &ClientId;
+
+	Status = NtCreateThreadEx(&hRemoteThread, THREAD_ALL_ACCESS, NULL, hProcess,
+		(LPTHREAD_START_ROUTINE)LoadLibraryAddress, lpBaseAddress, 0, 0, 0, 0, &PsAttrList);
+
+	if (!NT_SUCCESS(Status)) {
+		if (RtlNtStatusToDosErrorPtr) {
+			SetLastError(RtlNtStatusToDosErrorPtr(Status));
+		}
+		else {
+			SetLastError(ERROR_INTERNAL_ERROR);
+		}
+		print_last_error(_T("NtCreateThreadEx"));
+	}
+
+	else {
+		_tprintf(_T("Remote thread has been created successfully ...\n"));
+		WaitForSingleObject(hRemoteThread, INFINITE);
+		CloseHandle(hRemoteThread);
+
+		/* assign function success return result */
+		bStatus = TRUE;
+	}
+
+Cleanup:
+	/* If lpBaseAddress initialized then hProcess is initialized too because of upper check. */
+	if (lpBaseAddress) {
+		VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE);
+	}
+	if (hProcess) CloseHandle(hProcess);
+
+	return bStatus;
+}
diff --git a/al-khaser/al-khaser/CodeInjection/NtCreateThreadEx.h b/al-khaser/al-khaser/CodeInjection/NtCreateThreadEx.h
new file mode 100644
index 0000000000000000000000000000000000000000..f34038c538b2539ca282e29911d6df247e26ab52
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/NtCreateThreadEx.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL NtCreateThreadEx_Injection();
diff --git a/al-khaser/al-khaser/CodeInjection/QueueUserAPC.cpp b/al-khaser/al-khaser/CodeInjection/QueueUserAPC.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a8a4961e0e77d0aa9e2dfb91e883562fd8d6f51a
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/QueueUserAPC.cpp
@@ -0,0 +1,171 @@
+#include "pch.h"
+
+#include "QueueUserAPC.h"
+
+//
+//  Check whatever InjectedDLL.dll was loaded, because this dll
+//  does not provide any other way of caller notification.
+//
+BOOL IsDllInjected(DWORD dwProcessId, LPTSTR DllName)
+{
+	BOOL bFound = FALSE;
+	HANDLE hSnapshot;
+
+	hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
+	if (hSnapshot != INVALID_HANDLE_VALUE) {
+
+		MODULEENTRY32 me32;
+		me32.dwSize = sizeof(MODULEENTRY32);
+
+		if (Module32First(hSnapshot, &me32)) {
+
+			do {
+
+				if (StrCmpI(me32.szModule, DllName) == 0) {
+					bFound = TRUE;
+					break;
+				}
+
+			} while (Module32Next(hSnapshot, &me32));
+
+		}
+
+		CloseHandle(hSnapshot);
+	}
+
+	return bFound;
+}
+
+BOOL QueueUserAPC_Injection()
+{
+	TCHAR lpDllName[] = _T("InjectedDLL.dll");
+	TCHAR lpDllPath[MAX_PATH];
+
+	HANDLE hThreadSnapshot = INVALID_HANDLE_VALUE;
+
+	DWORD dwTargetProcessId, dwCurrentProcessId = GetCurrentProcessId();
+
+	HANDLE hProcess = NULL;
+	HANDLE hThread = NULL;
+
+	HMODULE hKernel32;
+
+	FARPROC LoadLibraryAddress;
+	LPVOID lpBaseAddress = NULL;
+	BOOL bStatus = FALSE;
+
+
+	/* Get Process ID from Process name */
+
+	//
+	// calc used because it has multiple threads and some of them maybe alertable.
+	//
+	dwTargetProcessId = GetProcessIdFromName(_T("calc.exe"));
+	if (dwTargetProcessId == 0)
+		dwTargetProcessId = GetProcessIdFromName(_T("win32calc.exe"));//w10 classic calc
+
+	if (dwTargetProcessId == 0) {
+		print_last_error(_T("GetProcessIdFromName"));
+		return FALSE;
+	}
+
+	/* Obtain a hmodule of kernel32 */
+	hKernel32 = GetModuleHandle(_T("kernel32.dll"));
+	if (hKernel32 == NULL) {
+		print_last_error(_T("GetModuleHandle"));
+		return FALSE;
+	}
+
+	/* Get LoadLibrary address */
+	_tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n"));
+	LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW");
+	if (LoadLibraryAddress == NULL) {
+		print_last_error(_T("GetProcAddress"));
+		return FALSE;
+	}
+	_tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress);
+
+	_tprintf(_T("\t[+] Getting proc id: %u\n"), dwTargetProcessId);
+
+	/* Obtain a handle the process */
+	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTargetProcessId);
+	if (hProcess == NULL) {
+		print_last_error(_T("OpenProcess"));
+		return FALSE;
+	}
+
+	do { // not a loop
+
+		/* Get the full path of the dll */
+		GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL);
+		_tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath);
+
+		// The maximum size of the string buffer.
+		SIZE_T WriteBufferSize = _tcslen(lpDllPath) * sizeof(TCHAR);
+
+		/* Allocate memory into the remote process */
+		_tprintf(_T("\t[+] Allocating space for the path of the DLL\n"));
+		lpBaseAddress = VirtualAllocEx(hProcess, NULL, WriteBufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+		if (lpBaseAddress == NULL) {
+			print_last_error(_T("VirtualAllocEx"));
+			break;
+		}
+
+		/* Write to the remote process */
+		printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress);
+		if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, WriteBufferSize, NULL)) {
+			print_last_error(_T("WriteProcessMemory"));
+			break;
+		}
+
+		hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+		if (hThreadSnapshot == INVALID_HANDLE_VALUE)
+			break;
+
+		THREADENTRY32 te32;
+		te32.dwSize = sizeof(THREADENTRY32);
+
+		//
+		// Brute force threads to find suitable alertable thread for APC injection (if any).
+		//
+		if (Thread32First(hThreadSnapshot, &te32)) {
+			do {
+				if (te32.th32OwnerProcessID == dwTargetProcessId) {
+
+					hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);
+					if (hThread) {
+
+						if (QueueUserAPC((PAPCFUNC)LoadLibraryAddress, hThread, (ULONG_PTR)lpBaseAddress)) {
+
+							if (IsDllInjected(dwTargetProcessId, lpDllName)) {
+								bStatus = TRUE;
+							}
+						}
+						CloseHandle(hThread);
+					}
+				}
+
+				// dll injected - leave
+				if (bStatus) {
+					_tprintf(_T("\t[+] Dll has been injected successfully ...\n"));
+					break;
+				}
+
+			} while (Thread32Next(hThreadSnapshot, &te32));
+		}
+
+	} while (FALSE); // not a loop
+
+	//
+	// Cleanup.
+	//
+	if (hThreadSnapshot != INVALID_HANDLE_VALUE) CloseHandle(hThreadSnapshot);
+
+	if (lpBaseAddress) {
+		VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE);
+	}
+
+	CloseHandle(hProcess);
+
+	return bStatus;
+}
diff --git a/al-khaser/al-khaser/CodeInjection/QueueUserAPC.h b/al-khaser/al-khaser/CodeInjection/QueueUserAPC.h
new file mode 100644
index 0000000000000000000000000000000000000000..a4401e9f4d3a31483234626ef08c00899593a3ca
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/QueueUserAPC.h
@@ -0,0 +1,4 @@
+#pragma once
+
+BOOL QueueUserAPC_Injection();
+
diff --git a/al-khaser/al-khaser/CodeInjection/RtlCreateUserThread.cpp b/al-khaser/al-khaser/CodeInjection/RtlCreateUserThread.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6505639c92842695aaef847648a35bf7b2023e69
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/RtlCreateUserThread.cpp
@@ -0,0 +1,127 @@
+#include "pch.h"
+
+#include "RtlCreateUserThread.h"
+
+BOOL RtlCreateUserThread_Injection()
+{
+	// some vars
+	HMODULE hNtdll;
+	DWORD dwProcessId;
+	HANDLE hProcess;
+	TCHAR lpDllName[] = _T("InjectedDLL.dll");
+	TCHAR lpDllPath[MAX_PATH];
+	LPVOID lpBaseAddress = NULL;
+	BOOL bStatus = FALSE;
+	HMODULE hKernel32;
+	FARPROC LoadLibraryAddress;
+	HANDLE  hRemoteThread = NULL;
+	SIZE_T dwSize;
+	NTSTATUS Status;
+
+	// we have to import our function
+	pRtlCreateUserThread RtlCreateUserThread = NULL;
+
+	/*
+	GetLastError cannot be used with RtlCreateUserThread because this routine does not set Win32 LastError value.
+	Native status code must be translated to Win32 error code and set manually.
+	*/
+	pRtlNtStatusToDosError RtlNtStatusToDosErrorPtr = NULL;
+
+	/* Get Process ID from Process name */
+	dwProcessId = GetProcessIdFromName(_T("notepad.exe"));
+	if (dwProcessId == NULL)
+		return FALSE;
+	_tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId);
+
+	/* Obtain a handle the process */
+	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
+	if (hProcess == NULL) {
+		print_last_error(_T("OpenProcess"));
+		return FALSE;
+	}
+
+	/* Get module handle of ntdll */
+	hNtdll = GetModuleHandle(_T("ntdll.dll"));
+	if (hNtdll == NULL) {
+		print_last_error(_T("GetModuleHandle"));
+		goto Cleanup;
+	}
+
+	/* Get routine pointer, failure is not critical */
+	RtlNtStatusToDosErrorPtr = (pRtlNtStatusToDosError)GetProcAddress(hNtdll, "RtlNtStatusToDosError");
+
+	/* Obtain a handle to kernel32 */
+	hKernel32 = GetModuleHandle(_T("kernel32.dll"));
+	if (hKernel32 == NULL) {
+		print_last_error(_T("GetModuleHandle"));
+		goto Cleanup;
+	}
+
+	// Get the address RtlCreateUserThread
+	_tprintf(_T("\t[+] Looking for RtlCreateUserThread in ntdll\n"));
+	RtlCreateUserThread = (pRtlCreateUserThread)GetProcAddress(hNtdll, "RtlCreateUserThread");
+	if (RtlCreateUserThread == NULL) {
+		print_last_error(_T("GetProcAddress"));
+		goto Cleanup;
+	}
+	_tprintf(_T("\t[+] Found at 0x%p\n"), RtlCreateUserThread);
+
+	/* Get LoadLibrary address */
+	_tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n"));
+	LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW");
+	if (LoadLibraryAddress == NULL) {
+		print_last_error(_T("GetProcAddress"));
+		goto Cleanup;
+	}
+	_tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress);
+
+	/* Get the full path of the dll */
+	GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL);
+	_tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath);
+
+	/* Calculate the number of bytes needed for the DLL's pathname */
+	dwSize = _tcslen(lpDllPath) * sizeof(TCHAR);
+
+	/* Allocate memory into the remote process */
+	_tprintf(_T("\t[+] Allocating space for the path of the DLL\n"));
+	lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+	if (lpBaseAddress == NULL) {
+		print_last_error(_T("VirtualAllocEx"));
+		goto Cleanup;
+	}
+
+	/* Write to the remote process */
+	printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress);
+	if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, dwSize, NULL)) {
+		print_last_error(_T("WriteProcessMemory"));
+		goto Cleanup;
+	}
+
+	/* Create the more thread */
+	Status = RtlCreateUserThread(hProcess, NULL, 0, 0, 0, 0, LoadLibraryAddress, lpBaseAddress, &hRemoteThread, NULL);
+	if (!NT_SUCCESS(Status)) {
+		if (RtlNtStatusToDosErrorPtr) {
+			SetLastError(RtlNtStatusToDosErrorPtr(Status));
+		}
+		else {
+			SetLastError(ERROR_INTERNAL_ERROR);
+		}
+		print_last_error(_T("RtlCreateUserThread"));
+	}
+	else {
+		_tprintf(_T("Remote thread has been created successfully ...\n"));
+		WaitForSingleObject(hRemoteThread, INFINITE);
+		CloseHandle(hRemoteThread);
+
+		/* assign function success return result */
+		bStatus = TRUE;
+	}
+Cleanup:
+	/* hProcess is always initialized here. */
+	if (lpBaseAddress) {
+		VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE);
+	}
+	CloseHandle(hProcess);
+
+	return bStatus;
+}
diff --git a/al-khaser/al-khaser/CodeInjection/RtlCreateUserThread.h b/al-khaser/al-khaser/CodeInjection/RtlCreateUserThread.h
new file mode 100644
index 0000000000000000000000000000000000000000..a20fee81ad8c1dbcd156568f59264aa67faae140
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/RtlCreateUserThread.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL RtlCreateUserThread_Injection();
diff --git a/al-khaser/al-khaser/CodeInjection/SetWindowsHooksEx.cpp b/al-khaser/al-khaser/CodeInjection/SetWindowsHooksEx.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..da05a553a42ebce8d96fe2ff538a74811b9b06f4
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/SetWindowsHooksEx.cpp
@@ -0,0 +1,61 @@
+#include "pch.h"
+
+#include "SetWindowsHooksEx.h"
+
+BOOL SetWindowsHooksEx_Injection()
+{
+	TCHAR lpDllName[] = _T("InjectedDLL.dll");
+	TCHAR lpDllPath[MAX_PATH];
+	HOOKPROC myFunctionAddress;
+	HMODULE hOurDll;
+	DWORD dwProcessId, dwThreadId;
+	HHOOK hHook;
+
+	/* Get Process ID from Process name */
+	dwProcessId = GetProcessIdFromName(_T("notepad.exe"));
+	if (dwProcessId == NULL)
+		return FALSE;
+	_tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId);
+
+	/* Get thread id from process id */
+	dwThreadId = GetMainThreadId(dwProcessId);
+	if (dwThreadId == NULL)
+		return FALSE;
+	_tprintf(_T("\t[+] Getting main thread id of proc id: %u\n"), dwThreadId);
+
+	/* Get the full path of the dll to be injected */
+	GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL);
+	_tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath);
+
+	/* Obtain a handle to our injected dll */
+	hOurDll = LoadLibrary(lpDllPath);
+	if (hOurDll == NULL) {
+		print_last_error(_T("LoadLibrary"));
+		return FALSE;
+	}
+	
+	/* Get 'MyProc' address */
+	_tprintf(_T("\t[+] Looking for 'MyProc' in our dll\n"));
+	 myFunctionAddress = (HOOKPROC)GetProcAddress(hOurDll, "MyProc");
+	if (myFunctionAddress == NULL) {
+		print_last_error(_T("GetProcAddress"));
+		return FALSE;
+	}
+	_tprintf(_T("\t[+] Found at 0x%p\n"), myFunctionAddress);
+
+	/* Injection happens here */
+	hHook = SetWindowsHookEx(WH_KEYBOARD, myFunctionAddress, hOurDll, dwThreadId);
+	if (hHook == NULL) {
+		print_last_error(_T("SetWindowsHookEx"));
+		return FALSE;
+	}
+
+	/* Unhook */
+	_tprintf(_T("SetWindowsHookEx created successfully ...\n"));
+
+	/* When we want to remove the hook */
+	// UnhookWindowsHookEx(hHook);
+
+	return TRUE;
+
+}
diff --git a/al-khaser/al-khaser/CodeInjection/SetWindowsHooksEx.h b/al-khaser/al-khaser/CodeInjection/SetWindowsHooksEx.h
new file mode 100644
index 0000000000000000000000000000000000000000..771588730189fcf5a249aa2a4506a612757ed014
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/SetWindowsHooksEx.h
@@ -0,0 +1,3 @@
+#pragma once
+
+BOOL SetWindowsHooksEx_Injection(); 
\ No newline at end of file
diff --git a/al-khaser/al-khaser/CodeInjection/pch.h b/al-khaser/al-khaser/CodeInjection/pch.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7df92d774ff3829efea501cff3b5b40e5b16f4b
--- /dev/null
+++ b/al-khaser/al-khaser/CodeInjection/pch.h
@@ -0,0 +1 @@
+#include "../pch.h"
\ No newline at end of file
diff --git a/al-khaser/al-khaser/OfficeMacro/al-khaser.docm b/al-khaser/al-khaser/OfficeMacro/al-khaser.docm
new file mode 100644
index 0000000000000000000000000000000000000000..ec99985eb4e8b041075cf27cd0767f4b127505c7
Binary files /dev/null and b/al-khaser/al-khaser/OfficeMacro/al-khaser.docm differ
diff --git a/al-khaser/al-khaser/OfficeMacro/macros.vba b/al-khaser/al-khaser/OfficeMacro/macros.vba
new file mode 100644
index 0000000000000000000000000000000000000000..759fc990b8f977a4c5b68b1473d61b2d98f3c2ed
--- /dev/null
+++ b/al-khaser/al-khaser/OfficeMacro/macros.vba
@@ -0,0 +1,29 @@
+Sub Document_Close()
+
+   On Error Resume Next
+
+   ActiveDocument.Range.Text = "Al-khaser 0.69 by Lord Noteworthy" & vbCrLf & vbCrLf & "Public malware techniques used in the wild: Virtual Machine, Emulation, Debuggers, Sandbox detection." & vbCrLf
+   
+   checkFileMRU
+End Sub
+
+
+Public Sub checkFileMRU()
+
+    printMsg "[*] Checking Application.RecentFiles.Count ..."
+
+    ActiveDocument.Range.Text = ActiveDocument.Range.Text & msg
+    If Application.RecentFiles.Count < 3 Then
+        printMsg "BAD"
+    Else
+        printMsg "GOOD"
+    End If
+    
+End Sub
+
+
+Public Function printMsg(msg)
+
+   ActiveDocument.Range.Text = ActiveDocument.Range.Text & msg
+    
+End Function
\ No newline at end of file
diff --git a/al-khaser/al-khaser/Shared/APIs.cpp b/al-khaser/al-khaser/Shared/APIs.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cd3358195b2d01b3a460fbc0635e33d886a15210
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/APIs.cpp
@@ -0,0 +1,181 @@
+#include "pch.h"
+#include "APIs.h"
+
+#define API_COUNT (sizeof(ApiData)/sizeof(*ApiData))
+
+API_DATA ApiData[] = {
+	/*                Identifier                            Library             Export Name                         X86/X64/either			Minimum OS Version              Removed in OS Version   */
+	{ API_IDENTIFIER::API_CsrGetProcessId,				    "ntdll.dll",		"CsrGetProcessId",				    API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	/* the EnumProcessModulesEx API was moved from psapi.dll into kernel32.dll for Windows 7, then back out afterwards, so we need both versions. */
+	{ API_IDENTIFIER::API_EnumProcessModulesEx_Kernel,		"kernel32.dll",		"EnumProcessModulesEx",				API_OS_BITS::ANY,		API_OS_VERSION::WIN_7,			API_OS_VERSION::WIN_80 },
+	{ API_IDENTIFIER::API_EnumProcessModulesEx_PSAPI,		"psapi.dll",		"EnumProcessModulesEx",				API_OS_BITS::ANY,		API_OS_VERSION::WIN_VISTA,		API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_EnumSystemFirmwareTables,		    "kernel32.dll",		"EnumSystemFirmwareTables",		    API_OS_BITS::ANY,		API_OS_VERSION::WIN_VISTA,		API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_GetActiveProcessorCount,		    "kernel32.dll",		"GetActiveProcessorCount",	    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_7,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_GetNativeSystemInfo,			    "kernel32.dll",		"GetNativeSystemInfo",		    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_GetProductInfo,				    "kernel32.dll",		"GetProductInfo",				    API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_GetSystemFirmwareTable,		    "kernel32.dll",		"GetSystemFirmwareTable",	    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_VISTA,		API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_IsWow64Process,				    "kernel32.dll",		"IsWow64Process",			    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP_SP2,		API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_LdrEnumerateLoadedModules,	    "ntdll.dll",		"LdrEnumerateLoadedModules",    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP_SP1,		API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtClose,						    "ntdll.dll",		"NtClose",					    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtSystemDebugControl,             "ntdll.dll",        "NtSystemDebugControl",             API_OS_BITS::ANY,       API_OS_VERSION::WIN_XP,         API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtCreateDebugObject,			    "ntdll.dll",		"NtCreateDebugObject",		    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtDelayExecution,				    "ntdll.dll",		"NtDelayExecution",			    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtOpenDirectoryObject,		    "ntdll.dll",		"NtOpenDirectoryObject",	    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtQueryDirectoryObject,		    "ntdll.dll",		"NtQueryDirectoryObject",	    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtQueryInformationThread,		    "ntdll.dll",		"NtQueryInformationThread",	    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtQueryInformationProcess,	    "ntdll.dll",		"NtQueryInformationProcess",	    API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtQueryLicenseValue,			    "ntdll.dll",		"NtQueryLicenseValue",	    		API_OS_BITS::ANY,		API_OS_VERSION::WIN_VISTA,		API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtQueryObject,				    "ntdll.dll",		"NtQueryObject",				    API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtQuerySystemInformation,		    "ntdll.dll",		"NtQuerySystemInformation",		    API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtSetInformationThread,		    "ntdll.dll",		"NtSetInformationThread",		    API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtWow64QueryInformationProcess64, "ntdll.dll",        "NtWow64QueryInformationProcess64",	API_OS_BITS::X86_ONLY,	API_OS_VERSION::WIN_XP_SP1,		API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtWow64ReadVirtualMemory64,	    "ntdll.dll",		"NtWow64ReadVirtualMemory64",	    API_OS_BITS::X86_ONLY,	API_OS_VERSION::WIN_XP_SP1,		API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_NtWow64QueryVirtualMemory64,	    "ntdll.dll",		"NtWow64QueryVirtualMemory64",	    API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP_SP1,		API_OS_VERSION::WIN_10 },
+	{ API_IDENTIFIER::API_NtYieldExecution,			    	"ntdll.dll",		"NtYieldExecution",			    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_RtlInitUnicodeString,			    "ntdll.dll",		"RtlInitUnicodeString",		    	API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_RtlGetVersion,		    		"ntdll.dll",		"RtlGetVersion",		    		API_OS_BITS::ANY,		API_OS_VERSION::WIN_XP,			API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_WudfIsAnyDebuggerPresent,	    	"WUDFPlatform.dll",	"WudfIsAnyDebuggerPresent",	    	API_OS_BITS::X64_ONLY,	API_OS_VERSION::WIN_VISTA,		API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_WudfIsKernelDebuggerPresent,	    "WUDFPlatform.dll",	"WudfIsKernelDebuggerPresent",	    API_OS_BITS::X64_ONLY,	API_OS_VERSION::WIN_VISTA,		API_OS_VERSION::NONE },
+	{ API_IDENTIFIER::API_WudfIsUserDebuggerPresent,	    "WUDFPlatform.dll",	"WudfIsUserDebuggerPresent",    	API_OS_BITS::X64_ONLY,	API_OS_VERSION::WIN_VISTA,		API_OS_VERSION::NONE }
+};
+
+void API::Init()
+{
+	for (int i = 0; i < API_COUNT; i++)
+	{
+		ApiData[i].ExpectedAvailable = ShouldFunctionExistOnCurrentPlatform(ApiData[i].PlatformBits, ApiData[i].MinVersion, ApiData[i].RemovedInVersion);
+
+		HMODULE hLib = LoadLibraryA(ApiData[i].Library);
+		if (hLib == NULL)
+		{
+			ApiData[i].Available = false;
+			continue;
+		}
+		ApiData[i].Pointer = GetProcAddress(hLib, ApiData[i].EntryName);
+		if (ApiData[i].Pointer == NULL)
+		{
+			ApiData[i].Available = false;
+			continue;
+		}
+		else
+		{
+			ApiData[i].Available = true;
+		}
+	}
+}
+
+bool API::ShouldFunctionExistOnCurrentPlatform(API_OS_BITS bits, API_OS_VERSION minVersion, API_OS_VERSION removedInVersion)
+{
+	// check if the API should exist on the OS
+
+	// does it meet bitness requirements?
+	if (bits != API_OS_BITS::ANY)
+	{
+#ifdef ENV64BIT
+		if (bits != API_OS_BITS::X64_ONLY)
+			return false;
+#endif
+#ifdef ENV32BIT
+		if (bits != API_OS_BITS::X86_ONLY)
+			return false;
+#endif
+	}
+
+	// does it meet minimum version
+	bool foundMinVer = false;
+	bool metMinimumRequirement = false;
+
+	for (int i = 0; i < API_OS_VERSION::VERSION_MAX; i++)
+	{
+		if (i == API_OS_VERSION::NONE)
+			continue;
+
+		if (VersionFunctionMap[i].Version == minVersion)
+		{
+			foundMinVer = true;
+			metMinimumRequirement = VersionFunctionMap[i].Function();
+		}
+	}
+	if (!foundMinVer)
+	{
+		printf("ERROR: Minimum version value was invalid.\n");
+		assert(false);
+		return false;
+	}
+	if (!metMinimumRequirement)
+		return false;
+
+	// if there's no maximum OS restriction, the API should exist
+	if (removedInVersion == API_OS_VERSION::NONE)
+		return true;
+
+	// we have an upper restriction. was the API removed in this version?
+	bool foundRemovedVer = false;
+	bool metMaximumRequirement = false;
+	for (int i = 0; i < API_OS_VERSION::VERSION_MAX; i++)
+	{
+		if (VersionFunctionMap[i].Version == removedInVersion)
+		{
+			foundRemovedVer = true;
+			metMaximumRequirement = !VersionFunctionMap[i].Function();
+		}
+	}
+	if (!foundRemovedVer)
+	{
+		printf("ERROR: Removed version value was invalid.\n");
+		assert(false);
+		return false;
+	}
+
+	return metMaximumRequirement;
+}
+
+void API::PrintAvailabilityReport()
+{
+	int warningCount = 0;
+	for (int i = 0; i < API_COUNT; i++)
+	{
+		if (ApiData[i].ExpectedAvailable && !ApiData[i].Available)
+		{
+			printf("[*] Warning: API %s!%s was expected to exist but was not found.\n", ApiData[i].Library, ApiData[i].EntryName);
+			warningCount += 1;
+		}
+	}
+	if (warningCount == 0)
+	{
+		printf("[*] All APIs present and accounted for.\n");
+	}
+}
+
+bool API::IsAvailable(API_IDENTIFIER api)
+{
+	for (int i = 0; i < API_COUNT; i++)
+	{
+		if (ApiData[i].Identifier == api)
+		{
+			return ApiData[i].Available;
+		}
+	}
+	assert(false);
+	return false;
+}
+
+void* API::GetAPI(API_IDENTIFIER api)
+{
+	for (int i = 0; i < API_COUNT; i++)
+	{
+		if (ApiData[i].Identifier == api)
+		{
+			if (ApiData[i].Available)
+			{
+				return ApiData[i].Pointer;
+			}
+			else
+			{
+				return nullptr;
+			}
+		}
+	}
+	assert(false);
+	return nullptr;
+}
diff --git a/al-khaser/al-khaser/Shared/APIs.h b/al-khaser/al-khaser/Shared/APIs.h
new file mode 100644
index 0000000000000000000000000000000000000000..349a46ffdbc39dc3dd49dacf4172d25c95452a40
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/APIs.h
@@ -0,0 +1,130 @@
+#pragma once
+
+enum API_IDENTIFIER
+{
+	API_CsrGetProcessId,
+	API_EnumSystemFirmwareTables,
+	API_GetActiveProcessorCount,
+	API_GetSystemFirmwareTable,
+	API_GetNativeSystemInfo,
+	API_GetProductInfo,
+	API_EnumProcessModulesEx_Kernel,
+	API_EnumProcessModulesEx_PSAPI,
+	API_IsWow64Process,
+	API_LdrEnumerateLoadedModules,
+	API_NtClose,
+	API_NtSystemDebugControl,
+	API_NtCreateDebugObject,
+	API_NtDelayExecution,
+	API_NtOpenDirectoryObject,
+	API_NtQueryInformationThread,
+	API_NtQueryInformationProcess,
+	API_NtQueryLicenseValue,
+	API_NtQueryDirectoryObject,
+	API_NtQueryObject,
+	API_NtQuerySystemInformation,
+	API_NtSetInformationThread,
+	API_NtWow64QueryInformationProcess64,
+	API_NtWow64QueryVirtualMemory64,
+	API_NtWow64ReadVirtualMemory64,
+	API_NtYieldExecution,
+	API_RtlGetVersion,
+	API_RtlInitUnicodeString,
+	API_WudfIsAnyDebuggerPresent,
+	API_WudfIsKernelDebuggerPresent,
+	API_WudfIsUserDebuggerPresent,
+};
+
+enum API_OS_VERSION
+{
+	NONE,
+	WIN_XP,
+	WIN_XP_SP1,
+	WIN_XP_SP2,
+	WIN_XP_SP3,
+	WIN_VISTA,
+	WIN_VISTA_SP1,
+	WIN_VISTA_SP2,
+	WIN_7,
+	WIN_7_SP1,
+	WIN_80,
+	WIN_81,
+	WIN_10,
+	VERSION_MAX
+};
+
+enum API_OS_BITS
+{
+	ANY,
+	X86_ONLY,
+	X64_ONLY,
+};
+
+struct VERSION_FUNCTION_MAP
+{
+	API_OS_VERSION Version;
+	bool(*Function)();
+
+	VERSION_FUNCTION_MAP(API_OS_VERSION version, bool(*function)())
+	{
+		Version = version;
+		Function = function;
+	}
+
+	VERSION_FUNCTION_MAP()
+	{
+	}
+};
+
+struct API_DATA
+{
+	API_IDENTIFIER Identifier;
+	const char* Library;
+	const char* EntryName;
+	API_OS_BITS PlatformBits;
+	API_OS_VERSION MinVersion;
+	API_OS_VERSION RemovedInVersion;
+	bool Available;
+	bool ExpectedAvailable;
+	void* Pointer;
+
+	API_DATA(API_IDENTIFIER identifier, const char* lib, const char* name, API_OS_BITS bits, API_OS_VERSION minVersion, API_OS_VERSION removedInVersion)
+	{
+		Identifier = identifier;
+		Library = lib;
+		EntryName = name;
+		PlatformBits = bits;
+		MinVersion = minVersion;
+		RemovedInVersion = removedInVersion;
+		Available = false;
+		ExpectedAvailable = false;
+		Pointer = nullptr;
+	}
+};
+
+const VERSION_FUNCTION_MAP VersionFunctionMap[] = {
+	{ API_OS_VERSION::NONE, nullptr },
+	{ API_OS_VERSION::WIN_XP, IsWindowsXPOrGreater },
+	{ API_OS_VERSION::WIN_XP_SP1, IsWindowsXPSP1OrGreater },
+	{ API_OS_VERSION::WIN_XP_SP2, IsWindowsXPSP2OrGreater },
+	{ API_OS_VERSION::WIN_XP_SP3, IsWindowsXPSP3OrGreater },
+	{ API_OS_VERSION::WIN_VISTA, IsWindowsVistaOrGreater },
+	{ API_OS_VERSION::WIN_VISTA_SP1, IsWindowsVistaSP1OrGreater },
+	{ API_OS_VERSION::WIN_VISTA_SP2, IsWindowsVistaSP2OrGreater },
+	{ API_OS_VERSION::WIN_7, IsWindows7OrGreater },
+	{ API_OS_VERSION::WIN_7_SP1, IsWindows7SP1OrGreater },
+	{ API_OS_VERSION::WIN_80, IsWindows8OrGreater },
+	{ API_OS_VERSION::WIN_81, IsWindows8Point1OrGreater },
+	{ API_OS_VERSION::WIN_10, IsWindows10OrGreater },
+};
+
+class API
+{
+private:
+	static bool ShouldFunctionExistOnCurrentPlatform(API_OS_BITS bits, API_OS_VERSION minVersion, API_OS_VERSION removedInVersion);
+public:
+	static void Init();
+	static void PrintAvailabilityReport();
+	static bool IsAvailable(API_IDENTIFIER api);
+	static void* GetAPI(API_IDENTIFIER api);
+};
\ No newline at end of file
diff --git a/al-khaser/al-khaser/Shared/ApiTypeDefs.cpp b/al-khaser/al-khaser/Shared/ApiTypeDefs.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1d9f38c57d63f197d552a5283424f75f885bb1c2
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/ApiTypeDefs.cpp
@@ -0,0 +1 @@
+#include "pch.h"
diff --git a/al-khaser/al-khaser/Shared/ApiTypeDefs.h b/al-khaser/al-khaser/Shared/ApiTypeDefs.h
new file mode 100644
index 0000000000000000000000000000000000000000..5cd3d6b4b4c0457aa722dfe18164cbc306c526f8
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/ApiTypeDefs.h
@@ -0,0 +1,136 @@
+#pragma once
+
+typedef DWORD(NTAPI* pCsrGetId)(VOID);
+typedef BOOL(WINAPI* pEnumProcessModulesEx)(
+	HANDLE hProcess,
+	HMODULE *lphModule,
+	DWORD cb,
+	LPDWORD lpcbNeeded,
+	DWORD dwFilterFlag);
+typedef UINT(WINAPI* pEnumSystemFirmwareTables)(DWORD, PVOID, DWORD);
+typedef DWORD(WINAPI* pGetActiveProcessorCount)(WORD);
+typedef UINT(WINAPI* pGetSystemFirmwareTable)(DWORD, DWORD, PVOID, DWORD); 
+typedef void (WINAPI *pGetNativeSystemInfo)(LPSYSTEM_INFO);
+typedef BOOL(WINAPI *pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD);
+typedef BOOL(WINAPI *pIsWow64Process) (HANDLE, PBOOL);
+typedef DWORD(WINAPI * pRtlCreateUserThread)(
+	IN HANDLE 					ProcessHandle,
+	IN PSECURITY_DESCRIPTOR 	SecurityDescriptor,
+	IN BOOL 					CreateSuspended,
+	IN ULONG					StackZeroBits,
+	IN OUT PULONG				StackReserved,
+	IN OUT PULONG				StackCommit,
+	IN LPVOID					StartAddress,
+	IN LPVOID					StartParameter,
+	OUT HANDLE 					ThreadHandle,
+	OUT LPVOID					ClientID
+	);
+typedef NTSTATUS(WINAPI* pNtClose)(HANDLE);
+typedef enum _SYSDBG_COMMAND {
+	SysDbgQueryModuleInformation,
+	SysDbgQueryTraceInformation,
+	SysDbgSetTracepoint,
+	SysDbgSetSpecialCall,
+	SysDbgClearSpecialCalls,
+	SysDbgQuerySpecialCalls,
+	SysDbgBreakPoint,
+	SysDbgQueryVersion,
+	SysDbgReadVirtual,
+	SysDbgWriteVirtual,
+	SysDbgReadPhysical,
+	SysDbgWritePhysical,
+	SysDbgReadControlSpace,
+	SysDbgWriteControlSpace,
+	SysDbgReadIoSpace,
+	SysDbgWriteIoSpace,
+	SysDbgReadMsr,
+	SysDbgWriteMsr,
+	SysDbgReadBusData,
+	SysDbgWriteBusData,
+	SysDbgCheckLowMemory,
+	SysDbgEnableKernelDebugger,
+	SysDbgDisableKernelDebugger,
+	SysDbgGetAutoKdEnable,
+	SysDbgSetAutoKdEnable,
+	SysDbgGetPrintBufferSize,
+	SysDbgSetPrintBufferSize,
+	SysDbgGetKdUmExceptionEnable,
+	SysDbgSetKdUmExceptionEnable,
+	SysDbgGetTriageDump,
+	SysDbgGetKdBlockEnable,
+	SysDbgSetKdBlockEnable,
+} SYSDBG_COMMAND, * PSYSDBG_COMMAND;
+typedef NTSTATUS(NTAPI* pNtSystemDebugControl)(
+	IN SYSDBG_COMMAND Command,
+	IN PVOID InputBuffer,
+	IN ULONG InputBufferLength,
+	OUT PVOID OutputBuffer,
+	IN ULONG OutputBufferLength,
+	OUT PULONG ReturnLength);
+typedef NTSTATUS(WINAPI *pNtCreateDebugObject)(OUT PHANDLE, IN ACCESS_MASK, IN POBJECT_ATTRIBUTES, IN ULONG);
+typedef NTSTATUS(WINAPI *pNtCreateThreadEx)(
+	OUT PHANDLE ThreadHandle,
+	IN ACCESS_MASK DesiredAccess,
+	IN OPTIONAL POBJECT_ATTRIBUTES ObjectAttributes,
+	IN HANDLE ProcessHandle,
+	IN PVOID StartRoutine,
+	IN OPTIONAL PVOID Argument,
+	IN ULONG CreateFlags, //THREAD_CREATE_FLAGS_*
+	IN OPTIONAL ULONG_PTR ZeroBits,
+	IN OPTIONAL SIZE_T StackSize,
+	IN OPTIONAL SIZE_T MaximumStackSize,
+	IN OPTIONAL PPS_ATTRIBUTE_LIST AttributeList
+	);
+typedef NTSTATUS(WINAPI *pNtDelayExecution)(IN BOOLEAN, IN PLARGE_INTEGER);
+typedef NTSTATUS(WINAPI *pNtQueryInformationProcess)(IN  HANDLE, IN  UINT, OUT PVOID, IN ULONG, OUT PULONG);
+typedef NTSTATUS(WINAPI *pNtQueryInformationThread)(HANDLE, UINT, PVOID, ULONG, PULONG);
+
+typedef NTSTATUS(NTAPI *pNtQueryLicenseValue)(
+	IN PUNICODE_STRING ValueName,
+	OUT OPTIONAL PULONG Type,
+	OUT PVOID Data,
+	IN ULONG DataSize,
+	OUT PULONG ResultDataSize);
+
+typedef VOID (NTAPI *pRtlInitUnicodeString)(
+	_Out_ PUNICODE_STRING DestinationString,
+	_In_opt_ PCWSTR SourceString);
+
+
+typedef NTSTATUS(WINAPI *pNtQueryDirectoryObject)(_In_ HANDLE, _Out_opt_ PVOID, _In_ ULONG, _In_ BOOLEAN, _In_ BOOLEAN, _Inout_ PULONG, _Out_opt_ PULONG);
+typedef NTSTATUS(WINAPI *pNtOpenDirectoryObject)(OUT PHANDLE, IN ACCESS_MASK, IN POBJECT_ATTRIBUTES);
+
+typedef NTSTATUS(WINAPI *pNtQueryObject)(IN HANDLE, IN UINT, OUT PVOID, IN ULONG, OUT PULONG);
+typedef NTSTATUS(WINAPI *pNtQuerySystemInformation)(IN UINT, OUT PVOID, IN ULONG, OUT PULONG);
+typedef NTSTATUS(WINAPI *pNtSetInformationThread)(HANDLE, UINT, PVOID, ULONG);
+typedef NTSTATUS(WINAPI* pNtUnmapViewOfSection)(HANDLE ProcessHandle, PVOID BaseAddress);
+typedef NTSTATUS(WINAPI* pNtYieldExecution)();
+typedef NTSTATUS(WINAPI* pRtlGetVersion)(RTL_OSVERSIONINFOEXW*);
+typedef ULONG (NTAPI* pRtlNtStatusToDosError)(IN NTSTATUS Status);
+typedef NTSTATUS(NTAPI * pNtWow64QueryInformationProcess64)(
+    IN HANDLE ProcessHandle,
+    ULONG ProcessInformationClass,
+    OUT PVOID ProcessInformation,
+    IN ULONG ProcessInformationLength,
+    OUT PULONG ReturnLength OPTIONAL);
+typedef NTSTATUS(WINAPI *pNtWow64ReadVirtualMemory64)(
+	HANDLE ProcessHandle,
+	PVOID64 BaseAddress,
+	PVOID Buffer,
+	ULONGLONG BufferSize,
+	PULONGLONG NumberOfBytesRead
+);
+typedef NTSTATUS(NTAPI *pNtWow64QueryVirtualMemory64)(
+	IN HANDLE ProcessHandle,
+	IN PVOID64 BaseAddress,
+	IN DWORD MemoryInformationClass,
+	OUT PMEMORY_BASIC_INFORMATION64 MemoryInformation,
+	IN ULONG64 Size,
+	OUT PULONG64 ReturnLength OPTIONAL);
+typedef NTSTATUS(NTAPI *pLdrEnumerateLoadedModules)(
+	IN BOOLEAN ReservedFlag,
+	IN PLDR_ENUM_CALLBACK EnumProc,
+	IN PVOID Context);
+typedef INT(NTAPI *pWudfIsAnyDebuggerPresent)();
+typedef INT(NTAPI *pWudfIsKernelDebuggerPresent)();
+typedef INT(NTAPI *pWudfIsUserDebuggerPresent)();
diff --git a/al-khaser/al-khaser/Shared/Common.cpp b/al-khaser/al-khaser/Shared/Common.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..079156e031bc9900f1c90939fe1694bb718fb7c5
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/Common.cpp
@@ -0,0 +1,199 @@
+#include "pch.h"
+#include "Common.h"
+
+VOID print_detected()
+{
+	/* Get handle to standard output */
+	HANDLE nStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
+	CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
+	SecureZeroMemory(&ConsoleScreenBufferInfo, sizeof(CONSOLE_SCREEN_BUFFER_INFO));
+
+	/* Save the original console color */
+	GetConsoleScreenBufferInfo(nStdHandle, &ConsoleScreenBufferInfo);
+	WORD OriginalColors = *(&ConsoleScreenBufferInfo.wAttributes);
+
+	SetConsoleTextAttribute(nStdHandle, 12);
+	_tprintf(TEXT("[ BAD  ]\n"));
+	SetConsoleTextAttribute(nStdHandle, OriginalColors);
+}
+
+VOID print_not_detected()
+{
+	/* Get handle to standard output */
+	HANDLE nStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
+	CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
+	SecureZeroMemory(&ConsoleScreenBufferInfo, sizeof(CONSOLE_SCREEN_BUFFER_INFO));
+
+	/* Save the original console color */
+	GetConsoleScreenBufferInfo(nStdHandle, &ConsoleScreenBufferInfo);
+	WORD OriginalColors = *(&ConsoleScreenBufferInfo.wAttributes);
+
+	SetConsoleTextAttribute(nStdHandle, 10);
+	_tprintf(TEXT("[ GOOD ]\n"));
+	SetConsoleTextAttribute(nStdHandle, OriginalColors);
+}
+
+VOID print_category(const TCHAR* text)
+{
+	/* Get handle to standard output */
+	HANDLE nStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);  
+	CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
+	SecureZeroMemory(&ConsoleScreenBufferInfo, sizeof(CONSOLE_SCREEN_BUFFER_INFO));
+
+	/* Save the original console color */
+	GetConsoleScreenBufferInfo(nStdHandle, &ConsoleScreenBufferInfo);
+	WORD OriginalColors = *(&ConsoleScreenBufferInfo.wAttributes);
+
+	SetConsoleTextAttribute(nStdHandle, 13);
+	_tprintf(TEXT("\n-------------------------[%s]-------------------------\n"), text);
+	SetConsoleTextAttribute(nStdHandle, OriginalColors);
+}
+
+VOID _print_check_text(const TCHAR* szMsg)
+{
+	_tprintf(TEXT("[*] %s"), szMsg);
+
+	/* align the result according to the length of the text */
+	size_t spaces_to_padd = 95 - _tcslen(szMsg);
+	while (spaces_to_padd > 0) {
+		_tprintf(TEXT(" "));
+		spaces_to_padd--;
+	}
+}
+
+VOID _print_check_result(int result, const TCHAR* szMsg)
+{
+	if (result == TRUE)
+		print_detected();
+	else
+		print_not_detected();
+
+	/* log to file*/
+	TCHAR buffer[256] = _T("");
+	_stprintf_s(buffer, sizeof(buffer) / sizeof(TCHAR), _T("[*] %s -> %d"), szMsg, result);
+	LOG_PRINT(buffer);
+}
+
+VOID print_results(int result, TCHAR* szMsg)
+{
+	_print_check_text(szMsg);
+	_print_check_result(result, szMsg);
+}
+
+// note: templated version of this function is in Common.h
+VOID exec_check(int(*callback)(), const TCHAR* szMsg)
+{
+	/* Print the text to screen so we can see what's currently running */
+	_print_check_text(szMsg);
+
+	/* Call our check */
+	int result = callback();
+
+	/* Print / Log the result */
+	if (szMsg)
+		_print_check_result(result, szMsg);
+}
+
+VOID resize_console_window()
+{
+	// Change the window title:
+	SetConsoleTitle(_T("Al-Khaser - by Lord Noteworthy"));
+
+	// Get console window handle
+	HWND wh = GetConsoleWindow();
+
+	// Move window to required position
+	MoveWindow(wh, 100, 100, 900, 900, TRUE);
+}
+
+
+VOID print_os()
+{
+	TCHAR szOS[MAX_PATH] = _T("");
+	if (GetOSDisplayString(szOS))
+	{
+		//_tcscpy_s(szOS, MAX_PATH, szOS);
+		_tprintf(_T("\n[*] You are running: %s\n"), szOS);
+	}
+}
+
+VOID print_last_error(LPCTSTR lpszFunction)
+{
+	// Retrieve the system error message for the last-error code
+
+	LPVOID lpMsgBuf;
+	LPVOID lpDisplayBuf;
+	DWORD dw = GetLastError();
+
+	if (FormatMessage(
+		FORMAT_MESSAGE_ALLOCATE_BUFFER |
+		FORMAT_MESSAGE_FROM_SYSTEM |
+		FORMAT_MESSAGE_IGNORE_INSERTS,
+		NULL,
+		dw,
+		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+		(LPTSTR)&lpMsgBuf,
+		0, NULL) == 0)
+	{
+		//FormatMessage failed, return
+		return;
+	}
+
+	// Display the error message and exit the process
+
+	lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
+		(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
+
+	if (lpDisplayBuf) {
+
+		StringCchPrintf((LPTSTR)lpDisplayBuf,
+			LocalSize(lpDisplayBuf) / sizeof(TCHAR),
+			TEXT("%s failed with error %u: %s"),
+			lpszFunction, dw, lpMsgBuf);
+
+		_tprintf((LPCTSTR)lpDisplayBuf);
+
+		LocalFree(lpDisplayBuf);
+	}
+	LocalFree(lpMsgBuf);
+}
+
+WCHAR* ascii_to_wide_str(CHAR* lpMultiByteStr)
+{
+
+	/* Get the required size */
+	INT iNumChars = MultiByteToWideChar(CP_ACP, 0, lpMultiByteStr, -1, NULL, 0);
+
+	/* Allocate new wide string */
+
+	SIZE_T Size = (1 + iNumChars) * sizeof(WCHAR);
+	
+	WCHAR *lpWideCharStr = reinterpret_cast<WCHAR*>(malloc(Size));
+
+	if (lpWideCharStr) {
+		SecureZeroMemory(lpWideCharStr, Size);
+		/* Do the conversion */
+		iNumChars = MultiByteToWideChar(CP_ACP, 0, lpMultiByteStr, -1, lpWideCharStr, iNumChars);
+	}
+	return lpWideCharStr;
+}
+
+CHAR* wide_str_to_multibyte (TCHAR* lpWideStr)
+{
+	errno_t status;
+	int *pRetValue = NULL;
+	CHAR *mbchar = NULL;
+	size_t sizeInBytes = 0;
+	
+	status = wctomb_s(pRetValue, mbchar, sizeInBytes, *lpWideStr);
+	return mbchar;
+}
+
+BOOL IsHexString(WCHAR* szStr) {
+	std::wstring s(szStr);
+
+	if (std::find_if(s.begin(), s.end(), [](wchar_t c) {return !std::isxdigit(static_cast<unsigned char>(c)); }) == s.end())
+		return TRUE;
+	else
+		return FALSE;
+}
diff --git a/al-khaser/al-khaser/Shared/Common.h b/al-khaser/al-khaser/Shared/Common.h
new file mode 100644
index 0000000000000000000000000000000000000000..14a53a5b564a2354093a9cb70bb3e5aadebbcde9
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/Common.h
@@ -0,0 +1,32 @@
+#pragma once
+
+VOID print_detected() ;
+VOID print_not_detected() ;
+VOID print_category(const TCHAR* text);
+VOID print_last_error(LPCTSTR lpszFunction);
+VOID print_os();
+WCHAR* ascii_to_wide_str(CHAR* lpMultiByteStr);
+CHAR* wide_str_to_multibyte(TCHAR* lpWideStr);
+BOOL IsHexString(WCHAR* szStr);
+VOID resize_console_window();
+VOID print_results(int result, TCHAR* szMsg);
+VOID _print_check_text(const TCHAR* szMsg);
+VOID _print_check_result(int result, const TCHAR* szMsg);
+
+VOID exec_check(int(*callback)(), const TCHAR* szMsg);
+
+// this must be defined in this header file
+// see: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file
+template <typename T>
+VOID exec_check(int(*callback)(T param), T param, const TCHAR* szMsg)
+{
+	/* Print the text to screen so we can see what's currently running */
+	_print_check_text(szMsg);
+
+	/* Call our check */
+	int result = callback(param);
+
+	/* Print / Log the result */
+	if (szMsg)
+		_print_check_result(result, szMsg);
+}
\ No newline at end of file
diff --git a/al-khaser/al-khaser/Shared/Utils.cpp b/al-khaser/al-khaser/Shared/Utils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..78ad268f89a5e79183512b5de7b402e438c9a3e9
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/Utils.cpp
@@ -0,0 +1,1121 @@
+#include "pch.h"
+#include "Utils.h"
+
+BOOL IsWoW64()
+{
+	BOOL bIsWow64 = FALSE;
+	
+	if (API::IsAvailable(API_IDENTIFIER::API_IsWow64Process))
+	{
+		auto fnIsWow64Process = static_cast<pIsWow64Process>(API::GetAPI(API_IDENTIFIER::API_IsWow64Process));
+		if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
+		{
+			// handle error
+		}
+	}
+
+	return bIsWow64;
+}
+
+PVOID64 GetPeb64()
+{
+	PVOID64 peb64 = NULL;
+
+	if (API::IsAvailable(API_IDENTIFIER::API_NtWow64QueryInformationProcess64))
+	{
+		PROCESS_BASIC_INFORMATION_WOW64 pbi64 = {};
+
+		auto NtWow64QueryInformationProcess64 = static_cast<pNtWow64QueryInformationProcess64>(API::GetAPI(API_IDENTIFIER::API_NtWow64QueryInformationProcess64));
+		NTSTATUS status = NtWow64QueryInformationProcess64(GetCurrentProcess(), ProcessBasicInformation, &pbi64, sizeof(pbi64), nullptr);
+		if ( NT_SUCCESS ( status ) )
+			peb64 = pbi64.PebBaseAddress;
+	}
+
+	return peb64;
+}
+
+BOOL Is_RegKeyValueExists(HKEY hKey, const TCHAR* lpSubKey, const TCHAR* lpValueName, const TCHAR* search_str)
+{
+	HKEY hkResult = NULL;
+	TCHAR lpData[1024] = { 0 };
+	DWORD cbData = MAX_PATH;
+
+	if (RegOpenKeyEx(hKey, lpSubKey, NULL, KEY_READ, &hkResult) == ERROR_SUCCESS)
+	{
+		if (RegQueryValueEx(hkResult, lpValueName, NULL, NULL, (LPBYTE)lpData, &cbData) == ERROR_SUCCESS)
+		{
+			if (StrStrI((PCTSTR)lpData, search_str) != NULL)
+			{
+				RegCloseKey(hkResult);
+				return TRUE;
+			}
+		}
+		RegCloseKey(hkResult);
+	}
+	return FALSE;
+
+}
+
+BOOL Is_RegKeyExists(HKEY hKey, const TCHAR* lpSubKey)
+{
+	HKEY hkResult = NULL;
+	TCHAR lpData[1024] = { 0 };
+	DWORD cbData = MAX_PATH;
+
+	if (RegOpenKeyEx(hKey, lpSubKey, NULL, KEY_READ, &hkResult) == ERROR_SUCCESS)
+	{
+		RegCloseKey(hkResult);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+BOOL is_FileExists(TCHAR* szPath)
+{
+	DWORD dwAttrib = GetFileAttributes(szPath);
+	return (dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
+}
+
+BOOL is_DirectoryExists(TCHAR* szPath)
+{
+	DWORD dwAttrib = GetFileAttributes(szPath);
+	return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
+}
+
+BOOL check_mac_addr(const TCHAR* szMac)
+{
+	BOOL bResult = FALSE;
+	PIP_ADAPTER_INFO pAdapterInfo, pAdapterInfoPtr;
+	ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
+
+	pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(sizeof(IP_ADAPTER_INFO));
+	if (pAdapterInfo == NULL)
+	{
+		_tprintf(_T("Error allocating memory needed to call GetAdaptersinfo.\n"));
+		return -1;
+	}
+
+	DWORD dwResult = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
+
+	// Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable
+	if (dwResult == ERROR_BUFFER_OVERFLOW)
+	{
+		FREE(pAdapterInfo);
+		pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(ulOutBufLen);
+		if (pAdapterInfo == NULL) {
+			printf("Error allocating memory needed to call GetAdaptersinfo\n");
+			return 1;
+		}
+
+		// Now, we can call GetAdaptersInfo
+		dwResult = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
+	}
+
+	if (dwResult == ERROR_SUCCESS)
+	{
+		// Convert the given mac address to an array of multibyte chars so we can compare.
+		CHAR szMacMultiBytes[4];
+		for (int i = 0; i < 4; i++) {
+			szMacMultiBytes[i] = (CHAR)szMac[i];
+		}
+
+		pAdapterInfoPtr = pAdapterInfo;
+
+		while (pAdapterInfoPtr)
+		{
+
+			if (pAdapterInfoPtr->AddressLength == 6 && !memcmp(szMacMultiBytes, pAdapterInfoPtr->Address, 3))
+			{
+				bResult = TRUE;
+				break;
+			}
+			pAdapterInfoPtr = pAdapterInfoPtr->Next;
+		}
+	}
+
+	FREE(pAdapterInfo);
+
+	return bResult;
+}
+
+BOOL check_adapter_name(const TCHAR* szName)
+{
+	BOOL bResult = FALSE;
+	PIP_ADAPTER_INFO pAdapterInfo, pAdapterInfoPtr;
+	ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
+
+	WCHAR *pwszConverted;
+
+	pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(sizeof(IP_ADAPTER_INFO));
+	if (pAdapterInfo == NULL)
+	{
+		_tprintf(_T("Error allocating memory needed to call GetAdaptersinfo.\n"));
+		return -1;
+	}
+
+	// Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable
+
+	DWORD dwResult = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
+
+	if (dwResult == ERROR_BUFFER_OVERFLOW)
+	{
+		FREE(pAdapterInfo);
+		pAdapterInfo = (PIP_ADAPTER_INFO)MALLOC(ulOutBufLen);
+		if (pAdapterInfo == NULL) {
+			printf("Error allocating memory needed to call GetAdaptersinfo\n");
+			return 1;
+		}
+
+		dwResult = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
+	}
+
+	if (dwResult == ERROR_SUCCESS)
+	{
+		pAdapterInfoPtr = pAdapterInfo;
+
+		while (pAdapterInfoPtr)
+		{
+			pwszConverted = ascii_to_wide_str(pAdapterInfoPtr->Description);
+			if (pwszConverted) {
+				if (StrStrI(pwszConverted, szName) != NULL)
+				{
+					bResult = TRUE;
+				}
+				free(pwszConverted);
+
+				if (bResult)
+					break;
+			}
+			pAdapterInfoPtr = pAdapterInfoPtr->Next;
+		}
+	}
+
+	FREE(pAdapterInfo);
+
+	return bResult;
+}
+
+BOOL GetOSDisplayString(LPTSTR pszOS)
+{
+	OSVERSIONINFOEX osvi;
+	SYSTEM_INFO si;
+	//PGNSI pGNSI;
+	//PGPI pGPI;
+	BOOL bOsVersionInfoEx;
+	DWORD dwType;
+
+	SecureZeroMemory(&si, sizeof(SYSTEM_INFO));
+	SecureZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+
+	if (!API::IsAvailable(API_RtlGetVersion))
+		return FALSE;
+
+	auto RtlGetVersion = static_cast<pRtlGetVersion>(API::GetAPI(API_IDENTIFIER::API_RtlGetVersion));
+
+	bOsVersionInfoEx = RtlGetVersion((RTL_OSVERSIONINFOEXW*)&osvi);
+
+	if (API::IsAvailable(API_GetNativeSystemInfo))
+	{
+		auto GetNativeSystemInfo = static_cast<pGetNativeSystemInfo>(API::GetAPI(API_IDENTIFIER::API_GetNativeSystemInfo));
+		GetNativeSystemInfo(&si);
+	}
+	else
+	{
+		GetSystemInfo(&si);
+	}
+
+	if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && osvi.dwMajorVersion > 4)
+	{
+		StringCchCopy(pszOS, MAX_PATH, TEXT("Microsoft "));
+
+		// Test for the specific product.
+		// todo: Not working in Win10, I should use VersionHelpers
+		if (osvi.dwMajorVersion == 10)
+		{
+			if (osvi.dwMinorVersion == 0)
+			{
+				if (osvi.wProductType == VER_NT_WORKSTATION)
+					StringCchCat(pszOS, MAX_PATH, TEXT("Windows 10 "));
+				else {
+					if (osvi.dwBuildNumber > 17763) {
+						StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 20XX "));
+					}
+					else if (osvi.dwBuildNumber > 14393) {
+						StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2019 "));
+					}
+					else {
+						StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2016 "));
+					}
+				}
+			}
+		}
+
+		else if (osvi.dwMajorVersion == 6)
+		{
+			if (osvi.dwMinorVersion == 0)
+			{
+				if (osvi.wProductType == VER_NT_WORKSTATION)
+					StringCchCat(pszOS, MAX_PATH, TEXT("Windows Vista "));
+				else StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2008 "));
+			}
+
+			if (osvi.dwMinorVersion == 1)
+			{
+				if (osvi.wProductType == VER_NT_WORKSTATION)
+					StringCchCat(pszOS, MAX_PATH, TEXT("Windows 7 "));
+				else StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2008 R2 "));
+			}
+
+			if (osvi.dwMinorVersion == 2)
+			{
+				if (osvi.wProductType == VER_NT_WORKSTATION)
+					StringCchCat(pszOS, MAX_PATH, TEXT("Windows 8 "));
+				else
+					StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2012"));
+			}
+
+			auto GetProductInfo = static_cast<pGetProductInfo>(API::GetAPI(API_IDENTIFIER::API_GetProductInfo));
+
+			GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);
+
+			switch (dwType)
+			{
+			case PRODUCT_ULTIMATE:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Ultimate Edition"));
+				break;
+			case PRODUCT_PROFESSIONAL:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Professional"));
+				break;
+			case PRODUCT_HOME_PREMIUM:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Home Premium Edition"));
+				break;
+			case PRODUCT_HOME_BASIC:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Home Basic Edition"));
+				break;
+			case PRODUCT_ENTERPRISE:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise Edition"));
+				break;
+			case PRODUCT_BUSINESS:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Business Edition"));
+				break;
+			case PRODUCT_STARTER:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Starter Edition"));
+				break;
+			case PRODUCT_CLUSTER_SERVER:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Cluster Server Edition"));
+				break;
+			case PRODUCT_DATACENTER_SERVER:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Datacenter Edition"));
+				break;
+			case PRODUCT_DATACENTER_SERVER_CORE:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Datacenter Edition (core installation)"));
+				break;
+			case PRODUCT_ENTERPRISE_SERVER:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise Edition"));
+				break;
+			case PRODUCT_ENTERPRISE_SERVER_CORE:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise Edition (core installation)"));
+				break;
+			case PRODUCT_ENTERPRISE_SERVER_IA64:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise Edition for Itanium-based Systems"));
+				break;
+			case PRODUCT_SMALLBUSINESS_SERVER:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Small Business Server"));
+				break;
+			case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Small Business Server Premium Edition"));
+				break;
+			case PRODUCT_STANDARD_SERVER:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Standard Edition"));
+				break;
+			case PRODUCT_STANDARD_SERVER_CORE:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Standard Edition (core installation)"));
+				break;
+			case PRODUCT_WEB_SERVER:
+				StringCchCat(pszOS, MAX_PATH, TEXT("Web Server Edition"));
+				break;
+			}
+		}
+
+		else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
+		{
+			if (GetSystemMetrics(SM_SERVERR2))
+				StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2003 R2, "));
+			else if (osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER)
+				StringCchCat(pszOS, MAX_PATH, TEXT("Windows Storage Server 2003"));
+			else if (osvi.wSuiteMask & VER_SUITE_WH_SERVER)
+				StringCchCat(pszOS, MAX_PATH, TEXT("Windows Home Server"));
+			else if (osvi.wProductType == VER_NT_WORKSTATION &&
+				si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+			{
+				StringCchCat(pszOS, MAX_PATH, TEXT("Windows XP Professional x64 Edition"));
+			}
+			else StringCchCat(pszOS, MAX_PATH, TEXT("Windows Server 2003, "));
+
+			// Test for the server type.
+			if (osvi.wProductType != VER_NT_WORKSTATION)
+			{
+				if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
+				{
+					if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
+						StringCchCat(pszOS, MAX_PATH, TEXT("Datacenter Edition for Itanium-based Systems"));
+					else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+						StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise Edition for Itanium-based Systems"));
+				}
+
+				else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+				{
+					if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
+						StringCchCat(pszOS, MAX_PATH, TEXT("Datacenter x64 Edition"));
+					else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+						StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise x64 Edition"));
+					else StringCchCat(pszOS, MAX_PATH, TEXT("Standard x64 Edition"));
+				}
+
+				else
+				{
+					if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER)
+						StringCchCat(pszOS, MAX_PATH, TEXT("Compute Cluster Edition"));
+					else if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
+						StringCchCat(pszOS, MAX_PATH, TEXT("Datacenter Edition"));
+					else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+						StringCchCat(pszOS, MAX_PATH, TEXT("Enterprise Edition"));
+					else if (osvi.wSuiteMask & VER_SUITE_BLADE)
+						StringCchCat(pszOS, MAX_PATH, TEXT("Web Edition"));
+					else StringCchCat(pszOS, MAX_PATH, TEXT("Standard Edition"));
+				}
+			}
+		}
+
+		else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
+		{
+			StringCchCat(pszOS, MAX_PATH, TEXT("Windows XP "));
+			if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
+				StringCchCat(pszOS, MAX_PATH, TEXT("Home Edition"));
+			else StringCchCat(pszOS, MAX_PATH, TEXT("Professional"));
+		}
+
+		else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
+		{
+			StringCchCat(pszOS, MAX_PATH, TEXT("Windows 2000 "));
+
+			if (osvi.wProductType == VER_NT_WORKSTATION)
+			{
+				StringCchCat(pszOS, MAX_PATH, TEXT("Professional"));
+			}
+			else
+			{
+				if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
+					StringCchCat(pszOS, MAX_PATH, TEXT("Datacenter Server"));
+				else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+					StringCchCat(pszOS, MAX_PATH, TEXT("Advanced Server"));
+				else StringCchCat(pszOS, MAX_PATH, TEXT("Server"));
+			}
+		}
+
+		// Include service pack (if any) and build number.
+		size_t targetSize;
+		StringCchLength(osvi.szCSDVersion, MAX_PATH, &targetSize);
+		if (targetSize > 0)
+		{
+			StringCchCat(pszOS, MAX_PATH, TEXT(" "));
+			StringCchCat(pszOS, MAX_PATH, osvi.szCSDVersion);
+		}
+
+		TCHAR buf[80];
+
+		StringCchPrintf(buf, 80, TEXT(" (build %u)"), osvi.dwBuildNumber);
+		StringCchCat(pszOS, MAX_PATH, buf);
+
+		if (osvi.dwMajorVersion >= 6)
+		{
+			if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+				StringCchCat(pszOS, MAX_PATH, TEXT(" 64-bit"));
+			else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
+				StringCchCat(pszOS, MAX_PATH, TEXT(" 32-bit"));
+		}
+
+		return TRUE;
+	}
+
+	else
+	{
+		return FALSE;
+	}
+}
+
+BOOL IsWindowsVista() {
+	OSVERSIONINFOEX osvi;
+	DWORDLONG dwlConditionMask = 0;
+	int op = VER_EQUAL;
+
+	// Initialize the OSVERSIONINFOEX structure.
+
+	ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+	osvi.dwMajorVersion = 6;
+	osvi.dwMinorVersion = 0;
+
+	// Initialize the condition mask.
+
+	VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
+	VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
+
+	// Perform the test.
+
+	return VerifyVersionInfo(
+		&osvi,
+		VER_MAJORVERSION | VER_MINORVERSION,
+		dwlConditionMask);
+}
+
+BOOL IsWindows7() {
+	OSVERSIONINFOEX osvi;
+	DWORDLONG dwlConditionMask = 0;
+	int op = VER_EQUAL;
+
+	// Initialize the OSVERSIONINFOEX structure.
+
+	ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+	osvi.dwMajorVersion = 6;
+	osvi.dwMinorVersion = 1;
+
+	// Initialize the condition mask.
+
+	VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
+	VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
+
+	// Perform the test.
+
+	return VerifyVersionInfo(
+		&osvi,
+		VER_MAJORVERSION | VER_MINORVERSION,
+		dwlConditionMask);
+}
+
+BOOL IsWindows8or8PointOne() {
+	OSVERSIONINFOEX osvi;
+	DWORDLONG dwlConditionMask = 0;
+	int MajorOp = VER_EQUAL;
+	int MinorOp = VER_GREATER_EQUAL;
+
+	// Initialize the OSVERSIONINFOEX structure.
+
+	ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+	osvi.dwMajorVersion = 6;
+	osvi.dwMinorVersion = 2;
+
+	// Initialize the condition mask.
+
+	VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, MajorOp);
+	VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, MinorOp);
+
+	// Perform the test.
+
+	return VerifyVersionInfo(
+		&osvi,
+		VER_MAJORVERSION | VER_MINORVERSION,
+		dwlConditionMask);
+}
+
+DWORD GetProccessIDByName(TCHAR* szProcessNameTarget)
+{
+	DWORD processIds[1024];
+	DWORD dBytesReturned;
+	BOOL bStatus;
+	HMODULE hMod;
+	DWORD cbNeeded;
+	TCHAR szProcessName[MAX_PATH] = _T("");
+
+	// Get the list of process identifiers.
+	bStatus = EnumProcesses(processIds, sizeof(processIds), &dBytesReturned);
+	if (!bStatus)
+	{
+		// Something bad happened
+	}
+
+	// Calculate how many process identifiers were returned.
+	int cProcesses = dBytesReturned / sizeof(DWORD);
+
+	for (int i = 0; i < cProcesses; i++)
+	{
+		// Get a handle to the process.
+		HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processIds[i]);
+
+		// Get the process name.
+		if (hProcess != NULL)
+		{
+			EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded);
+			GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName) / sizeof(TCHAR));
+
+			CloseHandle(hProcess);
+
+			// Make the comparaison
+			if (StrCmpI(szProcessName, szProcessNameTarget) == 0)
+				return processIds[i];
+
+		}
+
+		_tprintf(TEXT("%s  (PID: %u)\n"), szProcessName, processIds[i]);
+	}
+
+	return FALSE;
+}
+
+BOOL SetPrivilege(
+	HANDLE hToken,          // token handle
+	LPCTSTR Privilege,      // Privilege to enable/disable
+	BOOL bEnablePrivilege   // TRUE to enable.  FALSE to disable
+)
+{
+	TOKEN_PRIVILEGES tp;
+	LUID luid;
+	TOKEN_PRIVILEGES tpPrevious;
+	DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
+
+	if (!LookupPrivilegeValue(NULL, Privilege, &luid))
+		return FALSE;
+
+	/* first pass.  get current privilege setting */
+	tp.PrivilegeCount = 1;
+	tp.Privileges[0].Luid = luid;
+	tp.Privileges[0].Attributes = 0;
+
+	AdjustTokenPrivileges(
+		hToken,
+		FALSE,
+		&tp,
+		sizeof(TOKEN_PRIVILEGES),
+		&tpPrevious,
+		&cbPrevious
+	);
+
+	if (GetLastError() != ERROR_SUCCESS) return FALSE;
+
+	// 
+	// second pass.  set privilege based on previous setting
+	// 
+	tpPrevious.PrivilegeCount = 1;
+	tpPrevious.Privileges[0].Luid = luid;
+
+	if (bEnablePrivilege) {
+		tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
+	}
+	else {
+		tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
+			tpPrevious.Privileges[0].Attributes);
+	}
+
+	AdjustTokenPrivileges(hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL);
+
+	if (GetLastError() != ERROR_SUCCESS) return FALSE;
+
+	return TRUE;
+}
+
+
+BOOL SetDebugPrivileges(VOID) {
+	TOKEN_PRIVILEGES priv = { 0 };
+	HANDLE hToken = NULL;
+	BOOL bResult = FALSE;
+
+	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
+		print_last_error(_T("OpenProcessToken"));
+		return bResult;
+	}
+
+	priv.PrivilegeCount = 1;
+	priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+	if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid)) {
+		
+		bResult = AdjustTokenPrivileges(hToken, FALSE, &priv, 0, NULL, NULL);
+		if (!bResult) {
+			print_last_error(_T("AdjustTokenPrivileges"));
+		}
+	}
+	else {
+		print_last_error(_T("LookupPrivilegeValue"));
+	}
+
+	CloseHandle(hToken);
+	return bResult;
+}
+
+DWORD GetProcessIdFromName(LPCTSTR szProcessName)
+{
+	PROCESSENTRY32 pe32;
+	HANDLE hSnapshot = NULL;
+	SecureZeroMemory(&pe32, sizeof(PROCESSENTRY32));
+
+	// We want a snapshot of processes
+	hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+
+	// Check for a valid handle, in this case we need to check for
+	// INVALID_HANDLE_VALUE instead of NULL
+	if (hSnapshot == INVALID_HANDLE_VALUE) {
+		print_last_error(_T("CreateToolhelp32Snapshot"));
+		return 0;
+	}
+
+	// Now we can enumerate the running process, also 
+	// we can't forget to set the PROCESSENTRY32.dwSize member
+	// otherwise the following functions will fail
+	pe32.dwSize = sizeof(PROCESSENTRY32);
+
+	if (Process32First(hSnapshot, &pe32) == FALSE)
+	{
+		// Cleanup the mess
+		print_last_error(_T("Process32First"));
+		CloseHandle(hSnapshot);
+		return 0;
+	}
+
+	// Do our first comparison
+	if (StrCmpI(pe32.szExeFile, szProcessName) == 0)
+	{
+		// Cleanup the mess
+		CloseHandle(hSnapshot);
+		return pe32.th32ProcessID;
+	}
+
+	// Most likely it won't match on the first try so 
+	// we loop through the rest of the entries until
+	// we find the matching entry or not one at all
+	while (Process32Next(hSnapshot, &pe32))
+	{
+		if (StrCmpI(pe32.szExeFile, szProcessName) == 0)
+		{
+			// Cleanup the mess
+			CloseHandle(hSnapshot);
+			return pe32.th32ProcessID;
+		}
+	}
+
+	// If we made it this far there wasn't a match, so we'll return 0
+	// _tprintf(_T("\n-> Process %s is not running on this system ..."), szProcessName);
+
+	CloseHandle(hSnapshot);
+	return 0;
+}
+
+DWORD GetMainThreadId(DWORD pid)
+{
+	/* Get main thread id from process id */
+	HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+	if (h != INVALID_HANDLE_VALUE) {
+		THREADENTRY32 te;
+		te.dwSize = sizeof(te);
+		if (Thread32First(h, &te))
+		{
+			do
+			{
+				if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID)) {
+					if (te.th32OwnerProcessID == pid) {
+						HANDLE hThread = OpenThread(READ_CONTROL, FALSE, te.th32ThreadID);
+						if (!hThread)
+							print_last_error(_T("OpenThread"));
+						else {
+							CloseHandle(hThread);
+							CloseHandle(h);
+							return te.th32ThreadID;
+						}
+					}
+				}
+
+			} while (Thread32Next(h, &te));
+		}
+		CloseHandle(h);
+	}
+
+	print_last_error(_T("CreateToolhelp32Snapshot"));
+	return (DWORD)0;
+}
+
+BOOL InitWMI(IWbemServices **pSvc, IWbemLocator **pLoc, const TCHAR* szNetworkResource)
+{
+	// Initialize COM.
+	HRESULT hres;
+	hres = CoInitializeEx(0, COINIT_MULTITHREADED);
+	if (FAILED(hres)) {
+		print_last_error(_T("CoInitializeEx"));
+		return 0;
+	}
+
+	// Set general COM security levels
+	hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
+	if (FAILED(hres)) {
+		print_last_error(_T("CoInitializeSecurity"));
+		CoUninitialize();
+		return 0;
+	}
+
+	// Obtain the initial locator to WMI 
+	hres = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(pLoc));
+	if (FAILED(hres)) {
+		print_last_error(_T("CoCreateInstance"));
+		CoUninitialize();
+		return 0;
+	}
+
+	BSTR strNetworkResource = SysAllocString(szNetworkResource);
+	if (strNetworkResource) {
+
+		// Connect to the root\cimv2 namespace 
+		hres = (*pLoc)->ConnectServer(strNetworkResource, NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, 0, 0, pSvc);
+		if (FAILED(hres)) {
+			SysFreeString(strNetworkResource);
+			print_last_error(_T("ConnectServer"));
+			(*pLoc)->Release();
+			CoUninitialize();
+			return 0;
+		}
+		SysFreeString(strNetworkResource);
+	}
+
+	// Set security levels on the proxy -------------------------
+	hres = CoSetProxyBlanket(*pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
+	if (FAILED(hres))
+	{
+		print_last_error(_T("CoSetProxyBlanket"));
+		(*pSvc)->Release();
+		(*pLoc)->Release();
+		CoUninitialize();
+		return 0;
+	}
+
+	return 1;
+}
+
+BOOL ExecWMIQuery(IWbemServices **pSvc, IWbemLocator **pLoc, IEnumWbemClassObject **pEnumerator, const TCHAR* szQuery)
+{
+	// Execute WMI query
+	BSTR strQueryLanguage = SysAllocString(OLESTR("WQL"));
+	BSTR strQuery = SysAllocString(szQuery);
+
+	BOOL bQueryResult = TRUE;
+
+	if (strQueryLanguage && strQuery) {
+
+		HRESULT hres = (*pSvc)->ExecQuery(strQueryLanguage, strQuery,
+			WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
+			NULL, pEnumerator);
+
+		if (FAILED(hres)) {
+			bQueryResult = FALSE;
+			print_last_error(_T("ExecQuery"));
+			(*pSvc)->Release();
+			(*pLoc)->Release();
+			CoUninitialize();
+		}
+
+	}
+
+	if (strQueryLanguage) SysFreeString(strQueryLanguage);
+	if (strQuery) SysFreeString(strQuery);
+
+	return bQueryResult;
+}
+
+
+ULONG get_idt_base()
+{
+	// Get the base of Interupt Descriptor Table (IDT)
+
+	UCHAR idtr[6];
+	ULONG idt = 0;
+
+	// sidt instruction stores the contents of the IDT Register
+	// (the IDTR which points to the IDT) in a processor register.
+
+#if defined (ENV32BIT)
+	_asm sidt idtr
+#endif
+	idt = *((unsigned long *)&idtr[2]);
+	// printf("IDT base: 0x%x\n", idt);
+
+	return idt;
+}
+
+
+ULONG get_ldt_base()
+{
+	// Get the base of Local Descriptor Table (LDT)
+
+	UCHAR ldtr[5] = "\xef\xbe\xad\xde";
+	ULONG ldt = 0;
+
+	// sldt instruction stores the contents of the LDT Register
+	// (the LDTR which points to the LDT) in a processor register.
+#if defined (ENV32BIT)
+	_asm sldt ldtr
+#endif
+	ldt = *((unsigned long *)&ldtr[0]);
+	// printf("LDT base: 0x%x\n", ldt);
+
+	return ldt;
+}
+
+
+ULONG get_gdt_base()
+{
+	// Get the base of Global Descriptor Table (GDT)
+
+	UCHAR gdtr[6];
+	ULONG gdt = 0;
+
+	// sgdt instruction stores the contents of the GDT Register
+	// (the GDTR which points to the GDT) in a processor register.
+#if defined (ENV32BIT)
+	_asm sgdt gdtr
+#endif
+	gdt = *((unsigned long *)&gdtr[2]);
+	// printf("GDT base: 0x%x\n", gdt);
+
+	return gdt;
+}
+
+
+/*
+Check if a process is running with admin rights
+*/
+BOOL IsElevated()
+{
+	BOOL fRet = FALSE;
+	HANDLE hToken = NULL;
+
+	if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
+		TOKEN_ELEVATION Elevation;
+		DWORD cbSize = sizeof(TOKEN_ELEVATION);
+		if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) {
+			fRet = Elevation.TokenIsElevated;
+		}
+	}
+	if (hToken) {
+		CloseHandle(hToken);
+	}
+	return fRet;
+}
+
+
+BOOL find_str_in_data(PBYTE needle, size_t needleLen, PBYTE haystack, size_t haystackLen)
+{
+	for (size_t i = 0; i < haystackLen - needleLen; i++)
+	{
+		if (memcmp(&haystack[i], needle, needleLen) == 0)
+		{
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+
+UINT enum_system_firmware_tables(DWORD FirmwareTableProviderSignature, PVOID pFirmwareTableBuffer, DWORD BufferSize)
+{
+	if (!API::IsAvailable(API_IDENTIFIER::API_EnumSystemFirmwareTables))
+	{
+		return -1;
+	}
+
+	auto EnumSystemFirmwareTables = static_cast<pEnumSystemFirmwareTables>(API::GetAPI(API_IDENTIFIER::API_EnumSystemFirmwareTables));
+	return EnumSystemFirmwareTables(FirmwareTableProviderSignature, pFirmwareTableBuffer, BufferSize);
+}
+
+PBYTE get_system_firmware(_In_ DWORD signature, _In_ DWORD table, _Out_ PDWORD pBufferSize)
+{
+	if (!API::IsAvailable(API_IDENTIFIER::API_GetSystemFirmwareTable))
+	{
+		return NULL;
+	}
+
+	DWORD bufferSize = 4096;
+	PBYTE firmwareTable = static_cast<PBYTE>(malloc(bufferSize));
+
+	if (firmwareTable == NULL)
+		return NULL;
+
+	SecureZeroMemory(firmwareTable, bufferSize);
+	
+	auto GetSystemFirmwareTable = static_cast<pGetSystemFirmwareTable>(API::GetAPI(API_IDENTIFIER::API_GetSystemFirmwareTable));
+
+	DWORD resultBufferSize = GetSystemFirmwareTable(signature, table, firmwareTable, bufferSize);
+	if (resultBufferSize == 0)
+	{
+		printf("First call failed :(\n");
+		free(firmwareTable);
+		return NULL;
+	}
+
+	// if the buffer was too small, realloc and try again
+	if (resultBufferSize > bufferSize)
+	{
+		PBYTE tmp;
+
+		tmp = static_cast<BYTE*>(realloc(firmwareTable, resultBufferSize));
+		if (tmp) {
+			firmwareTable = tmp;
+			SecureZeroMemory(firmwareTable, resultBufferSize);
+			if (GetSystemFirmwareTable(signature, table, firmwareTable, resultBufferSize) == 0)
+			{
+				printf("Second call failed :(\n");
+				free(firmwareTable);
+				return NULL;
+			}
+		}
+	}
+
+	*pBufferSize = resultBufferSize;
+	return firmwareTable;
+}
+
+bool attempt_to_read_memory(void* addr, void* buf, int size)
+{
+	// this is a dumb trick and I love it
+	BOOL b = ReadProcessMemory(GetCurrentProcess(), addr, buf, size, nullptr);
+	return b != FALSE;
+}
+
+bool attempt_to_read_memory_wow64(PVOID buffer, DWORD size, PVOID64 address)
+{
+	auto NtWow64ReadVirtualMemory64 = static_cast<pNtWow64ReadVirtualMemory64>(API::GetAPI(API_IDENTIFIER::API_NtWow64ReadVirtualMemory64));
+	ULONGLONG bytesRead = 0;
+
+	//printf("dbg: read %llx\n", reinterpret_cast<uint64_t>(address));
+
+	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
+
+	if (hProcess != NULL)
+	{
+		NTSTATUS status = NtWow64ReadVirtualMemory64(hProcess, address, buffer, size, &bytesRead);
+		/*if (status != 0)
+		printf("NTSTATUS: %x\n", status);*/
+
+		CloseHandle(hProcess);
+
+		return status == 0;
+	}
+
+	printf("attempt_to_read_memory_wow64: Couldn't open process: %u\n", GetLastError());
+	return false;
+}
+
+bool attempt_to_read_memory_wow64(PVOID buffer, DWORD size, ULONGLONG address)
+{
+	return attempt_to_read_memory_wow64(buffer, size, reinterpret_cast<PVOID64>(address));
+}
+
+std::vector<PMEMORY_BASIC_INFORMATION>* enumerate_memory()
+{
+	auto regions = new std::vector<PMEMORY_BASIC_INFORMATION>();
+
+#ifdef ENV32BIT
+	const PBYTE MaxAddress = (PBYTE)0x7FFFFFFF;
+#else
+	const PBYTE MaxAddress = (PBYTE)0x7FFFFFFFFFFFFFFFULL;
+#endif
+
+	PBYTE addr = 0;
+	while (addr < MaxAddress)
+	{
+		auto mbi = new MEMORY_BASIC_INFORMATION();
+		if (VirtualQuery(addr, mbi, sizeof(MEMORY_BASIC_INFORMATION)) <= 0)
+			break;
+		
+		regions->push_back(mbi);
+
+		addr += mbi->RegionSize;
+	}
+
+	return regions;
+}
+
+std::vector<PMEMORY_BASIC_INFORMATION64>* enumerate_memory_wow64()
+{
+	if (IsWoW64() == FALSE)
+	{
+		printf("Not WoW64.\n");
+		return nullptr;
+	}
+
+	if (!API::IsAvailable(API_NtWow64QueryVirtualMemory64))
+	{
+		printf("API unavailable.\n");
+		return nullptr;
+	}
+
+	auto NtWow64QueryVirtualMemory64 = static_cast<pNtWow64QueryVirtualMemory64>(API::GetAPI(API_IDENTIFIER::API_NtWow64QueryVirtualMemory64));
+
+	auto regions = new std::vector<PMEMORY_BASIC_INFORMATION64>();
+
+	const INT64 MaxAddress = 0x7FFFFFFFFFFFFFFFULL;
+
+	INT64 addr = 0;
+	while (addr < MaxAddress)
+	{
+		auto mbi = new MEMORY_BASIC_INFORMATION64();
+		ULONG64 returnLength;
+		NTSTATUS status;
+		if ((status = NtWow64QueryVirtualMemory64(GetCurrentProcess(), (PVOID64)addr, 0, mbi, sizeof(MEMORY_BASIC_INFORMATION64), &returnLength)) != 0)
+		{
+			printf("Failed at %llx with status %d.\n", addr, status);
+			break;
+		}
+
+		regions->push_back(mbi);
+
+		addr += mbi->RegionSize;
+	}
+
+	return regions;
+}
+
+
+std::vector<wchar_t*>* enumerate_object_directory(const wchar_t* path)
+{
+	if (!API::IsAvailable(API_NtOpenDirectoryObject) || !API::IsAvailable(API_NtQueryDirectoryObject))
+	{
+		return nullptr;
+	}
+
+	UNICODE_STRING usPath = { 0 };
+	usPath.Buffer = const_cast<wchar_t*>(path);
+	usPath.Length = lstrlenW(path) * sizeof(wchar_t);
+	usPath.MaximumLength = usPath.Length;
+	
+	OBJECT_ATTRIBUTES objAttr = { 0 };
+	InitializeObjectAttributes(&objAttr, &usPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+	auto ntOpenDirectoryObject = static_cast<pNtOpenDirectoryObject>(API::GetAPI(API_NtOpenDirectoryObject));
+	auto ntQueryDirectoryObject = static_cast<pNtQueryDirectoryObject>(API::GetAPI(API_NtQueryDirectoryObject));
+
+	const int DIRECTORY_QUERY = 0x0001;
+	HANDLE hDirectory = 0;
+	NTSTATUS status = ntOpenDirectoryObject(&hDirectory, DIRECTORY_QUERY, &objAttr);
+	if (status != 0)
+	{
+		//printf("\nNTODO failed: %x\n", status);
+		return nullptr;
+	}
+
+	auto pObjDirInfo = static_cast<OBJECT_DIRECTORY_INFORMATION*>(calloc(0x800, 1));
+	ULONG returnedLength = 0;
+	ULONG context = 0;
+	auto results = new std::vector<wchar_t*>();
+	while (ntQueryDirectoryObject(hDirectory, pObjDirInfo, 0x800, TRUE, FALSE, &context, &returnedLength) == 0 && returnedLength > 0)
+	{
+		//wprintf(L"\nobject: %s\n", pObjDirInfo->Name.Buffer);
+		wchar_t* name = static_cast<wchar_t*>(calloc(pObjDirInfo->Name.Length + 1, sizeof(wchar_t)));
+		memcpy(name, pObjDirInfo->Name.Buffer, pObjDirInfo->Name.Length * sizeof(wchar_t));
+		results->push_back(name);
+	}
+
+	free(pObjDirInfo);
+
+	return results;
+}
\ No newline at end of file
diff --git a/al-khaser/al-khaser/Shared/Utils.h b/al-khaser/al-khaser/Shared/Utils.h
new file mode 100644
index 0000000000000000000000000000000000000000..336104ed03fb4c2d783186c8d85a52a0ccd3c6fb
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/Utils.h
@@ -0,0 +1,45 @@
+#pragma once
+
+BOOL IsWoW64();
+PVOID64 GetPeb64();
+BOOL Is_RegKeyValueExists(HKEY hKey, const TCHAR* lpSubKey, const TCHAR* lpValueName, const TCHAR* search_str);
+BOOL Is_RegKeyExists(HKEY hKey, const TCHAR* lpSubKey);
+BOOL is_FileExists(TCHAR* szPath);
+BOOL is_DirectoryExists(TCHAR* szPath);
+BOOL check_mac_addr(const TCHAR* szMac);
+BOOL check_adapter_name(const TCHAR* szName);
+BOOL GetOSDisplayString(LPTSTR pszOS);
+BOOL IsWindowsVista();
+BOOL IsWindows7();
+BOOL IsWindows8or8PointOne();
+DWORD GetProccessIDByName(TCHAR* szProcessNameTarget);
+DWORD GetProcessIdFromName(LPCTSTR ProcessName);
+BOOL SetPrivilege(HANDLE, LPCTSTR, BOOL);
+BOOL SetDebugPrivileges(VOID);
+DWORD GetMainThreadId(DWORD pid);
+BOOL InitWMI(IWbemServices **pSvc, IWbemLocator **pLoc, const TCHAR* szNetworkResource);
+BOOL ExecWMIQuery(IWbemServices **pSvc, IWbemLocator **pLoc, IEnumWbemClassObject **pEnumerator, const TCHAR* szQuery);
+ULONG get_idt_base();
+ULONG get_ldt_base();
+ULONG get_gdt_base();
+BOOL IsElevated();
+BOOL find_str_in_data(PBYTE needle, size_t needleLen, PBYTE haystack, size_t haystackLen);
+UINT enum_system_firmware_tables(_In_ DWORD FirmwareTableProviderSignature, _Out_ PVOID pFirmwareTableBuffer, _In_ DWORD BufferSize);
+PBYTE get_system_firmware(_In_ DWORD signature, _In_ DWORD table, _Out_ PDWORD pBufferSize);
+bool attempt_to_read_memory(void* addr, void* buf, int size);
+bool attempt_to_read_memory_wow64(PVOID buffer, DWORD size, PVOID64 address);
+bool attempt_to_read_memory_wow64(PVOID buffer, DWORD size, ULONGLONG address);
+std::vector<PMEMORY_BASIC_INFORMATION>* enumerate_memory();
+std::vector<PMEMORY_BASIC_INFORMATION64>* enumerate_memory_wow64();
+std::vector<wchar_t*>* enumerate_object_directory(const wchar_t* path);
+
+#define	MALLOC(x)	HeapAlloc(GetProcessHeap(), 0, x)
+#define FREE(x)		HeapFree(GetProcessHeap(), 0, x)
+
+#if _WIN32 || _WIN64
+#if _WIN64
+#define ENV64BIT
+#else
+#define ENV32BIT
+#endif
+#endif
\ No newline at end of file
diff --git a/al-khaser/al-khaser/Shared/VersionHelpers.h b/al-khaser/al-khaser/Shared/VersionHelpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..de9cf36dc16af484b3f5db6d4de8cd2a08f0c4a8
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/VersionHelpers.h
@@ -0,0 +1,166 @@
+/******************************************************************
+*                                                                 *
+*  VersionHelpers.h -- This module defines helper functions to    *
+*                      promote version check with proper          *
+*                      comparisons.                               *
+*                                                                 *
+*  Copyright (c) Microsoft Corp.  All rights reserved.            *
+*                                                                 *
+******************************************************************/
+#pragma once
+
+#include "winapifamily.h"
+
+#ifdef _MSC_VER
+#pragma once
+#endif  // _MSC_VER
+
+#pragma region Application Family
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+
+#include <specstrings.h>    // for _In_, etc.
+
+#if !defined(__midl) && !defined(SORTPP_PASS)
+
+#if (NTDDI_VERSION >= NTDDI_WINXP)
+
+#ifdef __cplusplus
+
+#define VERSIONHELPERAPI inline bool
+
+#else  // __cplusplus
+
+#define VERSIONHELPERAPI FORCEINLINE BOOL
+
+#endif // __cplusplus
+
+VERSIONHELPERAPI
+IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
+{
+    OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
+    DWORDLONG        const dwlConditionMask = VerSetConditionMask(
+        VerSetConditionMask(
+        VerSetConditionMask(
+            0, VER_MAJORVERSION, VER_GREATER_EQUAL),
+               VER_MINORVERSION, VER_GREATER_EQUAL),
+               VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
+
+    osvi.dwMajorVersion = wMajorVersion;
+    osvi.dwMinorVersion = wMinorVersion;
+    osvi.wServicePackMajor = wServicePackMajor;
+
+    return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
+}
+
+VERSIONHELPERAPI
+IsWindowsVersionOrLesser(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
+{
+	OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, { 0 }, 0, 0 };
+	DWORDLONG        const dwlConditionMask = VerSetConditionMask(
+		VerSetConditionMask(
+		0, VER_MAJORVERSION, VER_EQUAL),
+		VER_MINORVERSION, VER_LESS_EQUAL);
+
+	osvi.dwMajorVersion = wMajorVersion;
+	osvi.dwMinorVersion = wMinorVersion;
+	osvi.wServicePackMajor = wServicePackMajor;
+
+	return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask) != FALSE;
+}
+
+VERSIONHELPERAPI
+IsWindowsXPOrGreater()
+{
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0);
+}
+
+VERSIONHELPERAPI
+IsWindowsXPSP1OrGreater()
+{
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1);
+}
+
+VERSIONHELPERAPI
+IsWindowsXPSP2OrGreater()
+{
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2);
+}
+
+VERSIONHELPERAPI
+IsWindowsXPSP3OrGreater()
+{
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3);
+}
+
+VERSIONHELPERAPI
+IsWindowsVistaOrGreater()
+{
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0);
+}
+
+VERSIONHELPERAPI
+IsWindowsVistaSP1OrGreater()
+{
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1);
+}
+
+VERSIONHELPERAPI
+IsWindowsVistaSP2OrGreater()
+{
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
+}
+
+VERSIONHELPERAPI
+IsWindows7OrGreater()
+{
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0);
+}
+
+VERSIONHELPERAPI
+IsWindows7SP1OrGreater()
+{
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1);
+}
+
+VERSIONHELPERAPI
+IsWindows8OrGreater()
+{
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0);
+}
+
+VERSIONHELPERAPI
+IsWindows8Point1OrGreater()
+{
+    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0);
+}
+
+VERSIONHELPERAPI
+IsWindows10OrGreater()
+{
+	return IsWindowsVersionOrGreater(10, 0, 0);
+}
+
+VERSIONHELPERAPI
+IsWindowsServer()
+{
+    OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0, 0, VER_NT_WORKSTATION };
+    DWORDLONG        const dwlConditionMask = VerSetConditionMask( 0, VER_PRODUCT_TYPE, VER_EQUAL );
+
+    return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask);
+}
+
+
+
+VERSIONHELPERAPI
+IsWindowsXPOr2k()
+{
+	return IsWindowsVersionOrLesser(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0);
+}
+
+
+#endif // NTDDI_VERSION
+
+#endif // defined(__midl)
+
+#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
+#pragma endregion
diff --git a/al-khaser/al-khaser/Shared/WinStructs.h b/al-khaser/al-khaser/Shared/WinStructs.h
new file mode 100644
index 0000000000000000000000000000000000000000..46fda9ee601639d557ce4a5b889385e503f627e5
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/WinStructs.h
@@ -0,0 +1,133 @@
+#pragma once
+
+typedef struct _LDR_MODULE {
+	LIST_ENTRY              InLoadOrderModuleList;
+	LIST_ENTRY              InMemoryOrderModuleList;
+	LIST_ENTRY              InInitializationOrderModuleList;
+	PVOID                   BaseAddress;
+	PVOID                   EntryPoint;
+	ULONG                   SizeOfImage;
+	UNICODE_STRING          FullDllName;
+	UNICODE_STRING          BaseDllName;
+	ULONG                   Flags;
+	SHORT                   LoadCount;
+	SHORT                   TlsIndex;
+	LIST_ENTRY              HashTableEntry;
+	ULONG                   TimeDateStamp;
+} LDR_MODULE, *PLDR_MODULE;
+
+typedef LONG KPRIORITY;
+
+typedef struct _THREAD_BASIC_INFORMATION {
+	NTSTATUS                ExitStatus;
+	PVOID                   TebBaseAddress;
+	CLIENT_ID               ClientId;
+	KAFFINITY               AffinityMask;
+	KPRIORITY               Priority;
+	KPRIORITY               BasePriority;
+} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
+
+typedef struct _PROCESS_BASIC_INFORMATION_WOW64 {
+	PVOID Reserved1[2];
+	PVOID64 PebBaseAddress;
+	PVOID Reserved2[4];
+	ULONG_PTR UniqueProcessId[2];
+	PVOID Reserved3[2];
+} PROCESS_BASIC_INFORMATION_WOW64;
+
+typedef struct _PEB64 {
+	BYTE Reserved1[2];
+	BYTE BeingDebugged;
+	BYTE Reserved2[1];
+	PVOID64 Reserved3[2];
+	PVOID64 Ldr;
+	PVOID64 ProcessParameters;
+	BYTE Reserved4[104];
+	PVOID64 Reserved5[52];
+	PVOID64 PostProcessInitRoutine;
+	BYTE Reserved6[128];
+	PVOID64 Reserved7[1];
+	ULONG SessionId;
+} PEB64, *PPEB64;
+
+typedef struct _PEB_LDR_DATA64 {
+	BYTE Reserved1[8];
+	PVOID64 Reserved2[3];
+	LIST_ENTRY64 InMemoryOrderModuleList;
+} PEB_LDR_DATA64, *PPEB_LDR_DATA64;
+
+typedef struct _UNICODE_STRING64 {
+	USHORT Length;
+	USHORT MaximumLength;
+	PVOID64  Buffer;
+} UNICODE_STRING64;
+
+typedef struct _LDR_DATA_TABLE_ENTRY64 {
+	PVOID64 Reserved1[2];
+	LIST_ENTRY64 InMemoryOrderLinks;
+	PVOID64 Reserved2[2];
+	PVOID64 DllBase;
+	PVOID64 Reserved3[2];
+	UNICODE_STRING64 FullDllName;
+	BYTE Reserved4[8];
+	PVOID64 Reserved5[3];
+	union {
+		ULONG CheckSum;
+		PVOID64 Reserved6;
+	} DUMMYUNIONNAME;
+	ULONG TimeDateStamp;
+} LDR_DATA_TABLE_ENTRY64, *PLDR_DATA_TABLE_ENTRY64;
+
+/*++ NtCreateThreadEx specific */
+
+typedef struct _PS_ATTRIBUTE {
+	ULONG Attribute;
+	SIZE_T Size;
+	union
+	{
+		ULONG Value;
+		PVOID ValuePtr;
+	} u1;
+	PSIZE_T ReturnLength;
+} PS_ATTRIBUTE, *PPS_ATTRIBUTE;
+
+typedef struct _PS_ATTRIBUTE_LIST {
+	SIZE_T TotalLength;
+	PS_ATTRIBUTE Attributes[1];
+} PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST;
+
+#define PS_ATTRIBUTE_NUMBER_MASK 0x0000ffff
+#define PS_ATTRIBUTE_THREAD 0x00010000
+#define PS_ATTRIBUTE_INPUT 0x00020000
+#define PS_ATTRIBUTE_ADDITIVE 0x00040000
+
+#define PsAttributeValue(Number, Thread, Input, Additive) \
+	(((Number) & PS_ATTRIBUTE_NUMBER_MASK) | \
+	((Thread) ? PS_ATTRIBUTE_THREAD : 0) | \
+	((Input) ? PS_ATTRIBUTE_INPUT : 0) | \
+	((Additive) ? PS_ATTRIBUTE_ADDITIVE : 0))
+
+typedef enum _PS_ATTRIBUTE_NUM {
+	PsAttributeClientId = 3,
+} PS_ATTRIBUTE_NUM;
+
+#define PS_ATTRIBUTE_CLIENT_ID \
+    PsAttributeValue(PsAttributeClientId, TRUE, FALSE, FALSE)
+
+/* NtCreateThreadEx specific --*/
+
+typedef struct _SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION
+{
+	ULONG NumberOfLogicalProcessors;
+	ULONG NumberOfCores;
+} SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION, *PSYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION;
+
+
+typedef struct _OBJECT_DIRECTORY_INFORMATION
+{
+	UNICODE_STRING Name;
+	UNICODE_STRING TypeName;
+} OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION;
+
+typedef VOID(NTAPI LDR_ENUM_CALLBACK)(_In_ PLDR_DATA_TABLE_ENTRY ModuleInformation, _In_ PVOID Parameter, _Out_ BOOLEAN *Stop);
+typedef LDR_ENUM_CALLBACK *PLDR_ENUM_CALLBACK;
diff --git a/al-khaser/al-khaser/Shared/log.cpp b/al-khaser/al-khaser/Shared/log.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1587c6462cebbb5d3452d79f137ca7678e009d8b
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/log.cpp
@@ -0,0 +1,104 @@
+#include "pch.h"
+#include "log.h"
+
+static int SESSION_TRACKER; //Keeps track of session
+
+TCHAR* print_time()
+{
+	size_t size = 0;
+	TCHAR *buf;
+	errno_t err;
+	TCHAR timestr[32];
+
+	/* get current calendar time */
+	time_t const sourceTime = time(NULL); 
+	tm tmDest = { 0 };
+	err = localtime_s(&tmDest, &sourceTime);
+	if (err)
+	{
+		print_last_error(_T("localtime_s"));
+		exit(1);
+	}
+	
+	// Converts a time_t time value to a tm structure, and corrects for the local time zone. 
+	err = _tasctime_s(timestr, 32, &tmDest);
+	if (err)
+	{
+		print_last_error(_T("_tasctime_s"));
+		exit(1);
+	}
+
+	//Getting rid of \n
+	timestr[_tcsclen(timestr) - 1] = 0;
+
+	//Additional +2 for square braces
+	size = (_tcsclen(timestr) + 1 + 2) * sizeof(TCHAR);
+	buf = (TCHAR*)malloc(size);
+	if (buf) {
+		memset(buf, 0x0, size);
+		_stprintf_s(buf, size / sizeof(TCHAR), _T("[%s]"), timestr);
+	}
+	return buf;
+}
+void log_print(const TCHAR* filename, const TCHAR *fmt, ...)
+{
+	va_list list;
+	const TCHAR *p, *r;
+	int e;
+
+	FILE *fp = NULL;
+	errno_t error;
+
+	TCHAR *pszTime;
+
+	if (SESSION_TRACKER > 0)
+		error = _tfopen_s(&fp, _T("log.txt"), _T("a+"));
+	else
+		error = _tfopen_s(&fp, _T("log.txt"), _T("w"));
+
+	// file create/open failed
+	if ((error != 0) || (fp == NULL))
+		return;
+
+	pszTime = print_time();
+	if (pszTime) {
+		_ftprintf(fp, _T("%s "), pszTime);
+		free(pszTime);
+	}
+	va_start(list, fmt);
+
+	for (p = fmt; *p; ++p)
+	{
+		if (*p != '%')//If simple string
+			fputc(*p, fp);
+
+		else
+		{
+			switch (*++p)
+			{
+				/* string */
+			case 's':
+			{
+				r = va_arg(list, TCHAR *);
+				_ftprintf(fp, _T("%s"), r);
+				continue;
+			}
+
+			/* integer */
+			case 'd':
+			{
+				e = va_arg(list, int);
+				_ftprintf(fp, _T("%d"), e);
+				continue;
+			}
+
+			default:
+				fputc(*p, fp);
+			}
+		}
+	}
+	va_end(list);
+	fputc('\n', fp);
+	SESSION_TRACKER++;
+	fclose(fp);
+}
diff --git a/al-khaser/al-khaser/Shared/log.h b/al-khaser/al-khaser/Shared/log.h
new file mode 100644
index 0000000000000000000000000000000000000000..3f6db18f920e2fa036adaaf040c275b149876051
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/log.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#define WIDEN2(x) L##x
+#define WIDEN(x) WIDEN2(x)
+#define __WFILE__ WIDEN(__FILE__)
+
+#ifdef UNICODE
+#define __TFILE__ __WFILE__
+#else
+#define __TFILE__ __FILE__
+#endif
+
+void log_print(const TCHAR* filename, const TCHAR *fmt, ...);
+
+#define LOG_PRINT(...) log_print(__TFILE__, __VA_ARGS__ )
+
+
+
+
diff --git a/al-khaser/al-khaser/Shared/pch.h b/al-khaser/al-khaser/Shared/pch.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7df92d774ff3829efea501cff3b5b40e5b16f4b
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/pch.h
@@ -0,0 +1 @@
+#include "../pch.h"
\ No newline at end of file
diff --git a/al-khaser/al-khaser/Shared/winapifamily.h b/al-khaser/al-khaser/Shared/winapifamily.h
new file mode 100644
index 0000000000000000000000000000000000000000..28ce845a55bc119ffe5b349dc34ed6c5a40eabf8
--- /dev/null
+++ b/al-khaser/al-khaser/Shared/winapifamily.h
@@ -0,0 +1,183 @@
+/*
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+    winapifamily.h
+
+Abstract:
+
+    Master include file for API family partitioning.
+
+*/
+
+#define _WIN32_WINNT_WIN8                   0x0602
+#define _WIN32_WINNT_WINBLUE                0x0603
+
+#ifndef _INC_WINAPIFAMILY
+#define _INC_WINAPIFAMILY
+
+#if defined(_MSC_VER) && !defined(MOFCOMP_PASS)
+#pragma once
+#endif // defined(_MSC_VER) && !defined(MOFCOMP_PASS)
+
+/*
+ * When compiling C and C++ code using SDK header files, the development
+ * environment can specify a target platform by #define-ing the
+ * pre-processor symbol WINAPI_FAMILY to one of the following values.
+ * Each FAMILY value denotes an application family for which a different
+ * subset of the total set of header-file-defined APIs are available.
+ * Setting the WINAPI_FAMILY value will effectively hide from the
+ * editing and compilation environments the existence of APIs that
+ * are not applicable to the family of applications targeting a
+ * specific platform.
+ */
+
+/*
+ * The WINAPI_FAMILY values of 0 and 1 are reserved to ensure that
+ * an error will occur if WINAPI_FAMILY is set to any
+ * WINAPI_PARTITION value (which must be 0 or 1, see below).
+ */
+#define WINAPI_FAMILY_PC_APP      2     /* Windows Store Applications */
+#define WINAPI_FAMILY_PHONE_APP   3     /* Windows Phone Applications */
+#define WINAPI_FAMILY_DESKTOP_APP 100   /* Windows Desktop Applications */
+/* The value of WINAPI_FAMILY_DESKTOP_APP may change in future SDKs. */
+/* Additional WINAPI_FAMILY values may be defined in future SDKs. */
+
+/*
+ * For compatibility with Windows 8 header files, the following
+ * synonym for WINAPI_FAMILY_PC_APP is temporarily #define'd.
+ * Use of this symbol should be considered deprecated.
+ */
+#define WINAPI_FAMILY_APP  WINAPI_FAMILY_PC_APP
+
+/*
+ * If no WINAPI_FAMILY value is specified, then all APIs available to
+ * Windows desktop applications are exposed.
+ */
+#ifndef WINAPI_FAMILY
+#define WINAPI_FAMILY WINAPI_FAMILY_DESKTOP_APP
+#endif
+
+/*
+ * API PARTITONs are part of an indirection mechanism for mapping between
+ * individual APIs and the FAMILYs to which they apply.
+ * Each PARTITION is a category or subset of named APIs.  PARTITIONs
+ * are permitted to have overlapping membership -- some single API
+ * might be part of more than one PARTITION.  In support of new
+ * FAMILYs that might be added in future SDKs, any single current
+ * PARTITION might in that future SDK be split into two or more new PARTITIONs.
+ * Accordingly, application developers should avoid taking dependencies on
+ * PARTITION names; developers' only dependency upon the symbols defined
+ * in this file should be their reliance on the WINAPI_FAMILY names and values.
+ */
+
+/*
+ * Current PARTITIONS are each #undef'ed below, and then will be #define-ed
+ * to be either 1 or 0 or depending on the active WINAPI_FAMILY.
+ */
+
+#undef WINAPI_PARTITION_DESKTOP   /* usable for PC desktop apps (but not store apps) */
+#undef WINAPI_PARTITION_APP       /* usable for most platforms' store apps */
+#undef WINAPI_PARTITION_PC_APP    /* specific to PC store apps */
+#undef WINAPI_PARTITION_PHONE_APP /* specific to phone store apps */
+
+
+/*
+ * The mapping between families and partitions is summarized here.
+ * An X indicates that the given partition is active for the given
+ * platform/family.
+ *
+ *                             +---------------+
+ *                             |  *Partition*  |
+ *                             +---+---+---+---+
+ *                             |   |   |   | P |
+ *                             |   |   |   | H |
+ *                             | D |   |   | O |
+ *                             | E |   | P | N |
+ *                             | S |   | C | E |
+ *                             | K |   | _ | _ |
+ *                             | T | A | A | A |
+ * +-------------------------+-+ O | P | P | P |
+ * |     *Platform/Family*    \| P | P | P | P |
+ * +---------------------------+---+---+---+---+
+ * | WINAPI_FAMILY_DESKTOP_APP | X | X | X |   |
+ * +---------------------------+---+---+---+---+
+ * |      WINAPI_FAMILY_PC_APP |   | X | X |   |
+ * +---------------------------+---+---+---+---+
+ * |   WINAPI_FAMILY_PHONE_APP |   | X |   | X |
+ * +---------------------------+---+---+---+---+
+ *
+ * The table above is encoded in the following expressions,
+ * each of which evaluates to 1 or 0.
+ *
+ * Whenever a new family is added, all of these expressions
+ * need to be reconsidered.
+ */
+#if WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP && WINAPI_FAMILY != WINAPI_FAMILY_PC_APP && WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
+#   error Unknown WINAPI_FAMILY value. Was it defined in terms of a WINAPI_PARTITION_* value?
+#endif
+#define WINAPI_PARTITION_DESKTOP   (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
+#define WINAPI_PARTITION_APP       1  /* active for all current families */ 
+#define WINAPI_PARTITION_PC_APP    (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP || WINAPI_FAMILY == WINAPI_FAMILY_PC_APP)
+#define WINAPI_PARTITION_PHONE_APP (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+
+/*
+ * For compatibility with Windows Phone 8 header files, the following
+ * synonym for WINAPI_PARTITION_PHONE_APP is temporarily #define'd.
+ * Use of this symbol should be regarded as deprecated.
+ */
+#define WINAPI_PARTITION_PHONE  WINAPI_PARTITION_PHONE_APP
+
+/*
+ * Header files use the WINAPI_FAMILY_PARTITION macro to assign one or
+ * more declarations to some group of partitions.  The macro chooses
+ * whether the preprocessor will emit or omit a sequence of declarations
+ * bracketed by an #if/#endif pair.  All header file references to the
+ * WINAPI_PARTITION_* values should be in the form of occurrences of
+ * WINAPI_FAMILY_PARTITION(...).
+ *
+ * For example, the following usage of WINAPI_FAMILY_PARTITION identifies
+ * a sequence of declarations that are part of both the Windows Desktop
+ * Partition and the Windows-Phone-Specific Store Partition:
+ *
+ *     #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PHONE_APP)
+ *     ...
+ *     #endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PHONE_APP)
+ *
+ * The comment on the closing #endif allow tools as well as people to find the
+ * matching #ifdef properly.
+ *
+ * Usages of WINAPI_FAMILY_PARTITION may be combined, when the partitition definitions are
+ * related.  In particular one might use declarations like
+ * 
+ *     #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+ *
+ * or
+ *
+ *     #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
+ *
+ * Direct references to WINAPI_PARTITION_ values (eg #if !WINAPI_FAMILY_PARTITION_...)
+ * should not be used.
+ */ 
+#define WINAPI_FAMILY_PARTITION(Partitions)     (Partitions)
+
+/*
+ * Macro used to #define or typedef a symbol used for selective deprecation
+ * of individual methods of a COM interfaces that are otherwise available
+ * for a given set of partitions.
+ */
+#define _WINAPI_DEPRECATED_DECLARATION  __declspec(deprecated("This API cannot be used in the context of the caller's application type."))
+
+/*
+ * For compatibility with Windows 8 header files, the following
+ * symbol is temporarily conditionally #define'd.  Additional symbols
+ * like this should be not defined in winapifamily.h, but rather should be
+ * introduced locally to the header files of the component that needs them.
+ */
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#   define APP_DEPRECATED_HRESULT    HRESULT _WINAPI_DEPRECATED_DECLARATION
+#endif // WINAPIFAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+
+#endif  /* !_INC_WINAPIFAMILY */
diff --git a/al-khaser/al-khaser/TimingAttacks/pch.h b/al-khaser/al-khaser/TimingAttacks/pch.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7df92d774ff3829efea501cff3b5b40e5b16f4b
--- /dev/null
+++ b/al-khaser/al-khaser/TimingAttacks/pch.h
@@ -0,0 +1 @@
+#include "../pch.h"
\ No newline at end of file
diff --git a/al-khaser/al-khaser/TimingAttacks/timing.cpp b/al-khaser/al-khaser/TimingAttacks/timing.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..63c5ec61a2738bd7d4251c27c06ec0436be7e91c
--- /dev/null
+++ b/al-khaser/al-khaser/TimingAttacks/timing.cpp
@@ -0,0 +1,375 @@
+#include "pch.h"
+#include "timing.h"
+
+/* Timing attacks or sleepy malwares are used to bypass sandboxed in general
+Every system which run in a timeout is vulnerable to this types of attacks */
+
+BOOL timing_NtDelayexecution(UINT delayInMillis)
+{
+	// In this example, I will demonstrate NtDelayExecution because it is the lowest user mode
+	// api to delay execution Sleep -> SleepEx -> NtDelayExecution.
+	LARGE_INTEGER DelayInterval;
+	LONGLONG llDelay = delayInMillis * 10000LL;
+	DelayInterval.QuadPart = -llDelay;
+
+	if (!API::IsAvailable(API_IDENTIFIER::API_NtDelayExecution))
+		return TRUE; // TODO: make this a warning (NtDelayExecution should always exist)
+
+	auto NtDelayExecution = static_cast<pNtDelayExecution>(API::GetAPI(API_IDENTIFIER::API_NtDelayExecution));
+	NtDelayExecution(FALSE, &DelayInterval);
+
+	return FALSE;
+}
+
+BOOL bProcessed = FALSE;
+
+VOID CALLBACK TimerProc(HWND hwnd, UINT message, UINT_PTR iTimerID, DWORD dwTime)
+{
+	// Malicious code is place here ....
+	bProcessed = TRUE;
+}
+
+
+BOOL timing_SetTimer(UINT delayInMillis)
+{
+	MSG Msg;
+	UINT_PTR iTimerID;
+	
+	// Set our timer without window handle
+	iTimerID = SetTimer(NULL, 0, delayInMillis, TimerProc);
+
+	if (iTimerID == NULL)
+		return TRUE;
+	
+	// Because we are running in a console app, we should get the messages from
+	// the queue and check if msg is WM_TIMER
+	while (GetMessage(&Msg, NULL, 0, 0) & !bProcessed) 
+	{
+		TranslateMessage(&Msg); 
+		DispatchMessage(&Msg);
+	}
+
+	// Kill the timer
+	KillTimer(NULL, iTimerID);
+
+	return FALSE;
+}
+
+
+VOID CALLBACK TimerFunction(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
+{
+	bProcessed = TRUE;
+}
+
+BOOL timing_timeSetEvent(UINT delayInMillis)
+{
+	// Some vars
+	UINT uResolution;
+	TIMECAPS tc;
+	MMRESULT idEvent;
+
+	// We can obtain this minimum value by calling
+	timeGetDevCaps(&tc, sizeof(TIMECAPS));
+	uResolution = min(max(tc.wPeriodMin, 0), tc.wPeriodMax);
+
+	// Create the timer
+	idEvent = timeSetEvent(
+		delayInMillis,
+		uResolution,
+		TimerFunction,
+		0,
+		TIME_ONESHOT);
+
+	if (idEvent == NULL)
+		return TRUE;
+
+	while (!bProcessed){
+		// wait until uor function finish
+	}
+
+	// destroy the timer
+	timeKillEvent(idEvent);
+
+	// reset the timer
+	timeEndPeriod(uResolution);
+
+	return FALSE;
+}
+
+
+BOOL timing_WaitForSingleObject(UINT delayInMillis)
+{
+	HANDLE hEvent;
+
+	// Create a nonsignaled event
+	hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+	if (hEvent == NULL)
+	{
+		print_last_error(_T("CreateEvent"));
+		return TRUE;
+	}
+
+	// Wait until timeout 
+	DWORD x = WaitForSingleObject(hEvent, delayInMillis);
+
+	// Malicious code goes here
+
+	return FALSE;
+}
+
+BOOL timing_WaitForMultipleObjects(UINT delayInMillis) {
+	HANDLE hThread;
+	HANDLE ghEvents[2];
+	DWORD i, dwEvent, dwThreadID;
+
+	// Create two event objects
+
+	for (i = 0; i < 2; i++)
+	{
+		ghEvents[i] = CreateEvent(
+			NULL,  // default security attributes
+			FALSE, // auto-reset event object
+			FALSE, // initial state is nonsignaled
+			NULL); // unnamed object
+
+		if (ghEvents[i] == NULL)
+		{
+			print_last_error(_T("CreateEvent"));
+			return TRUE;
+		}
+	}
+
+	dwEvent = WaitForMultipleObjects(
+		2,        // number of objects in array
+		ghEvents, // array of objects
+		FALSE,    // wait for any object
+		delayInMillis);    // delay in milliseconds
+
+	return FALSE;
+}
+
+BOOL timing_sleep_loop (UINT delayInMillis)
+{
+	/* 
+	This trick is about performing a low number of seconds to sleep but in a loop,
+	the reason behind that sandboxes tries to avoid patching such sleeps because it
+	could lead to race conditions and also because it is just negliable. However,
+	when you do it in a loop, you can make it efficiant to cuz the sandboxe to reach
+	its timeout.
+	*/
+
+	int delayInMillis_divided  = delayInMillis / 1000;
+
+	/* Example: we want to sleep 300 seeconds, then we can sleep
+	0.3s for 1000 times which is like: 300 seconds = 5 minues */
+	for (int i = 0; i < 1000; i++) {
+		Sleep(delayInMillis_divided);
+	}
+
+	// Malicious code goes here
+
+	return FALSE;
+}
+
+
+/*
+RDSTC is a famous x86 instruction to count the number of cycle since reset.
+This can be used to detect the VM. Thanks to Forcepoint for blog article.
+*/
+
+#define LODWORD(_qw)    ((DWORD)(_qw))
+BOOL rdtsc_diff_locky()
+{
+	ULONGLONG tsc1;
+	ULONGLONG tsc2;
+	ULONGLONG tsc3;
+	DWORD i = 0;
+
+	// Try this 10 times in case of small fluctuations
+	for (i = 0; i < 10; i++)
+	{
+		tsc1 = __rdtsc();
+
+		// Waste some cycles - should be faster than CloseHandle on bare metal
+		GetProcessHeap();
+
+		tsc2 = __rdtsc();
+
+		// Waste some cycles - slightly longer than GetProcessHeap() on bare metal
+		CloseHandle(0);
+
+		tsc3 = __rdtsc();
+
+		// Did it take at least 10 times more CPU cycles to perform CloseHandle than it took to perform GetProcessHeap()?
+		if ((LODWORD(tsc3) - LODWORD(tsc2)) / (LODWORD(tsc2) - LODWORD(tsc1)) >= 10)
+			return FALSE;
+	}
+
+	// We consistently saw a small ratio of difference between GetProcessHeap and CloseHandle execution times
+	// so we're probably in a VM!
+	return TRUE;
+}
+
+
+/*
+CPUID is an instruction which cauz a VM Exit to the VMM, 
+this little overhead can show the presence of a hypervisor
+*/
+
+BOOL rdtsc_diff_vmexit()
+{
+	ULONGLONG tsc1 = 0;
+	ULONGLONG tsc2 = 0;
+	ULONGLONG avg = 0;
+	INT cpuInfo[4] = {};
+
+	// Try this 10 times in case of small fluctuations
+	for (INT i = 0; i < 10; i++)
+	{
+		tsc1 = __rdtsc();
+		__cpuid(cpuInfo, 0);
+		tsc2 = __rdtsc();
+
+		// Get the delta of the two RDTSC
+		avg += (tsc2 - tsc1);
+	}
+
+	// We repeated the process 10 times so we make sure our check is as much reliable as we can
+	avg = avg / 10;
+	return (avg < 1000 && avg > 0) ? FALSE : TRUE;
+}
+
+
+/*
+Another timinig attack using the API IcmpSendEcho which takes a TimeOut 
+in milliseconds as a parameter, to wait for IPv4 ICMP packets replies.
+First time observed: http://blog.talosintelligence.com/2017/09/avast-distributes-malware.html
+*/
+BOOL timing_IcmpSendEcho(UINT delayInMillis)
+{
+
+	HANDLE hIcmpFile;
+	unsigned long DestinationAddress = INADDR_NONE;
+	char SendData[32] = "Data Buffer";
+	LPVOID ReplyBuffer = NULL;
+	DWORD ReplySize = 0;
+	const char ipaddr[] = "224.0.0.0";
+
+	hIcmpFile = IcmpCreateFile();
+	if (hIcmpFile == INVALID_HANDLE_VALUE) {
+		printf("\tUnable to open handle.\n");
+		printf("IcmpCreatefile returned error: %u\n", GetLastError());
+		return TRUE;
+	}
+
+	//
+	// Size of ICMP_ECHO_REPLY + size of send data + 8 extra bytes for ICMP error message
+	//
+	ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData) + 8;
+	ReplyBuffer = (VOID*)malloc(ReplySize);
+	if (ReplyBuffer == NULL) {
+		IcmpCloseHandle(hIcmpFile);
+		printf("\tUnable to allocate memory\n");
+		return TRUE;
+	}
+
+	IcmpSendEcho(hIcmpFile, DestinationAddress, SendData, sizeof(SendData), NULL, ReplyBuffer, ReplySize, delayInMillis);
+	IcmpCloseHandle(hIcmpFile);
+	free(ReplyBuffer);
+
+	return FALSE;
+}
+
+/*
+Timing attack using waitable timers. Test fails if any of the calls return an error state.
+*/
+BOOL timing_CreateWaitableTimer(UINT delayInMillis)
+{
+	HANDLE hTimer;
+	LARGE_INTEGER dueTime;
+
+	BOOL bResult = FALSE;
+
+	dueTime.QuadPart = delayInMillis * -10000LL;
+	
+	hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
+	
+	if (hTimer == NULL)
+	{
+		return TRUE;
+	}
+
+	if (SetWaitableTimer(hTimer, &dueTime, 0, NULL, NULL, FALSE) == FALSE)
+	{
+		bResult = TRUE;
+	}
+	else {
+		if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0)
+		{
+			bResult = TRUE;
+		}
+	}
+
+	CancelWaitableTimer(hTimer);
+	CloseHandle(hTimer);
+	return bResult;
+}
+
+HANDLE g_hEventCTQT = NULL;
+
+/*
+Timing attack using CreateTimerQueueTimer. Test fails if any of the calls return an error state.
+*/
+BOOL timing_CreateTimerQueueTimer(UINT delayInMillis)
+{
+	HANDLE hTimerQueue;
+	HANDLE hTimerQueueTimer = NULL;
+	BOOL bResult = FALSE;
+
+	g_hEventCTQT = CreateEvent(NULL, FALSE, FALSE, NULL);
+	if (g_hEventCTQT == NULL)
+		return FALSE;
+
+	hTimerQueue = CreateTimerQueue();
+	if (hTimerQueue == NULL)
+	{
+		return TRUE;
+	}
+
+	if (CreateTimerQueueTimer(
+		&hTimerQueueTimer,
+		hTimerQueue,
+		&CallbackCTQT,
+		reinterpret_cast<PVOID>(0xDEADBEEFULL),
+		delayInMillis,
+		0,
+		WT_EXECUTEDEFAULT) == FALSE)
+	{
+		bResult = TRUE;
+	}
+	else {
+
+		// idea here is to wait only 10x the expected delay time
+		// if the wait expires before the timer comes back, we fail the test
+		if (WaitForSingleObject(g_hEventCTQT, delayInMillis * 10) != WAIT_OBJECT_0)
+		{
+			bResult = FALSE;
+		}
+
+	}
+
+	// Delete all timers in the timer queue.
+	DeleteTimerQueueEx(hTimerQueue, NULL);
+
+	CloseHandle(g_hEventCTQT);
+
+	return bResult;
+}
+
+VOID CALLBACK CallbackCTQT(PVOID lParam, BOOLEAN TimerOrWaitFired)
+{
+	if (TimerOrWaitFired == TRUE && lParam == reinterpret_cast<PVOID>(0xDEADBEEFULL))
+	{
+		SetEvent(g_hEventCTQT);
+	}
+}
diff --git a/al-khaser/al-khaser/TimingAttacks/timing.h b/al-khaser/al-khaser/TimingAttacks/timing.h
new file mode 100644
index 0000000000000000000000000000000000000000..4523d211c83d312647dfaad2da8de6b6c4adc559
--- /dev/null
+++ b/al-khaser/al-khaser/TimingAttacks/timing.h
@@ -0,0 +1,14 @@
+#pragma once
+
+BOOL timing_SetTimer(UINT delayInMillis);
+BOOL timing_NtDelayexecution(UINT delayInMillis);
+BOOL timing_timeSetEvent(UINT delayInMillis);
+BOOL timing_WaitForSingleObject(UINT delayInMillis);
+BOOL timing_WaitForMultipleObjects(UINT delayInMillis);
+BOOL timing_sleep_loop(UINT delayInMillis);
+BOOL rdtsc_diff_locky();
+BOOL rdtsc_diff_vmexit();
+BOOL timing_IcmpSendEcho(UINT delayInMillis);
+BOOL timing_CreateWaitableTimer(UINT delayInMillis);
+BOOL timing_CreateTimerQueueTimer(UINT delayInMillis);
+VOID CALLBACK CallbackCTQT(PVOID lParam, BOOLEAN TimerOrWaitFired);
diff --git a/al-khaser/al-khaser/al-khaser.manifest b/al-khaser/al-khaser/al-khaser.manifest
new file mode 100644
index 0000000000000000000000000000000000000000..d38d8695876d7171efbd967da5d098ef92f06b4a
--- /dev/null
+++ b/al-khaser/al-khaser/al-khaser.manifest
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
+	<!-- This manifest is critical, as without it the application cannot detect the OS version properly. -->
+    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+        <application>
+            <!-- Windows 10 -->
+            <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+            <!-- Windows 8.1 -->
+            <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+            <!-- Windows 8 -->
+            <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+            <!-- Windows 7 -->
+            <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+            <!-- Windows Vista -->
+            <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
+        </application>
+    </compatibility>
+</assembly>
diff --git a/al-khaser/al-khaser/al-khaser.vcxproj b/al-khaser/al-khaser/al-khaser.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..9b96d3332edc8737269d0041b48d820893cb49c8
--- /dev/null
+++ b/al-khaser/al-khaser/al-khaser.vcxproj
@@ -0,0 +1,351 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>15.0</VCProjectVersion>
+    <ProjectGuid>{77AEFBC3-0ECE-46AD-A113-966AAAA838E1}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>alkhaser</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+    </Link>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+    </Link>
+    <PostBuildEvent>
+      <Command>copy $(OutDir)$(AssemblyName).exe $(SolutionDir)$(AssemblyName)_$(PlatformTarget).exe</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <PostBuildEvent>
+      <Command>copy $(OutDir)$(AssemblyName).exe $(SolutionDir)$(AssemblyName)_$(Platform).exe</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="AntiAnalysis\pch.h" />
+    <ClInclude Include="AntiAnalysis\process.h" />
+    <ClInclude Include="AntiDebug\BeingDebugged.h" />
+    <ClInclude Include="AntiDebug\CheckRemoteDebuggerPresent.h" />
+    <ClInclude Include="AntiDebug\CloseHandle_InvalidHandle.h" />
+    <ClInclude Include="AntiDebug\HardwareBreakpoints.h" />
+    <ClInclude Include="AntiDebug\Interrupt_0x2d.h" />
+    <ClInclude Include="AntiDebug\Interrupt_3.h" />
+    <ClInclude Include="AntiDebug\IsDebuggerPresent.h" />
+    <ClInclude Include="AntiDebug\LowFragmentationHeap.h" />
+    <ClInclude Include="AntiDebug\MemoryBreakpoints_PageGuard.h" />
+    <ClInclude Include="AntiDebug\ModuleBoundsHookCheck.h" />
+    <ClInclude Include="AntiDebug\NtGlobalFlag.h" />
+    <ClInclude Include="AntiDebug\NtQueryInformationProcess_ProcessDebugFlags.h" />
+    <ClInclude Include="AntiDebug\NtQueryInformationProcess_ProcessDebugObject.h" />
+    <ClInclude Include="AntiDebug\NtQueryInformationProcess_ProcessDebugPort.h" />
+    <ClInclude Include="AntiDebug\NtQueryObject_ObjectInformation.h" />
+    <ClInclude Include="AntiDebug\NtQuerySystemInformation_SystemKernelDebuggerInformation.h" />
+    <ClInclude Include="AntiDebug\NtSetInformationThread_ThreadHideFromDebugger.h" />
+    <ClInclude Include="AntiDebug\NtSystemDebugControl.h" />
+    <ClInclude Include="AntiDebug\NtYieldExecution.h" />
+    <ClInclude Include="AntiDebug\OutputDebugStringAPI.h" />
+    <ClInclude Include="AntiDebug\PageExceptionBreakpointCheck.h" />
+    <ClInclude Include="AntiDebug\ParentProcess.h" />
+    <ClInclude Include="AntiDebug\pch.h" />
+    <ClInclude Include="AntiDebug\ProcessHeap_Flags.h" />
+    <ClInclude Include="AntiDebug\ProcessHeap_ForceFlags.h" />
+    <ClInclude Include="AntiDebug\ProcessJob.h" />
+    <ClInclude Include="AntiDebug\ScanForModules.h" />
+    <ClInclude Include="AntiDebug\SeDebugPrivilege.h" />
+    <ClInclude Include="AntiDebug\SetHandleInformation_API.h" />
+    <ClInclude Include="AntiDebug\SharedUserData_KernelDebugger.h" />
+    <ClInclude Include="AntiDebug\SoftwareBreakpoints.h" />
+    <ClInclude Include="AntiDebug\TLS_callbacks.h" />
+    <ClInclude Include="AntiDebug\TrapFlag.h" />
+    <ClInclude Include="AntiDebug\UnhandledExceptionFilter_Handler.h" />
+    <ClInclude Include="AntiDebug\WriteWatch.h" />
+    <ClInclude Include="AntiDebug\WUDF_IsDebuggerPresent.h" />
+    <ClInclude Include="AntiDisassm\AntiDisassm.h" />
+    <ClInclude Include="AntiDisassm\pch.h" />
+    <ClInclude Include="AntiDump\ErasePEHeaderFromMemory.h" />
+    <ClInclude Include="AntiDump\pch.h" />
+    <ClInclude Include="AntiDump\SizeOfImage.h" />
+    <ClInclude Include="AntiVM\Generic.h" />
+    <ClInclude Include="AntiVM\HyperV.h" />
+    <ClInclude Include="AntiVM\KVM.h" />
+    <ClInclude Include="AntiVM\Parallels.h" />
+    <ClInclude Include="AntiVM\pch.h" />
+    <ClInclude Include="AntiVM\Qemu.h" />
+    <ClInclude Include="AntiVM\Services.h" />
+    <ClInclude Include="AntiVM\VirtualBox.h" />
+    <ClInclude Include="AntiVM\VirtualPC.h" />
+    <ClInclude Include="AntiVM\VMWare.h" />
+    <ClInclude Include="AntiVM\Wine.h" />
+    <ClInclude Include="AntiVM\Xen.h" />
+    <ClInclude Include="CodeInjection\CreateRemoteThread.h" />
+    <ClInclude Include="CodeInjection\GetSetThreadContext.h" />
+    <ClInclude Include="CodeInjection\NtCreateThreadEx.h" />
+    <ClInclude Include="CodeInjection\pch.h" />
+    <ClInclude Include="CodeInjection\QueueUserAPC.h" />
+    <ClInclude Include="CodeInjection\RtlCreateUserThread.h" />
+    <ClInclude Include="CodeInjection\SetWindowsHooksEx.h" />
+    <ClInclude Include="pch.h" />
+    <ClInclude Include="Shared\APIs.h" />
+    <ClInclude Include="Shared\ApiTypeDefs.h" />
+    <ClInclude Include="Shared\Common.h" />
+    <ClInclude Include="Shared\log.h" />
+    <ClInclude Include="Shared\pch.h" />
+    <ClInclude Include="Shared\Utils.h" />
+    <ClInclude Include="Shared\VersionHelpers.h" />
+    <ClInclude Include="Shared\winapifamily.h" />
+    <ClInclude Include="Shared\WinStructs.h" />
+    <ClInclude Include="TimingAttacks\pch.h" />
+    <ClInclude Include="TimingAttacks\timing.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="al-khaser.cpp" />
+    <ClCompile Include="AntiAnalysis\process.cpp" />
+    <ClCompile Include="AntiDebug\BeingDebugged.cpp" />
+    <ClCompile Include="AntiDebug\CheckRemoteDebuggerPresent.cpp" />
+    <ClCompile Include="AntiDebug\CloseHandle_InvalidHandle.cpp" />
+    <ClCompile Include="AntiDebug\HardwareBreakpoints.cpp" />
+    <ClCompile Include="AntiDebug\Interrupt_0x2d.cpp" />
+    <ClCompile Include="AntiDebug\Interrupt_3.cpp" />
+    <ClCompile Include="AntiDebug\IsDebuggerPresent.cpp" />
+    <ClCompile Include="AntiDebug\LowFragmentationHeap.cpp" />
+    <ClCompile Include="AntiDebug\MemoryBreakpoints_PageGuard.cpp" />
+    <ClCompile Include="AntiDebug\ModuleBoundsHookCheck.cpp" />
+    <ClCompile Include="AntiDebug\NtGlobalFlag.cpp" />
+    <ClCompile Include="AntiDebug\NtQueryInformationProcess_ProcessDebugFlags.cpp" />
+    <ClCompile Include="AntiDebug\NtQueryInformationProcess_ProcessDebugObject.cpp" />
+    <ClCompile Include="AntiDebug\NtQueryInformationProcess_ProcessDebugPort.cpp" />
+    <ClCompile Include="AntiDebug\NtQueryObject_AllTypesInformation.cpp" />
+    <ClCompile Include="AntiDebug\NtQueryObject_ObjectTypeInformation.cpp" />
+    <ClCompile Include="AntiDebug\NtQuerySystemInformation_SystemKernelDebuggerInformation.cpp" />
+    <ClCompile Include="AntiDebug\NtSetInformationThread_ThreadHideFromDebugger.cpp" />
+    <ClCompile Include="AntiDebug\NtSystemDebugControl.cpp" />
+    <ClCompile Include="AntiDebug\NtYieldExecution.cpp" />
+    <ClCompile Include="AntiDebug\OutputDebugStringAPI.cpp" />
+    <ClCompile Include="AntiDebug\PageExceptionBreakpointCheck.cpp" />
+    <ClCompile Include="AntiDebug\ParentProcess.cpp" />
+    <ClCompile Include="AntiDebug\ProcessHeap_Flags.cpp" />
+    <ClCompile Include="AntiDebug\ProcessHeap_ForceFlags.cpp" />
+    <ClCompile Include="AntiDebug\ProcessJob.cpp" />
+    <ClCompile Include="AntiDebug\ScanForModules.cpp" />
+    <ClCompile Include="AntiDebug\SeDebugPrivilege.cpp" />
+    <ClCompile Include="AntiDebug\SetHandleInformation_API.cpp" />
+    <ClCompile Include="AntiDebug\SharedUserData_KernelDebugger.cpp" />
+    <ClCompile Include="AntiDebug\SoftwareBreakpoints.cpp" />
+    <ClCompile Include="AntiDebug\TLS_callbacks.cpp" />
+    <ClCompile Include="AntiDebug\TrapFlag.cpp" />
+    <ClCompile Include="AntiDebug\UnhandledExceptionFilter_Handler.cpp" />
+    <ClCompile Include="AntiDebug\WriteWatch.cpp" />
+    <ClCompile Include="AntiDebug\WUDF_IsDebuggerPresent.cpp" />
+    <ClCompile Include="AntiDisassm\AntiDisassm.cpp" />
+    <ClCompile Include="AntiDump\ErasePEHeaderFromMemory.cpp" />
+    <ClCompile Include="AntiDump\SizeOfImage.cpp" />
+    <ClCompile Include="AntiVM\Generic.cpp" />
+    <ClCompile Include="AntiVM\HyperV.cpp" />
+    <ClCompile Include="AntiVM\KVM.cpp" />
+    <ClCompile Include="AntiVM\Parallels.cpp" />
+    <ClCompile Include="AntiVM\Qemu.cpp" />
+    <ClCompile Include="AntiVM\Services.cpp" />
+    <ClCompile Include="AntiVM\VirtualBox.cpp" />
+    <ClCompile Include="AntiVM\VirtualPC.cpp" />
+    <ClCompile Include="AntiVM\VMWare.cpp" />
+    <ClCompile Include="AntiVM\Wine.cpp" />
+    <ClCompile Include="AntiVM\Xen.cpp" />
+    <ClCompile Include="CodeInjection\CreateRemoteThread.cpp" />
+    <ClCompile Include="CodeInjection\GetSetThreadContext.cpp" />
+    <ClCompile Include="CodeInjection\NtCreateThreadEx.cpp" />
+    <ClCompile Include="CodeInjection\QueueUserAPC.cpp" />
+    <ClCompile Include="CodeInjection\RtlCreateUserThread.cpp" />
+    <ClCompile Include="CodeInjection\SetWindowsHooksEx.cpp" />
+    <ClCompile Include="pch.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="Shared\APIs.cpp" />
+    <ClCompile Include="Shared\ApiTypeDefs.cpp" />
+    <ClCompile Include="Shared\Common.cpp" />
+    <ClCompile Include="Shared\log.cpp" />
+    <ClCompile Include="Shared\Utils.cpp" />
+    <ClCompile Include="TimingAttacks\timing.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <MASM Include="AntiDebug\int2d_x64.asm">
+      <FileType>Document</FileType>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </MASM>
+    <MASM Include="AntiDebug\int2d_x86.asm">
+      <FileType>Document</FileType>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <UseSafeExceptionHandlers Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</UseSafeExceptionHandlers>
+    </MASM>
+    <MASM Include="AntiDisassm\AntiDisassm_x64.asm">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </MASM>
+    <MASM Include="AntiDisassm\AntiDisassm_x86.asm">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <UseSafeExceptionHandlers Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</UseSafeExceptionHandlers>
+    </MASM>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\CHANGELOG.md" />
+    <None Include="..\README.md" />
+  </ItemGroup>
+  <ItemGroup>
+    <Manifest Include="al-khaser.manifest" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/al-khaser/al-khaser/al-khaser.vcxproj.filters b/al-khaser/al-khaser/al-khaser.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..55a4a4c4932b6fbf2016fc1b22441685df840459
--- /dev/null
+++ b/al-khaser/al-khaser/al-khaser.vcxproj.filters
@@ -0,0 +1,509 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="AntiDebug">
+      <UniqueIdentifier>{18e12ba4-7f6b-434f-8271-d5bbb46fa4c9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiDebug\Source">
+      <UniqueIdentifier>{bf1fe4e8-39e0-495b-9f5b-b5c5da2a2d08}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiDebug\Header">
+      <UniqueIdentifier>{f97845a6-27f4-4e98-874d-63f896f1006b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiAnalysis">
+      <UniqueIdentifier>{666c0b5a-f811-4eb2-b4c9-a2e91c1ea6a0}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiVM">
+      <UniqueIdentifier>{33fc6fa5-2c5b-43c3-ba25-d67335382f71}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiDump">
+      <UniqueIdentifier>{41e90f25-fc84-4cdd-ace6-cca5db49fbb4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="TimingAttacks">
+      <UniqueIdentifier>{c260c597-7ad7-4fc7-b84d-fa69d45c4b99}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Shared">
+      <UniqueIdentifier>{5d11ce3d-06d9-4e4c-b7f1-aef4153ac76b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Shared\Source">
+      <UniqueIdentifier>{bc3f3752-625a-4170-bfae-873fc9a063ef}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Shared\Header">
+      <UniqueIdentifier>{0abe0968-9567-474e-8ee3-02ce966590e2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="CodeInjection">
+      <UniqueIdentifier>{7c1ba53c-7a4c-43a5-9c70-55888d8554b9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="CodeInjection\Source">
+      <UniqueIdentifier>{d8bae499-5da2-4540-b525-4de33b7b7719}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="CodeInjection\Header">
+      <UniqueIdentifier>{807d0507-ce74-4b62-ab79-8fbd34904fe7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiAnalysis\Source">
+      <UniqueIdentifier>{cf06cc61-c616-45d1-ae2f-7577948bc3e0}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiAnalysis\Header">
+      <UniqueIdentifier>{f9672dc2-2eb4-4fdb-87ea-763a7a86872e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiDump\Source">
+      <UniqueIdentifier>{1bbf6302-26d8-43f4-a4d3-befc9b58d300}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiDump\Header">
+      <UniqueIdentifier>{21cdc14d-e1ad-40cd-aa30-6e2635ef68cc}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiVM\Source">
+      <UniqueIdentifier>{a1ad376c-c1f2-45b7-9ae6-e9829edad1e2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiVM\Header">
+      <UniqueIdentifier>{7ac2da9c-be04-4cfd-8687-20a6ac63a45a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="TimingAttacks\Source">
+      <UniqueIdentifier>{6e37020f-ba4e-4b6f-82ed-0e4f5e5ec872}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="TimingAttacks\Header">
+      <UniqueIdentifier>{bcf9eab0-7525-4627-843b-878d0ae1732f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiDisassm">
+      <UniqueIdentifier>{3c7ae943-1975-45bf-a23c-2bdfc5e58f93}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiDisassm\Source">
+      <UniqueIdentifier>{fcfb2a05-4437-4cb4-a3e3-6467c256b185}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="AntiDisassm\Header">
+      <UniqueIdentifier>{c5411e59-e406-4610-87a8-321a00883ffe}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="pch.h" />
+    <ClInclude Include="AntiDebug\CloseHandle_InvalidHandle.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\HardwareBreakpoints.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\Interrupt_0x2d.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\Interrupt_3.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\IsDebuggerPresent.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\MemoryBreakpoints_PageGuard.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\ModuleBoundsHookCheck.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\NtQueryInformationProcess_ProcessDebugFlags.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\NtQueryInformationProcess_ProcessDebugObject.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\NtQueryInformationProcess_ProcessDebugPort.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\NtQueryObject_ObjectInformation.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\NtQuerySystemInformation_SystemKernelDebuggerInformation.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\NtSetInformationThread_ThreadHideFromDebugger.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\NtYieldExecution.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\OutputDebugStringAPI.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\PageExceptionBreakpointCheck.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\ParentProcess.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\ProcessHeap_Flags.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\ProcessHeap_ForceFlags.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\ProcessJob.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\ScanForModules.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\SeDebugPrivilege.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\SetHandleInformation_API.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\SharedUserData_KernelDebugger.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\SoftwareBreakpoints.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\TLS_callbacks.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\UnhandledExceptionFilter_Handler.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\WriteWatch.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\WUDF_IsDebuggerPresent.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="Shared\WinStructs.h">
+      <Filter>Shared\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="Shared\winapifamily.h">
+      <Filter>Shared\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="Shared\VersionHelpers.h">
+      <Filter>Shared\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="Shared\Utils.h">
+      <Filter>Shared\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="Shared\log.h">
+      <Filter>Shared\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="Shared\Common.h">
+      <Filter>Shared\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="Shared\ApiTypeDefs.h">
+      <Filter>Shared\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="Shared\APIs.h">
+      <Filter>Shared\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\pch.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="Shared\pch.h">
+      <Filter>Shared\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="CodeInjection\CreateRemoteThread.h">
+      <Filter>CodeInjection\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="CodeInjection\GetSetThreadContext.h">
+      <Filter>CodeInjection\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="CodeInjection\NtCreateThreadEx.h">
+      <Filter>CodeInjection\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="CodeInjection\pch.h">
+      <Filter>CodeInjection\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="CodeInjection\QueueUserAPC.h">
+      <Filter>CodeInjection\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="CodeInjection\RtlCreateUserThread.h">
+      <Filter>CodeInjection\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="CodeInjection\SetWindowsHooksEx.h">
+      <Filter>CodeInjection\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiAnalysis\pch.h">
+      <Filter>AntiAnalysis\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiAnalysis\process.h">
+      <Filter>AntiAnalysis\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDump\ErasePEHeaderFromMemory.h">
+      <Filter>AntiDump\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDump\pch.h">
+      <Filter>AntiDump\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDump\SizeOfImage.h">
+      <Filter>AntiDump\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiVM\Generic.h">
+      <Filter>AntiVM\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiVM\Parallels.h">
+      <Filter>AntiVM\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiVM\pch.h">
+      <Filter>AntiVM\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiVM\Qemu.h">
+      <Filter>AntiVM\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiVM\Services.h">
+      <Filter>AntiVM\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiVM\VirtualBox.h">
+      <Filter>AntiVM\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiVM\VirtualPC.h">
+      <Filter>AntiVM\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiVM\VMWare.h">
+      <Filter>AntiVM\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiVM\Wine.h">
+      <Filter>AntiVM\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiVM\Xen.h">
+      <Filter>AntiVM\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="TimingAttacks\pch.h">
+      <Filter>TimingAttacks\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="TimingAttacks\timing.h">
+      <Filter>TimingAttacks\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\CheckRemoteDebuggerPresent.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\BeingDebugged.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\NtGlobalFlag.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDisassm\AntiDisassm.h">
+      <Filter>AntiDisassm\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDisassm\pch.h">
+      <Filter>AntiDisassm\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\TrapFlag.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\LowFragmentationHeap.h">
+      <Filter>AntiDebug\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiVM\KVM.h">
+      <Filter>AntiVM\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiVM\HyperV.h">
+      <Filter>AntiVM\Header</Filter>
+    </ClInclude>
+    <ClInclude Include="AntiDebug\NtSystemDebugControl.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="al-khaser.cpp" />
+    <ClCompile Include="pch.cpp" />
+    <ClCompile Include="AntiDebug\CloseHandle_InvalidHandle.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\HardwareBreakpoints.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\Interrupt_0x2d.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\Interrupt_3.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\IsDebuggerPresent.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\MemoryBreakpoints_PageGuard.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\ModuleBoundsHookCheck.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\NtQueryInformationProcess_ProcessDebugFlags.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\NtQueryInformationProcess_ProcessDebugObject.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\NtQueryInformationProcess_ProcessDebugPort.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\NtQueryObject_AllTypesInformation.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\NtQueryObject_ObjectTypeInformation.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\NtQuerySystemInformation_SystemKernelDebuggerInformation.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\NtSetInformationThread_ThreadHideFromDebugger.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\NtYieldExecution.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\OutputDebugStringAPI.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\PageExceptionBreakpointCheck.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\ParentProcess.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\ProcessHeap_Flags.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\ProcessHeap_ForceFlags.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\ProcessJob.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\ScanForModules.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\SeDebugPrivilege.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\SetHandleInformation_API.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\SharedUserData_KernelDebugger.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\SoftwareBreakpoints.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\TLS_callbacks.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\UnhandledExceptionFilter_Handler.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\WriteWatch.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\WUDF_IsDebuggerPresent.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="Shared\APIs.cpp">
+      <Filter>Shared\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="Shared\ApiTypeDefs.cpp">
+      <Filter>Shared\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="Shared\Common.cpp">
+      <Filter>Shared\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="Shared\log.cpp">
+      <Filter>Shared\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="Shared\Utils.cpp">
+      <Filter>Shared\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="CodeInjection\CreateRemoteThread.cpp">
+      <Filter>CodeInjection\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="CodeInjection\GetSetThreadContext.cpp">
+      <Filter>CodeInjection\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="CodeInjection\NtCreateThreadEx.cpp">
+      <Filter>CodeInjection\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="CodeInjection\QueueUserAPC.cpp">
+      <Filter>CodeInjection\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="CodeInjection\RtlCreateUserThread.cpp">
+      <Filter>CodeInjection\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="CodeInjection\SetWindowsHooksEx.cpp">
+      <Filter>CodeInjection\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiAnalysis\process.cpp">
+      <Filter>AntiAnalysis\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDump\ErasePEHeaderFromMemory.cpp">
+      <Filter>AntiDump\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDump\SizeOfImage.cpp">
+      <Filter>AntiDump\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiVM\Generic.cpp">
+      <Filter>AntiVM\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiVM\Parallels.cpp">
+      <Filter>AntiVM\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiVM\Qemu.cpp">
+      <Filter>AntiVM\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiVM\Services.cpp">
+      <Filter>AntiVM\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiVM\VirtualBox.cpp">
+      <Filter>AntiVM\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiVM\VirtualPC.cpp">
+      <Filter>AntiVM\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiVM\VMWare.cpp">
+      <Filter>AntiVM\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiVM\Wine.cpp">
+      <Filter>AntiVM\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiVM\Xen.cpp">
+      <Filter>AntiVM\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="TimingAttacks\timing.cpp">
+      <Filter>TimingAttacks\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\CheckRemoteDebuggerPresent.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\NtGlobalFlag.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\BeingDebugged.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDisassm\AntiDisassm.cpp">
+      <Filter>AntiDisassm\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\TrapFlag.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\LowFragmentationHeap.cpp">
+      <Filter>AntiDebug\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiVM\KVM.cpp">
+      <Filter>AntiVM\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiVM\HyperV.cpp">
+      <Filter>AntiVM\Source</Filter>
+    </ClCompile>
+    <ClCompile Include="AntiDebug\NtSystemDebugControl.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <MASM Include="AntiDebug\int2d_x86.asm">
+      <Filter>AntiDebug\Source</Filter>
+    </MASM>
+    <MASM Include="AntiDebug\int2d_x64.asm">
+      <Filter>AntiDebug\Source</Filter>
+    </MASM>
+  </ItemGroup>
+  <ItemGroup>
+    <Manifest Include="al-khaser.manifest" />
+    <MASM Include="AntiDisassm\AntiDisassm_x86.asm">
+      <Filter>AntiDisassm\Source</Filter>
+    </MASM>
+    <MASM Include="AntiDisassm\AntiDisassm_x64.asm">
+      <Filter>AntiDisassm\Source</Filter>
+    </MASM>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\README.md" />
+    <None Include="..\CHANGELOG.md" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/al-khaser/al-khaser/packages.config b/al-khaser/al-khaser/packages.config
new file mode 100644
index 0000000000000000000000000000000000000000..2bf64c327c18c54b980d88261291c0601fcd1a40
--- /dev/null
+++ b/al-khaser/al-khaser/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="editorconfig" version="0.12.1" targetFramework="native" />
+</packages>
\ No newline at end of file
diff --git a/al-khaser/al-khaser/pch.cpp b/al-khaser/al-khaser/pch.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3a3d12b5a719d5ccd69ec655f551e224d5247f05
--- /dev/null
+++ b/al-khaser/al-khaser/pch.cpp
@@ -0,0 +1,5 @@
+// pch.cpp: source file corresponding to pre-compiled header; necessary for compilation to succeed
+
+#include "pch.h"
+
+// In general, ignore this file, but keep it around if you are using pre-compiled headers.
diff --git a/al-khaser/al-khaser/pch.h b/al-khaser/al-khaser/pch.h
new file mode 100644
index 0000000000000000000000000000000000000000..f546cf313c685a0e17c8eaf930b4b75538cb4ffe
--- /dev/null
+++ b/al-khaser/al-khaser/pch.h
@@ -0,0 +1,142 @@
+// Tips for Getting Started: 
+//   1. Use the Solution Explorer window to add/manage files
+//   2. Use the Team Explorer window to connect to source control
+//   3. Use the Output window to see build output and other messages
+//   4. Use the Error List window to view errors
+//   5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
+//   6. In the future, to open this project again, go to File > Open > Project and select the .sln file
+
+#ifndef PCH_H
+#define PCH_H
+
+// add headers that you want to pre-compile here
+
+
+
+#include <string>
+#include <vector>
+#include <filesystem>
+
+#include <Windows.h>
+#include <winternl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <IPTypes.h>
+#include <Iphlpapi.h>
+#include <icmpapi.h>
+#include <Psapi.h>
+#include <Shlwapi.h>
+#include <ShlObj.h>
+#include <stdarg.h>
+#include <strsafe.h>
+#include <tchar.h>
+#include <time.h>
+#include <TlHelp32.h>
+#include <Wbemidl.h>
+#include <devguid.h>    // Device guids
+#include <winioctl.h>	// IOCTL
+#include <intrin.h>		// cpuid()
+#include <locale.h>		// 64-bit wchar atoi
+#include <powrprof.h>	// check_power_modes()
+#include <SetupAPI.h>
+#include <algorithm>
+#include <cctype>
+#include <slpublic.h> // SLIsGenuineLocal
+
+#pragma comment(lib, "wbemuuid.lib")
+#pragma comment(lib, "Shlwapi.lib")
+#pragma comment(lib, "Mpr.lib")
+#pragma comment(lib, "Iphlpapi.lib")
+#pragma comment(lib, "Shlwapi.lib")
+#pragma comment(lib, "Psapi.lib")
+#pragma comment(lib, "wbemuuid.lib")
+#pragma comment(lib, "Winmm.lib")
+#pragma comment(lib, "setupapi.lib")
+#pragma comment(lib, "powrprof.lib")
+#pragma comment(lib, "Slwga.lib")
+
+#include "Shared/Common.h"
+#include "Shared/VersionHelpers.h"
+#include "Shared/log.h"
+#include "Shared/Utils.h"
+#include "Shared/WinStructs.h"
+#include "Shared/ApiTypeDefs.h"
+#include "Shared/APIs.h"
+#include "Shared/winapifamily.h"
+
+/* AntiDebugs headers */
+#include "AntiDebug/CheckRemoteDebuggerPresent.h"
+#include "AntiDebug/IsDebuggerPresent.h"
+#include "AntiDebug/BeingDebugged.h"
+#include "AntiDebug/ProcessHeap_Flags.h"
+#include "AntiDebug/ProcessHeap_ForceFlags.h"
+#include "AntiDebug/NtGlobalFlag.h"
+#include "AntiDebug/NtQueryInformationProcess_ProcessDebugPort.h"
+#include "AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.h"
+#include "AntiDebug/NtQueryInformationProcess_ProcessDebugObject.h"
+#include "AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.h"
+#include "AntiDebug/CloseHandle_InvalidHandle.h"
+#include "AntiDebug/NtSystemDebugControl.h"
+#include "AntiDebug/UnhandledExceptionFilter_Handler.h"
+#include "AntiDebug/OutputDebugStringAPI.h"
+#include "AntiDebug/HardwareBreakpoints.h"
+#include "AntiDebug/SoftwareBreakpoints.h"
+#include "AntiDebug/Interrupt_0x2d.h"
+#include "AntiDebug/Interrupt_3.h"
+#include "AntiDebug/TrapFlag.h"
+#include "AntiDebug/MemoryBreakpoints_PageGuard.h"
+#include "AntiDebug/ParentProcess.h"
+#include "AntiDebug/SeDebugPrivilege.h"
+#include "AntiDebug/NtQueryObject_ObjectInformation.h"
+#include "AntiDebug/NtYieldExecution.h"
+#include "AntiDebug/SetHandleInformation_API.h"
+#include "AntiDebug/TLS_callbacks.h"
+#include "AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.h"
+#include "AntiDebug/SharedUserData_KernelDebugger.h"
+#include "AntiDebug/ProcessJob.h"
+#include "AntiDebug/WriteWatch.h"
+#include "AntiDebug/PageExceptionBreakpointCheck.h"
+#include "AntiDebug/ModuleBoundsHookCheck.h"
+#include "AntiDebug/ScanForModules.h"
+#include "AntiDebug/WUDF_IsDebuggerPresent.h"
+#include "AntiDebug/LowFragmentationHeap.h"
+
+
+/* Anti dumping headers */
+#include "AntiDump/ErasePEHeaderFromMemory.h"
+#include "AntiDump/SizeOfImage.h"
+
+/* Anti VM headers */
+#include "AntiVM/VirtualBox.h"
+#include "AntiVM/VMware.h"
+#include "AntiVM/Wine.h"
+#include "AntiVM/Generic.h"
+#include "AntiVM/VirtualPC.h"
+#include "AntiVM/QEMU.h"
+#include "AntiVM/Xen.h"
+#include "AntiVM/KVM.h"
+#include "AntiVM/Parallels.h"
+#include "AntiVM/Services.h"
+#include "AntiVM/HyperV.h"
+
+/* Code Injections Headers */
+#include "CodeInjection/CreateRemoteThread.h"
+#include "CodeInjection/SetWindowsHooksEx.h"
+#include "CodeInjection/NtCreateThreadEx.h"
+#include "CodeInjection/RtlCreateUserThread.h"
+#include "CodeInjection/QueueUserAPC.h"
+#include "CodeInjection/GetSetThreadContext.h"
+
+/* Delay Execution */
+#include "TimingAttacks/timing.h"
+
+/* Anti-Analysis */
+#include "AntiAnalysis/process.h"
+
+/* Anti-Disassembly */
+#include "AntiDisassm/AntiDisassm.h"
+
+
+#endif //PCH_H
diff --git a/latex/projet_semestre.pdf b/latex/projet_semestre.pdf
index 272ba221672bfe0b7074309d85fd6ad22f309086..c9074123e6473268c9f80bbf572803d3935ec854 100644
Binary files a/latex/projet_semestre.pdf and b/latex/projet_semestre.pdf differ
diff --git a/latex/projet_semestre.synctex.gz b/latex/projet_semestre.synctex.gz
index 186c5733d81d5b32fca192a1a30559bee479ee16..39c8e91f0c8bdd228113aa14fad36b025fedabda 100644
Binary files a/latex/projet_semestre.synctex.gz and b/latex/projet_semestre.synctex.gz differ
diff --git a/latex/projet_semestre.tex b/latex/projet_semestre.tex
index c97508930b9c19cbcb9a516b9d0d4d0fb8c1fc93..588d2407d06b8bf480f9f1d78871acfcd44cadab 100644
--- a/latex/projet_semestre.tex
+++ b/latex/projet_semestre.tex
@@ -15,6 +15,32 @@
 	\clearpage
 	
 	\section{Introduction}
+	\section{Méthodes de détections}
+	\subsection{Outils de détection trouvés}
+	\begin{itemize}
+		\item \textbf{Linux:}
+		\begin{itemize}
+			\item \href{https://github.com/systemd/systemd}{systemd-detect-virt}, C
+		\end{itemize}
+		\item \textbf{Windows:}
+		\begin{itemize}
+			\item \href{https://github.com/LordNoteworthy/al-khaser}{Al-Khaser}, C, C++, C\#
+			\item \href{https://github.com/a0rtega/pafish}{Pafish}, C
+		\end{itemize}
+		\item \textbf{Apple:}
+		\item \textbf{Multi-Plateforme:}
+		\item \href{https://github.com/kernelwernel/VMAware}{VMAware}
+		\subsubitem Écrit en C++
+	\end{itemize}
+	\subsection{Table DMI (all plateform)}
+	\subsection{CPUID (x86\_64)}
+	\subsection{Device-tree (ARM, aarch64)}
+	\subsection{SeaBios (SMBIOS)}
+	\subsection{Détection de \textit{Dom0}}
+	\subsection{Existance de \textit{/proc/xen}}
+	\subsection{User Mode Linux dans \textit{/proc/cpuinfo}}
+	\subsection{Existance de \textit{/sys/hypervisor/type}}
+	\subsection{Hypervisor String}
 	\section{Systemd-detect-virt}
 	\subsection{Détection de Virtual Machines (VMs)}
 	Pour détecter la virtualisation, systemd-detect-virt commence par utiliser les tables DMI (Desktop Management Interface) afin de récupérer le nom de produit et les informations sur le vendeur (\textit{product\_name, sys\_vendor, board\_vendor, bios\_vendor et product\_version}) qui se situe dans \textit{/sys/class/dmi/id/}\\\\