mirror of
https://github.com/Bareflank/hypervisor
synced 2026-08-17 06:23:04 -04:00
Bareflank 3.0 Initial Upload
This patch provides the initial upload for Bareflank 3.0. It should be noted that this initial upload does not contain all of the intended features for 3.0, and instead provides a starting point for further development and review.
This commit is contained in:
parent
d2203d8fa4
commit
7e3f101819
1193 changed files with 65421 additions and 144010 deletions
92
CHANGELOG.md
92
CHANGELOG.md
|
|
@ -1,92 +0,0 @@
|
|||
# Change Log
|
||||
|
||||
## [1.1.0] - 2017-28-04
|
||||
### Added
|
||||
- New GDT class that provides a cleaner abstraction of the GDT
|
||||
- New IDT class that provides a cleaner abstraction of the IDT
|
||||
- New Page Table class that provides a cleaner abstraction of the Page Tables
|
||||
- New VMCS state classes that organize the creation of the VMM's state, as
|
||||
well as the Host VM's state.
|
||||
- New state save logic for the exit handler to support multi-core. The state
|
||||
save area is placed in "GS" allowing the exit handler to access CPU specific
|
||||
state logic in a reentrant, thread-safe manner without the need for lookups
|
||||
or APIC logic.
|
||||
- Added TSS structure to intrinsics code. This structure is used by the
|
||||
custom GDT for the VMM, but is not actually used.
|
||||
- The VMM now uses it's own GDT instead of the GDT provided by the Host OS.
|
||||
- The VMM now uses it's own IDT instead of the IDT provided by the Host OS.
|
||||
- The VMM now uses it's own CR0 instead of the CR0 provided by the Host OS.
|
||||
- The VMM now uses it's own CR3 instead of the CR3 provided by the Host OS.
|
||||
- The VMM now uses it's own CR4 instead of the CR4 provided by the Host OS.
|
||||
- The VMM now uses it's own RFLAGS instead of the RFLAGS provided by the Host OS.
|
||||
- The VMM now uses it's own EFER MSR instead of the EFER MSR provided by the Host OS.
|
||||
- New vCPU APIs that provide that ability to pass around a "user_data *" for extension
|
||||
support
|
||||
- Support for "-O3" optimizations
|
||||
- Support for SSE/AVX code in the VMM
|
||||
- Offical Windows 10 and Windows 8.1 Support
|
||||
- Offical OpenSUSE support
|
||||
- DWARF Expression support
|
||||
- Multi-Core support
|
||||
- Posix Mutex support (provides std::mutex)
|
||||
- Coveralls support
|
||||
- Coverity support
|
||||
- AppVeyor support
|
||||
- Clang Tidy 3.8 support
|
||||
- Clang / LLVM 3.8, 3.9, and 4.0 support
|
||||
- libc / libcxx / libcxxabi / bfcrt / bfunwind all loaded as shared libraries
|
||||
- VMCS unit tests
|
||||
- Intrinsics / VMCS namespace logic that provides useful functions / definitions
|
||||
found in the Intel manual
|
||||
- Libcxx unit tests
|
||||
- VMCall support
|
||||
|
||||
### Changed
|
||||
- The VMCS state classes are now shared by pointer (i.e. shared_ptr)
|
||||
instead of my reference. This was done to support inheritance.
|
||||
- The build system has been completely redone to provide both out-of-tree
|
||||
compilation, but also to provide support for docker. With this new system,
|
||||
it is possible to stand up the hypervisor in less than 10 minutes from start
|
||||
to finish, while also maintaining multiple build systems for testing
|
||||
- A lot of source code has been changed to address findings from Coverity
|
||||
and Clang-Tidy
|
||||
|
||||
### Fixed
|
||||
- If a VM-entry failure occurred, the exit handler would incorrectly read
|
||||
the error as unknown because it was not filtering the VM-entry failure
|
||||
bit
|
||||
- Some of the macros in the intrinsics file were causing unsigned integers
|
||||
because they hit touched bit 31. The macros have been expanded to 64 bits
|
||||
to prevent this
|
||||
- CPU-z support has been added via a Read MSR quirk.
|
||||
|
||||
### Removed
|
||||
- The old GDT logic that was in the intrinsics_x64 has been removed. Please
|
||||
use the new GDT class as it has the same functionality, but more.
|
||||
- The old IDT logic that was in the intrinsics_x64 has been removed. Please
|
||||
use the new IDT class as it has the same functionality, but more.
|
||||
- The old vmcs_intel_x64_state class has been removed in favor of inheritance
|
||||
to better support different state types (VMM, Host VM and Guest VM). Please
|
||||
use the subclasses instead, or inherit manually
|
||||
- The vCPU dispatch, halt and promote functions have been removed as they
|
||||
were specific to Intel.
|
||||
- GCC 5.x support for cross compilation (native still supported)
|
||||
|
||||
## [1.0.0] - 2016-27-04
|
||||
### Added
|
||||
- Linux support
|
||||
- Single core support (core 0)
|
||||
- Custom C runtime library for constructor / destructor support and registering
|
||||
exception handlers
|
||||
- Custom driver entry logic for loading the VMM
|
||||
- Custom ELF loader for loading the VMM modules
|
||||
- User-space management application (BFM) for starting / stopping the
|
||||
hypervisor
|
||||
- Custom kernel-safe unwind library for adding exception support to the VMM
|
||||
- Basic VMM with support for Intel x86_64. The VMM places the Host OS into
|
||||
a virtual machine and back out. Currently can be extended to provide
|
||||
additional functionality
|
||||
- Custom build environment
|
||||
- Complete set of unit tests
|
||||
- Documentation
|
||||
- Scripts for setting up Ubuntu, Debian and Fedora build environments.
|
||||
207
CMakeLists.txt
207
CMakeLists.txt
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (C) 2019 Assured Information Security, Inc.
|
||||
# Copyright (C) 2020 Assured Information Security, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -20,201 +20,24 @@
|
|||
# SOFTWARE.
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(hypervisor)
|
||||
project(hypervisor CXX)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Modules
|
||||
# ------------------------------------------------------------------------------
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/init_build.cmake)
|
||||
|
||||
include(ProcessorCount)
|
||||
include(ExternalProject)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Configs
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/scripts/cmake/config/default.cmake)
|
||||
include_external_config()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Macros
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
include(${SOURCE_CMAKE_DIR}/macros.cmake)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Testing
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
if(ENABLE_BUILD_TEST)
|
||||
include(CTest)
|
||||
enable_testing(true)
|
||||
if(HYPERVISOR_BUILD_LOADER)
|
||||
add_subdirectory(loader)
|
||||
endif()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Sub-project includes
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
add_project_include(${SOURCE_CMAKE_DIR}/macros.cmake)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# BFM VMM
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
set_bfm_vmm(${DEFAULT_VMM} DEFAULT TARGET bfvmm)
|
||||
message(STATUS "Bareflank Manager VMM")
|
||||
message(STATUS " vmm: ${BFM_VMM}")
|
||||
message(STATUS " target: ${BFM_VMM_TARGET}")
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Targets
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
include(${SOURCE_CMAKE_DIR}/targets.cmake)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# General Dependencies
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
include_dependency(SOURCE_DEPENDS_DIR gsl)
|
||||
include_dependency(SOURCE_DEPENDS_DIR cxxopts)
|
||||
include_dependency(SOURCE_DEPENDS_DIR json)
|
||||
include_dependency(SOURCE_DEPENDS_DIR astyle)
|
||||
include_dependency(SOURCE_DEPENDS_DIR clang_tidy)
|
||||
include_dependency(SOURCE_DEPENDS_DIR catch)
|
||||
include_dependency(SOURCE_DEPENDS_DIR hippomocks)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Package File
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${EXPORT_DIR})
|
||||
file(APPEND ${PKG_FILE} "")
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Root Targets
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
add_subproject(bfroot vmm SOURCE_DIR ${SOURCE_CMAKE_DIR})
|
||||
add_subproject(bfroot efi SOURCE_DIR ${SOURCE_CMAKE_DIR})
|
||||
add_subproject(bfroot test SOURCE_DIR ${SOURCE_CMAKE_DIR} DEPENDS catch)
|
||||
add_subproject(bfroot userspace SOURCE_DIR ${SOURCE_CMAKE_DIR})
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# VMM Components
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
include_dependency(SOURCE_DEPENDS_DIR binutils)
|
||||
include_dependency(SOURCE_DEPENDS_DIR newlib)
|
||||
include_dependency(SOURCE_DEPENDS_DIR llvm)
|
||||
include_dependency(SOURCE_DEPENDS_DIR libcxxabi)
|
||||
include_dependency(SOURCE_DEPENDS_DIR libcxx)
|
||||
|
||||
add_subproject(bfsdk vmm DEPENDS bfroot)
|
||||
|
||||
if(ENABLE_BUILD_VMM OR (ENABLE_BUILD_TEST AND NOT WIN32))
|
||||
add_subproject(bfruntime vmm DEPENDS gsl libcxx bfroot)
|
||||
add_subproject(bfunwind vmm DEPENDS bfruntime)
|
||||
if(HYPERVISOR_BUILD_VMMCTL)
|
||||
add_subdirectory(vmmctl)
|
||||
endif()
|
||||
|
||||
if(ENABLE_BUILD_VMM)
|
||||
add_subproject(bfintrinsics vmm DEPENDS bfruntime)
|
||||
add_subproject(bfvmm vmm DEPENDS bfunwind bfintrinsics bfsdk)
|
||||
endif()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Unit Tests
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
if(ENABLE_BUILD_TEST)
|
||||
add_subproject(bfsdk test DEPENDS gsl json hippomocks bfroot)
|
||||
endif()
|
||||
|
||||
if(ENABLE_BUILD_TEST AND NOT WIN32)
|
||||
add_subproject(bfdummy vmm DEPENDS bfunwind)
|
||||
add_subproject(bfdriver test DEPENDS bfsdk)
|
||||
endif()
|
||||
|
||||
if(ENABLE_BUILD_TEST)
|
||||
add_subproject(bfm test DEPENDS bfsdk)
|
||||
add_subproject(bfruntime test DEPENDS bfsdk)
|
||||
add_subproject(bfvmm test DEPENDS bfsdk)
|
||||
endif()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Userspace Components
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
if(ENABLE_BUILD_USERSPACE)
|
||||
add_subproject(bfsdk userspace DEPENDS bfroot)
|
||||
add_subproject(bfintrinsics userspace DEPENDS gsl json bfroot)
|
||||
add_subproject(bfm userspace DEPENDS gsl json cxxopts bfroot)
|
||||
add_subproject(bfack userspace DEPENDS bfintrinsics)
|
||||
endif()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# External Components
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
list(APPEND EXTENSION ${SOURCE_EXAMPLES_DIR}/cpuidcount)
|
||||
list(APPEND EXTENSION ${SOURCE_EXAMPLES_DIR}/hook)
|
||||
list(APPEND EXTENSION ${SOURCE_EXAMPLES_DIR}/rdtsc)
|
||||
list(APPEND EXTENSION ${SOURCE_EXAMPLES_DIR}/vpid)
|
||||
|
||||
include_external_extensions()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# EFI Components
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
if(ENABLE_BUILD_EFI AND NOT WIN32)
|
||||
include_dependency(SOURCE_DEPENDS_DIR gnuefi)
|
||||
add_subproject(bfdriver efi DEPENDS bfroot gnuefi ${BFM_VMM_TARGET})
|
||||
endif()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Force Rebuild
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
get_property(FORCE_REBUILD GLOBAL PROPERTY "FORCE_REBUILD")
|
||||
|
||||
if(FORCE_REBUILD STREQUAL "ON")
|
||||
set_property(GLOBAL PROPERTY "FORCE_REBUILD" "OFF")
|
||||
file(REMOVE_RECURSE ${DEPENDS_DIR})
|
||||
file(REMOVE_RECURSE ${PREFIXES_DIR})
|
||||
message(FATAL_ERROR "${Yellow}dependencies updated, rebuild is required. Rerun cmake${ColorReset}")
|
||||
endif()
|
||||
|
||||
|
||||
# TODO:
|
||||
#
|
||||
# Detect if the flags have changed, delete the depends and prefixes, and then
|
||||
# tell the user that cmake needs to be run again as a rebuild is required.
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Validate Build
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
include(scripts/cmake/validate.cmake)
|
||||
validate_build()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Banners
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
print_banner()
|
||||
print_usage()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
git_dir_script()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Info
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
if(NOT WIN32)
|
||||
add_custom_command(TARGET info COMMAND ${CMAKE_COMMAND} -E cmake_echo_color " ")
|
||||
hypervisor_add_mk_cross_compile(cmake/mk_cross_compile)
|
||||
hypervisor_add_ext_cross_compile(cmake/ext_cross_compile)
|
||||
|
||||
if(NOT DEFINED FIRST_TIME)
|
||||
message(STATUS "${BF_COLOR_YLW}-----------------------------------------${BF_COLOR_RST}")
|
||||
message(STATUS "run '${BF_COLOR_MAG}make info${BF_COLOR_RST}' for configuration details")
|
||||
message(STATUS "${BF_COLOR_YLW}-----------------------------------------${BF_COLOR_RST}")
|
||||
set(FIRST_TIME ON)
|
||||
endif()
|
||||
|
|
|
|||
21
LICENSE
21
LICENSE
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (C) 2019 Assured Information Security, Inc.
|
||||
|
||||
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.
|
||||
23
LICENSE.md
Normal file
23
LICENSE.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# **License**
|
||||
|
||||
**MIT License**
|
||||
|
||||
Copyright © 2016 - 2019 Martin Donath
|
||||
|
||||
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 NON-INFRINGEMENT. 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.
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (C) 2019 Assured Information Security, Inc.
|
||||
# Copyright (C) 2020 Assured Information Security, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
@ -19,37 +19,26 @@
|
|||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
if(ENABLE_BUILD_VMM OR ENABLE_BUILD_USERSPACE OR ENABLE_BUILD_TEST)
|
||||
message(STATUS "Including dependency: json")
|
||||
|
||||
download_dependency(
|
||||
json
|
||||
URL ${JSON_URL}
|
||||
URL_MD5 ${JSON_URL_MD5}
|
||||
)
|
||||
if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows)
|
||||
find_program(HYPERVISOR_NINJA "ninja")
|
||||
if(NOT HYPERVISOR_NINJA)
|
||||
message(FATAL_ERROR "Unable to find ninja")
|
||||
endif()
|
||||
set(CMAKE_GENERATOR "Ninja" CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
list(APPEND JSON_CONFIGURE_FLAGS
|
||||
-DJSON_BuildTests=OFF
|
||||
)
|
||||
|
||||
if(ENABLE_BUILD_VMM)
|
||||
add_dependency(
|
||||
json vmm
|
||||
CMAKE_ARGS ${JSON_CONFIGURE_FLAGS}
|
||||
)
|
||||
if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Darwin)
|
||||
set(HAVE_FLAG_SEARCH_PATHS_FIRST 0 CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
if(ENABLE_BUILD_USERSPACE)
|
||||
add_dependency(
|
||||
json userspace
|
||||
CMAKE_ARGS ${JSON_CONFIGURE_FLAGS}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_BUILD_TEST)
|
||||
add_dependency(
|
||||
json test
|
||||
CMAKE_ARGS ${JSON_CONFIGURE_FLAGS}
|
||||
)
|
||||
if(NOT DEFINED CMAKE_CXX_COMPILER)
|
||||
if(CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin)
|
||||
set(CMAKE_CXX_COMPILER llvm-clang++ CACHE INTERNAL "")
|
||||
else()
|
||||
set(CMAKE_CXX_COMPILER clang++ CACHE INTERNAL "")
|
||||
endif()
|
||||
find_program(CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER})
|
||||
if(NOT CMAKE_CXX_COMPILER)
|
||||
message(FATAL_ERROR "Unable to find a default C++ compiler")
|
||||
endif()
|
||||
endif()
|
||||
321
README.md
321
README.md
|
|
@ -1,95 +1,42 @@
|
|||

|
||||
|
||||
<br>
|
||||
|
||||
[](https://badge.fury.io/gh/bareflank%2Fhypervisor)
|
||||
[](https://travis-ci.org/Bareflank/hypervisor)
|
||||
[](https://ci.appveyor.com/project/rianquinn/hypervisor-13oyg/branch/master)
|
||||
[](https://www.codacy.com/app/rianquinn/hypervisor?utm_source=github.com&utm_medium=referral&utm_content=Bareflank/hypervisor&utm_campaign=Badge_Grade)
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/325)
|
||||
[](https://bareflank.herokuapp.com/)
|
||||
|
||||
## Description
|
||||
|
||||
The Bareflank Hypervisor is an open source, hypervisor Software Development Toolkit (SDK), led by
|
||||
Assured Information Security, Inc. (AIS), that provides a set of APIs needed to
|
||||
rapidly prototype and create new hypervisors. To ease development, Bareflank
|
||||
is written in C/C++, and includes support for C++ exceptions, JSON, the GSL and the C++ Standard
|
||||
Template Library (STL).
|
||||
The Bareflank Hypervisor is an open source hypervisor Software Development Toolkit (SDK), led by Assured Information Security, Inc. (AIS), that provides the tools needed to rapidly prototype and create your own hypervisor.
|
||||
|
||||
The Bareflank Hypervisor uses a layered, modular approach.
|
||||
- [hypervisor](https://github.com/Bareflank/hypervisor): provides the base SDK, hypervisor
|
||||
implementation, the build system, and architecture specific intrinsics.
|
||||
- [boxy](https://github.com/Bareflank/boxy): leverages the Bareflank SDK to provide a
|
||||
fully functional hypervisor with guest support.
|
||||
Most people think that hypervisors are meant to virtualize servers and provide a means to run Windows on a Mac, but there is a whole field of research where hypervisors are used without guest virtual machines. Since a hypervisor is capable of controlling the host OS running underneath it (so-called "ring -1"), host-only hypervisors support introspection, reverse engineering, anti-virus, containerization, diversity, and even architectural research like [MoRE](https://github.com/ainfosec/MoRE). All of these use cases start the same way, by spending months standing up the hypervisor itself before you can start working on your actual project. Existing open source hypervisors are burdened with legacy support, only support a single operating system or contain unnecessary complexity that make them painful to work with when conducting hypervisor research.
|
||||
|
||||
To support Bareflank's design approach, the hypervisor is licensed
|
||||
under MIT, specifically
|
||||
enabling users of the project to both contribute back to the project, but
|
||||
also create proprietary versions of the hypervisor if so desired.
|
||||
Instead, Bareflank uses a layered, modular approach, that lets you pick just how much complexity you need in your project:
|
||||
- [BSL](https://github.com/Bareflank/bsl): provides a header-only, AUTOSAR compliant implementation of a subset of the C++ Standard Library, used to implement Bareflank's C++ components ensuring Bareflank and projects built using Bareflank can support critical systems applications like Automotive.
|
||||
- [LLVM](https://github.com/Bareflank/llvm-project): provides our custom implementation of the LLVM Clang compiler and associated tools including additional static analysis checks in Clang Tidy to ensure compliance with AUTOSAR.
|
||||
- [PAL](https://github.com/Bareflank/pal): provides auto-generated intrinsics APIs for Intel, AMD and ARM on any combination of OS (e.g., Windows and Linux), ABI (e.g., SysV and MS64) and programming language (e.g., C, C++ and Python).
|
||||
- [hypervisor](https://github.com/Bareflank/hypervisor): provides the base SDK including the loader, the Bareflank microkernel and support applications. If all you need is host-only hypervisor support, this is the project to start with.
|
||||
- [MicroV](https://github.com/Bareflank/microv): provides support for guest VMs, allowing the user to create an execute additional virtual machines. If you need guest VM support, this is the project to start with.
|
||||
|
||||
In addition, the project comes complete with a set of unit tests to validate
|
||||
that the provided SDK works as expected. Furthermore,
|
||||
[Travis CI](https://travis-ci.org/Bareflank/hypervisor) has been set up to
|
||||
test source code formatting via
|
||||
[Astyle](http://astyle.sourceforge.net), and static / dynamic analysis
|
||||
via
|
||||
[Clang Tidy](http://clang.llvm.org/extra/clang-tidy/),
|
||||
[Codacy](https://www.codacy.com),
|
||||
and
|
||||
[Google's Sanitizers](https://github.com/google/sanitizers). Finally, we adhere
|
||||
to the
|
||||
[CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/325),
|
||||
the
|
||||
[High Integrity C++ Guidelines](http://www.codingstandard.com/)
|
||||
and the
|
||||
[C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md)
|
||||
including support for the
|
||||
[Guideline Support Library](https://github.com/Microsoft/GSL).
|
||||
To support Bareflank's ecosystem, the hypervisor SDK is licensed under MIT, specifically enabling users of the project to both contribute back to the project, but also create proprietary, closed source products that use the Bareflank SDK as their foundation. Feel free to use Bareflank to create your commercial products. All we ask is that if you find a bug or add a feature to the SDK that you consider contributing your changes back to the project.
|
||||
|
||||
Currently, we have support for the following 64bit host operating systems on
|
||||
Intel _Sandy Bridge_ and above hardware:
|
||||
- Arch Linux
|
||||
- Ubuntu 17.10+
|
||||
- Windows 10
|
||||
- Windows 7
|
||||
- UEFI
|
||||
## **Quick start**
|
||||
|
||||
In the future, we would also like to support:
|
||||
- macOS
|
||||
- BSD
|
||||
- ARM64 (still under development)
|
||||

|
||||
|
||||
## Motivation
|
||||
Get the latest version of the Bareflank Hypervisor SDK from GitHub:
|
||||
|
||||
Most people think that hypervisors are meant to virtualize servers and provide a means to run Windows on a Mac, but there is a whole field of research where hypervisors are used without guest virtual machines. Since a hypervisor is capable of controlling the host OS running underneath it (so-called "ring -1"), host-only hypervisors support introspection, reverse engineering, anti-virus, containerization, diversity, and even architectural research like [MoRE](https://github.com/ainfosec/MoRE). All of these use cases start the same way, by spending months standing up the hypervisor itself before you can start working on your actual project. Existing open source hypervisors are burdened with legacy support and unnecessary complexity that make them painful to work with when conducting hypervisor research.
|
||||
``` bash
|
||||
git clone https://github.com/bareflank/hypervisor
|
||||
mkdir bsl/build && cd bsl/build
|
||||
cmake -GNinja -DCMAKE_CXX_COMPILER="clang++" ..
|
||||
ninja
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
[Bareflank Hypervisor Website](http://bareflank.github.io/hypervisor/) <br>
|
||||
[Bareflank Hypervisor API Documentation](http://bareflank.github.io/hypervisor/html/)
|
||||
|
||||
## Demo
|
||||
|
||||
Check out the latest demo for how to compile and use the Bareflank Hypervisor on Ubuntu 18.04:
|
||||
|
||||
[](https://www.youtube.com/watch?v=fNLXxtdkhLg)
|
||||
|
||||
## Additional Videos
|
||||
|
||||
Checkout our [YouTube Channel](https://www.youtube.com/channel/UCH-7Pw96K5V1RHAPn5-cmYA) for more great content as well as
|
||||
the following videos at [CppCon](https://www.youtube.com/user/CppCon) below:
|
||||
|
||||
[](https://www.youtube.com/watch?v=bKPN-CGhEC0)
|
||||
[](https://www.youtube.com/watch?v=KdJhQuycD78)
|
||||
[](https://www.youtube.com/watch?v=uQSQy-7lveQ)
|
||||
Enjoy:
|
||||
```
|
||||
ninja driver_quick
|
||||
ninja start
|
||||
ninja dump
|
||||
```
|
||||
|
||||
## Interested In Working For AIS?
|
||||
Check out our [Can You Hack It?®](https://www.canyouhackit.com) challenge
|
||||
and test your skills! Submit your score to show us what you’ve got. We have
|
||||
offices across the country and offer competitive pay and outstanding
|
||||
benefits. Join a team that is not only committed to the future of cyberspace,
|
||||
but to our employee’s success as well.
|
||||
Check out our [Can You Hack It?®](https://www.canyouhackit.com) challenge and test your skills! Submit your score to show us what you’ve got. We have offices across the country and offer competitive pay and outstanding benefits. Join a team that is not only committed to the future of cyberspace, but to our employee’s success as well.
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.ainfosec.com/">
|
||||
|
|
@ -97,179 +44,117 @@ the following videos at [CppCon](https://www.youtube.com/user/CppCon) below:
|
|||
</a>
|
||||
</p>
|
||||
|
||||
## Dependencies
|
||||
## Demo
|
||||
|
||||
Although Bareflank can be made to run on most systems, the following are the
|
||||
supported platforms and their dependencies:
|
||||
Check out the latest demo for how to compile and use the Bareflank Hypervisor on Ubuntu 20.04:
|
||||
|
||||
#### Arch Linux:
|
||||
```
|
||||
sudo pacman -S git base-devel linux-headers nasm clang cmake
|
||||
## Additional Videos
|
||||
|
||||
Check out our [YouTube Channel](https://www.youtube.com/channel/UCH-7Pw96K5V1RHAPn5-cmYA) for more great content as well as
|
||||
the following videos at [CppCon](https://www.youtube.com/user/CppCon) below:
|
||||
|
||||
[](https://www.youtube.com/watch?v=bKPN-CGhEC0)
|
||||
[](https://www.youtube.com/watch?v=KdJhQuycD78)
|
||||
[](https://www.youtube.com/watch?v=uQSQy-7lveQ)
|
||||
|
||||
## **Build Requirements**
|
||||
Currently, the Bareflank hypervisor only supports the Clang/LLVM 11+ compiler. This, however, ensures the hypervisor can be natively compiled on Windows including support for cross-compiling. Support for other C++20 compilers can be added if needed, just let us know if that is something you need.
|
||||
|
||||
### **Windows**
|
||||
To compile Bareflank on Windows, you must first install the following:
|
||||
- [Visual Studio](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&rel=16) (Enable "Desktop development with C++")
|
||||
- [LLVM 11+](https://github.com/llvm/llvm-project/releases)
|
||||
- [CMake 3.16+](https://cmake.org/download/)
|
||||
- [Ninja](https://github.com/ninja-build/ninja/releases)
|
||||
|
||||
Visual Studio is needed as it contains Windows specific libraries that are needed during compilation. Instead of using the Clang/LLVM project that natively ships with Visual Studio, we use the standard Clang/LLVM binaries provided by the LLVM project which ensures we get all of the tools including LLD, Clang Tidy and Clang Format. Also note that you must put Ninja somewhere
|
||||
in your path (we usually drop into CMake's bin folder).
|
||||
|
||||
To compile use the following:
|
||||
``` bash
|
||||
git clone https://github.com/bareflank/hypervisor
|
||||
mkdir hypervisor/build && cd hypervisor/build
|
||||
cmake -GNinja -DCMAKE_CXX_COMPILER="clang++" -DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON ..
|
||||
ninja info
|
||||
ninja
|
||||
```
|
||||
|
||||
#### Ubuntu 17.10 (or Higher):
|
||||
```
|
||||
sudo apt-get install git build-essential linux-headers-$(uname -r) nasm clang cmake libelf-dev
|
||||
### **Ubuntu Linux**
|
||||
To compile Bareflank on Ubuntu, you must install the following:
|
||||
- [LLVM 11+](https://apt.llvm.org/)
|
||||
- [CMake 3.16+](https://cmake.org/download/)
|
||||
|
||||
Once you have the above setup, you can install all dependencies using the following command
|
||||
```bash
|
||||
sudo apt-get install -y clang-11 build-essential git ninja-build
|
||||
```
|
||||
|
||||
#### Windows (Visual Studio):
|
||||
- [Visual Studio 2019 / WDK 10](https://docs.microsoft.com/en-us/windows-hardware/drivers/)
|
||||
- Check "Desktop development with C++"
|
||||
- Check "C++ CLI / Support"
|
||||
- Check "VC++ 2019 version xxx Libs for Spectre (x86 and x64)"
|
||||
|
||||
After installing the above packages, you must enable test signing mode. This can be done from a
|
||||
command prompt with admin privileges:
|
||||
You might also have to update your build environment to point to the new version of LLVM as follows:
|
||||
```
|
||||
bcdedit.exe /set testsigning ON
|
||||
<reboot>
|
||||
sudo update-alternatives --remove-all clang++
|
||||
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-11 100
|
||||
```
|
||||
|
||||
#### Windows (Cygwin):
|
||||
- All of the Windows (Visual Studio) instructions
|
||||
- [Cygwin](https://www.cygwin.com/setup-x86_64.exe)
|
||||
|
||||
To install Cygwin, simply install using all default settings, and then copy
|
||||
setup-x86\_64.exe to C:\\cygwin64\\bin. From there, open a Cygwin terminal and
|
||||
run the following:
|
||||
|
||||
To compile use the following:
|
||||
``` bash
|
||||
git clone https://github.com/bareflank/hypervisor
|
||||
mkdir hypervisor/build && cd hypervisor/build
|
||||
cmake -GNinja -DCMAKE_CXX_COMPILER="clang++" -DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON ..
|
||||
ninja info
|
||||
ninja
|
||||
```
|
||||
setup-x86_64.exe -q -P git,make,gcc-core,gcc-g++,nasm,clang,clang++,cmake,python,gettext,bash-completion,flex,bison,texinfo
|
||||
```
|
||||
|
||||
This build environment provides a complete toolchain for building and running Bareflank. Most
|
||||
developers using Bareflank on Windows will need Cygwin for this reason. The remaining compilation
|
||||
instructions follow below.
|
||||
|
||||
## Compilation Instructions
|
||||
|
||||
To compile with default settings for your host environment, run the following commands:
|
||||
|
||||
```
|
||||
git clone https://github.com/bareflank/hypervisor.git
|
||||
mkdir build; cd build
|
||||
cmake ../hypervisor
|
||||
make -j<# cores + 1>
|
||||
```
|
||||
|
||||
For more detailed build instructions, see the
|
||||
[detailed build instructions](scripts/docs/build_instructions.md).
|
||||
For instructions on building and creating Bareflank extensions, see the
|
||||
[extension build instructions](scripts/docs/extension_instructions.md)
|
||||
|
||||
## Usage Instructions
|
||||
|
||||
To use the hypervisor, run the following commands:
|
||||
|
||||
```
|
||||
make driver_quick
|
||||
make quick
|
||||
ninja driver_quick
|
||||
ninja start
|
||||
```
|
||||
|
||||
to get status information, use the following:
|
||||
to get debug information, use the following:
|
||||
|
||||
```
|
||||
make status
|
||||
make dump
|
||||
ninja dump
|
||||
```
|
||||
|
||||
to reverse this:
|
||||
|
||||
```
|
||||
make unload
|
||||
make driver_unload
|
||||
```
|
||||
to clean up:
|
||||
|
||||
```
|
||||
make distclean
|
||||
```
|
||||
## Example Extensions
|
||||
As stated above, the Bareflank Hypervisor is an SDK to create your own, more complicated
|
||||
hypervisors. One example of an extension is the [boxy](https://github.com/Bareflank/boxy)
|
||||
hypervisor, which provides support for Linux based guest virtual machines. There are
|
||||
several other examples in our [examples](https://github.com/Bareflank/hypervisor/tree/master/examples)
|
||||
folder.
|
||||
|
||||
To use one of these examples, you must tell the build system which Virtual Machine
|
||||
Monitor (VMM) you wish to use. By default, the build system will use "bfvmm", but
|
||||
you can override this by defining DEFAULT_VMM variable when running cmake. Each
|
||||
example has its own VMM target. For example, the CPUID count example's VMM is
|
||||
"example_cpuidcount_vmm" which can be seen in the following
|
||||
[CMakeLists.txt](https://github.com/Bareflank/hypervisor/blob/master/examples/cpuidcount/CMakeLists.txt)
|
||||
file. So for example, to compile Bareflank and test out the CPUID count example,
|
||||
you would configure Bareflank using the following:
|
||||
|
||||
```
|
||||
cmake -DDEFAULT_VMM=example_cpuidcount_vmm ..
|
||||
ninja stop
|
||||
ninja driver_unload
|
||||
```
|
||||
|
||||
In addition to setting the DEFAULT_VMM, if you are using the
|
||||
[example_config.cmake](https://github.com/Bareflank/hypervisor/blob/master/scripts/cmake/config/example_config.cmake)
|
||||
config file you would set the OVERRIDE_VMM variable which will set the DEFAULT_VMM for you.
|
||||
## **Resources**
|
||||
|
||||
Finally, if you are creating your own out-of-tree extension, you must tell the build system
|
||||
where your extension is located so that it can include it when building the hypervisor.
|
||||
To do this, you must define the EXTENSION variable. So for example, if you are creating your
|
||||
own extension, with your own VMM target, you would use the following when configuring
|
||||
cmake:
|
||||
[](https://bareflank.herokuapp.com/)
|
||||
|
||||
```
|
||||
cmake -DDEFAULT_VMM=<vmm target name> -DEXTENSION=<path to extension> ..
|
||||
```
|
||||
The Bareflank Support Library provides a ton of useful resources to learn how to use the library including:
|
||||
|
||||
## UEFI:
|
||||
A UEFI application version of Bareflank may be compiled on Linux and used to boot
|
||||
both Linux and Windows The following
|
||||
describes how to build and execute Bareflank with EFI. For additional information,
|
||||
please see the following YouTube [video](https://www.youtube.com/watch?v=FuEyjDqA53M&t=4s)
|
||||
- **Documentation**: <https://bareflank.github.io/hypervisor/>
|
||||
- **Examples**: <https://github.com/Bareflank/hypervisor/tree/master/examples>
|
||||
- **Unit Tests**: <https://github.com/Bareflank/hypervisor/tree/master/tests>
|
||||
|
||||
To compile for UEFI, add the following to CMake when configuring:
|
||||
```
|
||||
-DENABLE_BUILD_EFI=ON
|
||||
```
|
||||
It should be noted that unit tests must be disabled, and static builds are currently
|
||||
required (the example config provides an example of how to configure Bareflank as
|
||||
needed for more complex builds).
|
||||
If you have any questions, bugs, or feature requests, please feel free to ask on any of the following:
|
||||
|
||||
To boot Windows or Linux you will need to provide your own
|
||||
extension that enables EPT. To see an example of this type of extension, please
|
||||
see the following integration test:
|
||||
```
|
||||
https://github.com/Bareflank/hypervisor/blob/master/bfvmm/integration/arch/intel_x64/efi/test_efi.cpp
|
||||
```
|
||||
Once you have your own extension, the example config is required to tell the build
|
||||
system which VMM and target to use. The example config can be found here:
|
||||
```
|
||||
https://github.com/Bareflank/hypervisor/blob/master/scripts/cmake/config/example_config.cmake
|
||||
```
|
||||
Our front page video on YouTube explains how to use this config, and the instructions
|
||||
are also in the config itself. To enable EFI, turn on the EFI
|
||||
flag. You will also need to set the following:
|
||||
```
|
||||
set(OVERRIDE_VMM <name>)
|
||||
set(OVERRIDE_VMM_TARGET <name>)
|
||||
```
|
||||
If for example, you are using the integration test listed above, these setting would
|
||||
be as follows:
|
||||
```
|
||||
set(OVERRIDE_VMM integration_intel_x64_efi_test_efi)
|
||||
set(OVERRIDE_VMM_TARGET integration)
|
||||
```
|
||||
The first variable defines the VMM's name and the second variable defines the target
|
||||
that builds this VMM (which tells the build system what dependency EFI has). From
|
||||
there build as normal.
|
||||
- **Slack**: <https://bareflank.herokuapp.com/>
|
||||
- **Issue Tracker**: <https://github.com/Bareflank/hypervisor/issues>
|
||||
|
||||
The resulting UEFI application can be found here:
|
||||
```
|
||||
build/prefixes/x86_64-efi-pe/bin/bareflank.efi
|
||||
```
|
||||
Place this binary in your EFI partition (e.g., on Ubuntu this is
|
||||
/boot/efi/EFI/BOOT/bareflank.efi) and execute it like any other EFI application.
|
||||
Once Bareflank is running, you can start Windows or Linux if you included the
|
||||
above. Also note that utilities like "make dump" do not work when using EFI as
|
||||
the driver doesn't have access to the debug ring. You can, however, use
|
||||
"make ack" to get the hypervisor to say "hi".
|
||||
And as always, we are always looking for more help:
|
||||
|
||||
- **Pull Requests**: <https://github.com/Bareflank/hypervisor/pulls>
|
||||
- **Contributing Guidelines**: <https://github.com/Bareflank/hypervisor/blob/master/contributing.md>
|
||||
|
||||
## **Testing**
|
||||
The Bareflank hypervisor leverages the following tools to ensure the highest possible code quality. Each pull request undergoes the following rigorous testing and review:
|
||||
|
||||
- **Static Analysis:** [Clang Tidy](https://github.com/Bareflank/llvm-project)
|
||||
- **Dynamic Analysis:** Google's ASAN and UBSAN
|
||||
- **Code Coverage:** Code Coverage with CodeCov
|
||||
- **Coding Standards**: [AUTOSAR C++14](https://www.autosar.org/fileadmin/user_upload/standards/adaptive/17-03/AUTOSAR_RS_CPP14Guidelines.pdf) and [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md)
|
||||
- **Style**: Clang Format
|
||||
- **Documentation**: Doxygen
|
||||
|
||||
## Serial Instructions
|
||||
|
||||
|
|
|
|||
0
SUPPORT.md
Normal file
0
SUPPORT.md
Normal file
33
Vagrantfile
vendored
33
Vagrantfile
vendored
|
|
@ -1,33 +0,0 @@
|
|||
#
|
||||
# Copyright (C) 2019 Assured Information Security, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
Vagrant.configure(2) do |config|
|
||||
config.vm.provider "virtualbox" do |vb|
|
||||
vb.memory = "2048"
|
||||
vb.cpus = 2
|
||||
end
|
||||
|
||||
config.vm.define "ubuntu17_10", primary: true do |ubuntu17_10|
|
||||
ubuntu17_10.vm.box = "ubuntu/artful64"
|
||||
ubuntu17_10.vm.provision "shell",
|
||||
path: "scripts/vagrant/provision_ubuntu17_10.sh"
|
||||
end
|
||||
end
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <bfack.h>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
if (bfack() != 0) {
|
||||
std::clog << "ack: success" << '\n';
|
||||
}
|
||||
else {
|
||||
std::clog << "ack: failure" << '\n';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
#
|
||||
# Copyright (C) 2019 Assured Information Security, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(bfdriver C CXX)
|
||||
|
||||
init_project(bfdriver INTERFACE)
|
||||
target_link_libraries(bfdriver INTERFACE ${PREFIX}::bfroot)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Generator expressions
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
set(C $<COMPILE_LANGUAGE:C>)
|
||||
set(CXX $<COMPILE_LANGUAGE:CXX>)
|
||||
set(BUILD $<BOOL:$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>>)
|
||||
set(BUILD_INCLUDE $<AND:$<OR:${C},${CXX}>,${BUILD}>)
|
||||
set(BUILD_INCLUDE_CXX $<AND:${CXX},${BUILD}>)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# EFI
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
if(${PREFIX} STREQUAL efi)
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/vmm.h
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS -E copy ${BFM_VMM_BIN_PATH}/${BFM_VMM} vmm
|
||||
COMMAND xxd
|
||||
ARGS -i vmm > ${CMAKE_BINARY_DIR}/vmm.h
|
||||
DEPENDS ${BFM_VMM_BIN_PATH}/${BFM_VMM}
|
||||
COMMENT " EFI VMM: ${BFM_VMM_BIN_PATH}/${BFM_VMM}"
|
||||
)
|
||||
add_custom_target(
|
||||
bareflank_xxd
|
||||
DEPENDS ${CMAKE_BINARY_DIR}/vmm.h
|
||||
)
|
||||
|
||||
add_library(bareflank SHARED)
|
||||
add_dependencies(bareflank bareflank_xxd)
|
||||
|
||||
target_link_libraries(bareflank PRIVATE bfdriver)
|
||||
target_include_directories(bareflank PRIVATE
|
||||
$<${BUILD_INCLUDE}:${CMAKE_CURRENT_LIST_DIR}/include>
|
||||
$<${BUILD_INCLUDE}:${CMAKE_CURRENT_LIST_DIR}/../bfsdk/include>
|
||||
$<${BUILD_INCLUDE}:${CMAKE_CURRENT_LIST_DIR}/../bfelf_loader/include>
|
||||
$<${BUILD_INCLUDE}:${CMAKE_BINARY_DIR}>
|
||||
)
|
||||
target_sources(bareflank PRIVATE
|
||||
src/platform/efi/entry.c
|
||||
src/platform/efi/platform.c
|
||||
src/platform/efi/platform.asm
|
||||
src/common.c
|
||||
${EFI_EXTENSION_SOURCES}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET bareflank
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_OBJCOPY}
|
||||
ARGS -j .text -j .sdata -j .data -j .dynamic -j .dynsym
|
||||
ARGS -j .rel -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* -j .reloc
|
||||
ARGS --target efi-app-${BUILD_TARGET_ARCH} libbareflank.so ${CMAKE_BINARY_DIR}/bareflank.efi
|
||||
)
|
||||
|
||||
install(FILES ${CMAKE_BINARY_DIR}/bareflank.efi DESTINATION bin)
|
||||
endif()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Test
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
if(${PREFIX} STREQUAL test)
|
||||
target_include_directories(bfdriver INTERFACE
|
||||
$<${BUILD_INCLUDE}:${CMAKE_CURRENT_LIST_DIR}/include>
|
||||
$<${BUILD_INCLUDE}:${CMAKE_CURRENT_LIST_DIR}/../bfsdk/include>
|
||||
$<${BUILD_INCLUDE}:${CMAKE_CURRENT_LIST_DIR}/../bfelf_loader/include>
|
||||
)
|
||||
target_compile_definitions(bfdriver INTERFACE
|
||||
$<${BUILD_INCLUDE_CXX}:VMM_PREFIX_PATH=\"${VMM_PREFIX_PATH}\">
|
||||
)
|
||||
add_library(support)
|
||||
target_link_libraries(support PRIVATE bfdriver)
|
||||
target_sources(support PRIVATE
|
||||
tests/test_support.cpp
|
||||
src/common.c
|
||||
src/platform/test/platform.c
|
||||
)
|
||||
endif()
|
||||
|
||||
fini_project()
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include <bftypes.h>
|
||||
#include <bferrorcodes.h>
|
||||
#include <bfelf_loader.h>
|
||||
#include <bfdebugringinterface.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* VMM Status
|
||||
*
|
||||
* @return returns the current status of the VMM.
|
||||
*/
|
||||
int64_t
|
||||
common_vmm_status(void);
|
||||
|
||||
/**
|
||||
* Reset
|
||||
*
|
||||
* This function should not be called directly. Instead, use common_unload.
|
||||
* This is only exposed publically for unit testing.
|
||||
*/
|
||||
void
|
||||
common_reset(void);
|
||||
|
||||
/**
|
||||
* Initialize Driver Entry
|
||||
*
|
||||
* This code should be run as part of the driver entry's init code. This
|
||||
* sets up some resources that are needed throughout the lifetime of the
|
||||
* driver entry.
|
||||
*/
|
||||
int64_t
|
||||
common_init(void);
|
||||
|
||||
/**
|
||||
* Finalize Driver Entry
|
||||
*
|
||||
* This code should be run as part of the driver entry's fini code. This
|
||||
* cleans up some resources that were needed throughout the lifetime of the
|
||||
* driver entry.
|
||||
*
|
||||
* @return BF_SUCCESS on success, negative error code on failure
|
||||
*/
|
||||
int64_t
|
||||
common_fini(void);
|
||||
|
||||
/**
|
||||
* Add Module
|
||||
*
|
||||
* Add's a module into memory to be executed once start_vmm is run. This
|
||||
* function uses the platform functions to allocate memory for the executable.
|
||||
* The file that is provided should not be removed until after stop_vmm is
|
||||
* run. Removing the file from memory could cause a crash, as the start_vmm
|
||||
* function uses the file that is being added to search for symbols that are
|
||||
* needed, as well as the stop_vmm function. Once stop_vmm is run, it's safe
|
||||
* to remove the files. Also, this function cannot be run if the vmm has
|
||||
* already been started.
|
||||
*
|
||||
* @param file the file to add to memory
|
||||
* @param fsize the size of the file in bytes
|
||||
* @return BF_SUCCESS on success, negative error code on failure
|
||||
*/
|
||||
int64_t
|
||||
common_add_module(const char *file, uint64_t fsize);
|
||||
|
||||
/**
|
||||
* Load VMM
|
||||
*
|
||||
* This function loads the vmm (assuming that the modules that were
|
||||
* loaded are actually a vmm). Once a VMM is loaded, it is placed in memory,
|
||||
* and all of the modules are properly reloacted such that, code within each
|
||||
* module is now capable of executing.
|
||||
*
|
||||
* @return BF_SUCCESS on success, negative error code on failure
|
||||
*/
|
||||
int64_t
|
||||
common_load_vmm(void);
|
||||
|
||||
/**
|
||||
* Unload VMM
|
||||
*
|
||||
* This function unloads the vmm. Once the VMM is unloaded, all of the symbols
|
||||
* for the VMM are removed from memory, and are no longer accessible. The VMM
|
||||
* cannot be unloaded unless the VMM is already loaded, but is not running.
|
||||
*
|
||||
* @return BF_SUCCESS on success, negative error code on failure
|
||||
*/
|
||||
int64_t
|
||||
common_unload_vmm(void);
|
||||
|
||||
/**
|
||||
* Start VMM
|
||||
*
|
||||
* This function starts the vmm. Before the VMM can be started, it must first
|
||||
* be loaded.
|
||||
*
|
||||
* @return BF_SUCCESS on success, negative error code on failure
|
||||
*/
|
||||
int64_t
|
||||
common_start_vmm(void);
|
||||
|
||||
/**
|
||||
* Stop VMM
|
||||
*
|
||||
* This function stops the vmm. Before a VMM can be stopped, it must first be
|
||||
* loaded, and running.
|
||||
*
|
||||
* @return BF_SUCCESS on success, negative error code on failure
|
||||
*/
|
||||
int64_t
|
||||
common_stop_vmm(void);
|
||||
|
||||
/**
|
||||
* Dump VMM
|
||||
*
|
||||
* This grabs the conents of the debug ring, and dumps the contents to the
|
||||
* driver entry's console. This is one of a couple of ways to get feedback
|
||||
* from the VMM. Note that the VMM must at least be loaded for this function
|
||||
* to work as it has to do a symbol lookup
|
||||
*
|
||||
* @param drr a pointer to the drr provided by the user
|
||||
* @param vcpuid indicates which drr to get as each vcpu has its own drr
|
||||
* @return BF_SUCCESS on success, negative error code on failure
|
||||
*/
|
||||
int64_t
|
||||
common_dump_vmm(struct debug_ring_resources_t **drr, uint64_t vcpuid);
|
||||
|
||||
/**
|
||||
* Call VMM
|
||||
*
|
||||
* Executes the VMM. The VMM has a single entry point, with a switch statement
|
||||
* that executes the provided "request". When this occurs, arg1 and arg2 are
|
||||
* provided to the requested function. Note that the first arg takes a cpuid,
|
||||
* which is the core number you are currently executing on. This is needed
|
||||
* because this function needs to set up the proper stack before executing
|
||||
* the VMM, and it needs to know which core you are on to use the proper stack
|
||||
* which in turn also executes with the proper TLS region.
|
||||
*
|
||||
* @param cpuid the core id this code is currently being executed on
|
||||
* @param request the requested function in the VMM to execute
|
||||
* @param arg1 arg #1
|
||||
* @param arg2 arg #2
|
||||
* @return BF_SUCCESS on success, negative error code on failure
|
||||
*/
|
||||
int64_t
|
||||
common_call_vmm(uint64_t cpuid, uint64_t request, uintptr_t arg1, uintptr_t arg2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,524 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <bftypes.h>
|
||||
#include <bfdebug.h>
|
||||
#include <bfmemory.h>
|
||||
#include <bfplatform.h>
|
||||
#include <bfconstants.h>
|
||||
#include <bfthreadcontext.h>
|
||||
#include <bfdriverinterface.h>
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Global */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int64_t g_num_modules = 0;
|
||||
struct bfelf_binary_t g_modules[MAX_NUM_MODULES];
|
||||
|
||||
_start_t _start_func = 0;
|
||||
struct crt_info_t g_info;
|
||||
struct bfelf_loader_t g_loader;
|
||||
|
||||
int64_t g_num_cpus_started = 0;
|
||||
int64_t g_vmm_status = VMM_UNLOADED;
|
||||
|
||||
void *g_tls = 0;
|
||||
void *g_stack = 0;
|
||||
|
||||
uint64_t g_tls_size = 0;
|
||||
uint64_t g_stack_size = 0;
|
||||
uint64_t g_stack_top = 0;
|
||||
|
||||
void *g_rsdp = 0;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Helpers */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int64_t
|
||||
private_setup_stack(void)
|
||||
{
|
||||
g_stack_size = STACK_SIZE * 2;
|
||||
|
||||
g_stack = platform_alloc_rw(g_stack_size);
|
||||
if (g_stack == 0) {
|
||||
return BF_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
g_stack_top = (uint64_t)g_stack + g_stack_size;
|
||||
g_stack_top = (g_stack_top & ~(STACK_SIZE - 1)) - 1;
|
||||
|
||||
platform_memset(g_stack, 0, g_stack_size);
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
private_setup_tls(void)
|
||||
{
|
||||
g_tls_size = THREAD_LOCAL_STORAGE_SIZE * (uint64_t)platform_num_cpus();
|
||||
|
||||
g_tls = platform_alloc_rw(g_tls_size);
|
||||
if (g_tls == 0) {
|
||||
return BF_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
platform_memset(g_tls, 0, g_tls_size);
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
private_setup_rsdp(void)
|
||||
{
|
||||
g_rsdp = platform_get_rsdp();
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
private_add_raw_md_to_memory_manager(uint64_t virt, uint64_t type)
|
||||
{
|
||||
int64_t ret = 0;
|
||||
struct memory_descriptor md = {0, 0, 0};
|
||||
|
||||
md.virt = virt;
|
||||
md.phys = (uint64_t)platform_virt_to_phys((void *)md.virt);
|
||||
md.type = type;
|
||||
|
||||
ret = platform_call_vmm_on_core(
|
||||
0, BF_REQUEST_ADD_MDL, (uintptr_t)&md, 0);
|
||||
|
||||
if (ret != MEMORY_MANAGER_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
private_add_md_to_memory_manager(struct bfelf_binary_t *module)
|
||||
{
|
||||
bfelf64_word s = 0;
|
||||
|
||||
for (s = 0; s < bfelf_file_get_num_load_instrs(&module->ef); s++) {
|
||||
|
||||
int64_t ret = 0;
|
||||
|
||||
uint64_t exec_s = 0;
|
||||
uint64_t exec_e = 0;
|
||||
const struct bfelf_load_instr *instr = 0;
|
||||
|
||||
ret = bfelf_file_get_load_instr(&module->ef, s, &instr);
|
||||
bfignored(ret);
|
||||
|
||||
exec_s = (uint64_t)module->exec + instr->mem_offset;
|
||||
exec_e = (uint64_t)module->exec + instr->mem_offset + instr->memsz;
|
||||
exec_s &= ~(BAREFLANK_PAGE_SIZE - 1);
|
||||
exec_e &= ~(BAREFLANK_PAGE_SIZE - 1);
|
||||
|
||||
for (; exec_s <= exec_e; exec_s += BAREFLANK_PAGE_SIZE) {
|
||||
if ((instr->perm & bfpf_x) != 0) {
|
||||
ret = private_add_raw_md_to_memory_manager(
|
||||
exec_s, MEMORY_TYPE_R | MEMORY_TYPE_E);
|
||||
}
|
||||
else {
|
||||
ret = private_add_raw_md_to_memory_manager(
|
||||
exec_s, MEMORY_TYPE_R | MEMORY_TYPE_W);
|
||||
}
|
||||
|
||||
if (ret != MEMORY_MANAGER_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
private_add_tss_mdl(void)
|
||||
{
|
||||
uint64_t i = 0;
|
||||
|
||||
for (i = 0; i < g_tls_size; i += BAREFLANK_PAGE_SIZE) {
|
||||
|
||||
int64_t ret = private_add_raw_md_to_memory_manager(
|
||||
(uint64_t)g_tls + i, MEMORY_TYPE_R | MEMORY_TYPE_W);
|
||||
|
||||
if (ret != BF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
private_add_modules_mdl(void)
|
||||
{
|
||||
int64_t i = 0;
|
||||
|
||||
for (i = 0; i < g_num_modules; i++) {
|
||||
int64_t ret = private_add_md_to_memory_manager(&g_modules[i]);
|
||||
if (ret != BF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Implementation */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int64_t
|
||||
common_vmm_status(void)
|
||||
{ return g_vmm_status; }
|
||||
|
||||
void
|
||||
common_reset(void)
|
||||
{
|
||||
int64_t i;
|
||||
|
||||
for (i = 0; i < g_num_modules; i++) {
|
||||
if (g_modules[i].exec != 0) {
|
||||
platform_free_rwe(g_modules[i].exec, g_modules[i].exec_size);
|
||||
}
|
||||
}
|
||||
|
||||
platform_memset(&g_modules, 0, sizeof(g_modules));
|
||||
platform_memset(&g_loader, 0, sizeof(struct bfelf_loader_t));
|
||||
platform_memset(&g_info, 0, sizeof(struct crt_info_t));
|
||||
platform_memset(&g_loader, 0, sizeof(struct bfelf_loader_t));
|
||||
|
||||
_start_func = 0;
|
||||
|
||||
g_num_modules = 0;
|
||||
g_num_cpus_started = 0;
|
||||
g_vmm_status = VMM_UNLOADED;
|
||||
|
||||
if (g_tls != 0) {
|
||||
platform_free_rw(g_tls, g_tls_size);
|
||||
}
|
||||
|
||||
if (g_stack != 0) {
|
||||
platform_free_rw(g_stack, g_stack_size);
|
||||
}
|
||||
|
||||
g_tls = 0;
|
||||
g_stack = 0;
|
||||
g_stack_top = 0;
|
||||
|
||||
g_rsdp = 0;
|
||||
}
|
||||
|
||||
int64_t
|
||||
common_init(void)
|
||||
{
|
||||
int64_t ret = platform_init();
|
||||
if (ret != BF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
common_reset();
|
||||
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
common_fini(void)
|
||||
{
|
||||
if (common_vmm_status() == VMM_RUNNING) {
|
||||
if (common_stop_vmm() != BF_SUCCESS) {
|
||||
BFALERT("common_fini: failed to stop vmm\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (common_vmm_status() == VMM_LOADED) {
|
||||
if (common_unload_vmm() != BF_SUCCESS) {
|
||||
BFALERT("common_fini: failed to unload vmm\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (common_vmm_status() == VMM_CORRUPT) {
|
||||
return BF_ERROR_VMM_CORRUPTED;
|
||||
}
|
||||
|
||||
if (g_num_modules > 0) {
|
||||
common_reset();
|
||||
}
|
||||
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
common_add_module(const char *file, uint64_t fsize)
|
||||
{
|
||||
if (file == 0 || fsize == 0) {
|
||||
return BF_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
switch (common_vmm_status()) {
|
||||
case VMM_CORRUPT:
|
||||
return BF_ERROR_VMM_CORRUPTED;
|
||||
case VMM_LOADED:
|
||||
return BF_ERROR_VMM_INVALID_STATE;
|
||||
case VMM_RUNNING:
|
||||
return BF_ERROR_VMM_INVALID_STATE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_num_modules >= MAX_NUM_MODULES) {
|
||||
return BF_ERROR_MAX_MODULES_REACHED;
|
||||
}
|
||||
|
||||
g_modules[g_num_modules].file = file;
|
||||
g_modules[g_num_modules].file_size = fsize;
|
||||
|
||||
g_num_modules++;
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
common_load_vmm(void)
|
||||
{
|
||||
int64_t ret = 0;
|
||||
int64_t ignore_ret = 0;
|
||||
|
||||
switch (common_vmm_status()) {
|
||||
case VMM_CORRUPT:
|
||||
return BF_ERROR_VMM_CORRUPTED;
|
||||
case VMM_LOADED:
|
||||
return BF_SUCCESS;
|
||||
case VMM_RUNNING:
|
||||
return BF_ERROR_VMM_INVALID_STATE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_num_modules == 0) {
|
||||
return BF_ERROR_NO_MODULES_ADDED;
|
||||
}
|
||||
|
||||
ret = private_setup_stack();
|
||||
if (ret != BF_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ret = private_setup_tls();
|
||||
if (ret != BF_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ret = private_setup_rsdp();
|
||||
if (ret != BF_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ret = bfelf_load(g_modules, (uint64_t)g_num_modules, (void **)&_start_func, &g_info, &g_loader);
|
||||
if (ret != BF_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ret = platform_call_vmm_on_core(0, BF_REQUEST_INIT, 0, 0);
|
||||
if (ret != BF_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ret = platform_call_vmm_on_core(0, BF_REQUEST_SET_RSDP, (uint64_t)g_rsdp, 0);
|
||||
if (ret != BF_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ret = private_add_modules_mdl();
|
||||
if (ret != BF_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ret = private_add_tss_mdl();
|
||||
if (ret != BF_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
g_vmm_status = VMM_LOADED;
|
||||
return BF_SUCCESS;
|
||||
|
||||
failure:
|
||||
|
||||
ignore_ret = common_unload_vmm();
|
||||
bfignored(ignore_ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t
|
||||
common_unload_vmm(void)
|
||||
{
|
||||
int64_t ret = 0;
|
||||
|
||||
switch (common_vmm_status()) {
|
||||
case VMM_CORRUPT:
|
||||
return BF_ERROR_VMM_CORRUPTED;
|
||||
case VMM_RUNNING:
|
||||
return BF_ERROR_VMM_INVALID_STATE;
|
||||
case VMM_UNLOADED:
|
||||
goto unloaded;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = platform_call_vmm_on_core(0, BF_REQUEST_FINI, 0, 0);
|
||||
if (ret != BF_SUCCESS) {
|
||||
goto corrupted;
|
||||
}
|
||||
|
||||
unloaded:
|
||||
|
||||
common_reset();
|
||||
|
||||
g_vmm_status = VMM_UNLOADED;
|
||||
return BF_SUCCESS;
|
||||
|
||||
corrupted:
|
||||
|
||||
g_vmm_status = VMM_CORRUPT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t
|
||||
common_start_vmm(void)
|
||||
{
|
||||
int64_t ret = 0;
|
||||
int64_t cpuid = 0;
|
||||
int64_t ignore_ret = 0;
|
||||
|
||||
switch (common_vmm_status()) {
|
||||
case VMM_CORRUPT:
|
||||
return BF_ERROR_VMM_CORRUPTED;
|
||||
case VMM_RUNNING:
|
||||
return BF_SUCCESS;
|
||||
case VMM_UNLOADED:
|
||||
return BF_ERROR_VMM_INVALID_STATE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (cpuid = 0, g_num_cpus_started = 0; cpuid < platform_num_cpus(); cpuid++) {
|
||||
ret = platform_call_vmm_on_core(
|
||||
(uint64_t)cpuid, BF_REQUEST_VMM_INIT, (uint64_t)cpuid, 0);
|
||||
|
||||
if (ret != BF_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
g_num_cpus_started++;
|
||||
}
|
||||
|
||||
g_vmm_status = VMM_RUNNING;
|
||||
return BF_SUCCESS;
|
||||
|
||||
failure:
|
||||
|
||||
ignore_ret = common_stop_vmm();
|
||||
bfignored(ignore_ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t
|
||||
common_stop_vmm(void)
|
||||
{
|
||||
int64_t ret = 0;
|
||||
int64_t cpuid = 0;
|
||||
|
||||
switch (common_vmm_status()) {
|
||||
case VMM_CORRUPT:
|
||||
return BF_ERROR_VMM_CORRUPTED;
|
||||
case VMM_UNLOADED:
|
||||
return BF_ERROR_VMM_INVALID_STATE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (cpuid = g_num_cpus_started - 1; cpuid >= 0 ; cpuid--) {
|
||||
ret = platform_call_vmm_on_core(
|
||||
(uint64_t)cpuid, BF_REQUEST_VMM_FINI, (uint64_t)cpuid, 0);
|
||||
|
||||
if (ret != BFELF_SUCCESS) {
|
||||
goto corrupted;
|
||||
}
|
||||
|
||||
g_num_cpus_started--;
|
||||
}
|
||||
|
||||
g_vmm_status = VMM_LOADED;
|
||||
return BF_SUCCESS;
|
||||
|
||||
corrupted:
|
||||
|
||||
g_vmm_status = VMM_CORRUPT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t
|
||||
common_dump_vmm(struct debug_ring_resources_t **drr, uint64_t vcpuid)
|
||||
{
|
||||
int64_t ret = 0;
|
||||
|
||||
if (drr == 0) {
|
||||
return BF_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (common_vmm_status() == VMM_UNLOADED) {
|
||||
return BF_ERROR_VMM_INVALID_STATE;
|
||||
}
|
||||
|
||||
ret = platform_call_vmm_on_core(
|
||||
0, BF_REQUEST_GET_DRR, (uint64_t)vcpuid, (uint64_t)drr);
|
||||
|
||||
if (ret != BFELF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct thread_context_t tc_t;
|
||||
|
||||
int64_t
|
||||
common_call_vmm(
|
||||
uint64_t cpuid, uint64_t request, uintptr_t arg1, uintptr_t arg2)
|
||||
{
|
||||
int64_t ignored_ret = 0;
|
||||
tc_t *tc = (tc_t *)(g_stack_top - sizeof(tc_t));
|
||||
|
||||
ignored_ret = bfelf_set_integer_args(&g_info, request, arg1, arg2, 0);
|
||||
bfignored(ignored_ret);
|
||||
|
||||
tc->cpuid = cpuid;
|
||||
tc->tlsptr = (uint64_t *)((uint64_t)g_tls + (THREAD_LOCAL_STORAGE_SIZE * (uint64_t)cpuid));
|
||||
|
||||
return _start_func((void *)(g_stack_top - sizeof(tc_t) - 1), &g_info);
|
||||
}
|
||||
|
|
@ -1,626 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// This file describes the EFI MP Services Protocol. This protocol is not mentioned in the base
|
||||
// EFI specification (2.6), but an exceedingly similar protocol is described in the EFI platform
|
||||
// initialization specification (http://www.uefi.org/sites/default/files/resources/PI_Spec_1_6.pdf)
|
||||
|
||||
#ifndef _MP_SERVICE_PROTOCOL_H_
|
||||
#define _MP_SERVICE_PROTOCOL_H_
|
||||
|
||||
///
|
||||
/// Global ID for the EFI_MP_SERVICES_PROTOCOL.
|
||||
///
|
||||
#define EFI_MP_SERVICES_PROTOCOL_GUID \
|
||||
{ \
|
||||
0x3fdda605, 0xa76e, 0x4f46, {0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08} \
|
||||
}
|
||||
|
||||
///
|
||||
/// Forward declaration for the EFI_MP_SERVICES_PROTOCOL.
|
||||
///
|
||||
typedef struct _EFI_MP_SERVICES_PROTOCOL EFI_MP_SERVICES_PROTOCOL;
|
||||
|
||||
///
|
||||
/// Terminator for a list of failed CPUs returned by StartAllAPs().
|
||||
///
|
||||
#define END_OF_CPU_LIST 0xffffffff
|
||||
|
||||
///
|
||||
/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
|
||||
/// indicates whether the processor is playing the role of BSP. If the bit is 1,
|
||||
/// then the processor is BSP. Otherwise, it is AP.
|
||||
///
|
||||
#define PROCESSOR_AS_BSP_BIT 0x00000001
|
||||
|
||||
///
|
||||
/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
|
||||
/// indicates whether the processor is enabled. If the bit is 1, then the
|
||||
/// processor is enabled. Otherwise, it is disabled.
|
||||
///
|
||||
#define PROCESSOR_ENABLED_BIT 0x00000002
|
||||
|
||||
///
|
||||
/// This bit is used in the StatusFlag field of EFI_PROCESSOR_INFORMATION and
|
||||
/// indicates whether the processor is healthy. If the bit is 1, then the
|
||||
/// processor is healthy. Otherwise, some fault has been detected for the processor.
|
||||
///
|
||||
#define PROCESSOR_HEALTH_STATUS_BIT 0x00000004
|
||||
|
||||
///
|
||||
/// Structure that describes the pyhiscal location of a logical CPU.
|
||||
///
|
||||
typedef struct {
|
||||
///
|
||||
/// Zero-based physical package number that identifies the cartridge of the processor.
|
||||
///
|
||||
UINT32 Package;
|
||||
///
|
||||
/// Zero-based physical core number within package of the processor.
|
||||
///
|
||||
UINT32 Core;
|
||||
///
|
||||
/// Zero-based logical thread number within core of the processor.
|
||||
///
|
||||
UINT32 Thread;
|
||||
} EFI_CPU_PHYSICAL_LOCATION;
|
||||
|
||||
///
|
||||
/// Structure that describes information about a logical CPU.
|
||||
///
|
||||
typedef struct {
|
||||
///
|
||||
/// The unique processor ID determined by system hardware. For IA32 and X64,
|
||||
/// the processor ID is the same as the Local APIC ID. Only the lower 8 bits
|
||||
/// are used, and higher bits are reserved. For IPF, the lower 16 bits contains
|
||||
/// id/eid, and higher bits are reserved.
|
||||
///
|
||||
UINT64 ProcessorId;
|
||||
///
|
||||
/// Flags indicating if the processor is BSP or AP, if the processor is enabled
|
||||
/// or disabled, and if the processor is healthy. Bits 3..31 are reserved and
|
||||
/// must be 0.
|
||||
///
|
||||
/// <pre>
|
||||
/// BSP ENABLED HEALTH Description
|
||||
/// === ======= ====== ===================================================
|
||||
/// 0 0 0 Unhealthy Disabled AP.
|
||||
/// 0 0 1 Healthy Disabled AP.
|
||||
/// 0 1 0 Unhealthy Enabled AP.
|
||||
/// 0 1 1 Healthy Enabled AP.
|
||||
/// 1 0 0 Invalid. The BSP can never be in the disabled state.
|
||||
/// 1 0 1 Invalid. The BSP can never be in the disabled state.
|
||||
/// 1 1 0 Unhealthy Enabled BSP.
|
||||
/// 1 1 1 Healthy Enabled BSP.
|
||||
/// </pre>
|
||||
///
|
||||
UINT32 StatusFlag;
|
||||
///
|
||||
/// The physical location of the processor, including the physical package number
|
||||
/// that identifies the cartridge, the physical core number within package, and
|
||||
/// logical thread number within core.
|
||||
///
|
||||
EFI_CPU_PHYSICAL_LOCATION Location;
|
||||
} EFI_PROCESSOR_INFORMATION;
|
||||
|
||||
/**
|
||||
The function prototype for invoking a function on an Application Processor.
|
||||
|
||||
This definition is used by the UEFI MP Serices Protocol, and the
|
||||
PI SMM System Table.
|
||||
|
||||
@param[in,out] Buffer The pointer to private data buffer.
|
||||
**/
|
||||
typedef
|
||||
VOID
|
||||
(EFIAPI *EFI_AP_PROCEDURE)(
|
||||
IN OUT VOID *Buffer
|
||||
);
|
||||
|
||||
/**
|
||||
This service retrieves the number of logical processor in the platform
|
||||
and the number of those logical processors that are enabled on this boot.
|
||||
This service may only be called from the BSP.
|
||||
|
||||
This function is used to retrieve the following information:
|
||||
- The number of logical processors that are present in the system.
|
||||
- The number of enabled logical processors in the system at the instant
|
||||
this call is made.
|
||||
|
||||
Because MP Service Protocol provides services to enable and disable processors
|
||||
dynamically, the number of enabled logical processors may vary during the
|
||||
course of a boot session.
|
||||
|
||||
If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
|
||||
If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
|
||||
EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
|
||||
is returned in NumberOfProcessors, the number of currently enabled processor
|
||||
is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
|
||||
instance.
|
||||
@param[out] NumberOfProcessors Pointer to the total number of logical
|
||||
processors in the system, including the BSP
|
||||
and disabled APs.
|
||||
@param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
|
||||
processors that exist in system, including
|
||||
the BSP.
|
||||
|
||||
@retval EFI_SUCCESS The number of logical processors and enabled
|
||||
logical processors was retrieved.
|
||||
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||
@retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
|
||||
@retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS)(
|
||||
IN EFI_MP_SERVICES_PROTOCOL *This,
|
||||
OUT UINTN *NumberOfProcessors,
|
||||
OUT UINTN *NumberOfEnabledProcessors
|
||||
);
|
||||
|
||||
/**
|
||||
Gets detailed MP-related information on the requested processor at the
|
||||
instant this call is made. This service may only be called from the BSP.
|
||||
|
||||
This service retrieves detailed MP-related information about any processor
|
||||
on the platform. Note the following:
|
||||
- The processor information may change during the course of a boot session.
|
||||
- The information presented here is entirely MP related.
|
||||
|
||||
Information regarding the number of caches and their sizes, frequency of operation,
|
||||
slot numbers is all considered platform-related information and is not provided
|
||||
by this service.
|
||||
|
||||
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
|
||||
instance.
|
||||
@param[in] ProcessorNumber The handle number of processor.
|
||||
@param[out] ProcessorInfoBuffer A pointer to the buffer where information for
|
||||
the requested processor is deposited.
|
||||
|
||||
@retval EFI_SUCCESS Processor information was returned.
|
||||
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||
@retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
|
||||
@retval EFI_NOT_FOUND The processor with the handle specified by
|
||||
ProcessorNumber does not exist in the platform.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_MP_SERVICES_GET_PROCESSOR_INFO)(
|
||||
IN EFI_MP_SERVICES_PROTOCOL *This,
|
||||
IN UINTN ProcessorNumber,
|
||||
OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
|
||||
);
|
||||
|
||||
/**
|
||||
This service executes a caller provided function on all enabled APs. APs can
|
||||
run either simultaneously or one at a time in sequence. This service supports
|
||||
both blocking and non-blocking requests. The non-blocking requests use EFI
|
||||
events so the BSP can detect when the APs have finished. This service may only
|
||||
be called from the BSP.
|
||||
|
||||
This function is used to dispatch all the enabled APs to the function specified
|
||||
by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
|
||||
immediately and Procedure is not started on any AP.
|
||||
|
||||
If SingleThread is TRUE, all the enabled APs execute the function specified by
|
||||
Procedure one by one, in ascending order of processor handle number. Otherwise,
|
||||
all the enabled APs execute the function specified by Procedure simultaneously.
|
||||
|
||||
If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
|
||||
APs finish or TimeoutInMicroSecs expires. Otherwise, execution is in non-blocking
|
||||
mode, and the BSP returns from this service without waiting for APs. If a
|
||||
non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
|
||||
is signaled, then EFI_UNSUPPORTED must be returned.
|
||||
|
||||
If the timeout specified by TimeoutInMicroseconds expires before all APs return
|
||||
from Procedure, then Procedure on the failed APs is terminated. All enabled APs
|
||||
are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
|
||||
and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
|
||||
content points to the list of processor handle numbers in which Procedure was
|
||||
terminated.
|
||||
|
||||
Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
|
||||
to make sure that the nature of the code that is executed on the BSP and the
|
||||
dispatched APs is well controlled. The MP Services Protocol does not guarantee
|
||||
that the Procedure function is MP-safe. Hence, the tasks that can be run in
|
||||
parallel are limited to certain independent tasks and well-controlled exclusive
|
||||
code. EFI services and protocols may not be called by APs unless otherwise
|
||||
specified.
|
||||
|
||||
In blocking execution mode, BSP waits until all APs finish or
|
||||
TimeoutInMicroSeconds expires.
|
||||
|
||||
In non-blocking execution mode, BSP is freed to return to the caller and then
|
||||
proceed to the next task without having to wait for APs. The following
|
||||
sequence needs to occur in a non-blocking execution mode:
|
||||
|
||||
-# The caller that intends to use this MP Services Protocol in non-blocking
|
||||
mode creates WaitEvent by calling the EFI CreateEvent() service. The caller
|
||||
invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent
|
||||
is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests
|
||||
the function specified by Procedure to be started on all the enabled APs,
|
||||
and releases the BSP to continue with other tasks.
|
||||
-# The caller can use the CheckEvent() and WaitForEvent() services to check
|
||||
the state of the WaitEvent created in step 1.
|
||||
-# When the APs complete their task or TimeoutInMicroSecondss expires, the MP
|
||||
Service signals WaitEvent by calling the EFI SignalEvent() function. If
|
||||
FailedCpuList is not NULL, its content is available when WaitEvent is
|
||||
signaled. If all APs returned from Procedure prior to the timeout, then
|
||||
FailedCpuList is set to NULL. If not all APs return from Procedure before
|
||||
the timeout, then FailedCpuList is filled in with the list of the failed
|
||||
APs. The buffer is allocated by MP Service Protocol using AllocatePool().
|
||||
It is the caller's responsibility to free the buffer with FreePool() service.
|
||||
-# This invocation of SignalEvent() function informs the caller that invoked
|
||||
EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed
|
||||
the specified task or a timeout occurred. The contents of FailedCpuList
|
||||
can be examined to determine which APs did not complete the specified task
|
||||
prior to the timeout.
|
||||
|
||||
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
|
||||
instance.
|
||||
@param[in] Procedure A pointer to the function to be run on
|
||||
enabled APs of the system. See type
|
||||
EFI_AP_PROCEDURE.
|
||||
@param[in] SingleThread If TRUE, then all the enabled APs execute
|
||||
the function specified by Procedure one by
|
||||
one, in ascending order of processor handle
|
||||
number. If FALSE, then all the enabled APs
|
||||
execute the function specified by Procedure
|
||||
simultaneously.
|
||||
@param[in] WaitEvent The event created by the caller with CreateEvent()
|
||||
service. If it is NULL, then execute in
|
||||
blocking mode. BSP waits until all APs finish
|
||||
or TimeoutInMicroSeconds expires. If it's
|
||||
not NULL, then execute in non-blocking mode.
|
||||
BSP requests the function specified by
|
||||
Procedure to be started on all the enabled
|
||||
APs, and go on executing immediately. If
|
||||
all return from Procedure, or TimeoutInMicroSeconds
|
||||
expires, this event is signaled. The BSP
|
||||
can use the CheckEvent() or WaitForEvent()
|
||||
services to check the state of event. Type
|
||||
EFI_EVENT is defined in CreateEvent() in
|
||||
the Unified Extensible Firmware Interface
|
||||
Specification.
|
||||
@param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
|
||||
APs to return from Procedure, either for
|
||||
blocking or non-blocking mode. Zero means
|
||||
infinity. If the timeout expires before
|
||||
all APs return from Procedure, then Procedure
|
||||
on the failed APs is terminated. All enabled
|
||||
APs are available for next function assigned
|
||||
by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
|
||||
or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
|
||||
If the timeout expires in blocking mode,
|
||||
BSP returns EFI_TIMEOUT. If the timeout
|
||||
expires in non-blocking mode, WaitEvent
|
||||
is signaled with SignalEvent().
|
||||
@param[in] ProcedureArgument The parameter passed into Procedure for
|
||||
all APs.
|
||||
@param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise,
|
||||
if all APs finish successfully, then its
|
||||
content is set to NULL. If not all APs
|
||||
finish before timeout expires, then its
|
||||
content is set to address of the buffer
|
||||
holding handle numbers of the failed APs.
|
||||
The buffer is allocated by MP Service Protocol,
|
||||
and it's the caller's responsibility to
|
||||
free the buffer with FreePool() service.
|
||||
In blocking mode, it is ready for consumption
|
||||
when the call returns. In non-blocking mode,
|
||||
it is ready when WaitEvent is signaled. The
|
||||
list of failed CPU is terminated by
|
||||
END_OF_CPU_LIST.
|
||||
|
||||
@retval EFI_SUCCESS In blocking mode, all APs have finished before
|
||||
the timeout expired.
|
||||
@retval EFI_SUCCESS In non-blocking mode, function has been dispatched
|
||||
to all enabled APs.
|
||||
@retval EFI_UNSUPPORTED A non-blocking mode request was made after the
|
||||
UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
|
||||
signaled.
|
||||
@retval EFI_DEVICE_ERROR Caller processor is AP.
|
||||
@retval EFI_NOT_STARTED No enabled APs exist in the system.
|
||||
@retval EFI_NOT_READY Any enabled APs are busy.
|
||||
@retval EFI_TIMEOUT In blocking mode, the timeout expired before
|
||||
all enabled APs have finished.
|
||||
@retval EFI_INVALID_PARAMETER Procedure is NULL.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_MP_SERVICES_STARTUP_ALL_APS)(
|
||||
IN EFI_MP_SERVICES_PROTOCOL *This,
|
||||
IN EFI_AP_PROCEDURE Procedure,
|
||||
IN BOOLEAN SingleThread,
|
||||
IN EFI_EVENT WaitEvent OPTIONAL,
|
||||
IN UINTN TimeoutInMicroSeconds,
|
||||
IN VOID *ProcedureArgument OPTIONAL,
|
||||
OUT UINTN **FailedCpuList OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
This service lets the caller get one enabled AP to execute a caller-provided
|
||||
function. The caller can request the BSP to either wait for the completion
|
||||
of the AP or just proceed with the next task by using the EFI event mechanism.
|
||||
See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
|
||||
execution support. This service may only be called from the BSP.
|
||||
|
||||
This function is used to dispatch one enabled AP to the function specified by
|
||||
Procedure passing in the argument specified by ProcedureArgument. If WaitEvent
|
||||
is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
|
||||
TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
|
||||
BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
|
||||
is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
|
||||
then EFI_UNSUPPORTED must be returned.
|
||||
|
||||
If the timeout specified by TimeoutInMicroseconds expires before the AP returns
|
||||
from Procedure, then execution of Procedure by the AP is terminated. The AP is
|
||||
available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
|
||||
EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
|
||||
|
||||
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
|
||||
instance.
|
||||
@param[in] Procedure A pointer to the function to be run on the
|
||||
designated AP of the system. See type
|
||||
EFI_AP_PROCEDURE.
|
||||
@param[in] ProcessorNumber The handle number of the AP. The range is
|
||||
from 0 to the total number of logical
|
||||
processors minus 1. The total number of
|
||||
logical processors can be retrieved by
|
||||
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
|
||||
@param[in] WaitEvent The event created by the caller with CreateEvent()
|
||||
service. If it is NULL, then execute in
|
||||
blocking mode. BSP waits until this AP finish
|
||||
or TimeoutInMicroSeconds expires. If it's
|
||||
not NULL, then execute in non-blocking mode.
|
||||
BSP requests the function specified by
|
||||
Procedure to be started on this AP,
|
||||
and go on executing immediately. If this AP
|
||||
return from Procedure or TimeoutInMicroSeconds
|
||||
expires, this event is signaled. The BSP
|
||||
can use the CheckEvent() or WaitForEvent()
|
||||
services to check the state of event. Type
|
||||
EFI_EVENT is defined in CreateEvent() in
|
||||
the Unified Extensible Firmware Interface
|
||||
Specification.
|
||||
@param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
|
||||
this AP to finish this Procedure, either for
|
||||
blocking or non-blocking mode. Zero means
|
||||
infinity. If the timeout expires before
|
||||
this AP returns from Procedure, then Procedure
|
||||
on the AP is terminated. The
|
||||
AP is available for next function assigned
|
||||
by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
|
||||
or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
|
||||
If the timeout expires in blocking mode,
|
||||
BSP returns EFI_TIMEOUT. If the timeout
|
||||
expires in non-blocking mode, WaitEvent
|
||||
is signaled with SignalEvent().
|
||||
@param[in] ProcedureArgument The parameter passed into Procedure on the
|
||||
specified AP.
|
||||
@param[out] Finished If NULL, this parameter is ignored. In
|
||||
blocking mode, this parameter is ignored.
|
||||
In non-blocking mode, if AP returns from
|
||||
Procedure before the timeout expires, its
|
||||
content is set to TRUE. Otherwise, the
|
||||
value is set to FALSE. The caller can
|
||||
determine if the AP returned from Procedure
|
||||
by evaluating this value.
|
||||
|
||||
@retval EFI_SUCCESS In blocking mode, specified AP finished before
|
||||
the timeout expires.
|
||||
@retval EFI_SUCCESS In non-blocking mode, the function has been
|
||||
dispatched to specified AP.
|
||||
@retval EFI_UNSUPPORTED A non-blocking mode request was made after the
|
||||
UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
|
||||
signaled.
|
||||
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||
@retval EFI_TIMEOUT In blocking mode, the timeout expired before
|
||||
the specified AP has finished.
|
||||
@retval EFI_NOT_READY The specified AP is busy.
|
||||
@retval EFI_NOT_FOUND The processor with the handle specified by
|
||||
ProcessorNumber does not exist.
|
||||
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
|
||||
@retval EFI_INVALID_PARAMETER Procedure is NULL.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_MP_SERVICES_STARTUP_THIS_AP)(
|
||||
IN EFI_MP_SERVICES_PROTOCOL *This,
|
||||
IN EFI_AP_PROCEDURE Procedure,
|
||||
IN UINTN ProcessorNumber,
|
||||
IN EFI_EVENT WaitEvent OPTIONAL,
|
||||
IN UINTN TimeoutInMicroseconds,
|
||||
IN VOID *ProcedureArgument OPTIONAL,
|
||||
OUT BOOLEAN *Finished OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
This service switches the requested AP to be the BSP from that point onward.
|
||||
This service changes the BSP for all purposes. This call can only be performed
|
||||
by the current BSP.
|
||||
|
||||
This service switches the requested AP to be the BSP from that point onward.
|
||||
This service changes the BSP for all purposes. The new BSP can take over the
|
||||
execution of the old BSP and continue seamlessly from where the old one left
|
||||
off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
|
||||
is signaled.
|
||||
|
||||
If the BSP cannot be switched prior to the return from this service, then
|
||||
EFI_UNSUPPORTED must be returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
|
||||
@param[in] ProcessorNumber The handle number of AP that is to become the new
|
||||
BSP. The range is from 0 to the total number of
|
||||
logical processors minus 1. The total number of
|
||||
logical processors can be retrieved by
|
||||
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
|
||||
@param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
|
||||
enabled AP. Otherwise, it will be disabled.
|
||||
|
||||
@retval EFI_SUCCESS BSP successfully switched.
|
||||
@retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
|
||||
this service returning.
|
||||
@retval EFI_UNSUPPORTED Switching the BSP is not supported.
|
||||
@retval EFI_SUCCESS The calling processor is an AP.
|
||||
@retval EFI_NOT_FOUND The processor with the handle specified by
|
||||
ProcessorNumber does not exist.
|
||||
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
|
||||
a disabled AP.
|
||||
@retval EFI_NOT_READY The specified AP is busy.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_MP_SERVICES_SWITCH_BSP)(
|
||||
IN EFI_MP_SERVICES_PROTOCOL *This,
|
||||
IN UINTN ProcessorNumber,
|
||||
IN BOOLEAN EnableOldBSP
|
||||
);
|
||||
|
||||
/**
|
||||
This service lets the caller enable or disable an AP from this point onward.
|
||||
This service may only be called from the BSP.
|
||||
|
||||
This service allows the caller enable or disable an AP from this point onward.
|
||||
The caller can optionally specify the health status of the AP by Health. If
|
||||
an AP is being disabled, then the state of the disabled AP is implementation
|
||||
dependent. If an AP is enabled, then the implementation must guarantee that a
|
||||
complete initialization sequence is performed on the AP, so the AP is in a state
|
||||
that is compatible with an MP operating system. This service may not be supported
|
||||
after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.
|
||||
|
||||
If the enable or disable AP operation cannot be completed prior to the return
|
||||
from this service, then EFI_UNSUPPORTED must be returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
|
||||
@param[in] ProcessorNumber The handle number of AP.
|
||||
The range is from 0 to the total number of
|
||||
logical processors minus 1. The total number of
|
||||
logical processors can be retrieved by
|
||||
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
|
||||
@param[in] EnableAP Specifies the new state for the processor for
|
||||
enabled, FALSE for disabled.
|
||||
@param[in] HealthFlag If not NULL, a pointer to a value that specifies
|
||||
the new health status of the AP. This flag
|
||||
corresponds to StatusFlag defined in
|
||||
EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
|
||||
the PROCESSOR_HEALTH_STATUS_BIT is used. All other
|
||||
bits are ignored. If it is NULL, this parameter
|
||||
is ignored.
|
||||
|
||||
@retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
|
||||
@retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
|
||||
prior to this service returning.
|
||||
@retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
|
||||
@retval EFI_DEVICE_ERROR The calling processor is an AP.
|
||||
@retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
|
||||
does not exist.
|
||||
@retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_MP_SERVICES_ENABLEDISABLEAP)(
|
||||
IN EFI_MP_SERVICES_PROTOCOL *This,
|
||||
IN UINTN ProcessorNumber,
|
||||
IN BOOLEAN EnableAP,
|
||||
IN UINT32 *HealthFlag OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
This return the handle number for the calling processor. This service may be
|
||||
called from the BSP and APs.
|
||||
|
||||
This service returns the processor handle number for the calling processor.
|
||||
The returned value is in the range from 0 to the total number of logical
|
||||
processors minus 1. The total number of logical processors can be retrieved
|
||||
with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
|
||||
called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
|
||||
is returned. Otherwise, the current processors handle number is returned in
|
||||
ProcessorNumber, and EFI_SUCCESS is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
|
||||
@param[in] ProcessorNumber Pointer to the handle number of AP.
|
||||
The range is from 0 to the total number of
|
||||
logical processors minus 1. The total number of
|
||||
logical processors can be retrieved by
|
||||
EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
|
||||
|
||||
@retval EFI_SUCCESS The current processor handle number was returned
|
||||
in ProcessorNumber.
|
||||
@retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_MP_SERVICES_WHOAMI)(
|
||||
IN EFI_MP_SERVICES_PROTOCOL *This,
|
||||
OUT UINTN *ProcessorNumber
|
||||
);
|
||||
|
||||
///
|
||||
/// When installed, the MP Services Protocol produces a collection of services
|
||||
/// that are needed for MP management.
|
||||
///
|
||||
/// Before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the module
|
||||
/// that produces this protocol is required to place all APs into an idle state
|
||||
/// whenever the APs are disabled or the APs are not executing code as requested
|
||||
/// through the StartupAllAPs() or StartupThisAP() services. The idle state of
|
||||
/// an AP before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled is
|
||||
/// implementation dependent.
|
||||
///
|
||||
/// After the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, all the APs
|
||||
/// must be placed in the OS compatible CPU state as defined by the UEFI
|
||||
/// Specification. Implementations of this protocol may use the UEFI event
|
||||
/// EFI_EVENT_GROUP_READY_TO_BOOT to force APs into the OS compatible state as
|
||||
/// defined by the UEFI Specification. Modules that use this protocol must
|
||||
/// guarantee that all non-blocking mode requests on all APs have been completed
|
||||
/// before the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. Since the
|
||||
/// order that event notification functions in the same event group are executed
|
||||
/// is not deterministic, an event of type EFI_EVENT_GROUP_READY_TO_BOOT cannot
|
||||
/// be used to guarantee that APs have completed their non-blocking mode requests.
|
||||
///
|
||||
/// When the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, the StartAllAPs()
|
||||
/// and StartupThisAp() services must no longer support non-blocking mode requests.
|
||||
/// The support for SwitchBSP() and EnableDisableAP() may no longer be supported
|
||||
/// after this event is signaled. Since UEFI Applications and UEFI OS Loaders
|
||||
/// execute after the UEFI event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, these
|
||||
/// UEFI images must be aware that the functionality of this protocol may be reduced.
|
||||
///
|
||||
struct _EFI_MP_SERVICES_PROTOCOL {
|
||||
EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS GetNumberOfProcessors;
|
||||
EFI_MP_SERVICES_GET_PROCESSOR_INFO GetProcessorInfo;
|
||||
EFI_MP_SERVICES_STARTUP_ALL_APS StartupAllAPs;
|
||||
EFI_MP_SERVICES_STARTUP_THIS_AP StartupThisAP;
|
||||
EFI_MP_SERVICES_SWITCH_BSP SwitchBSP;
|
||||
EFI_MP_SERVICES_ENABLEDISABLEAP EnableDisableAP;
|
||||
EFI_MP_SERVICES_WHOAMI WhoAmI;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,262 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#include <vmm.h>
|
||||
#include <common.h>
|
||||
|
||||
#include <bfdebug.h>
|
||||
#include <bftypes.h>
|
||||
#include <bfconstants.h>
|
||||
#include <bfdriverinterface.h>
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Global */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
uint64_t g_vcpuid = 0;
|
||||
|
||||
struct pmodule_t {
|
||||
char *data;
|
||||
uint64_t size;
|
||||
};
|
||||
|
||||
uint64_t g_num_pmodules = 0;
|
||||
struct pmodule_t pmodules[MAX_NUM_MODULES] = {{0}};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Misc Device */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static int64_t
|
||||
ioctl_add_module(const char *file, uint64_t len)
|
||||
{
|
||||
char *buf;
|
||||
int64_t ret;
|
||||
|
||||
if (g_num_pmodules >= MAX_NUM_MODULES) {
|
||||
BFALERT("IOCTL_ADD_MODULE: too many modules have been loaded\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
buf = platform_alloc_rw(len);
|
||||
if (buf == NULL) {
|
||||
BFALERT("IOCTL_ADD_MODULE: failed to allocate memory for the module\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
gBS->CopyMem(buf, (void *)file, len);
|
||||
|
||||
ret = common_add_module(buf, len);
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_ADD_MODULE: common_add_module failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
pmodules[g_num_pmodules].data = buf;
|
||||
pmodules[g_num_pmodules].size = len;
|
||||
|
||||
g_num_pmodules++;
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
failed:
|
||||
|
||||
platform_free_rw(buf, len);
|
||||
|
||||
BFALERT("IOCTL_ADD_MODULE: failed\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_load_vmm(void)
|
||||
{
|
||||
int64_t ret;
|
||||
|
||||
ret = common_load_vmm();
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_LOAD_VMM: common_load_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
goto failure;
|
||||
}
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
failure:
|
||||
|
||||
BFDEBUG("IOCTL_LOAD_VMM: failed\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_start_vmm(void)
|
||||
{
|
||||
int64_t ret;
|
||||
|
||||
ret = common_start_vmm();
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_START_VMM: common_start_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
goto failure;
|
||||
}
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
failure:
|
||||
|
||||
BFDEBUG("IOCTL_START_VMM: failed\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Load / Image */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* Instead of loading the OS, we need to actually load a EFI/BOOT/chain.efi
|
||||
* file which is the previous EFI/BOOT/boot64.efi. This will allow us to
|
||||
* support the different types of loaders that are instealled regardless of
|
||||
* which one is actually installed.
|
||||
*/
|
||||
|
||||
static long
|
||||
load_start_vm(EFI_HANDLE ParentImage)
|
||||
{
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* Need to check to see if there are deallocate functions for a lot of
|
||||
* these functions as they are returning pointers.
|
||||
*/
|
||||
|
||||
EFI_STATUS status;
|
||||
|
||||
UINTN i;
|
||||
UINTN NumberFileSystemHandles = 0;
|
||||
EFI_HANDLE *FileSystemHandles = NULL;
|
||||
|
||||
status =
|
||||
gBS->LocateHandleBuffer(
|
||||
ByProtocol,
|
||||
&gEfiBlockIoProtocolGuid,
|
||||
NULL,
|
||||
&NumberFileSystemHandles,
|
||||
&FileSystemHandles
|
||||
);
|
||||
|
||||
if (EFI_ERROR(status)) {
|
||||
BFALERT("LocateHandleBuffer failed\n");
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
for (i = 0; i < NumberFileSystemHandles; ++i) {
|
||||
|
||||
EFI_DEVICE_PATH_PROTOCOL *FilePath = NULL;
|
||||
EFI_BLOCK_IO *BlkIo = NULL;
|
||||
EFI_HANDLE ImageHandle = NULL;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *ImageInfo = NULL;
|
||||
|
||||
status =
|
||||
gBS->HandleProtocol(
|
||||
FileSystemHandles[i],
|
||||
&gEfiBlockIoProtocolGuid,
|
||||
(VOID **) &BlkIo
|
||||
);
|
||||
|
||||
if (EFI_ERROR(status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FilePath = FileDevicePath(FileSystemHandles[i], L"\\EFI\\BOOT\\bootx64.efi");
|
||||
|
||||
status =
|
||||
gBS->LoadImage(
|
||||
FALSE,
|
||||
ParentImage,
|
||||
FilePath,
|
||||
NULL,
|
||||
0,
|
||||
&ImageHandle
|
||||
);
|
||||
|
||||
gBS->FreePool(FilePath);
|
||||
|
||||
if (EFI_ERROR(status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
status =
|
||||
gBS->HandleProtocol(
|
||||
ImageHandle,
|
||||
&gEfiLoadedImageProtocolGuid,
|
||||
(VOID **) &ImageInfo
|
||||
);
|
||||
|
||||
if (EFI_ERROR(status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ImageInfo->ImageCodeType != EfiLoaderCode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gBS->StartImage(ImageHandle, NULL, NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
BFALERT("Unable to locate EFI bootloader\n");
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Entry / Exit */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
EFI_STATUS
|
||||
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
InitializeLib(image, systab);
|
||||
|
||||
Print(L"\n");
|
||||
Print(L" ___ __ _ _ \n");
|
||||
Print(L" | _ ) __ _ _ _ ___ / _| |__ _ _ _ | |__\n");
|
||||
Print(L" | _ \\/ _` | '_/ -_) _| / _` | ' \\| / /\n");
|
||||
Print(L" |___/\\__,_|_| \\___|_| |_\\__,_|_||_|_\\_\\\n");
|
||||
Print(L"\n");
|
||||
Print(L" Please give us a star on: https://github.com/Bareflank/hypervisor\n");
|
||||
Print(L"\n");
|
||||
|
||||
if (common_init() != BF_SUCCESS) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
ioctl_add_module((char *)vmm, vmm_len);
|
||||
ioctl_load_vmm();
|
||||
ioctl_start_vmm();
|
||||
|
||||
load_start_vm(image);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
;
|
||||
; Copyright (C) 2019 Assured Information Security, Inc.
|
||||
;
|
||||
; 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.
|
||||
|
||||
bits 64
|
||||
default rel
|
||||
|
||||
section .text
|
||||
|
||||
global _set_ne
|
||||
_set_ne:
|
||||
mov rax, cr0
|
||||
or rax, 0x20
|
||||
mov cr0, rax
|
||||
|
||||
ret
|
||||
|
|
@ -1,232 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <bfarch.h>
|
||||
#include <bftypes.h>
|
||||
#include <bfdebug.h>
|
||||
#include <bfplatform.h>
|
||||
#include <bfelf_loader.h>
|
||||
#include <common.h>
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include "MpService.h"
|
||||
|
||||
EFI_MP_SERVICES_PROTOCOL *g_mp_services = nullptr;
|
||||
|
||||
void _set_ne(void);
|
||||
|
||||
int64_t
|
||||
platform_init(void)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
EFI_GUID gEfiMpServiceProtocolGuid = EFI_MP_SERVICES_PROTOCOL_GUID;
|
||||
|
||||
status =
|
||||
gBS->LocateProtocol(
|
||||
&gEfiMpServiceProtocolGuid,
|
||||
nullptr,
|
||||
(VOID **)&g_mp_services
|
||||
);
|
||||
|
||||
if (EFI_ERROR(status)) {
|
||||
BFALERT("locate_mp_services_protocol: LocateProtocol failed: %r\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_set_ne();
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
void *
|
||||
platform_alloc_rw(uint64_t len)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
EFI_PHYSICAL_ADDRESS addr = 0;
|
||||
|
||||
if (len == 0) {
|
||||
BFALERT("platform_alloc_rw: invalid length\n");
|
||||
return (void *)addr;
|
||||
}
|
||||
|
||||
status = gBS->AllocatePages(
|
||||
AllocateAnyPages, EfiRuntimeServicesData, (len / EFI_PAGE_SIZE) + 1, &addr
|
||||
);
|
||||
|
||||
if (EFI_ERROR(status)) {
|
||||
BFALERT("platform_alloc_rw: AllocatePages failed: %lld\n", len);
|
||||
}
|
||||
|
||||
return (void *)addr;
|
||||
}
|
||||
|
||||
void *
|
||||
platform_alloc_rwe(uint64_t len)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
EFI_PHYSICAL_ADDRESS addr = 0;
|
||||
|
||||
if (len == 0) {
|
||||
BFALERT("platform_alloc_rw: invalid length\n");
|
||||
return (void *)addr;
|
||||
}
|
||||
|
||||
status = gBS->AllocatePages(
|
||||
AllocateAnyPages, EfiRuntimeServicesCode, (len / EFI_PAGE_SIZE) + 1, &addr
|
||||
);
|
||||
|
||||
if (EFI_ERROR(status)) {
|
||||
BFALERT("platform_alloc_rw: AllocatePages failed: %lld\n", len);
|
||||
}
|
||||
|
||||
return (void *)addr;
|
||||
}
|
||||
|
||||
void
|
||||
platform_free_rw(void *addr, uint64_t len)
|
||||
{
|
||||
if (addr == nullptr) {
|
||||
BFALERT("platform_free_rw: invalid address %p\n", addr);
|
||||
return;
|
||||
}
|
||||
|
||||
gBS->FreePages(
|
||||
(EFI_PHYSICAL_ADDRESS) addr, (len / EFI_PAGE_SIZE) + 1
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
platform_free_rwe(void *addr, uint64_t len)
|
||||
{
|
||||
if (addr == nullptr) {
|
||||
BFALERT("platform_free_rw: invalid address %p\n", addr);
|
||||
return;
|
||||
}
|
||||
|
||||
gBS->FreePages(
|
||||
(EFI_PHYSICAL_ADDRESS) addr, (len / EFI_PAGE_SIZE) + 1
|
||||
);
|
||||
}
|
||||
|
||||
void *
|
||||
platform_virt_to_phys(void *virt)
|
||||
{
|
||||
return virt;
|
||||
}
|
||||
|
||||
void *
|
||||
platform_memset(void *ptr, char value, uint64_t num)
|
||||
{
|
||||
gBS->SetMem(ptr, num, value);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int64_t
|
||||
platform_memcpy(
|
||||
void *dst, uint64_t dst_size, const void *src, uint64_t src_size, uint64_t num)
|
||||
{
|
||||
if (dst == 0 || src == 0) {
|
||||
BFALERT("platform_memcpy: invalid dst or src\n");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (num > dst_size || num > src_size) {
|
||||
BFALERT("platform_memcpy: num out of range\n");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
gBS->CopyMem((VOID *)dst, (VOID *)src, num);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
platform_num_cpus(void)
|
||||
{
|
||||
UINTN NumberOfProcessors;
|
||||
UINTN NumberOfEnabledProcessors;
|
||||
|
||||
EFI_STATUS status =
|
||||
g_mp_services->GetNumberOfProcessors(
|
||||
g_mp_services,
|
||||
&NumberOfProcessors,
|
||||
&NumberOfEnabledProcessors
|
||||
);
|
||||
|
||||
if (EFI_ERROR(status)) {
|
||||
BFALERT("platform_num_cpus: GetNumberOfProcessors failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int64_t)NumberOfProcessors;
|
||||
}
|
||||
|
||||
struct call_vmm_args {
|
||||
uint64_t cpuid;
|
||||
uint64_t request;
|
||||
uintptr_t arg1;
|
||||
uintptr_t arg2;
|
||||
int64_t ret;
|
||||
};
|
||||
|
||||
EFI_FUNCTION static void
|
||||
call_vmm(struct call_vmm_args *args)
|
||||
{
|
||||
_set_ne();
|
||||
|
||||
args->ret =
|
||||
common_call_vmm(args->cpuid, args->request, args->arg1, args->arg2);
|
||||
}
|
||||
|
||||
int64_t
|
||||
platform_call_vmm_on_core(
|
||||
uint64_t cpuid, uint64_t request, uintptr_t arg1, uintptr_t arg2)
|
||||
{
|
||||
struct call_vmm_args args = {
|
||||
cpuid, request, arg1, arg2, 0
|
||||
};
|
||||
|
||||
if (cpuid == 0) {
|
||||
return common_call_vmm(cpuid, request, arg1, arg2);
|
||||
}
|
||||
|
||||
EFI_STATUS status =
|
||||
g_mp_services->StartupThisAP(
|
||||
g_mp_services,
|
||||
(EFI_AP_PROCEDURE)call_vmm,
|
||||
cpuid,
|
||||
nullptr,
|
||||
0,
|
||||
&args,
|
||||
nullptr
|
||||
);
|
||||
|
||||
if (EFI_ERROR(status)) {
|
||||
BFALERT("platform_num_cpus: StartupThisAP failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return args.ret;
|
||||
}
|
||||
|
||||
void *
|
||||
platform_get_rsdp(void)
|
||||
{ return 0; }
|
||||
|
|
@ -1,538 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <bfdebug.h>
|
||||
#include <bftypes.h>
|
||||
#include <bfconstants.h>
|
||||
#include <bfdriverinterface.h>
|
||||
|
||||
uint64_t _vmcall(uint64_t r1, uint64_t r2, uint64_t r3, uint64_t r4);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Global */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static uint64_t g_vcpuid = 0;
|
||||
static uint64_t g_module_length = 0;
|
||||
|
||||
struct pmodule_t {
|
||||
char *data;
|
||||
int64_t size;
|
||||
};
|
||||
|
||||
uint64_t g_num_pmodules = 0;
|
||||
struct pmodule_t pmodules[MAX_NUM_MODULES] = { 0 };
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Status */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static int g_status = 0;
|
||||
|
||||
#define STATUS_STOPPED 0
|
||||
#define STATUS_RUNNING 1
|
||||
#define STATUS_SUSPEND 2
|
||||
|
||||
DEFINE_MUTEX(g_status_mutex);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Misc Device */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
dev_open(struct inode *inode, struct file *file)
|
||||
{ return 0; }
|
||||
|
||||
static int
|
||||
dev_release(struct inode *inode, struct file *file)
|
||||
{ return 0; }
|
||||
|
||||
static long
|
||||
ioctl_add_module(const char *file)
|
||||
{
|
||||
char *buf;
|
||||
int64_t ret;
|
||||
|
||||
if (g_num_pmodules >= MAX_NUM_MODULES) {
|
||||
BFALERT("IOCTL_ADD_MODULE: too many modules have been loaded\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
buf = platform_alloc_rw(g_module_length);
|
||||
if (buf == NULL) {
|
||||
BFALERT("IOCTL_ADD_MODULE: failed to allocate memory for the module\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
ret = copy_from_user(buf, file, g_module_length);
|
||||
if (ret != 0) {
|
||||
BFALERT("IOCTL_ADD_MODULE: failed to copy memory from userspace\n");
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
ret = common_add_module(buf, g_module_length);
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_ADD_MODULE: common_add_module failed: %p - %s\n", \
|
||||
(void *)ret, ec_to_str(ret));
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
pmodules[g_num_pmodules].data = buf;
|
||||
pmodules[g_num_pmodules].size = g_module_length;
|
||||
|
||||
g_num_pmodules++;
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
IOCTL_FAILURE:
|
||||
|
||||
platform_free_rw(buf, g_module_length);
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_add_module_length(uint64_t *len)
|
||||
{
|
||||
int64_t ret;
|
||||
|
||||
if (len == 0) {
|
||||
BFALERT("IOCTL_ADD_MODULE_LENGTH: failed with len == NULL\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
ret = copy_from_user(&g_module_length, len, sizeof(uint64_t));
|
||||
if (ret != 0) {
|
||||
BFALERT("IOCTL_ADD_MODULE_LENGTH: failed to copy memory from userspace\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_unload_vmm(void)
|
||||
{
|
||||
int i;
|
||||
int64_t ret;
|
||||
|
||||
ret = common_unload_vmm();
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_UNLOAD_VMM: common_unload_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0; i < g_num_pmodules; i++) {
|
||||
platform_free_rw(pmodules[i].data, pmodules[i].size);
|
||||
}
|
||||
|
||||
g_num_pmodules = 0;
|
||||
platform_memset(&pmodules, 0, sizeof(pmodules));
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
IOCTL_FAILURE:
|
||||
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_load_vmm(void)
|
||||
{
|
||||
int64_t ret;
|
||||
|
||||
ret = common_load_vmm();
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_LOAD_VMM: common_load_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
IOCTL_FAILURE:
|
||||
|
||||
ioctl_unload_vmm();
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_stop_vmm(void)
|
||||
{
|
||||
int64_t ret;
|
||||
mutex_lock(&g_status_mutex);
|
||||
|
||||
ret = common_stop_vmm();
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_STOP_VMM: common_stop_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
g_status = STATUS_STOPPED;
|
||||
|
||||
mutex_unlock(&g_status_mutex);
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
IOCTL_FAILURE:
|
||||
|
||||
mutex_unlock(&g_status_mutex);
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_start_vmm(void)
|
||||
{
|
||||
int64_t ret;
|
||||
mutex_lock(&g_status_mutex);
|
||||
|
||||
ret = common_start_vmm();
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_START_VMM: common_start_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
g_status = STATUS_RUNNING;
|
||||
|
||||
mutex_unlock(&g_status_mutex);
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
IOCTL_FAILURE:
|
||||
|
||||
common_stop_vmm();
|
||||
|
||||
mutex_unlock(&g_status_mutex);
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_dump_vmm(struct debug_ring_resources_t *user_drr)
|
||||
{
|
||||
int64_t ret;
|
||||
struct debug_ring_resources_t *drr = 0;
|
||||
|
||||
ret = common_dump_vmm(&drr, g_vcpuid);
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_DUMP_VMM: common_dump_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
ret = copy_to_user(user_drr, drr, sizeof(struct debug_ring_resources_t));
|
||||
if (ret != 0) {
|
||||
BFALERT("IOCTL_DUMP_VMM: failed to copy memory from userspace\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_vmm_status(int64_t *status)
|
||||
{
|
||||
int64_t ret;
|
||||
int64_t vmm_status = common_vmm_status();
|
||||
|
||||
if (status == 0) {
|
||||
BFALERT("IOCTL_VMM_STATUS: common_vmm_status failed: NULL\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
ret = copy_to_user(status, &vmm_status, sizeof(int64_t));
|
||||
if (ret != 0) {
|
||||
BFALERT("IOCTL_VMM_STATUS: failed to copy memory from userspace\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_set_vcpuid(uint64_t *vcpuid)
|
||||
{
|
||||
int64_t ret;
|
||||
|
||||
if (vcpuid == 0) {
|
||||
BFALERT("IOCTL_SET_VCPUID: failed with vcpuid == NULL\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
ret = copy_from_user(&g_vcpuid, vcpuid, sizeof(uint64_t));
|
||||
if (ret != 0) {
|
||||
BFALERT("IOCTL_SET_VCPUID: failed to copy memory from userspace\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_vmcall(struct ioctl_vmcall_args_t *user_args)
|
||||
{
|
||||
int64_t ret;
|
||||
struct ioctl_vmcall_args_t args;
|
||||
|
||||
if (user_args == 0) {
|
||||
BFALERT("IOCTL_CALL: failed with args == NULL\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
ret = copy_from_user(&args, user_args, sizeof(struct ioctl_vmcall_args_t));
|
||||
if (ret != 0) {
|
||||
BFALERT("IOCTL_CALL: failed to copy memory from userspace\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
mutex_lock(&g_status_mutex);
|
||||
|
||||
switch (g_status) {
|
||||
case STATUS_RUNNING:
|
||||
args.reg1 = _vmcall(args.reg1, args.reg2, args.reg3, args.reg4);
|
||||
break;
|
||||
|
||||
case STATUS_SUSPEND:
|
||||
args.reg1 = SUSPEND;
|
||||
break;
|
||||
|
||||
default:
|
||||
args.reg1 = FAILURE;
|
||||
break;
|
||||
};
|
||||
|
||||
mutex_unlock(&g_status_mutex);
|
||||
|
||||
args.reg2 = 0;
|
||||
args.reg3 = 0;
|
||||
args.reg4 = 0;
|
||||
|
||||
ret = copy_to_user(user_args, &args, sizeof(struct ioctl_vmcall_args_t));
|
||||
if (ret != 0) {
|
||||
BFALERT("IOCTL_CALL: failed to copy memory from userspace\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
}
|
||||
|
||||
static long
|
||||
dev_unlocked_ioctl(
|
||||
struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case IOCTL_ADD_MODULE:
|
||||
return ioctl_add_module((char *)arg);
|
||||
|
||||
case IOCTL_ADD_MODULE_LENGTH:
|
||||
return ioctl_add_module_length((uint64_t *)arg);
|
||||
|
||||
case IOCTL_LOAD_VMM:
|
||||
return ioctl_load_vmm();
|
||||
|
||||
case IOCTL_UNLOAD_VMM:
|
||||
return ioctl_unload_vmm();
|
||||
|
||||
case IOCTL_START_VMM:
|
||||
return ioctl_start_vmm();
|
||||
|
||||
case IOCTL_STOP_VMM:
|
||||
return ioctl_stop_vmm();
|
||||
|
||||
case IOCTL_DUMP_VMM:
|
||||
return ioctl_dump_vmm((struct debug_ring_resources_t *)arg);
|
||||
|
||||
case IOCTL_VMM_STATUS:
|
||||
return ioctl_vmm_status((int64_t *)arg);
|
||||
|
||||
case IOCTL_SET_VCPUID:
|
||||
return ioctl_set_vcpuid((uint64_t *)arg);
|
||||
|
||||
case IOCTL_VMCALL:
|
||||
return ioctl_vmcall((struct ioctl_vmcall_args_t *)arg);
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct file_operations fops = {
|
||||
.open = dev_open,
|
||||
.release = dev_release,
|
||||
.unlocked_ioctl = dev_unlocked_ioctl,
|
||||
};
|
||||
|
||||
static struct miscdevice bareflank_dev = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = BAREFLANK_NAME,
|
||||
.fops = &fops,
|
||||
.mode = 0666
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Entry / Exit */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
dev_reboot(
|
||||
struct notifier_block *nb, unsigned long code, void *unused)
|
||||
{
|
||||
mutex_lock(&g_status_mutex);
|
||||
|
||||
common_fini();
|
||||
g_status = STATUS_STOPPED;
|
||||
|
||||
mutex_unlock(&g_status_mutex);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int
|
||||
resume(void)
|
||||
{
|
||||
mutex_lock(&g_status_mutex);
|
||||
|
||||
if (g_status != STATUS_SUSPEND) {
|
||||
mutex_unlock(&g_status_mutex);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
if (common_start_vmm() != BF_SUCCESS) {
|
||||
|
||||
common_fini();
|
||||
g_status = STATUS_STOPPED;
|
||||
|
||||
mutex_unlock(&g_status_mutex);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
g_status = STATUS_RUNNING;
|
||||
|
||||
mutex_unlock(&g_status_mutex);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int
|
||||
suspend(void)
|
||||
{
|
||||
mutex_lock(&g_status_mutex);
|
||||
|
||||
if (g_status != STATUS_RUNNING) {
|
||||
mutex_unlock(&g_status_mutex);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
if (common_stop_vmm() != BF_SUCCESS) {
|
||||
|
||||
common_fini();
|
||||
g_status = STATUS_STOPPED;
|
||||
|
||||
mutex_unlock(&g_status_mutex);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
g_status = STATUS_SUSPEND;
|
||||
|
||||
mutex_unlock(&g_status_mutex);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
int
|
||||
dev_pm(
|
||||
struct notifier_block *nb, unsigned long code, void *unused)
|
||||
{
|
||||
switch (code) {
|
||||
case PM_SUSPEND_PREPARE:
|
||||
case PM_HIBERNATION_PREPARE:
|
||||
case PM_RESTORE_PREPARE:
|
||||
return suspend();
|
||||
|
||||
case PM_POST_SUSPEND:
|
||||
case PM_POST_HIBERNATION:
|
||||
case PM_POST_RESTORE:
|
||||
return resume();
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block reboot_notifier_block = {
|
||||
.notifier_call = dev_reboot
|
||||
};
|
||||
|
||||
static struct notifier_block pm_notifier_block = {
|
||||
.notifier_call = dev_pm
|
||||
};
|
||||
|
||||
int
|
||||
dev_init(void)
|
||||
{
|
||||
register_reboot_notifier(&reboot_notifier_block);
|
||||
register_pm_notifier(&pm_notifier_block);
|
||||
|
||||
if (misc_register(&bareflank_dev) != 0) {
|
||||
BFALERT("misc_register failed\n");
|
||||
goto INIT_FAILURE;
|
||||
}
|
||||
|
||||
if (common_init() != 0) {
|
||||
BFALERT("common_init failed\n");
|
||||
goto INIT_FAILURE;
|
||||
}
|
||||
|
||||
g_status = STATUS_STOPPED;
|
||||
mutex_init(&g_status_mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
INIT_FAILURE:
|
||||
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
void
|
||||
dev_exit(void)
|
||||
{
|
||||
mutex_lock(&g_status_mutex);
|
||||
|
||||
common_fini();
|
||||
g_status = STATUS_STOPPED;
|
||||
|
||||
misc_deregister(&bareflank_dev);
|
||||
unregister_pm_notifier(&pm_notifier_block);
|
||||
unregister_reboot_notifier(&reboot_notifier_block);
|
||||
|
||||
mutex_unlock(&g_status_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(dev_init);
|
||||
module_exit(dev_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -1,199 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <bfarch.h>
|
||||
#include <bfdebug.h>
|
||||
#include <bfplatform.h>
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kallsyms.h>
|
||||
|
||||
#if defined(BF_AARCH64)
|
||||
# include <asm/io.h>
|
||||
#endif
|
||||
|
||||
typedef long (*set_affinity_fn)(pid_t, const struct cpumask *);
|
||||
set_affinity_fn set_cpu_affinity = nullptr;
|
||||
|
||||
int64_t
|
||||
platform_init(void)
|
||||
{
|
||||
set_cpu_affinity = (set_affinity_fn)kallsyms_lookup_name("sched_setaffinity");
|
||||
if (set_cpu_affinity == nullptr) {
|
||||
BFALERT("Failed to locate sched_setaffinity\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return BF_SUCCESS;
|
||||
}
|
||||
|
||||
void *
|
||||
platform_alloc_rw(uint64_t len)
|
||||
{
|
||||
void *addr = nullptr;
|
||||
|
||||
if (len == 0) {
|
||||
BFALERT("platform_alloc_rw: invalid length\n");
|
||||
return addr;
|
||||
}
|
||||
|
||||
addr = vmalloc(len);
|
||||
|
||||
if (addr == nullptr) {
|
||||
BFALERT("platform_alloc_rw: failed to vmalloc rw mem: %lld\n", len);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void *
|
||||
platform_alloc_rwe(uint64_t len)
|
||||
{
|
||||
void *addr = nullptr;
|
||||
|
||||
if (len == 0) {
|
||||
BFALERT("platform_alloc_rwe: invalid length\n");
|
||||
return addr;
|
||||
}
|
||||
|
||||
addr = __vmalloc(len, GFP_KERNEL, PAGE_KERNEL_EXEC);
|
||||
|
||||
if (addr == nullptr) {
|
||||
BFALERT("platform_alloc_rwe: failed to vmalloc rwe mem: %lld\n", len);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void
|
||||
platform_free_rw(void *addr, uint64_t len)
|
||||
{
|
||||
bfignored(len);
|
||||
|
||||
if (addr == nullptr) {
|
||||
BFALERT("platform_free_rw: invalid address %p\n", addr);
|
||||
return;
|
||||
}
|
||||
|
||||
vfree(addr);
|
||||
}
|
||||
|
||||
void
|
||||
platform_free_rwe(void *addr, uint64_t len)
|
||||
{
|
||||
bfignored(len);
|
||||
|
||||
if (addr == nullptr) {
|
||||
BFALERT("platform_free_rwe: invalid address %p\n", addr);
|
||||
return;
|
||||
}
|
||||
|
||||
vfree(addr);
|
||||
}
|
||||
|
||||
void *
|
||||
platform_virt_to_phys(void *virt)
|
||||
{
|
||||
if (is_vmalloc_addr(virt)) {
|
||||
return (void *)page_to_phys(vmalloc_to_page(virt));
|
||||
}
|
||||
else {
|
||||
return (void *)virt_to_phys(virt);
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
platform_memset(void *ptr, char value, uint64_t num)
|
||||
{
|
||||
if (!ptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return memset(ptr, value, num);
|
||||
}
|
||||
|
||||
int64_t
|
||||
platform_memcpy(
|
||||
void *dst, uint64_t dst_size, const void *src, uint64_t src_size, uint64_t num)
|
||||
{
|
||||
if (dst == 0 || src == 0) {
|
||||
BFALERT("platform_memcpy: invalid dst or src\n");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (num > dst_size || num > src_size) {
|
||||
BFALERT("platform_memcpy: num out of range\n");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
memcpy(dst, src, num);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
platform_num_cpus(void)
|
||||
{
|
||||
int64_t num_cpus = num_online_cpus();
|
||||
|
||||
if (num_cpus < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return num_cpus;
|
||||
}
|
||||
|
||||
int64_t
|
||||
platform_call_vmm_on_core(
|
||||
uint64_t cpuid, uint64_t request, uintptr_t arg1, uintptr_t arg2)
|
||||
{
|
||||
int64_t ret = 0;
|
||||
|
||||
if (set_cpu_affinity(current->pid, cpumask_of(cpuid)) != 0) {
|
||||
return BF_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
if (request == BF_REQUEST_VMM_FINI) {
|
||||
load_direct_gdt(raw_smp_processor_id());
|
||||
}
|
||||
|
||||
ret = common_call_vmm(cpuid, request, arg1, arg2);
|
||||
|
||||
if (request == BF_REQUEST_VMM_FINI) {
|
||||
load_fixmap_gdt(raw_smp_processor_id());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
platform_get_rsdp(void)
|
||||
{ return 0; }
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <bfplatform.h>
|
||||
#include <bfconstants.h>
|
||||
|
||||
#ifdef WIN64
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
int platform_info_should_fail = 0;
|
||||
|
||||
#define PAGE_ROUND_UP(x) ( (((uintptr_t)(x)) + BAREFLANK_PAGE_SIZE-1) & (~(BAREFLANK_PAGE_SIZE-1)) )
|
||||
|
||||
int64_t
|
||||
platform_init(void)
|
||||
{ return BF_SUCCESS; }
|
||||
|
||||
void *
|
||||
platform_alloc_rw(uint64_t len)
|
||||
{ return malloc(len); }
|
||||
|
||||
void *
|
||||
platform_alloc_rwe(uint64_t len)
|
||||
{
|
||||
void *addr = 0;
|
||||
|
||||
#ifdef WIN64
|
||||
DWORD oldProtect;
|
||||
#else
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
len = PAGE_ROUND_UP(len);
|
||||
addr = aligned_alloc(BAREFLANK_PAGE_SIZE, len);
|
||||
|
||||
#ifdef WIN64
|
||||
VirtualProtect(addr, len, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
#else
|
||||
ret = mprotect(addr, len, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
bfignored(ret);
|
||||
#endif
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void
|
||||
platform_free_rw(void *addr, uint64_t len)
|
||||
{
|
||||
bfignored(len);
|
||||
free(addr);
|
||||
}
|
||||
|
||||
void
|
||||
platform_free_rwe(void *addr, uint64_t len)
|
||||
{
|
||||
bfignored(len);
|
||||
free(addr);
|
||||
}
|
||||
|
||||
void *
|
||||
platform_virt_to_phys(void *virt)
|
||||
{ return virt; }
|
||||
|
||||
void *
|
||||
platform_memset(void *ptr, char value, uint64_t num)
|
||||
{ return memset(ptr, value, num); }
|
||||
|
||||
int64_t
|
||||
platform_memcpy(
|
||||
void *dst, uint64_t dst_size, const void *src, uint64_t src_size, uint64_t num)
|
||||
{
|
||||
bfignored(dst_size);
|
||||
bfignored(src_size);
|
||||
|
||||
memcpy(dst, src, num);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
platform_num_cpus(void)
|
||||
{ return 1; }
|
||||
|
||||
int64_t
|
||||
platform_call_vmm_on_core(
|
||||
uint64_t cpuid, uint64_t request, uintptr_t arg1, uintptr_t arg2)
|
||||
{
|
||||
return common_call_vmm(cpuid, request, arg1, arg2);
|
||||
}
|
||||
|
||||
void *
|
||||
platform_get_rsdp(void)
|
||||
{ return 0; }
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
;
|
||||
; Copyright (C) 2019 Assured Information Security, Inc.
|
||||
;
|
||||
; 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.
|
||||
|
||||
;
|
||||
; bareflank.inf
|
||||
;
|
||||
|
||||
[Version]
|
||||
Signature="$WINDOWS NT$"
|
||||
Class=System
|
||||
ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}
|
||||
Provider=%ManufacturerName%
|
||||
CatalogFile=bareflank.cat
|
||||
DriverVer=
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir = 12
|
||||
bareflank_Device_CoInstaller_CopyFiles = 11
|
||||
|
||||
; ================= Class section =====================
|
||||
|
||||
[SourceDisksNames]
|
||||
1 = %DiskName%,,,""
|
||||
|
||||
[SourceDisksFiles]
|
||||
bareflank.sys = 1,,
|
||||
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1
|
||||
|
||||
;*****************************************
|
||||
; Install Section
|
||||
;*****************************************
|
||||
|
||||
[Manufacturer]
|
||||
%ManufacturerName%=Standard,NT$ARCH$
|
||||
|
||||
[Standard.NT$ARCH$]
|
||||
%bareflank.DeviceDesc%=bareflank_Device, Root\bareflank
|
||||
|
||||
[bareflank_Device.NT]
|
||||
CopyFiles=Drivers_Dir
|
||||
|
||||
[Drivers_Dir]
|
||||
bareflank.sys
|
||||
|
||||
;-------------- Service installation
|
||||
[bareflank_Device.NT.Services]
|
||||
AddService = bareflank,%SPSVCINST_ASSOCSERVICE%, bareflank_Service_Inst
|
||||
|
||||
; -------------- bareflank driver install sections
|
||||
[bareflank_Service_Inst]
|
||||
DisplayName = %bareflank.SVCDESC%
|
||||
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
|
||||
StartType = 3 ; SERVICE_DEMAND_START
|
||||
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
|
||||
ServiceBinary = %12%\bareflank.sys
|
||||
|
||||
;
|
||||
;--- bareflank_Device Coinstaller installation ------
|
||||
;
|
||||
|
||||
[bareflank_Device.NT.CoInstallers]
|
||||
AddReg=bareflank_Device_CoInstaller_AddReg
|
||||
CopyFiles=bareflank_Device_CoInstaller_CopyFiles
|
||||
|
||||
[bareflank_Device_CoInstaller_AddReg]
|
||||
HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"
|
||||
|
||||
[bareflank_Device_CoInstaller_CopyFiles]
|
||||
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll
|
||||
|
||||
[bareflank_Device.NT.Wdf]
|
||||
KmdfService = bareflank, bareflank_wdfsect
|
||||
[bareflank_wdfsect]
|
||||
KmdfLibraryVersion = $KMDFVERSION$
|
||||
|
||||
[Strings]
|
||||
SPSVCINST_ASSOCSERVICE= 0x00000002
|
||||
ManufacturerName="Assured Information Security, Inc."
|
||||
DiskName = "Bareflank Installation Disk"
|
||||
bareflank.DeviceDesc = "Bareflank Device"
|
||||
bareflank.SVCDESC = "Bareflank Service"
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
|
||||
#
|
||||
# Copyright (C) 2019 Assured Information Security, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27004.2008
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bareflank", "bareflank.vcxproj", "{9299115C-8A76-408B-B25B-BB3571EA196A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{9299115C-8A76-408B-B25B-BB3571EA196A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9299115C-8A76-408B-B25B-BB3571EA196A}.Debug|x64.Build.0 = Debug|x64
|
||||
{9299115C-8A76-408B-B25B-BB3571EA196A}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{9299115C-8A76-408B-B25B-BB3571EA196A}.Release|x64.ActiveCfg = Release|x64
|
||||
{9299115C-8A76-408B-B25B-BB3571EA196A}.Release|x64.Build.0 = Release|x64
|
||||
{9299115C-8A76-408B-B25B-BB3571EA196A}.Release|x64.Deploy.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {5BB3266F-C8ED-491E-8FBD-B31BB90A5319}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
#
|
||||
# Copyright (C) 2019 Assured Information Security, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Visual Studio 15
|
||||
-->
|
||||
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Inf Include="bareflank.inf" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{9299115C-8A76-408B-B25B-BB3571EA196A}</ProjectGuid>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform Condition="'$(Platform)' == ''">x64</Platform>
|
||||
<RootNamespace>bareflank</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
<IncludePath>..\..\..\..\bfsdk\include;..\..\..\..\bfelf_loader\include;..\..\..\include;.;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
<IncludePath>..\..\..\..\bfsdk\include;..\..\..\..\bfelf_loader\include;..\..\..\include;.;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>KERNEL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>KERNEL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<FilesToPackage Include="$(TargetPath)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\common.c" />
|
||||
<ClCompile Include="device.c" />
|
||||
<ClCompile Include="driver.c" />
|
||||
<ClCompile Include="platform.c" />
|
||||
<ClCompile Include="queue.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="device.h" />
|
||||
<ClInclude Include="driver.h" />
|
||||
<ClInclude Include="queue.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="intrinsics.asm" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
#
|
||||
# Copyright (C) 2019 Assured Information Security, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Visual Studio 15
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Inf Include="bareflank.inf" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Sources">
|
||||
<UniqueIdentifier>{01371a61-2ed2-4da4-9ef8-a45467279dda}</UniqueIdentifier>
|
||||
<Extensions>*.c</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="device.h" />
|
||||
<ClInclude Include="driver.h" />
|
||||
<ClInclude Include="queue.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\common.c" />
|
||||
<ClCompile Include="device.c" />
|
||||
<ClCompile Include="driver.c" />
|
||||
<ClCompile Include="platform.c" />
|
||||
<ClCompile Include="queue.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="intrinsics.asm" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <driver.h>
|
||||
|
||||
extern int g_status;
|
||||
extern FAST_MUTEX g_status_mutex;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Driver */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
NTSTATUS
|
||||
DriverEntry(
|
||||
_In_ PDRIVER_OBJECT DriverObject,
|
||||
_In_ PUNICODE_STRING RegistryPath
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
WDF_DRIVER_CONFIG config;
|
||||
WDF_OBJECT_ATTRIBUTES attributes;
|
||||
|
||||
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
|
||||
attributes.EvtCleanupCallback = bareflankEvtDriverContextCleanup;
|
||||
|
||||
WDF_DRIVER_CONFIG_INIT(&config, bareflankEvtDeviceAdd);
|
||||
|
||||
status = WdfDriverCreate(DriverObject, RegistryPath, &attributes, &config, WDF_NO_HANDLE);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
bareflankEvtDeviceAdd(
|
||||
_In_ WDFDRIVER Driver,
|
||||
_Inout_ PWDFDEVICE_INIT DeviceInit
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
|
||||
|
||||
UNREFERENCED_PARAMETER(Driver);
|
||||
|
||||
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
|
||||
pnpPowerCallbacks.EvtDeviceD0Entry = bareflankEvtDeviceD0Entry;
|
||||
pnpPowerCallbacks.EvtDeviceD0Exit = bareflankEvtDeviceD0Exit;
|
||||
|
||||
WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
|
||||
|
||||
status = bareflankCreateDevice(DeviceInit);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
bareflankEvtDriverContextCleanup(
|
||||
_In_ WDFOBJECT DriverObject
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(DriverObject);
|
||||
ExAcquireFastMutex(&g_status_mutex);
|
||||
|
||||
common_fini();
|
||||
g_status = STATUS_STOPPED;
|
||||
|
||||
ExReleaseFastMutex(&g_status_mutex);
|
||||
}
|
||||
|
||||
static int g_sleeping = 0;
|
||||
|
||||
NTSTATUS
|
||||
bareflankEvtDeviceD0Entry(
|
||||
_In_ WDFDEVICE Device,
|
||||
_In_ WDF_POWER_DEVICE_STATE PreviousState
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Device);
|
||||
UNREFERENCED_PARAMETER(PreviousState);
|
||||
|
||||
ExAcquireFastMutex(&g_status_mutex);
|
||||
|
||||
if (g_status != STATUS_SUSPEND) {
|
||||
ExReleaseFastMutex(&g_status_mutex);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (common_start_vmm() != BF_SUCCESS) {
|
||||
|
||||
common_fini();
|
||||
g_status = STATUS_STOPPED;
|
||||
|
||||
ExReleaseFastMutex(&g_status_mutex);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
g_status = STATUS_RUNNING;
|
||||
|
||||
ExReleaseFastMutex(&g_status_mutex);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
bareflankEvtDeviceD0Exit(
|
||||
_In_ WDFDEVICE Device,
|
||||
_In_ WDF_POWER_DEVICE_STATE TargetState
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Device);
|
||||
UNREFERENCED_PARAMETER(TargetState);
|
||||
|
||||
ExAcquireFastMutex(&g_status_mutex);
|
||||
|
||||
if (g_status != STATUS_RUNNING) {
|
||||
ExReleaseFastMutex(&g_status_mutex);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (common_stop_vmm() != BF_SUCCESS) {
|
||||
|
||||
common_fini();
|
||||
g_status = STATUS_STOPPED;
|
||||
|
||||
ExReleaseFastMutex(&g_status_mutex);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
g_status = STATUS_SUSPEND;
|
||||
|
||||
ExReleaseFastMutex(&g_status_mutex);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
;
|
||||
; Copyright (C) 2019 Assured Information Security, Inc.
|
||||
;
|
||||
; 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.
|
||||
|
||||
.code
|
||||
|
||||
_vmcall PROC
|
||||
|
||||
push rbx
|
||||
|
||||
mov rax, rcx
|
||||
mov rbx, rdx
|
||||
mov rcx, r8
|
||||
mov rdx, r9
|
||||
|
||||
vmcall
|
||||
|
||||
pop rbx
|
||||
ret
|
||||
|
||||
_vmcall ENDP
|
||||
|
||||
end
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <ntddk.h>
|
||||
|
||||
#include <bfdebug.h>
|
||||
#include <bfplatform.h>
|
||||
#include <common.h>
|
||||
|
||||
#define BF_TAG 'BFLK'
|
||||
#define BF_NX_TAG 'BFNX'
|
||||
|
||||
int64_t
|
||||
platform_init(void)
|
||||
{ return BF_SUCCESS; }
|
||||
|
||||
void *
|
||||
platform_alloc_rw(uint64_t len)
|
||||
{
|
||||
void *addr = nullptr;
|
||||
|
||||
if (len == 0) {
|
||||
BFALERT("platform_alloc: invalid length\n");
|
||||
return addr;
|
||||
}
|
||||
|
||||
addr = ExAllocatePoolWithTag(NonPagedPool, len, BF_TAG);
|
||||
|
||||
if (addr == nullptr) {
|
||||
BFALERT("platform_alloc_rw: failed to ExAllocatePoolWithTag mem: %lld\n", len);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void *
|
||||
platform_alloc_rwe(uint64_t len)
|
||||
{
|
||||
void *addr = nullptr;
|
||||
|
||||
if (len == 0) {
|
||||
BFALERT("platform_alloc: invalid length\n");
|
||||
return addr;
|
||||
}
|
||||
|
||||
addr = ExAllocatePoolWithTag(NonPagedPoolExecute, len, BF_TAG);
|
||||
|
||||
if (addr == nullptr) {
|
||||
BFALERT("platform_alloc_rw: failed to ExAllocatePoolWithTag mem: %lld\n", len);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void *
|
||||
platform_virt_to_phys(void *virt)
|
||||
{
|
||||
PHYSICAL_ADDRESS addr = MmGetPhysicalAddress(virt);
|
||||
return (void *)addr.QuadPart;
|
||||
}
|
||||
|
||||
void
|
||||
platform_free_rw(void *addr, uint64_t len)
|
||||
{
|
||||
(void) len;
|
||||
|
||||
if (addr == nullptr) {
|
||||
BFALERT("platform_free_rw: invalid address %p\n", addr);
|
||||
return;
|
||||
}
|
||||
|
||||
ExFreePoolWithTag(addr, BF_TAG);
|
||||
}
|
||||
|
||||
void
|
||||
platform_free_rwe(void *addr, uint64_t len)
|
||||
{
|
||||
(void) len;
|
||||
|
||||
if (addr == nullptr) {
|
||||
BFALERT("platform_free_rw: invalid address %p\n", addr);
|
||||
return;
|
||||
}
|
||||
|
||||
ExFreePoolWithTag(addr, BF_TAG);
|
||||
}
|
||||
|
||||
void *
|
||||
platform_memset(void *ptr, char value, uint64_t num)
|
||||
{
|
||||
if (ptr == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RtlFillMemory(ptr, num, value);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int64_t
|
||||
platform_memcpy(
|
||||
void *dst, uint64_t dst_size, const void *src, uint64_t src_size, uint64_t num)
|
||||
{
|
||||
if (dst == 0 || src == 0) {
|
||||
BFALERT("platform_memcpy: invalid dst or src\n");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (num > dst_size || num > src_size) {
|
||||
BFALERT("platform_memcpy: num out of range\n");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
RtlCopyMemory(dst, src, num);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int64_t
|
||||
platform_num_cpus()
|
||||
{
|
||||
KAFFINITY k_affin;
|
||||
return (int64_t)KeQueryActiveProcessorCount(&k_affin);
|
||||
}
|
||||
|
||||
int64_t
|
||||
platform_call_vmm_on_core(
|
||||
uint64_t cpuid, uint64_t request, uintptr_t arg1, uintptr_t arg2)
|
||||
{
|
||||
int64_t ret;
|
||||
KAFFINITY old = KeSetSystemAffinityThreadEx(1ULL << cpuid);
|
||||
|
||||
ret = common_call_vmm(cpuid, request, arg1, arg2);
|
||||
|
||||
KeRevertToUserAffinityThreadEx(old);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
platform_get_rsdp(void)
|
||||
{ return 0; }
|
||||
|
|
@ -1,411 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <driver.h>
|
||||
|
||||
uint64_t _vmcall(uint64_t r1, uint64_t r2, uint64_t r3, uint64_t r4);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Status */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int g_status = 0;
|
||||
FAST_MUTEX g_status_mutex;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Global */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static uint64_t g_vcpuid = 0;
|
||||
|
||||
struct pmodule_t {
|
||||
char *data;
|
||||
int64_t size;
|
||||
};
|
||||
|
||||
static uint64_t g_num_pmodules = 0;
|
||||
static struct pmodule_t pmodules[MAX_NUM_MODULES] = { 0 };
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Misc Device */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static int64_t
|
||||
ioctl_add_module(const char *file, int64_t len)
|
||||
{
|
||||
char *buf;
|
||||
int64_t ret;
|
||||
|
||||
if (g_num_pmodules >= MAX_NUM_MODULES) {
|
||||
BFALERT("IOCTL_ADD_MODULE: too many modules have been loaded\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
buf = platform_alloc_rw(len);
|
||||
if (buf == NULL) {
|
||||
BFALERT("IOCTL_ADD_MODULE: failed to allocate memory for the module\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
RtlCopyMemory(buf, file, len);
|
||||
|
||||
ret = common_add_module(buf, len);
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_ADD_MODULE: common_add_module failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
pmodules[g_num_pmodules].data = buf;
|
||||
pmodules[g_num_pmodules].size = len;
|
||||
|
||||
g_num_pmodules++;
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
IOCTL_FAILURE:
|
||||
|
||||
platform_free_rw(buf, len);
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_unload_vmm(void)
|
||||
{
|
||||
int i;
|
||||
int64_t ret;
|
||||
|
||||
ret = common_unload_vmm();
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_UNLOAD_VMM: common_unload_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0; i < g_num_pmodules; i++) {
|
||||
platform_free_rw(pmodules[i].data, pmodules[i].size);
|
||||
}
|
||||
|
||||
g_num_pmodules = 0;
|
||||
platform_memset(&pmodules, 0, sizeof(pmodules));
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
IOCTL_FAILURE:
|
||||
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_load_vmm(void)
|
||||
{
|
||||
int64_t ret;
|
||||
|
||||
ret = common_load_vmm();
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_LOAD_VMM: common_load_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
IOCTL_FAILURE:
|
||||
|
||||
ioctl_unload_vmm();
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_stop_vmm(void)
|
||||
{
|
||||
int64_t ret;
|
||||
ExAcquireFastMutex(&g_status_mutex);
|
||||
|
||||
ret = common_stop_vmm();
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_STOP_VMM: common_stop_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
g_status = STATUS_STOPPED;
|
||||
|
||||
ExReleaseFastMutex(&g_status_mutex);
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
IOCTL_FAILURE:
|
||||
|
||||
ExReleaseFastMutex(&g_status_mutex);
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_start_vmm(void)
|
||||
{
|
||||
int64_t ret;
|
||||
ExAcquireFastMutex(&g_status_mutex);
|
||||
|
||||
ret = common_start_vmm();
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_START_VMM: common_start_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
g_status = STATUS_RUNNING;
|
||||
|
||||
ExReleaseFastMutex(&g_status_mutex);
|
||||
return BF_IOCTL_SUCCESS;
|
||||
|
||||
IOCTL_FAILURE:
|
||||
|
||||
common_stop_vmm();
|
||||
|
||||
ExReleaseFastMutex(&g_status_mutex);
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_dump_vmm(struct debug_ring_resources_t *user_drr)
|
||||
{
|
||||
int64_t ret;
|
||||
struct debug_ring_resources_t *drr = 0;
|
||||
|
||||
ret = common_dump_vmm(&drr, g_vcpuid);
|
||||
if (ret != BF_SUCCESS) {
|
||||
BFALERT("IOCTL_DUMP_VMM: common_dump_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret));
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
RtlCopyMemory(user_drr, drr, sizeof(struct debug_ring_resources_t));
|
||||
return BF_IOCTL_SUCCESS;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_vmm_status(int64_t *status)
|
||||
{
|
||||
int64_t vmm_status = common_vmm_status();
|
||||
|
||||
if (status == 0) {
|
||||
BFALERT("IOCTL_VMM_STATUS: common_vmm_status failed: NULL\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
*status = vmm_status;
|
||||
return BF_IOCTL_SUCCESS;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_set_vcpuid(uint64_t *vcpuid)
|
||||
{
|
||||
if (vcpuid == 0) {
|
||||
BFALERT("IOCTL_SET_VCPUID: failed with vcpuid == NULL\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
g_vcpuid = *vcpuid;
|
||||
return BF_IOCTL_SUCCESS;
|
||||
}
|
||||
|
||||
static long
|
||||
ioctl_vmcall(struct ioctl_vmcall_args_t *args_in, struct ioctl_vmcall_args_t *args_out)
|
||||
{
|
||||
struct ioctl_vmcall_args_t args = {0};
|
||||
|
||||
if (args_in == 0) {
|
||||
BFALERT("IOCTL_VMCALL: failed with args in == NULL\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
if (args_out == 0) {
|
||||
BFALERT("IOCTL_VMCALL: failed with args out == NULL\n");
|
||||
return BF_IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
RtlCopyMemory(&args, args_in, sizeof(struct ioctl_vmcall_args_t));
|
||||
|
||||
ExAcquireFastMutex(&g_status_mutex);
|
||||
|
||||
switch (g_status) {
|
||||
case STATUS_RUNNING:
|
||||
args.reg1 = _vmcall(args.reg1, args.reg2, args.reg3, args.reg4);
|
||||
break;
|
||||
|
||||
case STATUS_SUSPEND:
|
||||
args.reg1 = SUSPEND;
|
||||
break;
|
||||
|
||||
default:
|
||||
args.reg1 = FAILURE;
|
||||
break;
|
||||
};
|
||||
|
||||
ExReleaseFastMutex(&g_status_mutex);
|
||||
|
||||
args.reg2 = 0;
|
||||
args.reg3 = 0;
|
||||
args.reg4 = 0;
|
||||
|
||||
RtlCopyMemory(args_out, &args, sizeof(struct ioctl_vmcall_args_t));
|
||||
return BF_IOCTL_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
bareflankQueueInitialize(
|
||||
_In_ WDFDEVICE Device
|
||||
)
|
||||
{
|
||||
WDFQUEUE queue;
|
||||
NTSTATUS status;
|
||||
WDF_IO_QUEUE_CONFIG queueConfig;
|
||||
|
||||
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
|
||||
&queueConfig,
|
||||
WdfIoQueueDispatchParallel
|
||||
);
|
||||
|
||||
queueConfig.EvtIoStop = bareflankEvtIoStop;
|
||||
queueConfig.EvtIoDeviceControl = bareflankEvtIoDeviceControl;
|
||||
|
||||
status = WdfIoQueueCreate(Device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &queue);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
BFALERT("WdfIoQueueCreate failed\n");
|
||||
goto INIT_FAILURE;
|
||||
}
|
||||
|
||||
if (common_init() != 0) {
|
||||
BFALERT("common_init failed\n");
|
||||
goto INIT_FAILURE;
|
||||
}
|
||||
|
||||
g_status = STATUS_STOPPED;
|
||||
ExInitializeFastMutex(&g_status_mutex);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
INIT_FAILURE:
|
||||
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
VOID
|
||||
bareflankEvtIoDeviceControl(
|
||||
_In_ WDFQUEUE Queue,
|
||||
_In_ WDFREQUEST Request,
|
||||
_In_ size_t OutputBufferLength,
|
||||
_In_ size_t InputBufferLength,
|
||||
_In_ ULONG IoControlCode
|
||||
)
|
||||
{
|
||||
PVOID in = 0;
|
||||
PVOID out = 0;
|
||||
size_t in_size = 0;
|
||||
size_t out_size = 0;
|
||||
|
||||
int64_t ret = 0;
|
||||
NTSTATUS status;
|
||||
|
||||
UNREFERENCED_PARAMETER(Queue);
|
||||
|
||||
if (InputBufferLength != 0) {
|
||||
status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &in, &in_size);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (OutputBufferLength != 0) {
|
||||
status = WdfRequestRetrieveOutputBuffer(Request, OutputBufferLength, &out, &out_size);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
switch (IoControlCode) {
|
||||
case IOCTL_ADD_MODULE:
|
||||
ret = ioctl_add_module((char *)in, (int64_t)in_size);
|
||||
break;
|
||||
|
||||
case IOCTL_LOAD_VMM:
|
||||
ret = ioctl_load_vmm();
|
||||
break;
|
||||
|
||||
case IOCTL_UNLOAD_VMM:
|
||||
ret = ioctl_unload_vmm();
|
||||
break;
|
||||
|
||||
case IOCTL_START_VMM:
|
||||
ret = ioctl_start_vmm();
|
||||
break;
|
||||
|
||||
case IOCTL_STOP_VMM:
|
||||
ret = ioctl_stop_vmm();
|
||||
break;
|
||||
|
||||
case IOCTL_DUMP_VMM:
|
||||
ret = ioctl_dump_vmm((struct debug_ring_resources_t *)out);
|
||||
break;
|
||||
|
||||
case IOCTL_VMM_STATUS:
|
||||
ret = ioctl_vmm_status((int64_t *)out);
|
||||
break;
|
||||
|
||||
case IOCTL_SET_VCPUID:
|
||||
ret = ioctl_set_vcpuid((uint64_t *)in);
|
||||
break;
|
||||
|
||||
case IOCTL_VMCALL:
|
||||
ret = ioctl_vmcall((struct ioctl_vmcall_args_t *)in, (struct ioctl_vmcall_args_t *)out);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
if (OutputBufferLength != 0) {
|
||||
WdfRequestSetInformation(Request, out_size);
|
||||
}
|
||||
|
||||
if (ret != BF_IOCTL_SUCCESS) {
|
||||
goto IOCTL_FAILURE;
|
||||
}
|
||||
|
||||
WdfRequestComplete(Request, STATUS_SUCCESS);
|
||||
return;
|
||||
|
||||
IOCTL_FAILURE:
|
||||
|
||||
WdfRequestComplete(Request, STATUS_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
VOID
|
||||
bareflankEvtIoStop(
|
||||
_In_ WDFQUEUE Queue,
|
||||
_In_ WDFREQUEST Request,
|
||||
_In_ ULONG ActionFlags
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Queue);
|
||||
UNREFERENCED_PARAMETER(ActionFlags);
|
||||
|
||||
WdfRequestComplete(Request, STATUS_SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <bfdriverinterface.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <test_support.h>
|
||||
|
||||
TEST_CASE("common_add_module: invalid file")
|
||||
{
|
||||
CHECK(common_add_module(nullptr, 42) == BF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("common_add_module: invalid size")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
CHECK(common_add_module(info.back().file, 0) == BF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("common_add_module: success")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
CHECK(common_add_module(info.back().file, info.back().file_size) == BF_SUCCESS);
|
||||
|
||||
REQUIRE(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_add_module: already loaded")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_add_module(info.front().file, info.front().file_size) == BF_ERROR_VMM_INVALID_STATE); \
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_add_module: already running")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_add_module(info.front().file, info.front().file_size) == BF_ERROR_VMM_INVALID_STATE);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_add_module: corrupt")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_vmm_fini_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_ERROR_VMM_CORRUPTED);
|
||||
CHECK(common_add_module(info.front().file, info.front().file_size) == BF_ERROR_VMM_CORRUPTED);
|
||||
|
||||
common_reset();
|
||||
}
|
||||
|
||||
TEST_CASE("common_add_module: too many modules")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (auto i = 0; i < MAX_NUM_MODULES; i++) {
|
||||
CHECK(common_add_module(info.back().file, info.back().file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_add_module(info.front().file, info.front().file_size) == BF_ERROR_MAX_MODULES_REACHED);
|
||||
REQUIRE(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <bfdriverinterface.h>
|
||||
#include <bfdebugringinterface.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <test_support.h>
|
||||
|
||||
debug_ring_resources_t *g_drr;
|
||||
|
||||
TEST_CASE("common_add_module: invalid drr")
|
||||
{
|
||||
CHECK(common_dump_vmm(nullptr, 0) == BF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("common_add_module: unloaded")
|
||||
{
|
||||
CHECK(common_dump_vmm(&g_drr, 0) == BF_ERROR_VMM_INVALID_STATE);
|
||||
}
|
||||
|
||||
TEST_CASE("common_add_module: get drr fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_get_drr_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_dump_vmm(&g_drr, 0) == ENTRY_ERROR_UNKNOWN);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_add_module: success")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_dump_vmm(&g_drr, 0) == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <bfdriverinterface.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <test_support.h>
|
||||
|
||||
TEST_CASE("common_fini: unloaded")
|
||||
{
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_fini: add module")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_fini: load")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_fini: start")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_fini: corrupt")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_vmm_fini_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_ERROR_VMM_CORRUPTED);
|
||||
|
||||
common_reset();
|
||||
}
|
||||
|
||||
TEST_CASE("common_fini: unload fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_fini_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_ERROR_VMM_CORRUPTED);
|
||||
|
||||
common_reset();
|
||||
}
|
||||
|
||||
TEST_CASE("common_fini: stop fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_vmm_fini_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_ERROR_VMM_CORRUPTED);
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <hippomocks.h>
|
||||
|
||||
#include <bfdriverinterface.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <test_support.h>
|
||||
|
||||
#ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT
|
||||
|
||||
TEST_CASE("run init")
|
||||
{
|
||||
CHECK(common_init() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("failure")
|
||||
{
|
||||
MockRepository mocks;
|
||||
mocks.OnCallFunc(platform_init).Return(BF_ERROR_UNKNOWN);
|
||||
|
||||
CHECK(common_init() == BF_ERROR_UNKNOWN);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,208 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <hippomocks.h>
|
||||
|
||||
#include <bfdriverinterface.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <test_support.h>
|
||||
|
||||
#ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT
|
||||
|
||||
extern "C" int64_t private_setup_rsdp(void);
|
||||
extern "C" int64_t private_add_modules_mdl(void);
|
||||
|
||||
TEST_CASE("common_load_vmm: success")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_load_vmm: already loaded")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_load_vmm: already running")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_load_vmm() == BF_ERROR_VMM_INVALID_STATE);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_load_vmm: corrupt")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_vmm_fini_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_ERROR_VMM_CORRUPTED);
|
||||
CHECK(common_load_vmm() == BF_ERROR_VMM_CORRUPTED);
|
||||
|
||||
common_reset();
|
||||
}
|
||||
|
||||
TEST_CASE("common_load_vmm: alloc stack fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
MockRepository mocks;
|
||||
mocks.ExpectCallFunc(platform_alloc_rw).Return(nullptr);
|
||||
|
||||
CHECK(common_load_vmm() == BF_ERROR_OUT_OF_MEMORY);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_load_vmm: alloc tss fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
MockRepository mocks;
|
||||
mocks.ExpectCallFunc(platform_alloc_rw).Do(malloc);
|
||||
mocks.ExpectCallFunc(platform_alloc_rw).Return(nullptr);
|
||||
|
||||
CHECK(common_load_vmm() == BF_ERROR_OUT_OF_MEMORY);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_load_vmm: rsdp fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
MockRepository mocks;
|
||||
mocks.ExpectCallFunc(private_setup_rsdp).Return(-1);
|
||||
|
||||
CHECK(common_load_vmm() == -1);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_load_vmm: missing symbols")
|
||||
{
|
||||
auto filenames = g_filenames_success;
|
||||
filenames.pop_back();
|
||||
|
||||
binaries_info info{&g_file, filenames, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BFELF_ERROR_NO_SUCH_SYMBOL);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_load_vmm: no modules added")
|
||||
{
|
||||
CHECK(common_load_vmm() == BF_ERROR_NO_MODULES_ADDED);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_load_vmm: init fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_init_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == ENTRY_ERROR_UNKNOWN);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_load_vmm: set rsdp fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_set_rsdp_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == ENTRY_ERROR_UNKNOWN);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_load_vmm: add modules mdl fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_add_mdl_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == ENTRY_ERROR_UNKNOWN);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_load_vmm: add tss mdl fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_add_mdl_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
MockRepository mocks;
|
||||
mocks.OnCallFunc(private_add_modules_mdl).Return(BF_SUCCESS);
|
||||
|
||||
CHECK(common_load_vmm() == ENTRY_ERROR_UNKNOWN);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <hippomocks.h>
|
||||
|
||||
#include <bfdriverinterface.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <test_support.h>
|
||||
|
||||
#ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT
|
||||
|
||||
TEST_CASE("common_start_vmm: success")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_start_vmm: unloaded")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_start_vmm() == BF_ERROR_VMM_INVALID_STATE);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_start_vmm: already running")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_start_vmm: corrupt")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_vmm_fini_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_ERROR_VMM_CORRUPTED);
|
||||
CHECK(common_start_vmm() == BF_ERROR_VMM_CORRUPTED);
|
||||
|
||||
common_reset();
|
||||
}
|
||||
|
||||
TEST_CASE("common_start_vmm: start fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_vmm_init_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == ENTRY_ERROR_UNKNOWN);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_start_vmm: set affinity fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
|
||||
{
|
||||
MockRepository mocks;
|
||||
mocks.OnCallFunc(platform_call_vmm_on_core).Return(BF_ERROR_UNKNOWN);
|
||||
CHECK(common_start_vmm() == BF_ERROR_UNKNOWN);
|
||||
}
|
||||
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <hippomocks.h>
|
||||
|
||||
#include <bfdriverinterface.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <test_support.h>
|
||||
|
||||
#ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT
|
||||
|
||||
TEST_CASE("common_stop_vmm: success")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_stop_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_stop_vmm: unloaded")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_stop_vmm() == BF_ERROR_VMM_INVALID_STATE);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_stop_vmm: not running")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_stop_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_stop_vmm: already stopped")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_stop_vmm() == BF_SUCCESS);
|
||||
CHECK(common_stop_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_stop_vmm: corrupt")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_vmm_fini_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_ERROR_VMM_CORRUPTED);
|
||||
CHECK(common_stop_vmm() == BF_ERROR_VMM_CORRUPTED);
|
||||
|
||||
common_reset();
|
||||
}
|
||||
|
||||
TEST_CASE("common_start_vmm: stop fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_vmm_fini_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_stop_vmm() == ENTRY_ERROR_UNKNOWN);
|
||||
CHECK(common_fini() == BF_ERROR_VMM_CORRUPTED);
|
||||
|
||||
common_reset();
|
||||
}
|
||||
|
||||
TEST_CASE("common_stop_vmm: set affinity fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
|
||||
{
|
||||
MockRepository mocks;
|
||||
mocks.OnCallFunc(platform_call_vmm_on_core).Return(BF_ERROR_UNKNOWN);
|
||||
CHECK(common_stop_vmm() == BF_ERROR_UNKNOWN);
|
||||
}
|
||||
|
||||
CHECK(common_fini() == BF_ERROR_VMM_CORRUPTED);
|
||||
|
||||
common_reset();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <hippomocks.h>
|
||||
|
||||
#include <bfdriverinterface.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <test_support.h>
|
||||
|
||||
#ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT
|
||||
|
||||
TEST_CASE("common_unload_vmm: success")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_stop_vmm() == BF_SUCCESS);
|
||||
CHECK(common_unload_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_unload_vmm: already unloaded")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_unload_vmm() == BF_SUCCESS);
|
||||
CHECK(common_unload_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_unload_vmm: loaded")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_unload_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_unload_vmm: running")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_success, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_unload_vmm() == BF_ERROR_VMM_INVALID_STATE);
|
||||
CHECK(common_fini() == BF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("common_unload_vmm: corrupt")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_vmm_fini_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_fini() == BF_ERROR_VMM_CORRUPTED);
|
||||
CHECK(common_unload_vmm() == BF_ERROR_VMM_CORRUPTED);
|
||||
|
||||
common_reset();
|
||||
}
|
||||
|
||||
TEST_CASE("common_start_vmm: unload fails")
|
||||
{
|
||||
binaries_info info{&g_file, g_filenames_fini_fails, false};
|
||||
|
||||
for (const auto &binary : info.binaries()) {
|
||||
REQUIRE(common_add_module(binary.file, binary.file_size) == BF_SUCCESS);
|
||||
}
|
||||
|
||||
CHECK(common_load_vmm() == BF_SUCCESS);
|
||||
CHECK(common_start_vmm() == BF_SUCCESS);
|
||||
CHECK(common_stop_vmm() == BF_SUCCESS);
|
||||
CHECK(common_unload_vmm() == ENTRY_ERROR_UNKNOWN);
|
||||
CHECK(common_fini() == BF_ERROR_VMM_CORRUPTED);
|
||||
|
||||
common_reset();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// TIDY_EXCLUSION=-cert-err58-cpp
|
||||
//
|
||||
// Reason:
|
||||
// The operator+ may throw an exception, and since these vectors
|
||||
// have static storage, tidy raises this error. This is unlikely to happen,
|
||||
// and if it does, it will only happen in the bfdriver unittests
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <bffile.h>
|
||||
#include <bfelf_loader.h>
|
||||
|
||||
file g_file;
|
||||
|
||||
std::vector<std::string> g_filenames_success = {
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib1.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib2.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc++abi.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfpthread.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfsyscall.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfunwind.a"_s,
|
||||
VMM_PREFIX_PATH + "/bin/dummy_main"_s,
|
||||
};
|
||||
|
||||
std::vector<std::string> g_filenames_init_fails = {
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib1.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib2.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc++abi.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfpthread.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfsyscall.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfunwind.a"_s,
|
||||
VMM_PREFIX_PATH + "/bin/dummy_main_init_fails"_s,
|
||||
};
|
||||
|
||||
std::vector<std::string> g_filenames_fini_fails = {
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib1.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib2.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc++abi.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfpthread.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfsyscall.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfunwind.a"_s,
|
||||
VMM_PREFIX_PATH + "/bin/dummy_main_fini_fails"_s,
|
||||
};
|
||||
|
||||
std::vector<std::string> g_filenames_add_mdl_fails = {
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib1.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib2.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc++abi.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfpthread.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfsyscall.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfunwind.a"_s,
|
||||
VMM_PREFIX_PATH + "/bin/dummy_main_add_mdl_fails"_s,
|
||||
};
|
||||
|
||||
std::vector<std::string> g_filenames_get_drr_fails = {
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib1.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib2.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc++abi.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfpthread.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfsyscall.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfunwind.a"_s,
|
||||
VMM_PREFIX_PATH + "/bin/dummy_main_get_drr_fails"_s,
|
||||
};
|
||||
|
||||
std::vector<std::string> g_filenames_set_rsdp_fails = {
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib1.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib2.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc++abi.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfpthread.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfsyscall.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfunwind.a"_s,
|
||||
VMM_PREFIX_PATH + "/bin/dummy_main_set_rsdp_fails"_s,
|
||||
};
|
||||
|
||||
std::vector<std::string> g_filenames_vmm_init_fails = {
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib1.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib2.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc++abi.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfpthread.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfsyscall.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfunwind.a"_s,
|
||||
VMM_PREFIX_PATH + "/bin/dummy_main_vmm_init_fails"_s,
|
||||
};
|
||||
|
||||
std::vector<std::string> g_filenames_vmm_fini_fails = {
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib1.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib2.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libc++abi.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfpthread.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfsyscall.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfunwind.a"_s,
|
||||
VMM_PREFIX_PATH + "/bin/dummy_main_vmm_fini_fails"_s,
|
||||
};
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef TEST_SUPPORT_H
|
||||
#define TEST_SUPPORT_H
|
||||
|
||||
extern file g_file;
|
||||
extern std::vector<std::string> g_filenames_success;
|
||||
extern std::vector<std::string> g_filenames_init_fails;
|
||||
extern std::vector<std::string> g_filenames_fini_fails;
|
||||
extern std::vector<std::string> g_filenames_add_mdl_fails;
|
||||
extern std::vector<std::string> g_filenames_get_drr_fails;
|
||||
extern std::vector<std::string> g_filenames_set_rsdp_fails;
|
||||
extern std::vector<std::string> g_filenames_vmm_init_fails;
|
||||
extern std::vector<std::string> g_filenames_vmm_fini_fails;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
#
|
||||
# Copyright (C) 2019 Assured Information Security, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(bfdummy C CXX)
|
||||
|
||||
init_project(bfdummy INTERFACE)
|
||||
|
||||
target_include_directories(bfdummy INTERFACE
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
||||
)
|
||||
|
||||
target_link_libraries(bfdummy INTERFACE
|
||||
--whole-archive -lbfcrt -lbfdso --no-whole-archive
|
||||
${CMAKE_INSTALL_PREFIX}/lib/libc++.a
|
||||
${CMAKE_INSTALL_PREFIX}/lib/libc++abi.a
|
||||
vmm::bfpthread
|
||||
vmm::bfunwind
|
||||
${CMAKE_INSTALL_PREFIX}/lib/libm.a
|
||||
${CMAKE_INSTALL_PREFIX}/lib/libc.a
|
||||
vmm::bfsyscall
|
||||
)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Libraries
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
add_library(dummy_lib1 src/libs/dummy_lib1.cpp)
|
||||
add_library(dummy_lib2 src/libs/dummy_lib2.cpp)
|
||||
|
||||
target_link_libraries(dummy_lib1 PUBLIC bfdummy)
|
||||
target_link_libraries(dummy_lib2 PUBLIC bfdummy)
|
||||
|
||||
set_target_properties(dummy_lib1 PROPERTIES LINKER_LANGUAGE C)
|
||||
set_target_properties(dummy_lib2 PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
install(TARGETS dummy_lib1 DESTINATION lib EXPORT bfdummy-vmm-targets)
|
||||
install(TARGETS dummy_lib2 DESTINATION lib EXPORT bfdummy-vmm-targets)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Executables
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
add_executable(dummy_main src/main/dummy_main.cpp)
|
||||
add_executable(dummy_main_init_fails src/main/dummy_main.cpp)
|
||||
add_executable(dummy_main_fini_fails src/main/dummy_main.cpp)
|
||||
add_executable(dummy_main_add_mdl_fails src/main/dummy_main.cpp)
|
||||
add_executable(dummy_main_get_drr_fails src/main/dummy_main.cpp)
|
||||
add_executable(dummy_main_set_rsdp_fails src/main/dummy_main.cpp)
|
||||
add_executable(dummy_main_vmm_init_fails src/main/dummy_main.cpp)
|
||||
add_executable(dummy_main_vmm_fini_fails src/main/dummy_main.cpp)
|
||||
|
||||
target_link_libraries(dummy_main PRIVATE dummy_lib1 dummy_lib2)
|
||||
target_link_libraries(dummy_main_init_fails PRIVATE dummy_lib1 dummy_lib2)
|
||||
target_link_libraries(dummy_main_fini_fails PRIVATE dummy_lib1 dummy_lib2)
|
||||
target_link_libraries(dummy_main_add_mdl_fails PRIVATE dummy_lib1 dummy_lib2)
|
||||
target_link_libraries(dummy_main_get_drr_fails PRIVATE dummy_lib1 dummy_lib2)
|
||||
target_link_libraries(dummy_main_set_rsdp_fails PRIVATE dummy_lib1 dummy_lib2)
|
||||
target_link_libraries(dummy_main_vmm_init_fails PRIVATE dummy_lib1 dummy_lib2)
|
||||
target_link_libraries(dummy_main_vmm_fini_fails PRIVATE dummy_lib1 dummy_lib2)
|
||||
|
||||
target_compile_definitions(dummy_main_init_fails PRIVATE REQUEST_INIT_FAILS)
|
||||
target_compile_definitions(dummy_main_fini_fails PRIVATE REQUEST_FINI_FAILS)
|
||||
target_compile_definitions(dummy_main_add_mdl_fails PRIVATE REQUEST_ADD_MDL_FAILS)
|
||||
target_compile_definitions(dummy_main_get_drr_fails PRIVATE REQUEST_GET_DRR_FAILS)
|
||||
target_compile_definitions(dummy_main_set_rsdp_fails PRIVATE REQUEST_SET_RSDP_FAILS)
|
||||
target_compile_definitions(dummy_main_vmm_init_fails PRIVATE REQUEST_VMM_INIT_FAILS)
|
||||
target_compile_definitions(dummy_main_vmm_fini_fails PRIVATE REQUEST_VMM_FINI_FAILS)
|
||||
|
||||
install(TARGETS dummy_main DESTINATION bin EXPORT bfdummy-vmm-targets)
|
||||
install(TARGETS dummy_main_init_fails DESTINATION bin EXPORT bfdummy-vmm-targets)
|
||||
install(TARGETS dummy_main_fini_fails DESTINATION bin EXPORT bfdummy-vmm-targets)
|
||||
install(TARGETS dummy_main_add_mdl_fails DESTINATION bin EXPORT bfdummy-vmm-targets)
|
||||
install(TARGETS dummy_main_get_drr_fails DESTINATION bin EXPORT bfdummy-vmm-targets)
|
||||
install(TARGETS dummy_main_set_rsdp_fails DESTINATION bin EXPORT bfdummy-vmm-targets)
|
||||
install(TARGETS dummy_main_vmm_init_fails DESTINATION bin EXPORT bfdummy-vmm-targets)
|
||||
install(TARGETS dummy_main_vmm_fini_fails DESTINATION bin EXPORT bfdummy-vmm-targets)
|
||||
|
||||
fini_project()
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef DUMMY_LIBS_H
|
||||
#define DUMMY_LIBS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Definitions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/* @cond */
|
||||
|
||||
extern int global_var;
|
||||
|
||||
class base
|
||||
{
|
||||
public:
|
||||
base() noexcept = default;
|
||||
virtual ~base() = default;
|
||||
|
||||
virtual int
|
||||
foo(int) noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class derived1 : public base
|
||||
{
|
||||
public:
|
||||
derived1() noexcept;
|
||||
~derived1() override;
|
||||
|
||||
int
|
||||
foo(int arg) noexcept override;
|
||||
|
||||
private:
|
||||
int m_member{1000};
|
||||
};
|
||||
|
||||
class derived2 : public base
|
||||
{
|
||||
public:
|
||||
derived2() noexcept;
|
||||
~derived2() override;
|
||||
|
||||
int
|
||||
foo(int arg) noexcept override;
|
||||
|
||||
private:
|
||||
int m_member{2000};
|
||||
};
|
||||
|
||||
/* @endcond */
|
||||
|
||||
#endif
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <bfexports.h>
|
||||
#include <dummy_libs.h>
|
||||
|
||||
extern "C" int
|
||||
lib1_foo()
|
||||
{ return 1; }
|
||||
|
||||
derived1::derived1() noexcept
|
||||
{
|
||||
global_var++;
|
||||
}
|
||||
|
||||
derived1::~derived1()
|
||||
{
|
||||
global_var--;
|
||||
m_member = 0;
|
||||
}
|
||||
|
||||
int
|
||||
derived1::foo(int arg) noexcept
|
||||
{
|
||||
return arg + m_member;
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <dummy_libs.h>
|
||||
|
||||
extern "C" int lib1_foo();
|
||||
|
||||
derived2::derived2() noexcept
|
||||
{
|
||||
global_var += lib1_foo();
|
||||
}
|
||||
|
||||
derived2::~derived2()
|
||||
{
|
||||
global_var -= lib1_foo();
|
||||
m_member = 0;
|
||||
}
|
||||
|
||||
int
|
||||
derived2::foo(int arg) noexcept
|
||||
{
|
||||
return arg + m_member;
|
||||
}
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// TIDY_EXCLUSION=-cppcoreguidelines-pro*
|
||||
//
|
||||
// Reason:
|
||||
// Although written in C++, this code needs to implement C specific logic
|
||||
// that by its very definition will not adhere to the core guidelines
|
||||
// similar to libc which is needed by all C++ implementations.
|
||||
//
|
||||
|
||||
#ifndef REQUEST_INIT_FAILS
|
||||
#define REQUEST_INIT_RETURN ENTRY_SUCCESS
|
||||
#else
|
||||
#define REQUEST_INIT_RETURN ENTRY_ERROR_UNKNOWN
|
||||
#endif
|
||||
|
||||
#ifndef REQUEST_FINI_FAILS
|
||||
#define REQUEST_FINI_RETURN ENTRY_SUCCESS
|
||||
#else
|
||||
#define REQUEST_FINI_RETURN ENTRY_ERROR_UNKNOWN
|
||||
#endif
|
||||
|
||||
#ifndef REQUEST_ADD_MDL_FAILS
|
||||
#define REQUEST_ADD_MDL_RETURN ENTRY_SUCCESS
|
||||
#else
|
||||
#define REQUEST_ADD_MDL_RETURN ENTRY_ERROR_UNKNOWN
|
||||
#endif
|
||||
|
||||
#ifndef REQUEST_GET_DRR_FAILS
|
||||
#define REQUEST_GET_DRR_RETURN ENTRY_SUCCESS
|
||||
#else
|
||||
#define REQUEST_GET_DRR_RETURN ENTRY_ERROR_UNKNOWN
|
||||
#endif
|
||||
|
||||
#ifndef REQUEST_SET_RSDP_FAILS
|
||||
#define REQUEST_SET_RSDP_RETURN ENTRY_SUCCESS
|
||||
#else
|
||||
#define REQUEST_SET_RSDP_RETURN ENTRY_ERROR_UNKNOWN
|
||||
#endif
|
||||
|
||||
#ifndef REQUEST_VMM_INIT_FAILS
|
||||
#define REQUEST_VMM_INIT_RETURN ENTRY_SUCCESS
|
||||
#else
|
||||
#define REQUEST_VMM_INIT_RETURN ENTRY_ERROR_UNKNOWN
|
||||
#endif
|
||||
|
||||
#ifndef REQUEST_VMM_FINI_FAILS
|
||||
#define REQUEST_VMM_FINI_RETURN ENTRY_SUCCESS
|
||||
#else
|
||||
#define REQUEST_VMM_FINI_RETURN ENTRY_ERROR_UNKNOWN
|
||||
#endif
|
||||
|
||||
#include <bfgsl.h>
|
||||
#include <bftypes.h>
|
||||
#include <bfexports.h>
|
||||
#include <bfsupport.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <dummy_libs.h>
|
||||
|
||||
int g_errno;
|
||||
int *__errno() { return &g_errno; }
|
||||
|
||||
derived1 g_derived1;
|
||||
derived2 g_derived2;
|
||||
|
||||
int global_var = 0;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
try {
|
||||
throw std::runtime_error("test exceptions");
|
||||
}
|
||||
catch (std::exception &) {
|
||||
auto view = gsl::make_span(argv, argc);
|
||||
|
||||
return g_derived1.foo(gsl::narrow_cast<int>(strtol(view[0], nullptr, 10))) +
|
||||
g_derived2.foo(gsl::narrow_cast<int>(strtol(view[1], nullptr, 10)));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int64_t
|
||||
bfmain(uintptr_t request, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
|
||||
{
|
||||
bfignored(arg1);
|
||||
bfignored(arg2);
|
||||
bfignored(arg3);
|
||||
|
||||
switch (request) {
|
||||
case BF_REQUEST_INIT:
|
||||
return REQUEST_INIT_RETURN;
|
||||
|
||||
case BF_REQUEST_FINI:
|
||||
return REQUEST_FINI_RETURN;
|
||||
|
||||
case BF_REQUEST_ADD_MDL:
|
||||
return REQUEST_ADD_MDL_RETURN;
|
||||
|
||||
case BF_REQUEST_GET_DRR:
|
||||
return REQUEST_GET_DRR_RETURN;
|
||||
|
||||
case BF_REQUEST_VMM_INIT:
|
||||
return REQUEST_VMM_INIT_RETURN;
|
||||
|
||||
case BF_REQUEST_VMM_FINI:
|
||||
return REQUEST_VMM_FINI_RETURN;
|
||||
|
||||
case BF_REQUEST_SET_RSDP:
|
||||
return REQUEST_SET_RSDP_RETURN;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ENTRY_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Missing C Functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
int g_cursor = 0;
|
||||
char g_memory[0x100000] = {};
|
||||
|
||||
extern "C" int
|
||||
write(int file, const void *buffer, size_t count)
|
||||
{
|
||||
bfignored(file);
|
||||
bfignored(buffer);
|
||||
bfignored(count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" uint64_t
|
||||
unsafe_write_cstr(const char *cstr, size_t len)
|
||||
{
|
||||
bfignored(cstr);
|
||||
bfignored(len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void *
|
||||
_malloc_r(struct _reent *ent, size_t size)
|
||||
{
|
||||
bfignored(ent);
|
||||
|
||||
auto addr = &gsl::at(g_memory, g_cursor);
|
||||
g_cursor += size;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
_free_r(struct _reent *ent, void *ptr)
|
||||
{
|
||||
bfignored(ent);
|
||||
bfignored(ptr);
|
||||
}
|
||||
|
||||
extern "C" void *
|
||||
_calloc_r(struct _reent *ent, size_t nmemb, size_t size)
|
||||
{
|
||||
bfignored(ent);
|
||||
|
||||
if (auto ptr = _malloc_r(nullptr, nmemb * size)) {
|
||||
return memset(ptr, 0, nmemb * size);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" void *
|
||||
_realloc_r(struct _reent *ent, void *ptr, size_t size)
|
||||
{
|
||||
bfignored(ent);
|
||||
bfignored(ptr);
|
||||
bfignored(size);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" uint64_t *
|
||||
thread_context_tlsptr(void)
|
||||
{
|
||||
static uint64_t s_tls[0x1000] = {};
|
||||
return s_tls;
|
||||
}
|
||||
|
||||
extern "C" uint64_t
|
||||
thread_context_cpuid(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,266 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file bfelf_loader_reloc_aarch64.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* AArch64 Relocations
|
||||
*
|
||||
* The following is defined in the "ELF for the ARM 64-bit architecture"
|
||||
* specification:
|
||||
* http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf
|
||||
*
|
||||
* @cond
|
||||
*/
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Miscellaneous relocations */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
#define BFR_AARCH64_NONE bfscast(bfelf64_xword, 0)
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Static data relocations */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Data relocations */
|
||||
#define BFR_AARCH64_ABS64 bfscast(bfelf64_xword, 257)
|
||||
#define BFR_AARCH64_ABS32 bfscast(bfelf64_xword, 258)
|
||||
#define BFR_AARCH64_ABS16 bfscast(bfelf64_xword, 259)
|
||||
#define BFR_AARCH64_PREL64 bfscast(bfelf64_xword, 260)
|
||||
#define BFR_AARCH64_PREL32 bfscast(bfelf64_xword, 261)
|
||||
#define BFR_AARCH64_PREL16 bfscast(bfelf64_xword, 262)
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Static AArch64 relocations */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Group relocations to create an unsigned data value or address inline */
|
||||
#define BFR_AARCH64_MOVW_UABS_G0 bfscast(bfelf64_xword, 263)
|
||||
#define BFR_AARCH64_MOVW_UABS_G0_NC bfscast(bfelf64_xword, 264)
|
||||
#define BFR_AARCH64_MOVW_UABS_G1 bfscast(bfelf64_xword, 265)
|
||||
#define BFR_AARCH64_MOVW_UABS_G1_NC bfscast(bfelf64_xword, 266)
|
||||
#define BFR_AARCH64_MOVW_UABS_G2 bfscast(bfelf64_xword, 267)
|
||||
#define BFR_AARCH64_MOVW_UABS_G2_NC bfscast(bfelf64_xword, 268)
|
||||
#define BFR_AARCH64_MOVW_UABS_G3 bfscast(bfelf64_xword, 269)
|
||||
|
||||
/* Group relocations to create a signed data or offset value inline */
|
||||
#define BFR_AARCH64_MOVW_SABS_G0 bfscast(bfelf64_xword, 270)
|
||||
#define BFR_AARCH64_MOVW_SABS_G1 bfscast(bfelf64_xword, 271)
|
||||
#define BFR_AARCH64_MOVW_SABS_G2 bfscast(bfelf64_xword, 272)
|
||||
|
||||
/* Relocations to generate PC-relative addresses */
|
||||
#define BFR_AARCH64_LD_PREL_LO19 bfscast(bfelf64_xword, 273)
|
||||
#define BFR_AARCH64_ADR_PREL_LO21 bfscast(bfelf64_xword, 274)
|
||||
#define BFR_AARCH64_ADR_PREL_PG_HI21 bfscast(bfelf64_xword, 275)
|
||||
#define BFR_AARCH64_ADR_PREL_PG_HI21_NC bfscast(bfelf64_xword, 276)
|
||||
#define BFR_AARCH64_ADD_ABS_LO12_NC bfscast(bfelf64_xword, 277)
|
||||
#define BFR_AARCH64_LDST8_ABS_LO12_NC bfscast(bfelf64_xword, 278)
|
||||
#define BFR_AARCH64_LDST16_ABS_LO12_NC bfscast(bfelf64_xword, 284)
|
||||
#define BFR_AARCH64_LDST32_ABS_LO12_NC bfscast(bfelf64_xword, 285)
|
||||
#define BFR_AARCH64_LDST64_ABS_LO12_NC bfscast(bfelf64_xword, 286)
|
||||
#define BFR_AARCH64_LDST128_ABS_LO12_NC bfscast(bfelf64_xword, 299)
|
||||
|
||||
/* Relocations for control-flow instructions */
|
||||
#define BFR_AARCH64_TSTBR14 bfscast(bfelf64_xword, 279)
|
||||
#define BFR_AARCH64_CONDBR19 bfscast(bfelf64_xword, 280)
|
||||
#define BFR_AARCH64_JUMP26 bfscast(bfelf64_xword, 282)
|
||||
#define BFR_AARCH64_CALL26 bfscast(bfelf64_xword, 283)
|
||||
|
||||
/* Group relocations to create a PC-relative offset inline */
|
||||
#define BFR_AARCH64_MOVW_PREL_G0 bfscast(bfelf64_xword, 287)
|
||||
#define BFR_AARCH64_MOVW_PREL_G0_NC bfscast(bfelf64_xword, 288)
|
||||
#define BFR_AARCH64_MOVW_PREL_G1 bfscast(bfelf64_xword, 289)
|
||||
#define BFR_AARCH64_MOVW_PREL_G1_NC bfscast(bfelf64_xword, 290)
|
||||
#define BFR_AARCH64_MOVW_PREL_G2 bfscast(bfelf64_xword, 291)
|
||||
#define BFR_AARCH64_MOVW_PREL_G2_NC bfscast(bfelf64_xword, 292)
|
||||
#define BFR_AARCH64_MOVW_PREL_G3 bfscast(bfelf64_xword, 293)
|
||||
|
||||
/* Group relocations to create a GOT-relative offset inline */
|
||||
#define BFR_AARCH64_MOVW_GOTOFF_G0 bfscast(bfelf64_xword, 300)
|
||||
#define BFR_AARCH64_MOVW_GOTOFF_G0_NC bfscast(bfelf64_xword, 301)
|
||||
#define BFR_AARCH64_MOVW_GOTOFF_G1 bfscast(bfelf64_xword, 302)
|
||||
#define BFR_AARCH64_MOVW_GOTOFF_G1_NC bfscast(bfelf64_xword, 303)
|
||||
#define BFR_AARCH64_MOVW_GOTOFF_G2 bfscast(bfelf64_xword, 304)
|
||||
#define BFR_AARCH64_MOVW_GOTOFF_G2_NC bfscast(bfelf64_xword, 305)
|
||||
#define BFR_AARCH64_MOVW_GOTOFF_G3 bfscast(bfelf64_xword, 306)
|
||||
|
||||
/* GOT-relative data relocations */
|
||||
#define BFR_AARCH64_GOTREL64 bfscast(bfelf64_xword, 307)
|
||||
#define BFR_AARCH64_GOTREL32 bfscast(bfelf64_xword, 308)
|
||||
|
||||
/* GOT-relative instruction relocations */
|
||||
#define BFR_AARCH64_GOT_LD_PREL19 bfscast(bfelf64_xword, 309)
|
||||
#define BFR_AARCH64_LD64_GOTOFF_LO15 bfscast(bfelf64_xword, 310)
|
||||
#define BFR_AARCH64_ADR_GOT_PAGE bfscast(bfelf64_xword, 311)
|
||||
#define BFR_AARCH64_LD64_GOT_LO12_NC bfscast(bfelf64_xword, 312)
|
||||
#define BFR_AARCH64_LD64_GOTPAGE_LO15 bfscast(bfelf64_xword, 313)
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Relocations for thread-local storage */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* General dynamic TLS relocations */
|
||||
#define BFR_AARCH64_TLSGD_ADR_PREL21 bfscast(bfelf64_xword, 512)
|
||||
#define BFR_AARCH64_TLSGD_ADR_PAGE21 bfscast(bfelf64_xword, 513)
|
||||
#define BFR_AARCH64_TLSGD_ADD_LO12_NC bfscast(bfelf64_xword, 514)
|
||||
#define BFR_AARCH64_TLSGD_MOVW_G1 bfscast(bfelf64_xword, 515)
|
||||
#define BFR_AARCH64_TLSGD_MOVW_G0_NC bfscast(bfelf64_xword, 516)
|
||||
|
||||
/* Local dynamic TLS relocations */
|
||||
#define BFR_AARCH64_TLSLD_ADR_PREL21 bfscast(bfelf64_xword, 517)
|
||||
#define BFR_AARCH64_TLSLD_ADR_PAGE21 bfscast(bfelf64_xword, 518)
|
||||
#define BFR_AARCH64_TLSLD_ADD_LO12_NC bfscast(bfelf64_xword, 519)
|
||||
#define BFR_AARCH64_TLSLD_MOVW_G1 bfscast(bfelf64_xword, 520)
|
||||
#define BFR_AARCH64_TLSLD_MOVW_G0_NC bfscast(bfelf64_xword, 521)
|
||||
#define BFR_AARCH64_TLSLD_LD_PREL19 bfscast(bfelf64_xword, 522)
|
||||
#define BFR_AARCH64_TLSLD_MOVW_DTPREL_G2 bfscast(bfelf64_xword, 523)
|
||||
#define BFR_AARCH64_TLSLD_MOVW_DTPREL_G1 bfscast(bfelf64_xword, 524)
|
||||
#define BFR_AARCH64_TLSLD_MOVW_DTPREL_G1_NC bfscast(bfelf64_xword, 525)
|
||||
#define BFR_AARCH64_TLSLD_MOVW_DTPREL_G0 bfscast(bfelf64_xword, 526)
|
||||
#define BFR_AARCH64_TLSLD_MOVW_DTPREL_G0_NC bfscast(bfelf64_xword, 527)
|
||||
#define BFR_AARCH64_TLSLD_ADD_DTPREL_HI12 bfscast(bfelf64_xword, 528)
|
||||
#define BFR_AARCH64_TLSLD_ADD_DTPREL_LO12 bfscast(bfelf64_xword, 529)
|
||||
#define BFR_AARCH64_TLSLD_ADD_DTPREL_LO12_NC bfscast(bfelf64_xword, 530)
|
||||
#define BFR_AARCH64_TLSLD_LDST8_DTPREL_LO12 bfscast(bfelf64_xword, 531)
|
||||
#define BFR_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC bfscast(bfelf64_xword, 532)
|
||||
#define BFR_AARCH64_TLSLD_LDST16_DTPREL_LO12 bfscast(bfelf64_xword, 533)
|
||||
#define BFR_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC bfscast(bfelf64_xword, 534)
|
||||
#define BFR_AARCH64_TLSLD_LDST32_DTPREL_LO12 bfscast(bfelf64_xword, 535)
|
||||
#define BFR_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC bfscast(bfelf64_xword, 536)
|
||||
#define BFR_AARCH64_TLSLD_LDST64_DTPREL_LO12 bfscast(bfelf64_xword, 537)
|
||||
#define BFR_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC bfscast(bfelf64_xword, 538)
|
||||
#define BFR_AARCH64_TLSLD_LDST128_DTPREL_LO12 bfscast(bfelf64_xword, 572)
|
||||
#define BFR_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC bfscast(bfelf64_xword, 573)
|
||||
|
||||
/* Initial exec TLS relocations */
|
||||
#define BFR_AARCH64_TLSIE_MOVW_GOTTPREP_G1 bfscast(bfelf64_xword, 539)
|
||||
#define BFR_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC bfscast(bfelf64_xword, 540)
|
||||
#define BFR_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 bfscast(bfelf64_xword, 541)
|
||||
#define BFR_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC bfscast(bfelf64_xword, 542)
|
||||
#define BFR_AARCH64_TLSIE_LD_GOTTPREL_PREL19 bfscast(bfelf64_xword, 543)
|
||||
|
||||
/* Local exec TLS relocations */
|
||||
#define BFR_AARCH64_TLSLE_MOVW_TPREL_G2 bfscast(bfelf64_xword, 544)
|
||||
#define BFR_AARCH64_TLSLE_MOVW_TPREL_G1 bfscast(bfelf64_xword, 545)
|
||||
#define BFR_AARCH64_TLSLE_MOVW_TPREL_G1_NC bfscast(bfelf64_xword, 546)
|
||||
#define BFR_AARCH64_TLSLE_MOVW_TPREL_G0 bfscast(bfelf64_xword, 547)
|
||||
#define BFR_AARCH64_TLSLE_MOVW_TPREL_G0_NC bfscast(bfelf64_xword, 548)
|
||||
#define BFR_AARCH64_TLSLE_ADD_TPREL_HI12 bfscast(bfelf64_xword, 549)
|
||||
#define BFR_AARCH64_TLSLE_ADD_TPREL_LO12 bfscast(bfelf64_xword, 550)
|
||||
#define BFR_AARCH64_TLSLE_ADD_TPREL_LO12_NC bfscast(bfelf64_xword, 551)
|
||||
#define BFR_AARCH64_TLSLE_LDST8_TPREL_LO12 bfscast(bfelf64_xword, 552)
|
||||
#define BFR_AARCH64_TLSLE_LDST8_TPREL_LO12_NC bfscast(bfelf64_xword, 553)
|
||||
#define BFR_AARCH64_TLSLE_LDST16_TPREL_LO12 bfscast(bfelf64_xword, 554)
|
||||
#define BFR_AARCH64_TLSLE_LDST16_TPREL_LO12_NC bfscast(bfelf64_xword, 555)
|
||||
#define BFR_AARCH64_TLSLE_LDST32_TPREL_LO12 bfscast(bfelf64_xword, 556)
|
||||
#define BFR_AARCH64_TLSLE_LDST32_TPREL_LO12_NC bfscast(bfelf64_xword, 557)
|
||||
#define BFR_AARCH64_TLSLE_LDST64_TPREL_LO12 bfscast(bfelf64_xword, 558)
|
||||
#define BFR_AARCH64_TLSLE_LDST64_TPREL_LO12_NC bfscast(bfelf64_xword, 559)
|
||||
#define BFR_AARCH64_TLSLE_LDST128_TPREL_LO12 bfscast(bfelf64_xword, 570)
|
||||
#define BFR_AARCH64_TLSLE_LDST128_TPREL_LO12_NC bfscast(bfelf64_xword, 571)
|
||||
|
||||
/* TLS descriptor relocations */
|
||||
#define BFR_AARCH64_TLSDESC_LD_PREL19 bfscast(bfelf64_xword, 560)
|
||||
#define BFR_AARCH64_TLSDESC_ADR_PREL21 bfscast(bfelf64_xword, 561)
|
||||
#define BFR_AARCH64_TLSDESC_ADR_PAGE21 bfscast(bfelf64_xword, 562)
|
||||
#define BFR_AARCH64_TLSDESC_LD64_LO12 bfscast(bfelf64_xword, 563)
|
||||
#define BFR_AARCH64_TLSDESC_ADD_LO12 bfscast(bfelf64_xword, 564)
|
||||
#define BFR_AARCH64_TLSDESC_OFF_G1 bfscast(bfelf64_xword, 656)
|
||||
#define BFR_AARCH64_TLSDESC_OFF_G0_NC bfscast(bfelf64_xword, 566)
|
||||
#define BFR_AARCH64_TLSDESC_LDR bfscast(bfelf64_xword, 567)
|
||||
#define BFR_AARCH64_TLSDESC_ADD bfscast(bfelf64_xword, 568)
|
||||
#define BFR_AARCH64_TLSDESC_CALL bfscast(bfelf64_xword, 569)
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Dynamic relocations */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
#define BFR_AARCH64_COPY bfscast(bfelf64_xword, 1024)
|
||||
#define BFR_AARCH64_GLOB_DAT bfscast(bfelf64_xword, 1025)
|
||||
#define BFR_AARCH64_JUMP_SLOT bfscast(bfelf64_xword, 1026)
|
||||
#define BFR_AARCH64_RELATIVE bfscast(bfelf64_xword, 1027)
|
||||
#define BFR_AARCH64_TLS_DTPREL64 bfscast(bfelf64_xword, 1028)
|
||||
#define BFR_AARCH64_TLS_DTPMOD64 bfscast(bfelf64_xword, 1029)
|
||||
#define BFR_AARCH64_TLS_TPREL64 bfscast(bfelf64_xword, 1030)
|
||||
#define BFR_AARCH64_TLSDESC bfscast(bfelf64_xword, 1031)
|
||||
#define BFR_AARCH64_IRELATIVE bfscast(bfelf64_xword, 1032)
|
||||
|
||||
/* @endcond */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* ELF Relocations Implementation */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* @cond */
|
||||
|
||||
static inline int64_t
|
||||
private_relocate_symbol(
|
||||
struct bfelf_loader_t *loader, struct bfelf_file_t *ef, const struct bfelf_rela *rela)
|
||||
{
|
||||
const char *str = nullptr;
|
||||
const struct bfelf_sym *found_sym = nullptr;
|
||||
struct bfelf_file_t *found_ef = ef;
|
||||
bfelf64_addr *ptr = bfrcast(bfelf64_addr *, ef->exec_addr + rela->r_offset - ef->start_addr);
|
||||
|
||||
if (BFELF_REL_TYPE(rela->r_info) == BFR_AARCH64_RELATIVE) {
|
||||
*ptr = bfrcast(bfelf64_addr, ef->exec_virt + rela->r_addend);
|
||||
return BFELF_SUCCESS;
|
||||
}
|
||||
|
||||
found_sym = &(ef->symtab[BFELF_REL_SYM(rela->r_info)]);
|
||||
|
||||
if (BFELF_SYM_BIND(found_sym->st_info) == bfstb_weak) {
|
||||
found_ef = nullptr;
|
||||
}
|
||||
|
||||
if (found_sym->st_value == 0 || found_ef == nullptr) {
|
||||
int64_t ret;
|
||||
|
||||
str = &(ef->strtab[found_sym->st_name]);
|
||||
ret = private_get_sym_global(loader, str, &found_ef, &found_sym);
|
||||
|
||||
if (ret != BFELF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
switch (BFELF_REL_TYPE(rela->r_info)) {
|
||||
case BFR_AARCH64_GLOB_DAT:
|
||||
case BFR_AARCH64_JUMP_SLOT:
|
||||
case BFR_AARCH64_ABS64:
|
||||
*ptr = bfrcast(bfelf64_addr, found_ef->exec_virt + found_sym->st_value);
|
||||
break;
|
||||
|
||||
case BFR_AARCH64_ABS32:
|
||||
*(uint32_t *) ptr = bfrcast(uint32_t, found_ef->exec_virt + found_sym->st_value);
|
||||
break;
|
||||
|
||||
case BFR_AARCH64_ABS16:
|
||||
*(uint16_t *) ptr = bfrcast(uint16_t, found_ef->exec_virt + found_sym->st_value);
|
||||
break;
|
||||
|
||||
default:
|
||||
return bfunsupported_rel(str);
|
||||
}
|
||||
|
||||
return BFELF_SUCCESS;
|
||||
}
|
||||
|
||||
/* @endcond */
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Assured Information Security, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file bfelf_loader_reloc_x64.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* System V ABI 64bit Relocations
|
||||
*
|
||||
* The following is defined in the ELF 64bit file format specification:
|
||||
* http://www.x86-64.org/documentation/abi.pdf, page 71
|
||||
*
|
||||
* @cond
|
||||
*/
|
||||
#define BFR_X86_64_64 bfscast(bfelf64_xword, 1)
|
||||
#define BFR_X86_64_GLOB_DAT bfscast(bfelf64_xword, 6)
|
||||
#define BFR_X86_64_JUMP_SLOT bfscast(bfelf64_xword, 7)
|
||||
#define BFR_X86_64_RELATIVE bfscast(bfelf64_xword, 8)
|
||||
|
||||
/* @endcond */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* ELF Relocations Implementation */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* @cond */
|
||||
|
||||
static inline int64_t
|
||||
private_relocate_symbol(
|
||||
struct bfelf_loader_t *loader, struct bfelf_file_t *ef, const struct bfelf_rela *rela)
|
||||
{
|
||||
const char *str = nullptr;
|
||||
const struct bfelf_sym *found_sym = nullptr;
|
||||
struct bfelf_file_t *found_ef = ef;
|
||||
bfelf64_addr *ptr = bfrcast(bfelf64_addr *, ef->exec_addr + rela->r_offset - ef->start_addr);
|
||||
|
||||
if (BFELF_REL_TYPE(rela->r_info) == BFR_X86_64_RELATIVE) {
|
||||
*ptr = bfrcast(bfelf64_addr, ef->exec_virt + rela->r_addend);
|
||||
return BFELF_SUCCESS;
|
||||
}
|
||||
|
||||
found_sym = &(ef->symtab[BFELF_REL_SYM(rela->r_info)]);
|
||||
|
||||
if (BFELF_SYM_BIND(found_sym->st_info) == bfstb_weak) {
|
||||
found_ef = nullptr;
|
||||
}
|
||||
|
||||
if (found_sym->st_value == 0 || found_ef == nullptr) {
|
||||
int64_t ret = 0;
|
||||
str = &(ef->strtab[found_sym->st_name]);
|
||||
|
||||
ret = private_get_sym_global(loader, str, &found_ef, &found_sym);
|
||||
if (ret != BFELF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr = bfrcast(bfelf64_addr, found_ef->exec_virt + found_sym->st_value);
|
||||
|
||||
switch (BFELF_REL_TYPE(rela->r_info)) {
|
||||
case BFR_X86_64_64:
|
||||
*ptr += bfscast(bfelf64_addr, rela->r_addend);
|
||||
break;
|
||||
|
||||
case BFR_X86_64_GLOB_DAT:
|
||||
case BFR_X86_64_JUMP_SLOT:
|
||||
break;
|
||||
|
||||
default:
|
||||
return bfunsupported_rel(str);
|
||||
}
|
||||
|
||||
return BFELF_SUCCESS;
|
||||
}
|
||||
|
||||
/* @endcond */
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <hippomocks.h>
|
||||
|
||||
#include <test_real_elf.h>
|
||||
|
||||
#ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT
|
||||
|
||||
TEST_CASE("bfelf_binary: binary load fails")
|
||||
{
|
||||
MockRepository mocks;
|
||||
mocks.OnCallFunc(bfelf_load).Return(-1);
|
||||
|
||||
file f;
|
||||
CHECK_THROWS(binaries_info(&f, g_filenames.back(), {VMM_PREFIX_PATH + "/lib/"_s}));
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: binary success")
|
||||
{
|
||||
file f;
|
||||
CHECK_NOTHROW(binaries_info(&f, g_filenames.back(), {VMM_PREFIX_PATH + "/lib/"_s}));
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: module list load fails")
|
||||
{
|
||||
MockRepository mocks;
|
||||
mocks.OnCallFunc(bfelf_load).Return(-1);
|
||||
|
||||
file f;
|
||||
CHECK_THROWS(binaries_info(&f, g_filenames));
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: module list success")
|
||||
{
|
||||
file f;
|
||||
CHECK_NOTHROW(binaries_info(&f, g_filenames));
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: set args")
|
||||
{
|
||||
file f;
|
||||
binaries_info info(&f, g_filenames);
|
||||
|
||||
CHECK_NOTHROW(info.set_args(0, nullptr));
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: ef")
|
||||
{
|
||||
file f;
|
||||
binaries_info info(&f, g_filenames);
|
||||
|
||||
CHECK_NOTHROW(info.ef());
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: ef index")
|
||||
{
|
||||
file f;
|
||||
binaries_info info(&f, g_filenames);
|
||||
|
||||
CHECK_NOTHROW(info.ef(0));
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: at")
|
||||
{
|
||||
file f;
|
||||
binaries_info info(&f, g_filenames);
|
||||
|
||||
CHECK_NOTHROW(info.at(0));
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: front")
|
||||
{
|
||||
file f;
|
||||
binaries_info info(&f, g_filenames);
|
||||
|
||||
CHECK_NOTHROW(info.front());
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: back")
|
||||
{
|
||||
file f;
|
||||
binaries_info info(&f, g_filenames);
|
||||
|
||||
CHECK_NOTHROW(info.back());
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: binaries")
|
||||
{
|
||||
file f;
|
||||
binaries_info info(&f, g_filenames);
|
||||
|
||||
CHECK_NOTHROW(info.binaries());
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: info")
|
||||
{
|
||||
file f;
|
||||
binaries_info info(&f, g_filenames);
|
||||
|
||||
CHECK_NOTHROW(info.info());
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: entry")
|
||||
{
|
||||
file f;
|
||||
binaries_info info(&f, g_filenames);
|
||||
|
||||
CHECK_NOTHROW(info.entry());
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_binary: loader")
|
||||
{
|
||||
file f;
|
||||
binaries_info info(&f, g_filenames);
|
||||
|
||||
CHECK_NOTHROW(info.loader());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// TIDY_EXCLUSION=-cppcoreguidelines-pro-type-reinterpret-cast
|
||||
//
|
||||
// Reason:
|
||||
// Although in general this is a good rule, for hypervisor level code that
|
||||
// interfaces with the kernel, and raw hardware, this rule is
|
||||
// impractical.
|
||||
//
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <test_fake_elf.h>
|
||||
|
||||
#define offset(a, b) ((reinterpret_cast<uintptr_t>(&(a))) - (reinterpret_cast<uintptr_t>(&(b))))
|
||||
|
||||
std::pair<std::unique_ptr<char[]>, uint64_t>
|
||||
get_fake_elf()
|
||||
{
|
||||
auto &&size = sizeof(bfelf_test);
|
||||
auto &&buff = std::make_unique<char[]>(size);
|
||||
auto &&test = reinterpret_cast<bfelf_test *>(buff.get());
|
||||
|
||||
test->header.e_ident[bfei_mag0] = 0x7F;
|
||||
test->header.e_ident[bfei_mag1] = 'E';
|
||||
test->header.e_ident[bfei_mag2] = 'L';
|
||||
test->header.e_ident[bfei_mag3] = 'F';
|
||||
test->header.e_ident[bfei_class] = bfelfclass64;
|
||||
test->header.e_ident[bfei_data] = bfelfdata2lsb;
|
||||
test->header.e_ident[bfei_version] = bfev_current;
|
||||
test->header.e_ident[bfei_osabi] = bfelfosabi_sysv;
|
||||
test->header.e_ident[bfei_abiversion] = 0;
|
||||
test->header.e_type = bfet_dyn;
|
||||
test->header.e_machine = bfem_x86_64;
|
||||
test->header.e_version = bfev_current;
|
||||
test->header.e_entry = 0x150;
|
||||
test->header.e_phoff = offset(test->phdrtab, *test);
|
||||
test->header.e_shoff = offset(test->shdrtab, *test);
|
||||
test->header.e_flags = 0;
|
||||
test->header.e_ehsize = sizeof(bfelf_ehdr);
|
||||
test->header.e_phentsize = sizeof(bfelf_phdr);
|
||||
test->header.e_phnum = sizeof(test_phdrtab) / sizeof(bfelf_phdr);
|
||||
test->header.e_shentsize = sizeof(bfelf_shdr);
|
||||
test->header.e_shnum = sizeof(test_shdrtab) / sizeof(bfelf_shdr);
|
||||
test->header.e_shstrndx = 2;
|
||||
|
||||
test->phdrtab.re_segment.p_type = bfpt_load;
|
||||
test->phdrtab.re_segment.p_flags = bfpf_r | bfpf_x;
|
||||
test->phdrtab.re_segment.p_offset = 0;
|
||||
test->phdrtab.re_segment.p_vaddr = 0;
|
||||
test->phdrtab.re_segment.p_paddr = 0;
|
||||
test->phdrtab.re_segment.p_filesz = 0x500;
|
||||
test->phdrtab.re_segment.p_memsz = 0x500;
|
||||
test->phdrtab.re_segment.p_align = 0x1000;
|
||||
|
||||
test->phdrtab.rw_segment.p_type = bfpt_load;
|
||||
test->phdrtab.rw_segment.p_flags = bfpf_r | bfpf_w;
|
||||
test->phdrtab.rw_segment.p_offset = 0x500;
|
||||
test->phdrtab.rw_segment.p_vaddr = 0x500;
|
||||
test->phdrtab.rw_segment.p_paddr = 0x500;
|
||||
test->phdrtab.rw_segment.p_filesz = 0x500;
|
||||
test->phdrtab.rw_segment.p_memsz = 0x500;
|
||||
test->phdrtab.rw_segment.p_align = 0x1000;
|
||||
|
||||
test->phdrtab.dyn_segment.p_type = bfpt_dynamic;
|
||||
test->phdrtab.dyn_segment.p_flags = bfpf_r | bfpf_w;
|
||||
test->phdrtab.dyn_segment.p_offset = offset(test->dynamic, *test);
|
||||
test->phdrtab.dyn_segment.p_vaddr = 0x0;
|
||||
test->phdrtab.dyn_segment.p_paddr = 0x0;
|
||||
test->phdrtab.dyn_segment.p_filesz = sizeof(test_dynamic);
|
||||
test->phdrtab.dyn_segment.p_memsz = sizeof(test_dynamic);
|
||||
test->phdrtab.dyn_segment.p_align = 0x1000;
|
||||
|
||||
test->phdrtab.stack_segment.p_type = bfpt_gnu_stack;
|
||||
test->phdrtab.stack_segment.p_flags = bfpf_r | bfpf_w;
|
||||
test->phdrtab.stack_segment.p_offset = 0x0;
|
||||
test->phdrtab.stack_segment.p_vaddr = 0x0;
|
||||
test->phdrtab.stack_segment.p_paddr = 0x0;
|
||||
test->phdrtab.stack_segment.p_filesz = 0x0;
|
||||
test->phdrtab.stack_segment.p_memsz = 0x0;
|
||||
test->phdrtab.stack_segment.p_align = 0x0;
|
||||
|
||||
test->phdrtab.relro_segment.p_type = bfpt_gnu_relro;
|
||||
test->phdrtab.relro_segment.p_flags = bfpf_r;
|
||||
test->phdrtab.relro_segment.p_offset = 0x0;
|
||||
test->phdrtab.relro_segment.p_vaddr = 0x0;
|
||||
test->phdrtab.relro_segment.p_paddr = 0x0;
|
||||
test->phdrtab.relro_segment.p_filesz = 0x500;
|
||||
test->phdrtab.relro_segment.p_memsz = 0x500;
|
||||
test->phdrtab.relro_segment.p_align = 0x1000;
|
||||
|
||||
test->dynamic.needed1.d_tag = bfdt_needed;
|
||||
test->dynamic.needed2.d_tag = bfdt_needed;
|
||||
test->dynamic.pltgot.d_tag = bfdt_pltgot;
|
||||
test->dynamic.strtab.d_tag = bfdt_strtab;
|
||||
test->dynamic.strtab.d_val = offset(test->dynstr, *test);
|
||||
test->dynamic.symtab.d_tag = bfdt_symtab;
|
||||
test->dynamic.symtab.d_val = offset(test->dynsym, *test);
|
||||
test->dynamic.rela.d_tag = bfdt_rela;
|
||||
test->dynamic.rela.d_val = offset(test->relatab, *test);
|
||||
test->dynamic.relasz.d_tag = bfdt_relasz;
|
||||
test->dynamic.relasz.d_val = sizeof(test_relatab);
|
||||
test->dynamic.relaent.d_tag = bfdt_relaent;
|
||||
test->dynamic.relaent.d_val = sizeof(bfelf_rela);
|
||||
test->dynamic.strsz.d_tag = bfdt_strsz;
|
||||
test->dynamic.strsz.d_val = sizeof(test_dynstr);
|
||||
test->dynamic.init.d_tag = bfdt_init;
|
||||
test->dynamic.init.d_val = offset(test->init_array, *test);
|
||||
test->dynamic.fini.d_tag = bfdt_fini;
|
||||
test->dynamic.fini.d_val = offset(test->fini_array, *test);
|
||||
test->dynamic.init_array.d_tag = bfdt_init_array;
|
||||
test->dynamic.init_array.d_val = offset(test->init_array, *test);
|
||||
test->dynamic.fini_array.d_tag = bfdt_fini_array;
|
||||
test->dynamic.fini_array.d_val = offset(test->fini_array, *test);
|
||||
test->dynamic.init_arraysz.d_tag = bfdt_init_arraysz;
|
||||
test->dynamic.init_arraysz.d_val = sizeof(test_init_array);
|
||||
test->dynamic.fini_arraysz.d_tag = bfdt_fini_arraysz;
|
||||
test->dynamic.fini_arraysz.d_val = sizeof(test_fini_array);
|
||||
test->dynamic.flags_1.d_tag = bfdt_flags_1;
|
||||
test->dynamic.last.d_tag = bfdt_null;
|
||||
|
||||
test->shdrtab.eh_frame.sh_name = 0x0;
|
||||
test->shdrtab.eh_frame.sh_type = bfsht_strtab;
|
||||
test->shdrtab.eh_frame.sh_flags = 0;
|
||||
test->shdrtab.eh_frame.sh_addr = 0x250;
|
||||
test->shdrtab.eh_frame.sh_offset = offset(test->eh_frame, *test);
|
||||
test->shdrtab.eh_frame.sh_size = sizeof(test_eh_frame);
|
||||
test->shdrtab.eh_frame.sh_link = 0;
|
||||
test->shdrtab.eh_frame.sh_addralign = 1;
|
||||
test->shdrtab.eh_frame.sh_entsize = 0;
|
||||
|
||||
test->shdrtab.dynstr.sh_offset = offset(test->dynstr, *test);
|
||||
|
||||
test->shdrtab.eh_frame.sh_name = 10;
|
||||
test->shdrtab.ctors.sh_name = 20;
|
||||
test->shdrtab.dtors.sh_name = 30;
|
||||
|
||||
strncpy(static_cast<char *>(test->dynstr.str2), ".eh_frame", 10);
|
||||
strncpy(static_cast<char *>(test->dynstr.str3), ".ctors", 10);
|
||||
strncpy(static_cast<char *>(test->dynstr.str4), ".dtors", 10);
|
||||
|
||||
return {std::move(buff), size};
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef TEST_FAKE_ELF_H
|
||||
#define TEST_FAKE_ELF_H
|
||||
|
||||
#include <memory>
|
||||
#include <bfelf_loader.h>
|
||||
|
||||
std::pair<std::unique_ptr<char[]>, uint64_t>
|
||||
get_fake_elf();
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct test_phdrtab {
|
||||
bfelf_phdr re_segment;
|
||||
bfelf_phdr rw_segment;
|
||||
bfelf_phdr dyn_segment;
|
||||
bfelf_phdr stack_segment;
|
||||
bfelf_phdr relro_segment;
|
||||
};
|
||||
|
||||
struct test_hash {
|
||||
bfelf64_word nbucket;
|
||||
bfelf64_word nchain;
|
||||
bfelf64_word index1;
|
||||
bfelf64_word index2;
|
||||
bfelf64_word hash1;
|
||||
bfelf64_word hash2;
|
||||
};
|
||||
|
||||
struct test_dynsym {
|
||||
bfelf_sym syms[2];
|
||||
};
|
||||
|
||||
struct test_dynstr {
|
||||
char str1[10];
|
||||
char str2[10];
|
||||
char str3[10];
|
||||
char str4[10];
|
||||
};
|
||||
|
||||
struct test_relatab {
|
||||
struct bfelf_rela relas[2];
|
||||
};
|
||||
|
||||
struct test_eh_frame {
|
||||
const char *reserved[10];
|
||||
};
|
||||
|
||||
struct test_init_array {
|
||||
const char *reserved[10];
|
||||
};
|
||||
|
||||
struct test_fini_array {
|
||||
const char *reserved[10];
|
||||
};
|
||||
|
||||
struct test_dynamic {
|
||||
struct bfelf_dyn needed1;
|
||||
struct bfelf_dyn needed2;
|
||||
struct bfelf_dyn pltgot;
|
||||
struct bfelf_dyn strtab;
|
||||
struct bfelf_dyn symtab;
|
||||
struct bfelf_dyn rela;
|
||||
struct bfelf_dyn relasz;
|
||||
struct bfelf_dyn relaent;
|
||||
struct bfelf_dyn strsz;
|
||||
struct bfelf_dyn init;
|
||||
struct bfelf_dyn fini;
|
||||
struct bfelf_dyn init_array;
|
||||
struct bfelf_dyn fini_array;
|
||||
struct bfelf_dyn init_arraysz;
|
||||
struct bfelf_dyn fini_arraysz;
|
||||
struct bfelf_dyn flags_1;
|
||||
struct bfelf_dyn last;
|
||||
};
|
||||
|
||||
struct test_shdrtab {
|
||||
bfelf_shdr hash;
|
||||
bfelf_shdr dynsym;
|
||||
bfelf_shdr dynstr;
|
||||
bfelf_shdr relatab;
|
||||
bfelf_shdr eh_frame;
|
||||
bfelf_shdr init_array;
|
||||
bfelf_shdr fini_array;
|
||||
bfelf_shdr dynamic;
|
||||
bfelf_shdr ctors;
|
||||
bfelf_shdr dtors;
|
||||
};
|
||||
|
||||
struct bfelf_test {
|
||||
bfelf_ehdr header;
|
||||
test_phdrtab phdrtab;
|
||||
|
||||
test_dynsym dynsym;
|
||||
test_dynstr dynstr;
|
||||
test_hash hash;
|
||||
test_relatab relatab;
|
||||
test_eh_frame eh_frame;
|
||||
test_init_array init_array;
|
||||
test_fini_array fini_array;
|
||||
test_dynamic dynamic;
|
||||
|
||||
test_shdrtab shdrtab;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <test_fake_elf.h>
|
||||
#include <test_real_elf.h>
|
||||
|
||||
TEST_CASE("bfelf_file_get_entry: invalid elf file")
|
||||
{
|
||||
void *addr = nullptr;
|
||||
|
||||
auto ret = bfelf_file_get_entry(nullptr, &addr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_entry: invalid addr")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
bfelf_file_t ef = {};
|
||||
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
|
||||
ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
|
||||
ret = bfelf_file_get_entry(&ef, nullptr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_entry: not added to loader")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
void *addr = nullptr;
|
||||
bfelf_file_t ef = {};
|
||||
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
|
||||
ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
|
||||
ret = bfelf_file_get_entry(&ef, &addr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_entry: success")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
void *addr = nullptr;
|
||||
|
||||
binaries_info binaries{&g_file, g_filenames};
|
||||
|
||||
ret = bfelf_file_get_entry(&binaries.ef(), &addr);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <test_fake_elf.h>
|
||||
|
||||
TEST_CASE("bfelf_file_get_load_instr: invalid elf file")
|
||||
{
|
||||
const bfelf_load_instr *instr = nullptr;
|
||||
|
||||
auto ret = bfelf_file_get_load_instr(nullptr, 0, &instr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_load_instr: include index")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
bfelf_file_t ef = {};
|
||||
const bfelf_load_instr *instr = nullptr;
|
||||
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
|
||||
ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
|
||||
ret = bfelf_file_get_load_instr(&ef, 10, &instr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_INDEX);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_load_instr: invalid instr")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
bfelf_file_t ef = {};
|
||||
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
|
||||
ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
|
||||
ret = bfelf_file_get_load_instr(&ef, 0, nullptr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_load_instr: success")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
bfelf_file_t ef = {};
|
||||
const bfelf_load_instr *instr = nullptr;
|
||||
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
|
||||
ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
|
||||
ret = bfelf_file_get_load_instr(&ef, 0, &instr);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <test_real_elf.h>
|
||||
|
||||
TEST_CASE("bfelf_file_get_needed: invalid elf file")
|
||||
{
|
||||
uint64_t index = 0;
|
||||
const char *needed = nullptr;
|
||||
|
||||
auto ret = bfelf_file_get_needed(nullptr, index, &needed);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_needed: index")
|
||||
{
|
||||
uint64_t index = 0;
|
||||
bfelf_file_t ef = {};
|
||||
const char *needed = nullptr;
|
||||
|
||||
auto ret = bfelf_file_get_needed(&ef, index, &needed);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_INDEX);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_needed: invalid size")
|
||||
{
|
||||
uint64_t index = 0;
|
||||
bfelf_file_t ef = {};
|
||||
|
||||
auto ret = bfelf_file_get_needed(&ef, index, nullptr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_needed: success")
|
||||
{
|
||||
uint64_t index = 0;
|
||||
const char *needed = nullptr;
|
||||
binaries_info binaries{&g_file, g_filenames};
|
||||
|
||||
auto ret = bfelf_file_get_needed(&binaries.ef(), index, &needed);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <test_fake_elf.h>
|
||||
|
||||
TEST_CASE("bfelf_file_get_num_load_instrs: invalid elf file")
|
||||
{
|
||||
auto ret = bfelf_file_get_num_load_instrs(nullptr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_num_load_instrs: uninitialized")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
|
||||
auto ret = bfelf_file_get_num_load_instrs(&ef);
|
||||
CHECK(ret == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_num_load_instrs: success")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
bfelf_file_t ef = {};
|
||||
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
|
||||
ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
|
||||
ret = bfelf_file_get_num_load_instrs(&ef);
|
||||
CHECK(ret > 0);
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <bfelf_loader.h>
|
||||
|
||||
TEST_CASE("bfelf_file_get_num_needed: invalid elf file")
|
||||
{
|
||||
auto ret = bfelf_file_get_num_needed(nullptr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_num_needed: success")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
|
||||
auto ret = bfelf_file_get_num_needed(&ef);
|
||||
CHECK(ret == 0);
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <bfelf_loader.h>
|
||||
|
||||
TEST_CASE("bfelf_file_get_pic_pie: invalid elf file")
|
||||
{
|
||||
auto ret = bfelf_file_get_pic_pie(nullptr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_pic_pie: success")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
|
||||
auto ret = bfelf_file_get_pic_pie(&ef);
|
||||
CHECK(ret == 1);
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <test_real_elf.h>
|
||||
|
||||
TEST_CASE("bfelf_file_get_section_info: invalid elf")
|
||||
{
|
||||
section_info_t info = {};
|
||||
|
||||
auto ret = bfelf_file_get_section_info(nullptr, &info);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_section_info: invalid info")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
|
||||
auto ret = bfelf_file_get_section_info(&ef, nullptr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_section_info: not added to loader")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
section_info_t info = {};
|
||||
|
||||
auto ret = bfelf_file_get_section_info(&ef, &info);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_section_info: expected misc resources")
|
||||
{
|
||||
binaries_info binaries{&g_file, g_filenames};
|
||||
|
||||
section_info_t info = {};
|
||||
auto &dummy_main_ef = binaries.ef();
|
||||
|
||||
dummy_main_ef.init = 42;
|
||||
dummy_main_ef.fini = 42;
|
||||
dummy_main_ef.fini_array = 42;
|
||||
dummy_main_ef.fini_arraysz = 42;
|
||||
|
||||
auto ret = bfelf_file_get_section_info(&dummy_main_ef, &info);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
|
||||
CHECK(info.init_array_addr != nullptr);
|
||||
CHECK(info.init_array_size != 0);
|
||||
|
||||
CHECK(info.fini_array_addr != nullptr);
|
||||
CHECK(info.fini_array_size != 0);
|
||||
|
||||
CHECK(info.eh_frame_addr != nullptr);
|
||||
CHECK(info.eh_frame_size != 0);
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <bfelf_loader.h>
|
||||
|
||||
TEST_CASE("bfelf_file_get_total_size: invalid elf file")
|
||||
{
|
||||
auto ret = bfelf_file_get_total_size(nullptr);
|
||||
CHECK(ret == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_get_total_size: success")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
|
||||
auto ret = bfelf_file_get_total_size(&ef);
|
||||
CHECK(ret == 0);
|
||||
}
|
||||
|
|
@ -1,254 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// TIDY_EXCLUSION=-cppcoreguidelines-pro-type-reinterpret-cast
|
||||
//
|
||||
// Reason:
|
||||
// Although in general this is a good rule, for hypervisor level code that
|
||||
// interfaces with the kernel, and raw hardware, this rule is
|
||||
// impractical.
|
||||
//
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <test_fake_elf.h>
|
||||
|
||||
TEST_CASE("bfelf_file_init: success")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid file arg")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto size = std::get<1>(data);
|
||||
|
||||
auto ret = bfelf_file_init(nullptr, size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid size arg")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), 0, &ef);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid elf file")
|
||||
{
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, nullptr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid magic 0")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_ident[bfei_mag0] = 0;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_SIGNATURE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid magic 1")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_ident[bfei_mag1] = 0;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_SIGNATURE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid magic 2")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_ident[bfei_mag2] = 0;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_SIGNATURE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid magic 3")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_ident[bfei_mag3] = 0;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_SIGNATURE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid class")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_ident[bfei_class] = 0x4;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_UNSUPPORTED_FILE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid data")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_ident[bfei_data] = 0x8;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_UNSUPPORTED_FILE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid ident version")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_ident[bfei_version] = 0x15;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_UNSUPPORTED_FILE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid osabi")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_ident[bfei_osabi] = 0x16;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_UNSUPPORTED_FILE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid abiversion")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_ident[bfei_abiversion] = 0x23;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_UNSUPPORTED_FILE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid type")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_type = 0xDEAD;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_UNSUPPORTED_FILE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid machine")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_machine = 0xDEAD;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_UNSUPPORTED_FILE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid version")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_version = 0xDEAD;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_UNSUPPORTED_FILE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_file_init: invalid flags")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
auto test = reinterpret_cast<bfelf_test *>(buf.get());
|
||||
|
||||
test->header.e_flags = 0xDEAD;
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_ERROR_UNSUPPORTED_FILE);
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <test_fake_elf.h>
|
||||
#include <test_real_elf.h>
|
||||
|
||||
TEST_CASE("private_hash: strange characters")
|
||||
{
|
||||
auto str = "strange char here: \200";
|
||||
CHECK(private_hash(static_cast<const char *>(str)) != 0);
|
||||
}
|
||||
|
||||
TEST_CASE("private_relocate_symbol: invalid relocation")
|
||||
{
|
||||
bfelf_loader_t loader = {};
|
||||
bfelf_file_t ef = {};
|
||||
bfelf_rela rela = {};
|
||||
bfelf_sym symtab[1] = {};
|
||||
|
||||
auto file = "hello";
|
||||
auto exec = std::make_unique<char[]>(100);
|
||||
|
||||
ef.exec_addr = exec.get();
|
||||
ef.exec_virt = exec.get();
|
||||
ef.file = file;
|
||||
ef.symtab = static_cast<bfelf_sym *>(symtab);
|
||||
ef.symnum = 1;
|
||||
|
||||
rela.r_info = 0xFFFFFFFF;
|
||||
rela.r_offset = 0x0;
|
||||
|
||||
gsl::at(symtab, 0).st_name = 0xFFFFF;
|
||||
gsl::at(symtab, 0).st_value = 0x1;
|
||||
|
||||
CHECK(private_relocate_symbol(&loader, &ef, &rela) == BFELF_ERROR_UNSUPPORTED_RELA);
|
||||
}
|
||||
|
||||
TEST_CASE("private_process_dynamic_section: test all")
|
||||
{
|
||||
bfelf_file_t ef = {};
|
||||
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
|
||||
auto ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
|
||||
private_process_dynamic_section(&ef);
|
||||
|
||||
ef.dynnum = 0;
|
||||
private_process_dynamic_section(&ef);
|
||||
|
||||
ef.dynoff = 0;
|
||||
private_process_dynamic_section(&ef);
|
||||
}
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// TIDY_EXCLUSION=-cppcoreguidelines-pro-type-reinterpret-cast
|
||||
//
|
||||
// Reason:
|
||||
// Although in general this is a good rule, for hypervisor level code that
|
||||
// interfaces with the kernel, and raw hardware, this rule is
|
||||
// impractical.
|
||||
//
|
||||
|
||||
// TIDY_EXCLUSION=-cppcoreguidelines-pro-type-const-cast
|
||||
//
|
||||
// Reason:
|
||||
// This is test code, and we need to use const_cast so that we can modify
|
||||
// our ELF file so that it looks bad. This can safely be ignored.
|
||||
//
|
||||
|
||||
#include <hippomocks.h>
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <bfgsl.h>
|
||||
#include <bfplatform.h>
|
||||
|
||||
#include <list>
|
||||
#include <test_real_elf.h>
|
||||
|
||||
TEST_CASE("bfelf_load: invalid binaries")
|
||||
{
|
||||
void *entry = nullptr;
|
||||
crt_info_t info = {};
|
||||
bfelf_loader_t loader = {};
|
||||
|
||||
auto ret = bfelf_load(nullptr, 9, &entry, &info, &loader);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_load: invalid num binaries")
|
||||
{
|
||||
void *entry = nullptr;
|
||||
crt_info_t info = {};
|
||||
bfelf_loader_t loader = {};
|
||||
bfelf_binary_t binaries[9] = {};
|
||||
|
||||
auto ret = bfelf_load(reinterpret_cast<bfelf_binary_t *>(binaries), 0, &entry, &info, &loader);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_load: invalid entry")
|
||||
{
|
||||
crt_info_t info = {};
|
||||
bfelf_loader_t loader = {};
|
||||
bfelf_binary_t binaries[9] = {};
|
||||
|
||||
auto ret = bfelf_load(reinterpret_cast<bfelf_binary_t *>(binaries), 9, nullptr, &info, &loader);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_load: invalid info")
|
||||
{
|
||||
void *entry = nullptr;
|
||||
bfelf_loader_t loader = {};
|
||||
bfelf_binary_t binaries[9] = {};
|
||||
|
||||
auto ret = bfelf_load(reinterpret_cast<bfelf_binary_t *>(binaries), 9, &entry, nullptr, &loader);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_load: invalid loader")
|
||||
{
|
||||
void *entry = nullptr;
|
||||
crt_info_t info = {};
|
||||
bfelf_binary_t binaries[9] = {};
|
||||
|
||||
auto ret = bfelf_load(reinterpret_cast<bfelf_binary_t *>(binaries), 9, &entry, &info, nullptr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_load: init fail")
|
||||
{
|
||||
void *entry = nullptr;
|
||||
crt_info_t info = {};
|
||||
bfelf_loader_t loader = {};
|
||||
bfelf_binary_t binaries[9] = {};
|
||||
|
||||
std::list<bfn::buffer> files;
|
||||
for (auto i = 0ULL; i < 9; i++) {
|
||||
auto file = g_file.read_binary(g_filenames.at(i));
|
||||
|
||||
gsl::at(binaries, static_cast<std::ptrdiff_t>(i)).file = file.data();
|
||||
gsl::at(binaries, static_cast<std::ptrdiff_t>(i)).file_size = file.size();
|
||||
|
||||
files.emplace_back(std::move(file));
|
||||
}
|
||||
|
||||
auto view = gsl::make_span(const_cast<char *>(gsl::at(binaries, 0).file), 16);
|
||||
view[0] = 0;
|
||||
|
||||
|
||||
auto ret = bfelf_load(reinterpret_cast<bfelf_binary_t *>(binaries), 9, &entry, &info, &loader);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_SIGNATURE);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_load: out of memory fail")
|
||||
{
|
||||
void *entry = nullptr;
|
||||
crt_info_t info = {};
|
||||
bfelf_loader_t loader = {};
|
||||
bfelf_binary_t binaries[9] = {};
|
||||
|
||||
std::list<bfn::buffer> files;
|
||||
for (auto i = 0ULL; i < 9; i++) {
|
||||
auto file = g_file.read_binary(g_filenames.at(i));
|
||||
|
||||
gsl::at(binaries, static_cast<std::ptrdiff_t>(i)).file = file.data();
|
||||
gsl::at(binaries, static_cast<std::ptrdiff_t>(i)).file_size = file.size();
|
||||
|
||||
files.emplace_back(std::move(file));
|
||||
}
|
||||
|
||||
out_of_memory = true;
|
||||
auto ___ = gsl::finally([&] {
|
||||
out_of_memory = false;
|
||||
});
|
||||
|
||||
auto ret = bfelf_load(reinterpret_cast<bfelf_binary_t *>(binaries), 9, &entry, &info, &loader);
|
||||
CHECK(ret == BFELF_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_load: relocate fail")
|
||||
{
|
||||
void *entry = nullptr;
|
||||
crt_info_t info = {};
|
||||
bfelf_loader_t loader = {};
|
||||
bfelf_binary_t binaries[9] = {};
|
||||
|
||||
std::list<bfn::buffer> files;
|
||||
for (auto i = 0ULL; i < 9; i++) {
|
||||
auto file = g_file.read_binary(g_filenames.at(i));
|
||||
|
||||
gsl::at(binaries, static_cast<std::ptrdiff_t>(i)).file = file.data();
|
||||
gsl::at(binaries, static_cast<std::ptrdiff_t>(i)).file_size = file.size();
|
||||
|
||||
files.emplace_back(std::move(file));
|
||||
}
|
||||
|
||||
auto ret = bfelf_load(reinterpret_cast<bfelf_binary_t *>(binaries), 8, &entry, &info, &loader);
|
||||
CHECK(ret == BFELF_ERROR_NO_SUCH_SYMBOL);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_load: success")
|
||||
{
|
||||
void *entry = nullptr;
|
||||
crt_info_t info = {};
|
||||
bfelf_loader_t loader = {};
|
||||
bfelf_binary_t binaries[10] = {};
|
||||
|
||||
std::list<bfn::buffer> files;
|
||||
for (auto i = 0ULL; i < 10; i++) {
|
||||
auto file = g_file.read_binary(g_filenames.at(i));
|
||||
|
||||
gsl::at(binaries, static_cast<std::ptrdiff_t>(i)).file = file.data();
|
||||
gsl::at(binaries, static_cast<std::ptrdiff_t>(i)).file_size = file.size();
|
||||
|
||||
files.emplace_back(std::move(file));
|
||||
}
|
||||
|
||||
auto ret = bfelf_load(reinterpret_cast<bfelf_binary_t *>(binaries), 10, &entry, &info, &loader);
|
||||
CHECK(ret == BF_SUCCESS);
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <test_real_elf.h>
|
||||
#include <test_fake_elf.h>
|
||||
|
||||
char dummy[10];
|
||||
|
||||
TEST_CASE("bfelf_loader_add: invalid loader")
|
||||
{
|
||||
bfelf_file_t dummy_misc_ef = {};
|
||||
|
||||
auto ret = bfelf_loader_add(nullptr, &dummy_misc_ef, static_cast<char *>(dummy), static_cast<char *>(dummy));
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_add: invalid elf file")
|
||||
{
|
||||
bfelf_loader_t loader = {};
|
||||
|
||||
auto ret = bfelf_loader_add(&loader, nullptr, static_cast<char *>(dummy), static_cast<char *>(dummy));
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_add: invalid addr")
|
||||
{
|
||||
bfelf_loader_t loader = {};
|
||||
bfelf_file_t dummy_misc_ef = {};
|
||||
|
||||
auto ret = bfelf_loader_add(&loader, &dummy_misc_ef, nullptr, static_cast<char *>(dummy));
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_add: add twice")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
bfelf_loader_t loader = {};
|
||||
bfelf_file_t dummy_misc_ef = {};
|
||||
|
||||
ret = bfelf_loader_add(&loader, &dummy_misc_ef, static_cast<char *>(dummy), static_cast<char *>(dummy));
|
||||
CHECK(ret == BF_SUCCESS);
|
||||
|
||||
ret = bfelf_loader_add(&loader, &dummy_misc_ef, static_cast<char *>(dummy), static_cast<char *>(dummy));
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_add: too many files")
|
||||
{
|
||||
bfelf_loader_t loader = {};
|
||||
std::vector<bfelf_file_t> efs(MAX_NUM_MODULES + 1);
|
||||
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
|
||||
for (auto i = 0ULL; i < MAX_NUM_MODULES + 1; i++) {
|
||||
|
||||
int64_t ret = 0;
|
||||
|
||||
ret = bfelf_file_init(buf.get(), size, &gsl::at(efs, static_cast<std::ptrdiff_t>(i)));
|
||||
REQUIRE(ret == BFELF_SUCCESS);
|
||||
|
||||
ret = bfelf_loader_add(
|
||||
&loader,
|
||||
&gsl::at(efs, static_cast<std::ptrdiff_t>(i)),
|
||||
static_cast<char *>(dummy),
|
||||
static_cast<char *>(dummy)
|
||||
);
|
||||
|
||||
if (i < MAX_NUM_MODULES) {
|
||||
CHECK(ret == BF_SUCCESS);
|
||||
}
|
||||
else {
|
||||
CHECK(ret == BFELF_ERROR_LOADER_FULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_add: add fake")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
bfelf_file_t ef = {};
|
||||
bfelf_loader_t loader = {};
|
||||
|
||||
auto data = get_fake_elf();
|
||||
auto &buf = std::get<0>(data);
|
||||
auto size = std::get<1>(data);
|
||||
|
||||
ret = bfelf_file_init(buf.get(), size, &ef);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
|
||||
ret = bfelf_loader_add(&loader, &ef, static_cast<char *>(dummy), static_cast<char *>(dummy));
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <test_real_elf.h>
|
||||
|
||||
TEST_CASE("bfelf_loader_relocate: invalid loader")
|
||||
{
|
||||
auto ret = bfelf_loader_relocate(nullptr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_relocate: no files added")
|
||||
{
|
||||
bfelf_loader_t loader = {};
|
||||
|
||||
auto ret = bfelf_loader_relocate(&loader);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_relocate: success")
|
||||
{
|
||||
binaries_info binaries{&g_file, g_filenames};
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_relocate: twice")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
binaries_info binaries{&g_file, g_filenames};
|
||||
|
||||
ret = bfelf_loader_relocate(&binaries.loader());
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
}
|
||||
|
||||
#ifndef WIN64
|
||||
|
||||
TEST_CASE("bfelf_loader_relocate: no such symbol")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
binaries_info binaries{&g_file, g_filenames};
|
||||
|
||||
binaries.ef(0) = {};
|
||||
binaries.loader().relocated = 0;
|
||||
|
||||
ret = bfelf_loader_relocate(&binaries.loader());
|
||||
CHECK(ret == BFELF_ERROR_NO_SUCH_SYMBOL);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_relocate: no such symbol in plt")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
binaries_info binaries{&g_file, g_filenames};
|
||||
|
||||
binaries.ef(0) = {};
|
||||
binaries.loader().relocated = 0;
|
||||
|
||||
for (auto i = 0ULL; i < 9; i++) {
|
||||
binaries.ef(i).relanum_dyn = 0;
|
||||
}
|
||||
|
||||
ret = bfelf_loader_relocate(&binaries.loader());
|
||||
CHECK(ret == BFELF_ERROR_NO_SUCH_SYMBOL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// TIDY_EXCLUSION=-cppcoreguidelines-pro-type-reinterpret-cast
|
||||
//
|
||||
// Reason:
|
||||
// Although in general this is a good rule, for hypervisor level code that
|
||||
// interfaces with the kernel, and raw hardware, this rule is
|
||||
// impractical.
|
||||
//
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <test_real_elf.h>
|
||||
|
||||
using func_t = void (*)();
|
||||
|
||||
TEST_CASE("bfelf_loader_resolve_symbol: invalid loader")
|
||||
{
|
||||
func_t func;
|
||||
|
||||
auto ret = bfelf_loader_resolve_symbol(nullptr, "lib1_foo", reinterpret_cast<void **>(&func));
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_resolve_symbol: invalid name")
|
||||
{
|
||||
func_t func;
|
||||
bfelf_loader_t loader = {};
|
||||
|
||||
auto ret = bfelf_loader_resolve_symbol(&loader, nullptr, reinterpret_cast<void **>(&func));
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_resolve_symbol: invalid addr")
|
||||
{
|
||||
bfelf_loader_t loader = {};
|
||||
|
||||
auto ret = bfelf_loader_resolve_symbol(&loader, "lib1_foo", nullptr);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_resolve_symbol: no files added")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
bfelf_loader_t loader = {};
|
||||
|
||||
ret = bfelf_loader_relocate(&loader);
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
|
||||
func_t func;
|
||||
|
||||
ret = bfelf_loader_resolve_symbol(&loader, "lib1_foo", reinterpret_cast<void **>(&func));
|
||||
CHECK(ret == BFELF_ERROR_NO_SUCH_SYMBOL);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_resolve_symbol: no such symbol")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
binaries_info binaries{&g_file, g_filenames};
|
||||
|
||||
func_t func;
|
||||
|
||||
ret = bfelf_loader_resolve_symbol(&binaries.loader(), "invalid_sym", reinterpret_cast<void **>(&func));
|
||||
CHECK(ret == BFELF_ERROR_NO_SUCH_SYMBOL);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_resolve_symbol: success")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
binaries_info binaries{&g_file, g_filenames};
|
||||
|
||||
func_t func;
|
||||
|
||||
ret = bfelf_loader_resolve_symbol(&binaries.loader(), "lib1_foo", reinterpret_cast<void **>(&func));
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_resolve_symbol: no such symbol no hash")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
binaries_info binaries{&g_file, g_filenames};
|
||||
|
||||
binaries.ef(0).hash = nullptr;
|
||||
binaries.ef(1).hash = nullptr;
|
||||
|
||||
func_t func;
|
||||
|
||||
ret = bfelf_loader_resolve_symbol(&binaries.loader(), "invalid_sym", reinterpret_cast<void **>(&func));
|
||||
CHECK(ret == BFELF_ERROR_NO_SUCH_SYMBOL);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_resolve_symbol: success no hash")
|
||||
{
|
||||
int64_t ret = 0;
|
||||
binaries_info binaries{&g_file, g_filenames};
|
||||
|
||||
binaries.ef(0).hash = nullptr;
|
||||
binaries.ef(1).hash = nullptr;
|
||||
|
||||
func_t func;
|
||||
|
||||
ret = bfelf_loader_resolve_symbol(&binaries.loader(), "lib1_foo", reinterpret_cast<void **>(&func));
|
||||
CHECK(ret == BFELF_SUCCESS);
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <hippomocks.h>
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <bfgsl.h>
|
||||
#include <test_real_elf.h>
|
||||
|
||||
TEST_CASE("bfelf_set_integer_args: invalid info")
|
||||
{
|
||||
file f;
|
||||
bfn::buffer buffer{};
|
||||
bfelf_binary_t binary{};
|
||||
std::string filename{"test.txt"};
|
||||
|
||||
REQUIRE_NOTHROW(f.write_text(filename, "not an ELF file"));
|
||||
|
||||
CHECK_THROWS(
|
||||
bfelf_read_binary_and_get_needed_list(&f, filename, {}, buffer, binary)
|
||||
);
|
||||
|
||||
REQUIRE(std::remove(filename.c_str()) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_set_integer_args: no paths")
|
||||
{
|
||||
file f;
|
||||
bfn::buffer buffer{};
|
||||
bfelf_binary_t binary{};
|
||||
|
||||
CHECK_THROWS(
|
||||
bfelf_read_binary_and_get_needed_list(&f, g_filenames.back(), {"not a dir"}, buffer, binary)
|
||||
);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_set_integer_args: invalid filename")
|
||||
{
|
||||
file f;
|
||||
bfn::buffer buffer{};
|
||||
bfelf_binary_t binary{};
|
||||
|
||||
CHECK_THROWS(
|
||||
bfelf_read_binary_and_get_needed_list(&f, "not_a_real_file", {}, buffer, binary)
|
||||
);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_set_integer_args: success")
|
||||
{
|
||||
file f;
|
||||
bfn::buffer buffer{};
|
||||
bfelf_binary_t binary{};
|
||||
|
||||
CHECK_NOTHROW(
|
||||
bfelf_read_binary_and_get_needed_list(&f, g_filenames.back(), {VMM_PREFIX_PATH + "/lib/"_s}, buffer, binary)
|
||||
);
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// TIDY_EXCLUSION=-cppcoreguidelines-pro-type-reinterpret-cast
|
||||
//
|
||||
// Reason:
|
||||
// Although in general this is a good rule, for hypervisor level code that
|
||||
// interfaces with the kernel, and raw hardware, this rule is
|
||||
// impractical.
|
||||
//
|
||||
|
||||
#include <catch/catch.hpp>
|
||||
#include <test_real_elf.h>
|
||||
|
||||
std::array<char, 0x8000>fake_stack{};
|
||||
|
||||
TEST_CASE("bfelf_loader_resolve_symbol: real test (list)")
|
||||
{
|
||||
binaries_info binaries{&g_file, g_filenames};
|
||||
|
||||
std::array<const char *, 2> argv{{"1000", "2000"}};
|
||||
binaries.set_args(gsl::narrow_cast<int>(argv.size()), argv.data());
|
||||
|
||||
auto func = reinterpret_cast<_start_t>(binaries.entry());
|
||||
CHECK(func(&fake_stack.at(0x7999), &binaries.info()) == 6000);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_loader_resolve_symbol: real test (needed)")
|
||||
{
|
||||
binaries_info binaries{&g_file, g_filenames.back(), {VMM_PREFIX_PATH + "/lib/"_s}};
|
||||
|
||||
std::array<const char *, 2> argv{{"1000", "2000"}};
|
||||
binaries.set_args(gsl::narrow_cast<int>(argv.size()), argv.data());
|
||||
|
||||
auto func = reinterpret_cast<_start_t>(binaries.entry());
|
||||
CHECK(func(&fake_stack.at(0x7999), &binaries.info()) == 6000);
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// TIDY_EXCLUSION=-cert-err58-cpp
|
||||
//
|
||||
// Reason:
|
||||
// This triggers on g_filenames which is only used for testing. This
|
||||
// is not a false positive, but it can be safely ignored.
|
||||
//
|
||||
|
||||
// TIDY_EXCLUSION=-cppcoreguidelines-owning-memory
|
||||
//
|
||||
// Reason:
|
||||
// This triggers during the allocation which is part of the test harness
|
||||
// so this can be safely ignored.
|
||||
//
|
||||
|
||||
#include <test_real_elf.h>
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#ifdef WIN64
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
std::vector<std::string> g_filenames = {
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib1.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libdummy_lib2.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfpthread.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfsyscall.a"_s,
|
||||
VMM_PREFIX_PATH + "/lib/libbfunwind.a"_s,
|
||||
VMM_PREFIX_PATH + "/bin/dummy_main"_s
|
||||
};
|
||||
|
||||
file g_file;
|
||||
bool out_of_memory = false;
|
||||
static std::map<const void *, std::shared_ptr<char>> g_memory;
|
||||
|
||||
extern "C" void *
|
||||
platform_alloc_rwe(uint64_t len)
|
||||
{
|
||||
if (out_of_memory) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto addr = aligned_alloc(0x1000, len);
|
||||
g_memory[addr] = std::shared_ptr<char>(static_cast<char *>(addr), free);
|
||||
|
||||
#ifdef WIN64
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(addr, len, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
#else
|
||||
mprotect(addr, len, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
#endif
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
platform_free_rwe(void *addr, uint64_t len)
|
||||
{
|
||||
bfignored(len);
|
||||
g_memory.erase(addr);
|
||||
}
|
||||
|
||||
extern "C" void *
|
||||
platform_memset(void *ptr, char value, uint64_t num)
|
||||
{ return memset(ptr, value, num); }
|
||||
|
||||
extern "C" int64_t
|
||||
platform_memcpy(
|
||||
void *dst, uint64_t dst_size, const void *src, uint64_t src_size, uint64_t num)
|
||||
{
|
||||
bfignored(dst_size);
|
||||
bfignored(src_size);
|
||||
|
||||
memcpy(dst, src, num);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef TEST_REAL_ELF_H
|
||||
#define TEST_REAL_ELF_H
|
||||
|
||||
#include <bfgsl.h>
|
||||
#include <bffile.h>
|
||||
#include <bfelf_loader.h>
|
||||
|
||||
extern file g_file;
|
||||
extern bool out_of_memory;
|
||||
extern std::vector<std::string> g_filenames;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <hippomocks.h>
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <bfgsl.h>
|
||||
#include <test_real_elf.h>
|
||||
|
||||
TEST_CASE("bfelf_set_args: invalid info")
|
||||
{
|
||||
int argc = 0;
|
||||
const char *argv = nullptr;
|
||||
|
||||
auto ret = bfelf_set_args(nullptr, argc, &argv);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_set_args: success")
|
||||
{
|
||||
int argc = 0;
|
||||
crt_info_t info = {};
|
||||
const char *argv = nullptr;
|
||||
|
||||
auto ret = bfelf_set_args(&info, argc, &argv);
|
||||
CHECK(ret == BF_SUCCESS);
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <hippomocks.h>
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
#include <bfgsl.h>
|
||||
#include <test_real_elf.h>
|
||||
|
||||
TEST_CASE("bfelf_set_integer_args: invalid info")
|
||||
{
|
||||
auto ret = bfelf_set_integer_args(nullptr, 0, 0, 0, 0);
|
||||
CHECK(ret == BFELF_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
TEST_CASE("bfelf_set_integer_args: success")
|
||||
{
|
||||
crt_info_t info = {};
|
||||
|
||||
auto ret = bfelf_set_integer_args(&info, 0, 0, 0, 0);
|
||||
CHECK(ret == BF_SUCCESS);
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
#
|
||||
# Copyright (C) 2019 Assured Information Security, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(bfintrinsics C CXX)
|
||||
|
||||
init_project(bfintrinsics)
|
||||
|
||||
set(X64 $<STREQUAL:${BUILD_TARGET_ARCH},x86_64>)
|
||||
|
||||
target_link_libraries(bfintrinsics PUBLIC ${PREFIX}::bfroot)
|
||||
target_sources(bfintrinsics PRIVATE
|
||||
$<${X64}:src/arch/x64/cache.asm>
|
||||
$<${X64}:src/arch/x64/cpuid.asm>
|
||||
$<${X64}:src/arch/x64/gdt.asm>
|
||||
$<${X64}:src/arch/x64/idt.asm>
|
||||
$<${X64}:src/arch/x64/msrs.asm>
|
||||
$<${X64}:src/arch/x64/pm.asm>
|
||||
$<${X64}:src/arch/x64/portio.asm>
|
||||
$<${X64}:src/arch/x64/rdtsc.asm>
|
||||
$<${X64}:src/arch/x64/rflags.asm>
|
||||
$<${X64}:src/arch/x64/srs.asm>
|
||||
$<${X64}:src/arch/x64/tlb.asm>
|
||||
$<${X64}:src/arch/intel_x64/barrier.asm>
|
||||
$<${X64}:src/arch/intel_x64/bit.asm>
|
||||
$<${X64}:src/arch/intel_x64/crs.asm>
|
||||
$<${X64}:src/arch/intel_x64/drs.asm>
|
||||
$<${X64}:src/arch/intel_x64/pause.asm>
|
||||
$<${X64}:src/arch/intel_x64/vmx.asm>
|
||||
)
|
||||
|
||||
if(PREFIX STREQUAL vmm)
|
||||
install(DIRECTORY include/ DESTINATION include)
|
||||
endif()
|
||||
|
||||
fini_project()
|
||||
|
|
@ -1,424 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef IOAPIC_INTEL_X64_H
|
||||
#define IOAPIC_INTEL_X64_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <bfdebug.h>
|
||||
#include <bfbitmanip.h>
|
||||
|
||||
#include "lapic.h"
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
|
||||
/// IOAPIC intrinsics
|
||||
///
|
||||
/// The IOAPIC is memory-mapped to 0xFEC0000 by default, though
|
||||
/// it may be relocated. Like the xAPIC, it is accessed in 32-bit
|
||||
/// loads and stores.
|
||||
///
|
||||
/// Each data register is identified by a positive 8-bit id
|
||||
/// (called its offset). To read/write a data register, its
|
||||
/// id is written to the IOREGSEL control register. Once written,
|
||||
/// its data may be accessed through the IOREGWIN control register.
|
||||
///
|
||||
/// Note that IOREGSEL and IOREGWIN are the only IOAPIC registers directly
|
||||
/// accessible from software - all other registers are accessed through
|
||||
/// these two.
|
||||
///
|
||||
/// See chapter 3 of the IOAPIC spec for more details
|
||||
///
|
||||
namespace ioapic
|
||||
{
|
||||
/// @cond
|
||||
|
||||
using offset_t = uint8_t;
|
||||
using value_t = uint32_t;
|
||||
using base_t = uintptr_t;
|
||||
using rte_t = uint64_t;
|
||||
|
||||
/// First RTE index
|
||||
constexpr const auto rte_begin = 0x10U;
|
||||
|
||||
/// One-past-the-end of last RTE index
|
||||
constexpr const auto rte_end = 0x40U;
|
||||
|
||||
/// Align an arbitrary address to 16 bytes, which is
|
||||
/// required of ioapic base addresses
|
||||
inline auto align_base(const base_t addr)
|
||||
{ return addr & 0xFFFFFFFFFFFFFFF0ULL; }
|
||||
|
||||
namespace id
|
||||
{
|
||||
constexpr const auto offset = 0U;
|
||||
constexpr const auto default_val = 0U;
|
||||
constexpr const auto mask = 0x0F000000U;
|
||||
constexpr const auto from = 24U;
|
||||
constexpr const auto name = "id";
|
||||
|
||||
inline value_t get(value_t reg)
|
||||
{ return get_bits(reg, mask) >> from; }
|
||||
|
||||
inline void set(value_t ®, value_t id)
|
||||
{ reg = set_bits(reg, mask, (id << from)); }
|
||||
|
||||
inline void dump(int level, value_t ®, std::string *msg = nullptr)
|
||||
{ bfdebug_subnhex(level, name, get(reg), msg); }
|
||||
}
|
||||
|
||||
namespace ver
|
||||
{
|
||||
constexpr const auto offset = 1U;
|
||||
constexpr const auto default_val = 0x00170011U;
|
||||
constexpr const auto name = "ver";
|
||||
|
||||
namespace version
|
||||
{
|
||||
constexpr const auto mask = 0xFFU;
|
||||
constexpr const auto from = 0U;
|
||||
constexpr const auto name = "version";
|
||||
|
||||
inline value_t get(value_t reg)
|
||||
{ return get_bits(reg, mask) >> from; }
|
||||
|
||||
inline void set(value_t ®, value_t ver)
|
||||
{ reg = set_bits(reg, mask, (ver << from)); }
|
||||
|
||||
inline void dump(int level, value_t ®, std::string *msg = nullptr)
|
||||
{ bfdebug_subndec(level, name, get(reg), msg); }
|
||||
}
|
||||
|
||||
namespace max_rte_number
|
||||
{
|
||||
constexpr const auto mask = 0xFF0000U;
|
||||
constexpr const auto from = 16U;
|
||||
constexpr const auto name = "max_rte_number";
|
||||
|
||||
inline value_t get(value_t reg)
|
||||
{ return get_bits(reg, mask) >> from; }
|
||||
|
||||
inline void set(value_t ®, value_t ver)
|
||||
{ reg = set_bits(reg, mask, (ver << from)); }
|
||||
|
||||
inline void dump(int level, value_t ®, std::string *msg = nullptr)
|
||||
{ bfdebug_subndec(level, name, get(reg), msg); }
|
||||
}
|
||||
|
||||
inline void dump(int level, value_t ®, std::string *msg = nullptr)
|
||||
{
|
||||
version::dump(level, reg, msg);
|
||||
max_rte_number::dump(level, reg, msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace arb
|
||||
{
|
||||
constexpr const auto offset = 2U;
|
||||
constexpr const auto default_val = 0x0U;
|
||||
constexpr const auto name = "arb";
|
||||
|
||||
namespace id
|
||||
{
|
||||
constexpr const auto mask = 0x0F000000U;
|
||||
constexpr const auto from = 24U;
|
||||
constexpr const auto name = "id";
|
||||
|
||||
inline value_t get(value_t reg)
|
||||
{ return get_bits(reg, mask) >> from; }
|
||||
|
||||
inline void set(value_t ®, value_t arb)
|
||||
{ reg = set_bits(reg, mask, (arb << from)); }
|
||||
|
||||
inline void dump(int level, value_t ®, std::string *msg = nullptr)
|
||||
{ bfdebug_subndec(level, name, get(reg), msg); }
|
||||
}
|
||||
|
||||
inline void dump(int level, value_t ®, std::string *msg = nullptr)
|
||||
{ id::dump(level, reg, msg); }
|
||||
}
|
||||
|
||||
namespace rte
|
||||
{
|
||||
constexpr const auto name = "rte";
|
||||
constexpr const auto count = 24U;
|
||||
|
||||
namespace vector
|
||||
{
|
||||
constexpr const auto mask = 0x00000000000000FFULL;
|
||||
constexpr const auto from = 0U;
|
||||
constexpr const auto name = "vector";
|
||||
constexpr const auto min = 0x10U;
|
||||
constexpr const auto max = 0xFEU;
|
||||
|
||||
inline auto get(rte_t val) noexcept
|
||||
{ return get_bits(val, mask) >> from; }
|
||||
|
||||
inline void set(rte_t ®, rte_t val) noexcept
|
||||
{ reg = set_bits(reg, mask, val << from); }
|
||||
|
||||
inline void dump(int lev, rte_t &val, std::string *msg = nullptr)
|
||||
{ bfdebug_subnhex(lev, name, get(val), msg); }
|
||||
}
|
||||
|
||||
namespace delivery_mode
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000700ULL;
|
||||
constexpr const auto from = 8U;
|
||||
constexpr const auto name = "delivery_mode";
|
||||
|
||||
constexpr const auto fixed = 0U;
|
||||
constexpr const auto lowest_priority = 1U;
|
||||
constexpr const auto smi = 2U;
|
||||
constexpr const auto nmi = 4U;
|
||||
constexpr const auto init = 5U;
|
||||
constexpr const auto extint = 7U;
|
||||
|
||||
inline auto get(rte_t val) noexcept
|
||||
{ return get_bits(val, mask) >> from; }
|
||||
|
||||
inline void set(rte_t ®, rte_t val) noexcept
|
||||
{ reg = set_bits(reg, mask, val << from); }
|
||||
|
||||
inline void dump(int lev, rte_t &val, std::string *msg = nullptr)
|
||||
{
|
||||
const auto mode = get(val);
|
||||
if (mode == lowest_priority) {
|
||||
bfdebug_subtext(lev, name, "lowest_priority", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
::intel_x64::lapic::dump_lvt_delivery_mode(lev, get(val), msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace destination_mode
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000800ULL;
|
||||
constexpr const auto from = 11U;
|
||||
constexpr const auto name = "destination_mode";
|
||||
|
||||
constexpr const auto physical = 0U;
|
||||
constexpr const auto logical = 1U;
|
||||
|
||||
inline auto get(rte_t val) noexcept
|
||||
{ return get_bits(val, mask) >> from; }
|
||||
|
||||
inline void set(rte_t ®, rte_t val) noexcept
|
||||
{ reg = set_bits(reg, mask, val << from); }
|
||||
|
||||
inline void dump(int lev, rte_t &val, std::string *msg = nullptr)
|
||||
{
|
||||
if (get(val) == physical) {
|
||||
bfdebug_subtext(lev, name, "physical", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
bfdebug_subtext(lev, name, "logical", msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace delivery_status
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000001000ULL;
|
||||
constexpr const auto from = 12U;
|
||||
constexpr const auto name = "delivery_status";
|
||||
|
||||
constexpr const auto idle = 0U;
|
||||
constexpr const auto send_pending = 1U;
|
||||
|
||||
inline auto get(rte_t val) noexcept
|
||||
{ return get_bits(val, mask) >> from; }
|
||||
|
||||
inline void set(rte_t ®, rte_t val) noexcept
|
||||
{ reg = set_bits(reg, mask, val << from); }
|
||||
|
||||
inline void dump(int lev, rte_t &val, std::string *msg = nullptr)
|
||||
{ ::intel_x64::lapic::dump_delivery_status(lev, get(val), msg); }
|
||||
}
|
||||
|
||||
namespace polarity
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000002000ULL;
|
||||
constexpr const auto from = 13U;
|
||||
constexpr const auto name = "polarity";
|
||||
|
||||
constexpr const auto active_high = 0U;
|
||||
constexpr const auto active_low = 1U;
|
||||
|
||||
inline auto get(rte_t val) noexcept
|
||||
{ return get_bits(val, mask) >> from; }
|
||||
|
||||
inline void set(rte_t ®, rte_t val) noexcept
|
||||
{ reg = set_bits(reg, mask, val << from); }
|
||||
|
||||
inline void dump(int lev, rte_t &val, std::string *msg = nullptr)
|
||||
{
|
||||
if (get(val) == active_high) {
|
||||
bfdebug_subtext(lev, name, "active_high", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
bfdebug_subtext(lev, name, "active_low", msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace remote_irr
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000004000ULL;
|
||||
constexpr const auto from = 14U;
|
||||
constexpr const auto name = "remote_irr";
|
||||
|
||||
inline auto is_enabled(rte_t val)
|
||||
{ return is_bit_set(val, from); }
|
||||
|
||||
inline auto is_disabled(rte_t val)
|
||||
{ return is_bit_cleared(val, from); }
|
||||
|
||||
inline void enable(rte_t &val)
|
||||
{ val = set_bit(val, from); }
|
||||
|
||||
inline void disable(rte_t &val)
|
||||
{ val = clear_bit(val, from); }
|
||||
|
||||
inline void dump(int lev, rte_t &val, std::string *msg = nullptr)
|
||||
{ bfdebug_subbool(lev, name, is_enabled(val), msg); }
|
||||
}
|
||||
|
||||
namespace trigger_mode
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000008000ULL;
|
||||
constexpr const auto from = 15U;
|
||||
constexpr const auto name = "trigger_mode";
|
||||
|
||||
constexpr const auto edge = 0U;
|
||||
constexpr const auto level = 1U;
|
||||
|
||||
inline auto get(rte_t val) noexcept
|
||||
{ return get_bits(val, mask) >> from; }
|
||||
|
||||
inline void set(rte_t ®, rte_t val) noexcept
|
||||
{ reg = set_bits(reg, mask, val << from); }
|
||||
|
||||
inline void dump(int lev, rte_t &val, std::string *msg = nullptr)
|
||||
{
|
||||
if (get(val) == edge) {
|
||||
bfdebug_subtext(lev, name, "edge", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
bfdebug_subtext(lev, name, "level", msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace mask_bit
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000010000ULL;
|
||||
constexpr const auto from = 16U;
|
||||
constexpr const auto name = "mask_bit";
|
||||
|
||||
inline auto is_enabled(rte_t val)
|
||||
{ return is_bit_set(val, from); }
|
||||
|
||||
inline auto is_disabled(rte_t val)
|
||||
{ return is_bit_cleared(val, from); }
|
||||
|
||||
inline void enable(rte_t &val)
|
||||
{ val = set_bit(val, from); }
|
||||
|
||||
inline void disable(rte_t &val)
|
||||
{ val = clear_bit(val, from); }
|
||||
|
||||
inline void dump(int lev, rte_t &val, std::string *msg = nullptr)
|
||||
{ bfdebug_subbool(lev, name, is_enabled(val), msg); }
|
||||
}
|
||||
|
||||
namespace logical_destination
|
||||
{
|
||||
constexpr const auto mask = 0xFF00000000000000ULL;
|
||||
constexpr const auto from = 56U;
|
||||
constexpr const auto name = "logical_destination";
|
||||
|
||||
inline auto get(rte_t val) noexcept
|
||||
{ return get_bits(val, mask) >> from; }
|
||||
|
||||
inline void set(rte_t ®, rte_t val) noexcept
|
||||
{ reg = set_bits(reg, mask, val << from); }
|
||||
|
||||
inline void dump(int lev, rte_t &val, std::string *msg = nullptr)
|
||||
{ bfdebug_subnhex(lev, name, get(val), msg); }
|
||||
}
|
||||
|
||||
namespace physical_destination
|
||||
{
|
||||
constexpr const auto mask = 0x0F00000000000000ULL;
|
||||
constexpr const auto from = 56U;
|
||||
constexpr const auto name = "physical_destination";
|
||||
|
||||
inline auto get(rte_t val) noexcept
|
||||
{ return get_bits(val, mask) >> from; }
|
||||
|
||||
inline void set(rte_t ®, rte_t val) noexcept
|
||||
{ reg = set_bits(reg, mask, val << from); }
|
||||
|
||||
inline void dump(int lev, rte_t &val, std::string *msg = nullptr)
|
||||
{ bfdebug_subnhex(lev, name, get(val), msg); }
|
||||
}
|
||||
|
||||
inline void dump(int lev, rte_t &val, std::string *msg = nullptr)
|
||||
{
|
||||
bfdebug_nhex(lev, name, val, msg);
|
||||
vector::dump(lev, val, msg);
|
||||
delivery_status::dump(lev, val, msg);
|
||||
polarity::dump(lev, val, msg);
|
||||
remote_irr::dump(lev, val, msg);
|
||||
trigger_mode::dump(lev, val, msg);
|
||||
mask_bit::dump(lev, val, msg);
|
||||
logical_destination::dump(lev, val, msg);
|
||||
physical_destination::dump(lev, val, msg);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool exists(const offset_t offset)
|
||||
{ return (offset < 0x3U) || (offset >= rte_begin && offset < rte_end); }
|
||||
|
||||
inline bool is_read_only(const offset_t offset)
|
||||
{ return offset == ver::offset || offset == arb::offset; }
|
||||
|
||||
inline bool is_read_write(const offset_t offset)
|
||||
{ return exists(offset) && !is_read_only(offset); }
|
||||
|
||||
inline bool is_readable(const offset_t offset)
|
||||
{ return is_read_write(offset) || is_read_only(offset); }
|
||||
|
||||
inline bool is_writable(const offset_t offset)
|
||||
{ return is_read_write(offset); }
|
||||
|
||||
/// @endcond
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
|
|
@ -1,282 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef INTRINSICS_LAPIC_INTEL_X64_H
|
||||
#define INTRINSICS_LAPIC_INTEL_X64_H
|
||||
|
||||
#include <arch/intel_x64/msrs.h>
|
||||
#include <arch/intel_x64/cpuid.h>
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
using value_type = ::x64::msrs::value_type;
|
||||
|
||||
namespace msrs
|
||||
{
|
||||
namespace ia32_apic_base
|
||||
{
|
||||
constexpr const auto addr = 0x0000001BU;
|
||||
constexpr const auto name = "ia32_apic_base";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _read_msr(addr); }
|
||||
|
||||
inline void set(value_type val) noexcept
|
||||
{ _write_msr(addr, val); }
|
||||
|
||||
namespace bsp
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000100ULL;
|
||||
constexpr const auto from = 8ULL;
|
||||
constexpr const auto name = "bsp";
|
||||
|
||||
inline auto is_enabled()
|
||||
{ return is_bit_set(_read_msr(addr), from); }
|
||||
|
||||
inline auto is_enabled(value_type msr)
|
||||
{ return is_bit_set(msr, from); }
|
||||
|
||||
inline auto is_disabled()
|
||||
{ return is_bit_cleared(_read_msr(addr), from); }
|
||||
|
||||
inline auto is_disabled(value_type msr)
|
||||
{ return is_bit_cleared(msr, from); }
|
||||
|
||||
inline void enable()
|
||||
{ _write_msr(addr, set_bit(_read_msr(addr), from)); }
|
||||
|
||||
inline void enable(value_type &msr)
|
||||
{ msr = set_bit(msr, from); }
|
||||
|
||||
inline void disable()
|
||||
{ _write_msr(addr, clear_bit(_read_msr(addr), from)); }
|
||||
|
||||
inline void disable(value_type &msr)
|
||||
{ msr = clear_bit(msr, from); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_subbool(level, name, is_enabled(), msg); }
|
||||
|
||||
inline void dump(int level, value_type val, std::string *msg = nullptr)
|
||||
{ bfdebug_subbool(level, name, is_enabled(val), msg); }
|
||||
}
|
||||
|
||||
namespace extd
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000400ULL;
|
||||
constexpr const auto from = 10ULL;
|
||||
constexpr const auto name = "extd";
|
||||
|
||||
inline auto is_enabled()
|
||||
{ return is_bit_set(_read_msr(addr), from); }
|
||||
|
||||
inline auto is_enabled(value_type msr)
|
||||
{ return is_bit_set(msr, from); }
|
||||
|
||||
inline auto is_disabled()
|
||||
{ return is_bit_cleared(_read_msr(addr), from); }
|
||||
|
||||
inline auto is_disabled(value_type msr)
|
||||
{ return is_bit_cleared(msr, from); }
|
||||
|
||||
inline void enable()
|
||||
{ _write_msr(addr, set_bit(_read_msr(addr), from)); }
|
||||
|
||||
inline void enable(value_type &msr)
|
||||
{ msr = set_bit(msr, from); }
|
||||
|
||||
inline void disable()
|
||||
{ _write_msr(addr, clear_bit(_read_msr(addr), from)); }
|
||||
|
||||
inline void disable(value_type &msr)
|
||||
{ msr = clear_bit(msr, from); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_subbool(level, name, is_enabled(), msg); }
|
||||
|
||||
inline void dump(int level, value_type val, std::string *msg = nullptr)
|
||||
{ bfdebug_subbool(level, name, is_enabled(val), msg); }
|
||||
}
|
||||
|
||||
namespace en
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000800ULL;
|
||||
constexpr const auto from = 11ULL;
|
||||
constexpr const auto name = "en";
|
||||
|
||||
inline auto is_enabled()
|
||||
{ return is_bit_set(_read_msr(addr), from); }
|
||||
|
||||
inline auto is_enabled(value_type msr)
|
||||
{ return is_bit_set(msr, from); }
|
||||
|
||||
inline auto is_disabled()
|
||||
{ return is_bit_cleared(_read_msr(addr), from); }
|
||||
|
||||
inline auto is_disabled(value_type msr)
|
||||
{ return is_bit_cleared(msr, from); }
|
||||
|
||||
inline void enable()
|
||||
{ _write_msr(addr, set_bit(_read_msr(addr), from)); }
|
||||
|
||||
inline void enable(value_type &msr)
|
||||
{ msr = set_bit(msr, from); }
|
||||
|
||||
inline void disable()
|
||||
{ _write_msr(addr, clear_bit(_read_msr(addr), from)); }
|
||||
|
||||
inline void disable(value_type &msr)
|
||||
{ msr = clear_bit(msr, from); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_subbool(level, name, is_enabled(), msg); }
|
||||
|
||||
inline void dump(int level, value_type val, std::string *msg = nullptr)
|
||||
{ bfdebug_subbool(level, name, is_enabled(val), msg); }
|
||||
}
|
||||
|
||||
///
|
||||
/// NOTE: `state` is a combination field of `extd` and `en` to facilitate
|
||||
/// atomic apic state changes and to provide a simplified interface
|
||||
///
|
||||
namespace state
|
||||
{
|
||||
constexpr const auto mask = 0xC00ULL;
|
||||
constexpr const auto from = 10ULL;
|
||||
constexpr const auto name = "state";
|
||||
|
||||
constexpr const auto disabled = 0x0ULL;
|
||||
constexpr const auto invalid = 0x1ULL;
|
||||
constexpr const auto xapic = 0x2ULL;
|
||||
constexpr const auto x2apic = 0x3ULL;
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return get_bits(_read_msr(addr), mask) >> from; }
|
||||
|
||||
inline auto get(value_type msr) noexcept
|
||||
{ return get_bits(msr, mask) >> from; }
|
||||
|
||||
inline void set(value_type val) noexcept
|
||||
{ _write_msr(addr, set_bits(_read_msr(addr), mask, val << from)); }
|
||||
|
||||
inline void set(value_type &msr, value_type val) noexcept
|
||||
{ msr = set_bits(msr, mask, val << from); }
|
||||
|
||||
inline void enable_x2apic() noexcept
|
||||
{ set(x2apic); }
|
||||
|
||||
inline void enable_x2apic(value_type &msr) noexcept
|
||||
{ msr = set_bits(msr, mask, x2apic << from); }
|
||||
|
||||
inline void enable_xapic() noexcept
|
||||
{ set(xapic); }
|
||||
|
||||
inline void enable_xapic(value_type &msr) noexcept
|
||||
{ msr = set_bits(msr, mask, xapic << from); }
|
||||
|
||||
inline void disable() noexcept
|
||||
{ set(disabled); }
|
||||
|
||||
inline void disable(value_type &msr) noexcept
|
||||
{ msr = set_bits(msr, mask, disabled << from); }
|
||||
|
||||
inline void dump(int level, value_type val, std::string *msg = nullptr)
|
||||
{
|
||||
switch (val) {
|
||||
case x2apic:
|
||||
bfdebug_subtext(level, name, "x2apic", msg);
|
||||
return;
|
||||
case xapic:
|
||||
bfdebug_subtext(level, name, "xapic", msg);
|
||||
return;
|
||||
case disabled:
|
||||
bfdebug_subtext(level, name, "disabled", msg);
|
||||
return;
|
||||
case invalid:
|
||||
bfdebug_subtext(level, name, "invalid", msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump(level, get(), msg); }
|
||||
}
|
||||
|
||||
namespace apic_base
|
||||
{
|
||||
constexpr const auto mask = 0x0000000FFFFFF000ULL;
|
||||
constexpr const auto from = 12ULL;
|
||||
constexpr const auto name = "apic_base";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return get_bits(_read_msr(addr), mask); }
|
||||
|
||||
inline auto get(value_type msr) noexcept
|
||||
{ return get_bits(msr, mask); }
|
||||
|
||||
inline void set(value_type val) noexcept
|
||||
{ _write_msr(addr, set_bits(_read_msr(addr), mask, val)); }
|
||||
|
||||
inline void set(value_type &msr, value_type val) noexcept
|
||||
{ msr = set_bits(msr, mask, val); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_subnhex(level, name, get(), msg); }
|
||||
|
||||
inline void dump(int level, value_type val, std::string *msg = nullptr)
|
||||
{ bfdebug_subnhex(level, name, val, msg); }
|
||||
|
||||
}
|
||||
|
||||
inline void dump(int level, value_type val, std::string *msg = nullptr)
|
||||
{
|
||||
bfdebug_nhex(level, name, val, msg);
|
||||
bsp::dump(level, val, msg);
|
||||
extd::dump(level, val, msg);
|
||||
en::dump(level, val, msg);
|
||||
state::dump(level, val, msg);
|
||||
apic_base::dump(level, val, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace lapic
|
||||
{
|
||||
|
||||
/// Is present
|
||||
///
|
||||
/// @expects
|
||||
/// @ensures
|
||||
///
|
||||
/// @return true if a LAPIC is available on the platform
|
||||
/// @return false if a LAPIC is not available on the platform
|
||||
///
|
||||
inline auto is_present() noexcept
|
||||
{ return ::intel_x64::cpuid::feature_information::edx::apic::is_enabled(); }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,49 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef BARRIER_INTEL_X64_H
|
||||
#define BARRIER_INTEL_X64_H
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Definitions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
extern "C" void _rmb(void) noexcept;
|
||||
extern "C" void _wmb(void) noexcept;
|
||||
extern "C" void _mb(void) noexcept;
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64::barrier
|
||||
{
|
||||
inline void rmb() noexcept
|
||||
{ _rmb(); }
|
||||
|
||||
inline void wmb() noexcept
|
||||
{ _wmb(); }
|
||||
|
||||
inline void mb() noexcept
|
||||
{ _mb(); }
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef BIT_INTEL_X64_H
|
||||
#define BIT_INTEL_X64_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Definitions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
extern "C" uint64_t _bsf(uint64_t value) noexcept;
|
||||
extern "C" uint64_t _bsr(uint64_t value) noexcept;
|
||||
extern "C" uint64_t _popcnt(uint64_t value) noexcept;
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
namespace bit
|
||||
{
|
||||
inline uint64_t bsf(uint64_t value) noexcept
|
||||
{ return _bsf(value); }
|
||||
|
||||
inline uint64_t bsr(uint64_t value) noexcept
|
||||
{ return _bsr(value); }
|
||||
|
||||
inline uint64_t popcnt(uint64_t value) noexcept
|
||||
{ return _popcnt(value); }
|
||||
}
|
||||
}
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,50 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef DRS_INTEL_X64_H
|
||||
#define DRS_INTEL_X64_H
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Definitions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
extern "C" uint64_t _read_dr7(void) noexcept;
|
||||
extern "C" void _write_dr7(uint64_t val) noexcept;
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
namespace dr7
|
||||
{
|
||||
using value_type = uint64_t;
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _read_dr7(); }
|
||||
|
||||
inline void set(value_type val) noexcept
|
||||
{ _write_dr7(val); }
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
|
|
@ -1,890 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef EPT_INTEL_X64_H
|
||||
#define EPT_INTEL_X64_H
|
||||
|
||||
#include <bfdebug.h>
|
||||
#include <bfbitmanip.h>
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
namespace ept
|
||||
{
|
||||
|
||||
namespace pml4
|
||||
{
|
||||
constexpr const auto num_entries = 512;
|
||||
|
||||
constexpr const auto from = 39U;
|
||||
constexpr const auto size = num_entries * sizeof(uintptr_t);
|
||||
|
||||
inline auto index(uintptr_t virt)
|
||||
{
|
||||
return gsl::narrow_cast<std::ptrdiff_t>(
|
||||
(virt & ((0x1FFULL) << from)) >> from
|
||||
);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename = std::enable_if<std::is_pointer<T>::value >
|
||||
>
|
||||
auto index(T virt)
|
||||
{ return index(reinterpret_cast<uintptr_t>(virt)); }
|
||||
|
||||
namespace entry
|
||||
{
|
||||
using value_type = uint64_t;
|
||||
|
||||
namespace read_access
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000001ULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "read_access";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace write_access
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000002ULL;
|
||||
constexpr const auto from = 1ULL;
|
||||
constexpr const auto name = "write_access";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace execute_access
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000004ULL;
|
||||
constexpr const auto from = 2ULL;
|
||||
constexpr const auto name = "execute_access";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace accessed_flag
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000100ULL;
|
||||
constexpr const auto from = 8ULL;
|
||||
constexpr const auto name = "accessed_flag";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace execute_access_user
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000400ULL;
|
||||
constexpr const auto from = 10ULL;
|
||||
constexpr const auto name = "execute_access_user";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace phys_addr
|
||||
{
|
||||
constexpr const auto mask = 0x0000FFFFFFFFF000ULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "phys_addr";
|
||||
|
||||
inline auto get(value_type &entry) noexcept
|
||||
{ return get_bits(entry, mask) >> from; }
|
||||
|
||||
inline void set(value_type &entry, value_type val) noexcept
|
||||
{ entry = set_bits(entry, mask, val << from); }
|
||||
}
|
||||
|
||||
namespace suppress_ve
|
||||
{
|
||||
constexpr const auto mask = 0x8000000000000000ULL;
|
||||
constexpr const auto from = 63ULL;
|
||||
constexpr const auto name = "suppress_ve";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace pdpt
|
||||
{
|
||||
constexpr const auto num_entries = 512;
|
||||
|
||||
constexpr const auto from = 30U;
|
||||
constexpr const auto size = num_entries * sizeof(uintptr_t);
|
||||
|
||||
constexpr const auto page_size = 0x40000000ULL;
|
||||
|
||||
inline auto index(uintptr_t virt)
|
||||
{
|
||||
return gsl::narrow_cast<std::ptrdiff_t>(
|
||||
(virt & ((0x1FFULL) << from)) >> from
|
||||
);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename = std::enable_if<std::is_pointer<T>::value >
|
||||
>
|
||||
auto index(T virt)
|
||||
{ return index(reinterpret_cast<uintptr_t>(virt)); }
|
||||
|
||||
namespace entry
|
||||
{
|
||||
using value_type = uint64_t;
|
||||
|
||||
namespace read_access
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000001ULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "read_access";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace write_access
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000002ULL;
|
||||
constexpr const auto from = 1ULL;
|
||||
constexpr const auto name = "write_access";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace execute_access
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000004ULL;
|
||||
constexpr const auto from = 2ULL;
|
||||
constexpr const auto name = "execute_access";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace memory_type
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000038ULL;
|
||||
constexpr const auto from = 3ULL;
|
||||
constexpr const auto name = "memory_type";
|
||||
|
||||
constexpr const auto uncacheable = 0x0ULL;
|
||||
constexpr const auto write_combining = 0x1ULL;
|
||||
constexpr const auto write_through = 0x4ULL;
|
||||
constexpr const auto write_protected = 0x5ULL;
|
||||
constexpr const auto write_back = 0x6ULL;
|
||||
|
||||
inline auto get(value_type &entry) noexcept
|
||||
{ return get_bits(entry, mask) >> from; }
|
||||
|
||||
inline void set(value_type &entry, value_type val) noexcept
|
||||
{ entry = set_bits(entry, mask, val << from); }
|
||||
}
|
||||
|
||||
namespace ignore_pat
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000040ULL;
|
||||
constexpr const auto from = 6ULL;
|
||||
constexpr const auto name = "ignore_pat";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace ps
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000080ULL;
|
||||
constexpr const auto from = 7ULL;
|
||||
constexpr const auto name = "ps";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace accessed_flag
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000100ULL;
|
||||
constexpr const auto from = 8ULL;
|
||||
constexpr const auto name = "accessed_flag";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace dirty
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000200ULL;
|
||||
constexpr const auto from = 9ULL;
|
||||
constexpr const auto name = "dirty";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace execute_access_user
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000400ULL;
|
||||
constexpr const auto from = 10ULL;
|
||||
constexpr const auto name = "execute_access_user";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace phys_addr
|
||||
{
|
||||
constexpr const auto mask = 0x0000FFFFFFFFF000ULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "phys_addr";
|
||||
|
||||
inline auto get(value_type &entry) noexcept
|
||||
{ return get_bits(entry, mask) >> from; }
|
||||
|
||||
inline void set(value_type &entry, value_type val) noexcept
|
||||
{ entry = set_bits(entry, mask, val << from); }
|
||||
}
|
||||
|
||||
namespace suppress_ve
|
||||
{
|
||||
constexpr const auto mask = 0x8000000000000000ULL;
|
||||
constexpr const auto from = 63ULL;
|
||||
constexpr const auto name = "suppress_ve";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace pd
|
||||
{
|
||||
constexpr const auto num_entries = 512;
|
||||
|
||||
constexpr const auto from = 21U;
|
||||
constexpr const auto size = num_entries * sizeof(uintptr_t);
|
||||
|
||||
constexpr const auto page_size = 0x200000ULL;
|
||||
|
||||
inline auto index(uintptr_t virt)
|
||||
{
|
||||
return gsl::narrow_cast<std::ptrdiff_t>(
|
||||
(virt & ((0x1FFULL) << from)) >> from
|
||||
);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename = std::enable_if<std::is_pointer<T>::value >
|
||||
>
|
||||
auto index(T virt)
|
||||
{ return index(reinterpret_cast<uintptr_t>(virt)); }
|
||||
|
||||
namespace entry
|
||||
{
|
||||
using value_type = uint64_t;
|
||||
|
||||
namespace read_access
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000001ULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "read_access";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace write_access
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000002ULL;
|
||||
constexpr const auto from = 1ULL;
|
||||
constexpr const auto name = "write_access";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace execute_access
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000004ULL;
|
||||
constexpr const auto from = 2ULL;
|
||||
constexpr const auto name = "execute_access";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace memory_type
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000038ULL;
|
||||
constexpr const auto from = 3ULL;
|
||||
constexpr const auto name = "memory_type";
|
||||
|
||||
constexpr const auto uncacheable = 0x0ULL;
|
||||
constexpr const auto write_combining = 0x1ULL;
|
||||
constexpr const auto write_through = 0x4ULL;
|
||||
constexpr const auto write_protected = 0x5ULL;
|
||||
constexpr const auto write_back = 0x6ULL;
|
||||
|
||||
inline auto get(value_type &entry) noexcept
|
||||
{ return get_bits(entry, mask) >> from; }
|
||||
|
||||
inline void set(value_type &entry, value_type val) noexcept
|
||||
{ entry = set_bits(entry, mask, val << from); }
|
||||
}
|
||||
|
||||
namespace ignore_pat
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000040ULL;
|
||||
constexpr const auto from = 6ULL;
|
||||
constexpr const auto name = "ignore_pat";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace ps
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000080ULL;
|
||||
constexpr const auto from = 7ULL;
|
||||
constexpr const auto name = "ps";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace accessed_flag
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000100ULL;
|
||||
constexpr const auto from = 8ULL;
|
||||
constexpr const auto name = "accessed_flag";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace dirty
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000200ULL;
|
||||
constexpr const auto from = 9ULL;
|
||||
constexpr const auto name = "dirty";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace execute_access_user
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000400ULL;
|
||||
constexpr const auto from = 10ULL;
|
||||
constexpr const auto name = "execute_access_user";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace phys_addr
|
||||
{
|
||||
constexpr const auto mask = 0x0000FFFFFFFFF000ULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "phys_addr";
|
||||
|
||||
inline auto get(value_type &entry) noexcept
|
||||
{ return get_bits(entry, mask) >> from; }
|
||||
|
||||
inline void set(value_type &entry, value_type val) noexcept
|
||||
{ entry = set_bits(entry, mask, val << from); }
|
||||
}
|
||||
|
||||
namespace suppress_ve
|
||||
{
|
||||
constexpr const auto mask = 0x8000000000000000ULL;
|
||||
constexpr const auto from = 63ULL;
|
||||
constexpr const auto name = "suppress_ve";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace pt
|
||||
{
|
||||
constexpr const auto num_entries = 512;
|
||||
|
||||
constexpr const auto from = 12U;
|
||||
constexpr const auto size = num_entries * sizeof(uintptr_t);
|
||||
|
||||
constexpr const auto page_size = 0x1000ULL;
|
||||
|
||||
inline auto index(uintptr_t virt)
|
||||
{
|
||||
return gsl::narrow_cast<std::ptrdiff_t>(
|
||||
(virt & ((0x1FFULL) << from)) >> from
|
||||
);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename = std::enable_if<std::is_pointer<T>::value >
|
||||
>
|
||||
auto index(T virt)
|
||||
{ return index(reinterpret_cast<uintptr_t>(virt)); }
|
||||
|
||||
namespace entry
|
||||
{
|
||||
using value_type = uint64_t;
|
||||
|
||||
namespace read_access
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000001ULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "read_access";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace write_access
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000002ULL;
|
||||
constexpr const auto from = 1ULL;
|
||||
constexpr const auto name = "write_access";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace execute_access
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000004ULL;
|
||||
constexpr const auto from = 2ULL;
|
||||
constexpr const auto name = "execute_access";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace memory_type
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000038ULL;
|
||||
constexpr const auto from = 3ULL;
|
||||
constexpr const auto name = "memory_type";
|
||||
|
||||
constexpr const auto uncacheable = 0x0ULL;
|
||||
constexpr const auto write_combining = 0x1ULL;
|
||||
constexpr const auto write_through = 0x4ULL;
|
||||
constexpr const auto write_protected = 0x5ULL;
|
||||
constexpr const auto write_back = 0x6ULL;
|
||||
|
||||
inline auto get(value_type &entry) noexcept
|
||||
{ return get_bits(entry, mask) >> from; }
|
||||
|
||||
inline void set(value_type &entry, value_type val) noexcept
|
||||
{ entry = set_bits(entry, mask, val << from); }
|
||||
}
|
||||
|
||||
namespace ignore_pat
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000040ULL;
|
||||
constexpr const auto from = 6ULL;
|
||||
constexpr const auto name = "ignore_pat";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace ps
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000080ULL;
|
||||
constexpr const auto from = 7ULL;
|
||||
constexpr const auto name = "ps";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace accessed_flag
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000100ULL;
|
||||
constexpr const auto from = 8ULL;
|
||||
constexpr const auto name = "accessed_flag";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace dirty
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000200ULL;
|
||||
constexpr const auto from = 9ULL;
|
||||
constexpr const auto name = "dirty";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace execute_access_user
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000400ULL;
|
||||
constexpr const auto from = 10ULL;
|
||||
constexpr const auto name = "execute_access_user";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
|
||||
namespace phys_addr
|
||||
{
|
||||
constexpr const auto mask = 0x0000FFFFFFFFF000ULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "phys_addr";
|
||||
|
||||
inline auto get(value_type &entry) noexcept
|
||||
{ return get_bits(entry, mask) >> from; }
|
||||
|
||||
inline void set(value_type &entry, value_type val) noexcept
|
||||
{ entry = set_bits(entry, mask, val << from); }
|
||||
}
|
||||
|
||||
namespace suppress_ve
|
||||
{
|
||||
constexpr const auto mask = 0x8000000000000000ULL;
|
||||
constexpr const auto from = 63ULL;
|
||||
constexpr const auto name = "suppress_ve";
|
||||
|
||||
inline auto is_enabled(value_type &entry) noexcept
|
||||
{ return is_bit_set(entry, from); }
|
||||
|
||||
inline auto is_disabled(value_type &entry) noexcept
|
||||
{ return !is_bit_set(entry, from); }
|
||||
|
||||
inline void enable(value_type &entry) noexcept
|
||||
{ entry = set_bit(entry, from); }
|
||||
|
||||
inline void disable(value_type &entry) noexcept
|
||||
{ entry = clear_bit(entry, from); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,49 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef PAUSE_INTEL_X64_H
|
||||
#define PAUSE_INTEL_X64_H
|
||||
|
||||
#include <atomic>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Definitions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
extern "C" void _pause(void) noexcept;
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
inline auto pause() noexcept
|
||||
{ _pause(); }
|
||||
|
||||
inline void spin_until_true(std::atomic<bool> &flag) noexcept
|
||||
{ while (!flag) { pause(); } }
|
||||
|
||||
inline void spin_until_false(std::atomic<bool> &flag) noexcept
|
||||
{ while (flag) { pause(); } }
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef VMCS_INTEL_X64_16BIT_CONTROL_FIELDS_H
|
||||
#define VMCS_INTEL_X64_16BIT_CONTROL_FIELDS_H
|
||||
|
||||
#include <arch/intel_x64/vmcs/helpers.h>
|
||||
|
||||
/// Intel x86_64 VMCS 16-Bit Control Fields
|
||||
///
|
||||
/// The following provides the interface for the 16-bit control VMCS
|
||||
/// fields as defined in Appendix B.1.1, Vol. 3 of the Intel Software Developer's
|
||||
/// Manual.
|
||||
///
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
namespace vmcs
|
||||
{
|
||||
|
||||
namespace virtual_processor_identifier
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000000000ULL;
|
||||
constexpr const auto name = "virtual_processor_identifier";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::enable_vpid::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace posted_interrupt_notification_vector
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000000002ULL;
|
||||
constexpr const auto name = "posted_interrupt_notification_vector";
|
||||
|
||||
inline bool exists()
|
||||
{ return msrs::ia32_vmx_true_pinbased_ctls::process_posted_interrupts::is_allowed1(); }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace eptp_index
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000000004ULL;
|
||||
constexpr const auto name = "eptp_index";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::ept_violation_ve::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,70 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef VMCS_INTEL_X64_32BIT_HOST_STATE_FIELD_H
|
||||
#define VMCS_INTEL_X64_32BIT_HOST_STATE_FIELD_H
|
||||
|
||||
#include <arch/intel_x64/vmcs/helpers.h>
|
||||
|
||||
/// Intel x86_64 VMCS 32-bit Host-State Data Fields
|
||||
///
|
||||
/// The following provides the interface for the 32-bit host-state VMCS
|
||||
/// fields as defined in Appendix B.3.4, Vol. 3 of the Intel Software Developer's
|
||||
/// Manual.
|
||||
///
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
namespace vmcs
|
||||
{
|
||||
|
||||
namespace host_ia32_sysenter_cs
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000004C00ULL;
|
||||
constexpr const auto name = "host_ia32_sysenter_cs";
|
||||
|
||||
inline bool exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,957 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef VMCS_INTEL_X64_64BIT_CONTROL_FIELDS_H
|
||||
#define VMCS_INTEL_X64_64BIT_CONTROL_FIELDS_H
|
||||
|
||||
#include <arch/intel_x64/vmcs/helpers.h>
|
||||
|
||||
/// Intel x86_64 VMCS 64-bit Control Fields
|
||||
///
|
||||
/// The following provides the interface for the 64-bit control VMCS
|
||||
/// fields as defined in Appendix B.2.1, Vol. 3 of the Intel Software Developer's
|
||||
/// Manual.
|
||||
///
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
namespace vmcs
|
||||
{
|
||||
|
||||
namespace address_of_io_bitmap_a
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002000ULL;
|
||||
constexpr const auto name = "address_of_io_bitmap_a";
|
||||
|
||||
inline bool exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace address_of_io_bitmap_b
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002002ULL;
|
||||
constexpr const auto name = "address_of_io_bitmap_b";
|
||||
|
||||
inline bool exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace address_of_msr_bitmap
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002004ULL;
|
||||
constexpr const auto name = "address_of_msr_bitmap";
|
||||
|
||||
inline bool exists()
|
||||
{ return msrs::ia32_vmx_true_procbased_ctls::use_msr_bitmap::is_allowed1(); }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace vm_exit_msr_store_address
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002006ULL;
|
||||
constexpr const auto name = "vm_exit_msr_store_address";
|
||||
|
||||
inline bool exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace vm_exit_msr_load_address
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002008ULL;
|
||||
constexpr const auto name = "vm_exit_msr_load_address";
|
||||
|
||||
inline bool exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace vm_entry_msr_load_address
|
||||
{
|
||||
constexpr const auto addr = 0x000000000000200AULL;
|
||||
constexpr const auto name = "vm_entry_msr_load_address";
|
||||
|
||||
inline bool exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace executive_vmcs_pointer
|
||||
{
|
||||
constexpr const auto addr = 0x000000000000200CULL;
|
||||
constexpr const auto name = "executive_vmcs_pointer";
|
||||
|
||||
inline bool exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace pml_address
|
||||
{
|
||||
constexpr const auto addr = 0x000000000000200EULL;
|
||||
constexpr const auto name = "pml_address";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::enable_pml::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace tsc_offset
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002010ULL;
|
||||
constexpr const auto name = "tsc_offset";
|
||||
|
||||
inline bool exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace virtual_apic_address
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002012ULL;
|
||||
constexpr const auto name = "virtual_apic_address";
|
||||
|
||||
inline bool exists()
|
||||
{ return msrs::ia32_vmx_true_procbased_ctls::use_tpr_shadow::is_allowed1(); }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace apic_access_address
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002014ULL;
|
||||
constexpr const auto name = "apic_access_address";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::virtualize_apic_accesses::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace posted_interrupt_descriptor_address
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002016ULL;
|
||||
constexpr const auto name = "posted_interrupt_descriptor_address";
|
||||
|
||||
inline bool exists()
|
||||
{ return msrs::ia32_vmx_true_pinbased_ctls::process_posted_interrupts::is_allowed1(); }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace vm_function_controls
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002018ULL;
|
||||
constexpr const auto name = "vm_function_controls";
|
||||
constexpr const auto msr_addr = 0x00000491U;
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::enable_vm_functions::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
namespace eptp_switching
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000001ULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "eptp_switching";
|
||||
|
||||
inline auto is_enabled()
|
||||
{ return is_bit_set(get_vmcs_field(addr, name, exists()), from); }
|
||||
|
||||
inline auto is_enabled(value_type field)
|
||||
{ return is_bit_set(field, from); }
|
||||
|
||||
inline auto is_enabled_if_exists(bool verbose = false)
|
||||
{ return is_bit_set(get_vmcs_field_if_exists(addr, name, verbose, exists()), from); }
|
||||
|
||||
inline auto is_disabled()
|
||||
{ return is_bit_cleared(get_vmcs_field(addr, name, exists()), from); }
|
||||
|
||||
inline auto is_disabled(value_type field)
|
||||
{ return is_bit_cleared(field, from); }
|
||||
|
||||
inline auto is_disabled_if_exists(bool verbose = false)
|
||||
{ return is_bit_cleared(get_vmcs_field_if_exists(addr, name, verbose, exists()), from); }
|
||||
|
||||
inline void enable()
|
||||
{ set_vmcs_field_bit(addr, from, name, exists()); }
|
||||
|
||||
inline void enable(value_type &field)
|
||||
{ field = set_bit(field, from); }
|
||||
|
||||
inline void enable_if_exists(bool verbose = false)
|
||||
{ set_vmcs_field_bit_if_exists(addr, from, name, verbose, exists()); }
|
||||
|
||||
inline void disable()
|
||||
{ clear_vmcs_field_bit(addr, from, name, exists()); }
|
||||
|
||||
inline void disable(value_type &field)
|
||||
{ field = clear_bit(field, from); }
|
||||
|
||||
inline void disable_if_exists(bool verbose = false)
|
||||
{ clear_vmcs_field_bit_if_exists(addr, from, name, verbose, exists()); }
|
||||
|
||||
inline void set(bool val)
|
||||
{ val ? enable() : disable(); }
|
||||
|
||||
inline void set(value_type &field, bool val)
|
||||
{ val ? enable(field) : disable(field); }
|
||||
|
||||
inline void set_if_exists(bool val, bool verbose = false)
|
||||
{ val ? enable_if_exists(verbose) : disable_if_exists(verbose); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_subbool(level, msg); }
|
||||
}
|
||||
|
||||
namespace reserved
|
||||
{
|
||||
constexpr const auto mask = 0xFFFFFFFFFFFFFFFEULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "reserved";
|
||||
|
||||
inline auto get()
|
||||
{ return get_bits(get_vmcs_field(addr, name, exists()), mask) >> from; }
|
||||
|
||||
inline auto get(value_type field)
|
||||
{ return get_bits(field, mask) >> from; }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_bits(get_vmcs_field_if_exists(addr, name, verbose, exists()), mask) >> from; }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field_bits(val, addr, mask, from, name, exists()); }
|
||||
|
||||
inline void set(value_type &field, value_type val)
|
||||
{ field = set_bits(field, mask, (val << from)); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_bits_if_exists(val, addr, mask, from, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_subnhex(level, msg); }
|
||||
}
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{
|
||||
dump_vmcs_nhex(level, msg);
|
||||
eptp_switching::dump(level, msg);
|
||||
reserved::dump(level, msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace ept_pointer
|
||||
{
|
||||
constexpr const auto addr = 0x000000000000201AULL;
|
||||
constexpr const auto name = "ept_pointer";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::enable_ept::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
namespace memory_type
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000007ULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "memory_type";
|
||||
|
||||
constexpr const auto uncacheable = 0U;
|
||||
constexpr const auto write_back = 6U;
|
||||
|
||||
inline auto get()
|
||||
{ return get_bits(get_vmcs_field(addr, name, exists()), mask) >> from; }
|
||||
|
||||
inline auto get(value_type field)
|
||||
{ return get_bits(field, mask) >> from; }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_bits(get_vmcs_field_if_exists(addr, name, verbose, exists()), mask) >> from; }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field_bits(val, addr, mask, from, name, exists()); }
|
||||
|
||||
inline void set(value_type &field, value_type val)
|
||||
{ field = set_bits(field, mask, (val << from)); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_bits_if_exists(val, addr, mask, from, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_subnhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace page_walk_length_minus_one
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000038ULL;
|
||||
constexpr const auto from = 3ULL;
|
||||
constexpr const auto name = "page_walk_length_minus_one";
|
||||
|
||||
inline auto get()
|
||||
{ return get_bits(get_vmcs_field(addr, name, exists()), mask) >> from; }
|
||||
|
||||
inline auto get(value_type field)
|
||||
{ return get_bits(field, mask) >> from; }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_bits(get_vmcs_field_if_exists(addr, name, verbose, exists()), mask) >> from; }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field_bits(val, addr, mask, from, name, exists()); }
|
||||
|
||||
inline void set(value_type &field, value_type val)
|
||||
{ field = set_bits(field, mask, (val << from)); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_bits_if_exists(val, addr, mask, from, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_subnhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace accessed_and_dirty_flags
|
||||
{
|
||||
constexpr const auto mask = 0x0000000000000040ULL;
|
||||
constexpr const auto from = 6ULL;
|
||||
constexpr const auto name = "accessed_and_dirty_flags";
|
||||
|
||||
inline auto is_enabled()
|
||||
{ return is_bit_set(get_vmcs_field(addr, name, exists()), from); }
|
||||
|
||||
inline auto is_enabled(value_type field)
|
||||
{ return is_bit_set(field, from); }
|
||||
|
||||
inline auto is_enabled_if_exists(bool verbose = false)
|
||||
{ return is_bit_set(get_vmcs_field_if_exists(addr, name, verbose, exists()), from); }
|
||||
|
||||
inline auto is_disabled()
|
||||
{ return is_bit_cleared(get_vmcs_field(addr, name, exists()), from); }
|
||||
|
||||
inline auto is_disabled(value_type field)
|
||||
{ return is_bit_cleared(field, from); }
|
||||
|
||||
inline auto is_disabled_if_exists(bool verbose = false)
|
||||
{ return is_bit_cleared(get_vmcs_field_if_exists(addr, name, verbose, exists()), from); }
|
||||
|
||||
inline void enable()
|
||||
{ set_vmcs_field_bit(addr, from, name, exists()); }
|
||||
|
||||
inline void enable(value_type &field)
|
||||
{ field = set_bit(field, from); }
|
||||
|
||||
inline void enable_if_exists(bool verbose = false)
|
||||
{ set_vmcs_field_bit_if_exists(addr, from, name, verbose, exists()); }
|
||||
|
||||
inline void disable()
|
||||
{ clear_vmcs_field_bit(addr, from, name, exists()); }
|
||||
|
||||
inline void disable(value_type &field)
|
||||
{ field = clear_bit(field, from); }
|
||||
|
||||
inline void disable_if_exists(bool verbose = false)
|
||||
{ clear_vmcs_field_bit_if_exists(addr, from, name, verbose, exists()); }
|
||||
|
||||
inline void set(bool val)
|
||||
{ val ? enable() : disable(); }
|
||||
|
||||
inline void set(value_type &field, bool val)
|
||||
{ val ? enable(field) : disable(field); }
|
||||
|
||||
inline void set_if_exists(bool val, bool verbose = false)
|
||||
{ val ? enable_if_exists(verbose) : disable_if_exists(verbose); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_subbool(level, msg); }
|
||||
}
|
||||
|
||||
namespace phys_addr
|
||||
{
|
||||
constexpr const auto mask = 0x0000FFFFFFFFF000ULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "phys_addr";
|
||||
|
||||
inline auto get()
|
||||
{ return get_bits(get_vmcs_field(addr, name, exists()), mask) >> from; }
|
||||
|
||||
inline auto get(value_type field)
|
||||
{ return get_bits(field, mask) >> from; }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_bits(get_vmcs_field_if_exists(addr, name, verbose, exists()), mask) >> from; }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field_bits(val, addr, mask, from, name, exists()); }
|
||||
|
||||
inline void set(value_type &field, value_type val)
|
||||
{ field = set_bits(field, mask, (val << from)); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_bits_if_exists(val, addr, mask, from, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_subnhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace reserved
|
||||
{
|
||||
constexpr const auto mask = 0xFFFF000000000F80ULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "reserved";
|
||||
|
||||
inline auto get()
|
||||
{ return get_bits(get_vmcs_field(addr, name, exists()), mask) >> from; }
|
||||
|
||||
inline auto get(value_type field)
|
||||
{ return get_bits(field, mask) >> from; }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_bits(get_vmcs_field_if_exists(addr, name, verbose, exists()), mask) >> from; }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field_bits(val, addr, mask, from, name, exists()); }
|
||||
|
||||
inline void set(value_type &field, value_type val)
|
||||
{ field = set_bits(field, mask, (val << from)); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_bits_if_exists(val, addr, mask, from, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_subnhex(level, msg); }
|
||||
}
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{
|
||||
dump_vmcs_nhex(level, msg);
|
||||
memory_type::dump(level, msg);
|
||||
page_walk_length_minus_one::dump(level, msg);
|
||||
accessed_and_dirty_flags::dump(level, msg);
|
||||
phys_addr::dump(level, msg);
|
||||
reserved::dump(level, msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace eoi_exit_bitmap_0
|
||||
{
|
||||
constexpr const auto addr = 0x000000000000201CULL;
|
||||
constexpr const auto name = "eoi_exit_bitmap_0";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::virtual_interrupt_delivery::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace eoi_exit_bitmap_1
|
||||
{
|
||||
constexpr const auto addr = 0x000000000000201EULL;
|
||||
constexpr const auto name = "eoi_exit_bitmap_1";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::virtual_interrupt_delivery::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace eoi_exit_bitmap_2
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002020ULL;
|
||||
constexpr const auto name = "eoi_exit_bitmap_2";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::virtual_interrupt_delivery::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace eoi_exit_bitmap_3
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002022ULL;
|
||||
constexpr const auto name = "eoi_exit_bitmap_3";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::virtual_interrupt_delivery::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace eptp_list_address
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002024ULL;
|
||||
constexpr const auto name = "eptp_list_address";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::enable_vm_functions::is_allowed1() &&
|
||||
msrs::ia32_vmx_vmfunc::eptp_switching::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace vmread_bitmap_address
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002026ULL;
|
||||
constexpr const auto name = "vmread_bitmap_address";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::vmcs_shadowing::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace vmwrite_bitmap_address
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002028ULL;
|
||||
constexpr const auto name = "vmwrite_bitmap_address";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::vmcs_shadowing::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace virtualization_exception_information_address
|
||||
{
|
||||
constexpr const auto addr = 0x000000000000202AULL;
|
||||
constexpr const auto name = "virtualization_exception_information_address";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::ept_violation_ve::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace xss_exiting_bitmap
|
||||
{
|
||||
constexpr const auto addr = 0x000000000000202CULL;
|
||||
constexpr const auto name = "xss_exiting_bitmap";
|
||||
|
||||
inline bool exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::enable_xsaves_xrstors::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace encls_exiting_bitmap
|
||||
{
|
||||
constexpr const auto addr = 0x000000000000202EULL;
|
||||
constexpr const auto name = "encls_exiting_bitmap";
|
||||
|
||||
inline bool exists() noexcept
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::enable_encls_exiting::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace tsc_multiplier
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002032ULL;
|
||||
constexpr const auto name = "tsc_multiplier";
|
||||
|
||||
inline bool exists() noexcept
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::use_tsc_scaling::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,67 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef VMCS_INTEL_X64_64BIT_READ_ONLY_DATA_FIELD_H
|
||||
#define VMCS_INTEL_X64_64BIT_READ_ONLY_DATA_FIELD_H
|
||||
|
||||
#include <arch/intel_x64/vmcs/helpers.h>
|
||||
|
||||
/// Intel x86_64 VMCS 64-bit Read-Only Data Fields
|
||||
///
|
||||
/// The following provides the interface for the 64-bit read-only data VMCS
|
||||
/// fields as defined in Appendix B.2.2, Vol. 3 of the Intel Software Developer's
|
||||
/// Manual.
|
||||
///
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
namespace vmcs
|
||||
{
|
||||
|
||||
namespace guest_physical_address
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000002400ULL;
|
||||
constexpr const auto name = "guest_physical_address";
|
||||
|
||||
inline auto exists()
|
||||
{
|
||||
return msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::is_allowed1() &&
|
||||
msrs::ia32_vmx_procbased_ctls2::enable_ept::is_allowed1();
|
||||
}
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
|
|
@ -1,285 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef VMCS_INTEL_X64_DEBUG_H
|
||||
#define VMCS_INTEL_X64_DEBUG_H
|
||||
|
||||
#include <arch/intel_x64/vmcs/16bit_control_fields.h>
|
||||
#include <arch/intel_x64/vmcs/16bit_guest_state_fields.h>
|
||||
#include <arch/intel_x64/vmcs/16bit_host_state_fields.h>
|
||||
#include <arch/intel_x64/vmcs/32bit_control_fields.h>
|
||||
#include <arch/intel_x64/vmcs/32bit_guest_state_fields.h>
|
||||
#include <arch/intel_x64/vmcs/32bit_host_state_fields.h>
|
||||
#include <arch/intel_x64/vmcs/32bit_read_only_data_fields.h>
|
||||
#include <arch/intel_x64/vmcs/64bit_control_fields.h>
|
||||
#include <arch/intel_x64/vmcs/64bit_guest_state_fields.h>
|
||||
#include <arch/intel_x64/vmcs/64bit_host_state_fields.h>
|
||||
#include <arch/intel_x64/vmcs/64bit_read_only_data_fields.h>
|
||||
#include <arch/intel_x64/vmcs/natural_width_control_fields.h>
|
||||
#include <arch/intel_x64/vmcs/natural_width_guest_state_fields.h>
|
||||
#include <arch/intel_x64/vmcs/natural_width_host_state_fields.h>
|
||||
#include <arch/intel_x64/vmcs/natural_width_read_only_data_fields.h>
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
namespace vmcs
|
||||
{
|
||||
|
||||
namespace debug
|
||||
{
|
||||
inline void dump(int level = 0)
|
||||
{
|
||||
bfdebug_transaction(level, [&](std::string * msg) {
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "16bit control fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
virtual_processor_identifier::dump(level, msg);
|
||||
posted_interrupt_notification_vector::dump(level, msg);
|
||||
eptp_index::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "16bit guest state fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
guest_es_selector::dump(level, msg);
|
||||
guest_cs_selector::dump(level, msg);
|
||||
guest_ss_selector::dump(level, msg);
|
||||
guest_ds_selector::dump(level, msg);
|
||||
guest_fs_selector::dump(level, msg);
|
||||
guest_gs_selector::dump(level, msg);
|
||||
guest_ldtr_selector::dump(level, msg);
|
||||
guest_tr_selector::dump(level, msg);
|
||||
guest_interrupt_status::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "16bit host state fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
host_es_selector::dump(level, msg);
|
||||
host_cs_selector::dump(level, msg);
|
||||
host_ss_selector::dump(level, msg);
|
||||
host_ds_selector::dump(level, msg);
|
||||
host_fs_selector::dump(level, msg);
|
||||
host_gs_selector::dump(level, msg);
|
||||
host_tr_selector::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "64bit control fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
address_of_io_bitmap_a::dump(level, msg);
|
||||
address_of_io_bitmap_b::dump(level, msg);
|
||||
address_of_msr_bitmap::dump(level, msg);
|
||||
vm_exit_msr_store_address::dump(level, msg);
|
||||
vm_exit_msr_load_address::dump(level, msg);
|
||||
vm_entry_msr_load_address::dump(level, msg);
|
||||
executive_vmcs_pointer::dump(level, msg);
|
||||
tsc_offset::dump(level, msg);
|
||||
virtual_apic_address::dump(level, msg);
|
||||
apic_access_address::dump(level, msg);
|
||||
posted_interrupt_descriptor_address::dump(level, msg);
|
||||
vm_function_controls::dump(level, msg);
|
||||
ept_pointer::dump(level, msg);
|
||||
eoi_exit_bitmap_0::dump(level, msg);
|
||||
eoi_exit_bitmap_1::dump(level, msg);
|
||||
eoi_exit_bitmap_2::dump(level, msg);
|
||||
eoi_exit_bitmap_3::dump(level, msg);
|
||||
eptp_list_address::dump(level, msg);
|
||||
vmread_bitmap_address::dump(level, msg);
|
||||
vmwrite_bitmap_address::dump(level, msg);
|
||||
virtualization_exception_information_address::dump(level, msg);
|
||||
xss_exiting_bitmap::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "64bit read-only data fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
guest_physical_address::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "64bit guest state fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
vmcs_link_pointer::dump(level, msg);
|
||||
guest_ia32_debugctl::dump(level, msg);
|
||||
guest_ia32_pat::dump(level, msg);
|
||||
guest_ia32_efer::dump(level, msg);
|
||||
guest_ia32_perf_global_ctrl::dump(level, msg);
|
||||
guest_pdpte0::dump(level, msg);
|
||||
guest_pdpte1::dump(level, msg);
|
||||
guest_pdpte2::dump(level, msg);
|
||||
guest_pdpte3::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "64bit host state fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
host_ia32_pat::dump(level, msg);
|
||||
host_ia32_efer::dump(level, msg);
|
||||
host_ia32_perf_global_ctrl::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "32bit control fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
pin_based_vm_execution_controls::dump(level, msg);
|
||||
primary_processor_based_vm_execution_controls::dump(level, msg);
|
||||
exception_bitmap::dump(level, msg);
|
||||
page_fault_error_code_mask::dump(level, msg);
|
||||
page_fault_error_code_match::dump(level, msg);
|
||||
cr3_target_count::dump(level, msg);
|
||||
vm_exit_controls::dump(level, msg);
|
||||
vm_exit_msr_store_count::dump(level, msg);
|
||||
vm_exit_msr_load_count::dump(level, msg);
|
||||
vm_entry_controls::dump(level, msg);
|
||||
vm_entry_msr_load_count::dump(level, msg);
|
||||
vm_entry_interruption_information::dump(level, msg);
|
||||
vm_entry_exception_error_code::dump(level, msg);
|
||||
vm_entry_instruction_length::dump(level, msg);
|
||||
tpr_threshold::dump(level, msg);
|
||||
secondary_processor_based_vm_execution_controls::dump(level, msg);
|
||||
ple_gap::dump(level, msg);
|
||||
ple_window::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "32bit read-only data fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
exit_reason::dump(level, msg);
|
||||
vm_exit_interruption_information::dump(level, msg);
|
||||
vm_exit_interruption_error_code::dump(level, msg);
|
||||
idt_vectoring_information::dump(level, msg);
|
||||
idt_vectoring_error_code::dump(level, msg);
|
||||
vm_exit_instruction_length::dump(level, msg);
|
||||
vm_exit_instruction_information::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "32bit guest state fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
guest_es_limit::dump(level, msg);
|
||||
guest_cs_limit::dump(level, msg);
|
||||
guest_ss_limit::dump(level, msg);
|
||||
guest_ds_limit::dump(level, msg);
|
||||
guest_fs_limit::dump(level, msg);
|
||||
guest_gs_limit::dump(level, msg);
|
||||
guest_ldtr_limit::dump(level, msg);
|
||||
guest_tr_limit::dump(level, msg);
|
||||
guest_gdtr_limit::dump(level, msg);
|
||||
guest_idtr_limit::dump(level, msg);
|
||||
guest_es_access_rights::dump(level, msg);
|
||||
guest_cs_access_rights::dump(level, msg);
|
||||
guest_ss_access_rights::dump(level, msg);
|
||||
guest_ds_access_rights::dump(level, msg);
|
||||
guest_fs_access_rights::dump(level, msg);
|
||||
guest_gs_access_rights::dump(level, msg);
|
||||
guest_ldtr_access_rights::dump(level, msg);
|
||||
guest_tr_access_rights::dump(level, msg);
|
||||
guest_interruptibility_state::dump(level, msg);
|
||||
guest_activity_state::dump(level, msg);
|
||||
guest_smbase::dump(level, msg);
|
||||
guest_ia32_sysenter_cs::dump(level, msg);
|
||||
preemption_timer_value::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "32bit host state fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
host_ia32_sysenter_cs::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "natural width control fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
cr0_guest_host_mask::dump(level, msg);
|
||||
cr4_guest_host_mask::dump(level, msg);
|
||||
cr0_read_shadow::dump(level, msg);
|
||||
cr4_read_shadow::dump(level, msg);
|
||||
cr3_target_value_0::dump(level, msg);
|
||||
cr3_target_value_1::dump(level, msg);
|
||||
cr3_target_value_2::dump(level, msg);
|
||||
cr3_target_value_3::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "natural width read-only data fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
exit_qualification::dump(level, msg);
|
||||
io_rcx::dump(level, msg);
|
||||
io_rsi::dump(level, msg);
|
||||
io_rdi::dump(level, msg);
|
||||
io_rip::dump(level, msg);
|
||||
guest_linear_address::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "natural width guest state fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
guest_cr0::dump(level, msg);
|
||||
guest_cr3::dump(level, msg);
|
||||
guest_cr4::dump(level, msg);
|
||||
guest_es_base::dump(level, msg);
|
||||
guest_cs_base::dump(level, msg);
|
||||
guest_ss_base::dump(level, msg);
|
||||
guest_ds_base::dump(level, msg);
|
||||
guest_fs_base::dump(level, msg);
|
||||
guest_gs_base::dump(level, msg);
|
||||
guest_ldtr_base::dump(level, msg);
|
||||
guest_tr_base::dump(level, msg);
|
||||
guest_gdtr_base::dump(level, msg);
|
||||
guest_idtr_base::dump(level, msg);
|
||||
guest_dr7::dump(level, msg);
|
||||
guest_rsp::dump(level, msg);
|
||||
guest_rip::dump(level, msg);
|
||||
guest_rflags::dump(level, msg);
|
||||
guest_pending_debug_exceptions::dump(level, msg);
|
||||
guest_ia32_sysenter_esp::dump(level, msg);
|
||||
guest_ia32_sysenter_eip::dump(level, msg);
|
||||
|
||||
bfdebug_lnbr(level, msg);
|
||||
bfdebug_info(level, "natural width host state fields", msg);
|
||||
bfdebug_brk3(level, msg);
|
||||
|
||||
host_cr0::dump(level, msg);
|
||||
host_cr3::dump(level, msg);
|
||||
host_cr4::dump(level, msg);
|
||||
host_fs_base::dump(level, msg);
|
||||
host_gs_base::dump(level, msg);
|
||||
host_tr_base::dump(level, msg);
|
||||
host_gdtr_base::dump(level, msg);
|
||||
host_idtr_base::dump(level, msg);
|
||||
host_ia32_sysenter_esp::dump(level, msg);
|
||||
host_ia32_sysenter_eip::dump(level, msg);
|
||||
host_rsp::dump(level, msg);
|
||||
host_rip::dump(level, msg);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
|
|
@ -1,296 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef VMCS_INTEL_X64_HELPERS_H
|
||||
#define VMCS_INTEL_X64_HELPERS_H
|
||||
|
||||
#include <bfdebug.h>
|
||||
#include <bfbitmanip.h>
|
||||
|
||||
#include <arch/x64/misc.h>
|
||||
#include <arch/x64/cpuid.h>
|
||||
#include <arch/intel_x64/vmx.h>
|
||||
#include <arch/intel_x64/msrs.h>
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
namespace vmcs
|
||||
{
|
||||
|
||||
using field_type = uint64_t;
|
||||
using value_type = uint64_t;
|
||||
|
||||
inline value_type
|
||||
get_vmcs_field(
|
||||
field_type addr, const char *name, bool exists)
|
||||
{
|
||||
if (!exists) {
|
||||
throw std::logic_error("field doesn't exist: " + std::string(name));
|
||||
}
|
||||
|
||||
return intel_x64::vm::read(addr, name);
|
||||
}
|
||||
|
||||
inline value_type
|
||||
get_vmcs_field_if_exists(
|
||||
field_type addr, const char *name, bool verbose, bool exists)
|
||||
{
|
||||
if (exists) {
|
||||
return intel_x64::vm::read(addr, name);
|
||||
}
|
||||
else {
|
||||
if (verbose) {
|
||||
bfalert_text(0, "field doesn't exist: ", name);
|
||||
}
|
||||
}
|
||||
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
inline void
|
||||
set_vmcs_field(
|
||||
value_type val, field_type addr, const char *name, bool exists)
|
||||
{
|
||||
if (!exists) {
|
||||
throw std::logic_error("field doesn't exist: " + std::string(name));
|
||||
}
|
||||
|
||||
intel_x64::vm::write(addr, val, name);
|
||||
}
|
||||
|
||||
inline void
|
||||
set_vmcs_field_if_exists(
|
||||
value_type val, field_type addr, const char *name, bool verbose, bool exists)
|
||||
{
|
||||
if (exists) {
|
||||
intel_x64::vm::write(addr, val, name);
|
||||
}
|
||||
else {
|
||||
if (verbose) {
|
||||
bfalert_text(0, "field doesn't exist: ", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
set_vmcs_field_bits(
|
||||
value_type val, field_type addr, value_type mask, value_type from, const char *name, bool exists)
|
||||
{
|
||||
auto field = get_vmcs_field(addr, name, exists);
|
||||
set_vmcs_field(set_bits(field, mask, (val << from)), addr, name, exists);
|
||||
}
|
||||
|
||||
inline void
|
||||
set_vmcs_field_bits_if_exists(
|
||||
value_type val, field_type addr, value_type mask, value_type from, const char *name, bool verbose, bool exists)
|
||||
{
|
||||
auto field = get_vmcs_field_if_exists(addr, name, verbose, exists);
|
||||
set_vmcs_field_if_exists(set_bits(field, mask, (val << from)), addr, name, verbose, exists);
|
||||
}
|
||||
|
||||
inline void
|
||||
set_vmcs_field_bit(
|
||||
field_type addr, value_type from, const char *name, bool exists)
|
||||
{
|
||||
auto field = get_vmcs_field(addr, name, exists);
|
||||
set_vmcs_field(set_bit(field, from), addr, name, exists);
|
||||
}
|
||||
|
||||
inline void
|
||||
set_vmcs_field_bit_if_exists(
|
||||
field_type addr, value_type from, const char *name, bool verbose, bool exists)
|
||||
{
|
||||
auto field = get_vmcs_field_if_exists(addr, name, verbose, exists);
|
||||
set_vmcs_field_if_exists(set_bit(field, from), addr, name, verbose, exists);
|
||||
}
|
||||
|
||||
inline void
|
||||
clear_vmcs_field_bit(
|
||||
field_type addr, value_type from, const char *name, bool exists)
|
||||
{
|
||||
auto field = get_vmcs_field(addr, name, exists);
|
||||
set_vmcs_field(clear_bit(field, from), addr, name, exists);
|
||||
}
|
||||
|
||||
inline void
|
||||
clear_vmcs_field_bit_if_exists(
|
||||
field_type addr, value_type from, const char *name, bool verbose, bool exists)
|
||||
{
|
||||
auto field = get_vmcs_field_if_exists(addr, name, verbose, exists);
|
||||
set_vmcs_field_if_exists(clear_bit(field, from), addr, name, verbose, exists);
|
||||
}
|
||||
|
||||
inline void
|
||||
enable_vm_control(
|
||||
field_type addr, value_type from, bool is_allowed1, const char *name, bool exists)
|
||||
{
|
||||
if (!exists) {
|
||||
throw std::logic_error("field doesn't exist: " + std::string(name));
|
||||
}
|
||||
|
||||
if (!is_allowed1) {
|
||||
throw std::logic_error("field is_allowed1 false: " + std::string(name));
|
||||
}
|
||||
|
||||
intel_x64::vm::write(addr, set_bit(intel_x64::vm::read(addr, name), from), name);
|
||||
}
|
||||
|
||||
inline void
|
||||
enable_vm_control_if_allowed(
|
||||
field_type addr, value_type from, bool is_allowed1, const char *name, bool verbose, bool exists)
|
||||
{
|
||||
if (!exists) {
|
||||
if (verbose) {
|
||||
bfalert_text(0, "field doesn't exist: ", name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_allowed1) {
|
||||
if (verbose) {
|
||||
bfalert_text(0, "field is_allowed1 false: ", name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
intel_x64::vm::write(addr, set_bit(intel_x64::vm::read(addr, name), from), name);
|
||||
}
|
||||
|
||||
inline void
|
||||
disable_vm_control(
|
||||
field_type addr, value_type from, bool is_allowed0, const char *name, bool exists)
|
||||
{
|
||||
if (!exists) {
|
||||
throw std::logic_error("field doesn't exist: " + std::string(name));
|
||||
}
|
||||
|
||||
if (!is_allowed0) {
|
||||
throw std::logic_error("field is_allowed0 false: " + std::string(name));
|
||||
}
|
||||
|
||||
intel_x64::vm::write(addr, clear_bit(intel_x64::vm::read(addr, name), from), name);
|
||||
}
|
||||
|
||||
inline void
|
||||
disable_vm_control_if_allowed(
|
||||
field_type addr, value_type from, bool is_allowed0, const char *name, bool verbose, bool exists)
|
||||
{
|
||||
if (!exists) {
|
||||
if (verbose) {
|
||||
bfalert_text(0, "field doesn't exist: ", name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_allowed0) {
|
||||
if (verbose) {
|
||||
bfalert_text(0, "field is_allowed0 false: ", name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
intel_x64::vm::write(addr, clear_bit(intel_x64::vm::read(addr, name), from), name);
|
||||
}
|
||||
|
||||
inline void
|
||||
dump_vm_control(int level, bool exists, bool is_allowed1, bool enabled, const char *name, std::string *msg)
|
||||
{
|
||||
if (!exists || !is_allowed1) {
|
||||
bfdebug_subtext(level, name, "unsupported", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
bfdebug_subbool(level, name, enabled, msg);
|
||||
}
|
||||
|
||||
inline auto
|
||||
memory_type_reserved(value_type memory_type)
|
||||
{
|
||||
switch (memory_type) {
|
||||
case x64::memory_type::uncacheable:
|
||||
case x64::memory_type::write_combining:
|
||||
case x64::memory_type::write_through:
|
||||
case x64::memory_type::write_protected:
|
||||
case x64::memory_type::write_back:
|
||||
case x64::memory_type::uncacheable_minus:
|
||||
return false;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#define dump_vmcs_nhex(a,b) \
|
||||
if (exists()) { \
|
||||
bfdebug_nhex(a, name, get(), b); \
|
||||
} \
|
||||
else { \
|
||||
bfdebug_text(a, name, "unsupported", b); \
|
||||
}
|
||||
|
||||
#define dump_vmcs_subnhex(a,b) \
|
||||
if (exists()) { \
|
||||
bfdebug_subnhex(a, name, get(), b); \
|
||||
} \
|
||||
else { \
|
||||
bfdebug_subtext(a, name, "unsupported", b); \
|
||||
}
|
||||
|
||||
#define dump_vmcs_bool(a,b) \
|
||||
if (exists()) { \
|
||||
bfdebug_bool(a, name, is_enabled(), b); \
|
||||
} \
|
||||
else { \
|
||||
bfdebug_text(a, name, "unsupported", b); \
|
||||
}
|
||||
|
||||
#define dump_vmcs_subbool(a,b) \
|
||||
if (exists()) { \
|
||||
bfdebug_subbool(a, name, is_enabled(), b); \
|
||||
} \
|
||||
else { \
|
||||
bfdebug_subtext(a, name, "unsupported", b); \
|
||||
}
|
||||
|
||||
#define dump_vmcs_text(a,b) \
|
||||
if (exists()) { \
|
||||
bfdebug_text(a, name, description(), b); \
|
||||
} \
|
||||
else { \
|
||||
bfdebug_text(a, name, "unsupported", b); \
|
||||
}
|
||||
|
||||
#define dump_vmcs_subtext(a,b) \
|
||||
if (exists()) { \
|
||||
bfdebug_subtext(a, name, description(), b); \
|
||||
} \
|
||||
else { \
|
||||
bfdebug_subtext(a, name, "unsupported", b); \
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
|
|
@ -1,238 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef VMCS_INTEL_X64_NATURAL_WIDTH_CONTROL_FIELDS_H
|
||||
#define VMCS_INTEL_X64_NATURAL_WIDTH_CONTROL_FIELDS_H
|
||||
|
||||
#include <arch/intel_x64/vmcs/helpers.h>
|
||||
|
||||
/// Intel x86_64 VMCS Natural-Width Control Fields
|
||||
///
|
||||
/// The following provides the interface for the natural-width control VMCS
|
||||
/// fields as defined in Appendix B.4.1, Vol. 3 of the Intel Software Developer's
|
||||
/// Manual.
|
||||
///
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
namespace vmcs
|
||||
{
|
||||
|
||||
namespace cr0_guest_host_mask
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000006000ULL;
|
||||
constexpr const auto name = "cr0_guest_host_mask";
|
||||
|
||||
inline auto exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace cr4_guest_host_mask
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000006002ULL;
|
||||
constexpr const auto name = "cr4_guest_host_mask";
|
||||
|
||||
inline auto exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace cr0_read_shadow
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000006004ULL;
|
||||
constexpr const auto name = "cr0_read_shadow";
|
||||
|
||||
inline auto exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace cr4_read_shadow
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000006006ULL;
|
||||
constexpr const auto name = "cr4_read_shadow";
|
||||
|
||||
inline auto exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace cr3_target_value_0
|
||||
{
|
||||
constexpr const auto addr = 0x0000000000006008ULL;
|
||||
constexpr const auto name = "cr3_target_value_0";
|
||||
|
||||
inline auto exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace cr3_target_value_1
|
||||
{
|
||||
constexpr const auto addr = 0x000000000000600AULL;
|
||||
constexpr const auto name = "cr3_target_value_1";
|
||||
|
||||
inline auto exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace cr3_target_value_2
|
||||
{
|
||||
constexpr const auto addr = 0x000000000000600CULL;
|
||||
constexpr const auto name = "cr3_target_value_2";
|
||||
|
||||
inline auto exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
namespace cr3_target_value_3
|
||||
{
|
||||
constexpr const auto addr = 0x000000000000600EULL;
|
||||
constexpr const auto name = "cr3_target_value_3";
|
||||
|
||||
inline auto exists()
|
||||
{ return true; }
|
||||
|
||||
inline auto get()
|
||||
{ return get_vmcs_field(addr, name, exists()); }
|
||||
|
||||
inline auto get_if_exists(bool verbose = false)
|
||||
{ return get_vmcs_field_if_exists(addr, name, verbose, exists()); }
|
||||
|
||||
inline void set(value_type val)
|
||||
{ set_vmcs_field(val, addr, name, exists()); }
|
||||
|
||||
inline void set_if_exists(value_type val, bool verbose = false)
|
||||
{ set_vmcs_field_if_exists(val, addr, name, verbose, exists()); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ dump_vmcs_nhex(level, msg); }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,203 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef VMX_INTEL_X64_H
|
||||
#define VMX_INTEL_X64_H
|
||||
|
||||
#include <bfgsl.h>
|
||||
#include <bfdebug.h>
|
||||
#include <bfbitmanip.h>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Definitions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
extern "C" bool _vmxon(void *ptr) noexcept;
|
||||
extern "C" bool _vmxoff(void) noexcept;
|
||||
extern "C" bool _vmclear(void *ptr) noexcept;
|
||||
extern "C" bool _vmptrld(void *ptr) noexcept;
|
||||
extern "C" bool _vmptrst(void *ptr) noexcept;
|
||||
extern "C" bool _vmread(uint64_t field, uint64_t *value) noexcept;
|
||||
extern "C" bool _vmwrite(uint64_t field, uint64_t value) noexcept;
|
||||
extern "C" bool _vmlaunch_demote(void) noexcept;
|
||||
extern "C" bool _invept(uint64_t type, void *ptr) noexcept;
|
||||
extern "C" bool _invvpid(uint64_t type, void *ptr) noexcept;
|
||||
extern "C" uintptr_t _vmcall(uintptr_t r1, uintptr_t r2, uintptr_t r3, uintptr_t r4) noexcept;
|
||||
extern "C" uintptr_t _vmcall1(void *r1) noexcept;
|
||||
extern "C" uintptr_t _vmcall2(void *r1, void *r2) noexcept;
|
||||
extern "C" uintptr_t _vmcall3(void *r1, void *r2, void *r3) noexcept;
|
||||
extern "C" uintptr_t _vmcall4(void *r1, void *r2, void *r3, void *r4) noexcept;
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace intel_x64
|
||||
{
|
||||
namespace vmx
|
||||
{
|
||||
using vpid_type = uint64_t;
|
||||
using eptp_type = uint64_t;
|
||||
using integer_pointer = uintptr_t;
|
||||
|
||||
inline void on(gsl::not_null<void *> ptr)
|
||||
{
|
||||
if (!_vmxon(ptr)) {
|
||||
throw std::runtime_error("vmx::on failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline void off()
|
||||
{
|
||||
if (!_vmxoff()) {
|
||||
throw std::runtime_error("vmx::off failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline void invept_single_context(eptp_type eptp)
|
||||
{
|
||||
uint64_t descriptor[2] = { eptp, 0 };
|
||||
if (!_invept(1, static_cast<void *>(descriptor))) {
|
||||
throw std::runtime_error("vm::invept_singal_context failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline void invept_global()
|
||||
{
|
||||
uint64_t descriptor[2] = { 0, 0 };
|
||||
if (!_invept(2, static_cast<void *>(descriptor))) {
|
||||
throw std::runtime_error("vm::invept_global failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline void invvpid_individual_address(vpid_type vpid, integer_pointer addr)
|
||||
{
|
||||
uint64_t descriptor[2] = { vpid, addr };
|
||||
if (!_invvpid(0, static_cast<void *>(descriptor))) {
|
||||
throw std::runtime_error("vm::invvpid_individual_address failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline void invvpid_single_context(vpid_type vpid)
|
||||
{
|
||||
uint64_t descriptor[2] = { vpid, 0 };
|
||||
if (!_invvpid(1, static_cast<void *>(descriptor))) {
|
||||
throw std::runtime_error("vm::invvpid_single_context failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline void invvpid_all_contexts()
|
||||
{
|
||||
uint64_t descriptor[2] = { 0, 0 };
|
||||
if (!_invvpid(2, static_cast<void *>(descriptor))) {
|
||||
throw std::runtime_error("vm::invvpid_all_contexts failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline void invvpid_single_context_global(vpid_type vpid)
|
||||
{
|
||||
uint64_t descriptor[2] = { vpid, 0 };
|
||||
if (!_invvpid(3, static_cast<void *>(descriptor))) {
|
||||
throw std::runtime_error("vm::invvpid_single_context_global failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace vm
|
||||
{
|
||||
using field_type = uint64_t;
|
||||
using value_type = uint64_t;
|
||||
using name_type = const char *;
|
||||
using integer_pointer = uintptr_t;
|
||||
|
||||
inline void clear(gsl::not_null<void *> ptr)
|
||||
{
|
||||
if (!_vmclear(ptr)) {
|
||||
throw std::runtime_error("vm::clear failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline void load(gsl::not_null<void *> ptr)
|
||||
{
|
||||
if (!_vmptrld(ptr)) {
|
||||
throw std::runtime_error("vm::load failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline void store(gsl::not_null<void *> ptr)
|
||||
{
|
||||
if (!_vmptrst(ptr)) {
|
||||
throw std::runtime_error("vm::store failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline auto read(field_type field, name_type name = "")
|
||||
{
|
||||
value_type value = {};
|
||||
|
||||
if (!_vmread(field, &value))
|
||||
{
|
||||
bferror_info(0, "vm::read failed");
|
||||
bferror_subtext(0, "field", name);
|
||||
|
||||
throw std::runtime_error("vm::read failed");
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
inline void write(field_type field, value_type value, name_type name = "")
|
||||
{
|
||||
if (!_vmwrite(field, value))
|
||||
{
|
||||
bferror_info(0, "vm::write failed");
|
||||
bferror_subtext(0, "field", name);
|
||||
bferror_subnhex(0, "value", value);
|
||||
|
||||
throw std::runtime_error("vm::write failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline void launch_demote()
|
||||
{
|
||||
if (!_vmlaunch_demote()) {
|
||||
throw std::runtime_error("vm::launch_demote failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline uintptr_t call(uintptr_t r1 = 0, uintptr_t r2 = 0, uintptr_t r3 = 0, uintptr_t r4 = 0)
|
||||
{ return _vmcall(r1, r2, r3, r4); }
|
||||
|
||||
inline uintptr_t call(uintptr_t *r1)
|
||||
{ return _vmcall1(r1); }
|
||||
|
||||
inline uintptr_t call(uintptr_t *r1, uintptr_t *r2)
|
||||
{ return _vmcall2(r1, r2); }
|
||||
|
||||
inline uintptr_t call(uintptr_t *r1, uintptr_t *r2, uintptr_t *r3)
|
||||
{ return _vmcall3(r1, r2, r3); }
|
||||
|
||||
inline uintptr_t call(uintptr_t *r1, uintptr_t *r2, uintptr_t *r3, uintptr_t *r4)
|
||||
{ return _vmcall4(r1, r2, r3, r4); }
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef CACHE_X64_H
|
||||
#define CACHE_X64_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Definitions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
extern "C" void _invd(void) noexcept;
|
||||
extern "C" void _wbinvd(void) noexcept;
|
||||
extern "C" void _clflush(void *addr) noexcept;
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace x64
|
||||
{
|
||||
namespace cache
|
||||
{
|
||||
|
||||
using pointer = void *;
|
||||
using integer_pointer = uintptr_t;
|
||||
|
||||
inline void invd() noexcept
|
||||
{ _invd(); }
|
||||
|
||||
inline void wbinvd() noexcept
|
||||
{ _wbinvd(); }
|
||||
|
||||
inline void clflush(integer_pointer addr) noexcept
|
||||
{ _clflush(reinterpret_cast<pointer>(addr)); }
|
||||
|
||||
inline void clflush(pointer addr) noexcept
|
||||
{ _clflush(addr); }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#endif
|
||||
|
|
@ -1,359 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2019 Assured Information Security, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef CPUID_X64_H
|
||||
#define CPUID_X64_H
|
||||
|
||||
#include <bfdebug.h>
|
||||
#include <bfbitmanip.h>
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Definitions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
extern "C" uint32_t _cpuid_eax(uint32_t val) noexcept;
|
||||
extern "C" uint32_t _cpuid_ebx(uint32_t val) noexcept;
|
||||
extern "C" uint32_t _cpuid_ecx(uint32_t val) noexcept;
|
||||
extern "C" uint32_t _cpuid_edx(uint32_t val) noexcept;
|
||||
extern "C" uint32_t _cpuid_subeax(uint32_t val, uint32_t sub) noexcept;
|
||||
extern "C" uint32_t _cpuid_subebx(uint32_t val, uint32_t sub) noexcept;
|
||||
extern "C" uint32_t _cpuid_subecx(uint32_t val, uint32_t sub) noexcept;
|
||||
extern "C" uint32_t _cpuid_subedx(uint32_t val, uint32_t sub) noexcept;
|
||||
extern "C" void _cpuid(void *eax, void *ebx, void *ecx, void *edx) noexcept;
|
||||
|
||||
// *INDENT-OFF*
|
||||
|
||||
namespace x64
|
||||
{
|
||||
namespace cpuid
|
||||
{
|
||||
|
||||
using field_type = uint32_t;
|
||||
using value_type = uint32_t;
|
||||
|
||||
struct cpuid_regs {
|
||||
uint64_t rax;
|
||||
uint64_t rbx;
|
||||
uint64_t rcx;
|
||||
uint64_t rdx;
|
||||
};
|
||||
|
||||
inline auto get(field_type eax, field_type ebx, field_type ecx, field_type edx) noexcept
|
||||
{
|
||||
_cpuid(&eax, &ebx, &ecx, &edx);
|
||||
return cpuid_regs{eax, ebx, ecx, edx};
|
||||
}
|
||||
|
||||
namespace eax
|
||||
{
|
||||
inline auto get(field_type eax) noexcept
|
||||
{ return _cpuid_eax(eax); }
|
||||
}
|
||||
|
||||
namespace ebx
|
||||
{
|
||||
inline auto get(field_type ebx) noexcept
|
||||
{ return _cpuid_ebx(ebx); }
|
||||
}
|
||||
|
||||
namespace ecx
|
||||
{
|
||||
inline auto get(field_type ecx) noexcept
|
||||
{ return _cpuid_ecx(ecx); }
|
||||
}
|
||||
|
||||
namespace edx
|
||||
{
|
||||
inline auto get(field_type edx) noexcept
|
||||
{ return _cpuid_edx(edx); }
|
||||
}
|
||||
|
||||
namespace addr_size
|
||||
{
|
||||
constexpr const auto addr = 0x80000008ULL;
|
||||
constexpr const auto name = "addr_size";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_eax(addr); }
|
||||
|
||||
namespace phys
|
||||
{
|
||||
constexpr const auto mask = 0x000000FFULL;
|
||||
constexpr const auto from = 0ULL;
|
||||
constexpr const auto name = "phys";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return get_bits(_cpuid_eax(addr), mask) >> from; }
|
||||
|
||||
inline auto get(value_type msr) noexcept
|
||||
{ return get_bits(msr, mask) >> from; }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_subnhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
namespace linear
|
||||
{
|
||||
constexpr const auto mask = 0x0000FF00ULL;
|
||||
constexpr const auto from = 8ULL;
|
||||
constexpr const auto name = "linear";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return get_bits(_cpuid_eax(addr), mask) >> from; }
|
||||
|
||||
inline auto get(value_type msr) noexcept
|
||||
{ return get_bits(msr, mask) >> from; }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_subnhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{
|
||||
bfdebug_nhex(level, name, get(), msg);
|
||||
phys::dump(level, msg);
|
||||
linear::dump(level, msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace basic_cpuid_info
|
||||
{
|
||||
constexpr const auto addr = 0x00000000ULL;
|
||||
|
||||
namespace eax
|
||||
{
|
||||
constexpr const auto name = "basic_cpuid_info_eax";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_eax(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{
|
||||
eax::dump(level, msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace extend_cpuid_info
|
||||
{
|
||||
constexpr const auto addr = 0x80000000ULL;
|
||||
|
||||
namespace eax
|
||||
{
|
||||
constexpr const auto name = "extend_cpuid_info_eax";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_eax(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{
|
||||
eax::dump(level, msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace processor_string_1
|
||||
{
|
||||
constexpr const auto addr = 0x80000002ULL;
|
||||
|
||||
namespace eax
|
||||
{
|
||||
constexpr const auto name = "processor_string_1_eax";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_eax(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
namespace ebx
|
||||
{
|
||||
constexpr const auto name = "processor_string_1_ebx";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_ebx(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
namespace ecx
|
||||
{
|
||||
constexpr const auto name = "processor_string_1_ecx";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_ecx(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
namespace edx
|
||||
{
|
||||
constexpr const auto name = "processor_string_1_edx";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_edx(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{
|
||||
eax::dump(level, msg);
|
||||
ebx::dump(level, msg);
|
||||
ecx::dump(level, msg);
|
||||
edx::dump(level, msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace processor_string_2
|
||||
{
|
||||
constexpr const auto addr = 0x80000003ULL;
|
||||
|
||||
namespace eax
|
||||
{
|
||||
constexpr const auto name = "processor_string_2_eax";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_eax(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
namespace ebx
|
||||
{
|
||||
constexpr const auto name = "processor_string_2_ebx";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_ebx(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
namespace ecx
|
||||
{
|
||||
constexpr const auto name = "processor_string_2_ecx";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_ecx(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
namespace edx
|
||||
{
|
||||
constexpr const auto name = "processor_string_2_edx";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_edx(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{
|
||||
eax::dump(level, msg);
|
||||
ebx::dump(level, msg);
|
||||
ecx::dump(level, msg);
|
||||
edx::dump(level, msg);
|
||||
}
|
||||
}
|
||||
|
||||
namespace processor_string_3
|
||||
{
|
||||
constexpr const auto addr = 0x80000004ULL;
|
||||
|
||||
namespace eax
|
||||
{
|
||||
constexpr const auto name = "processor_string_3_eax";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_eax(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
namespace ebx
|
||||
{
|
||||
constexpr const auto name = "processor_string_3_ebx";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_ebx(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
namespace ecx
|
||||
{
|
||||
constexpr const auto name = "processor_string_3_ecx";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_ecx(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
namespace edx
|
||||
{
|
||||
constexpr const auto name = "processor_string_3_edx";
|
||||
|
||||
inline auto get() noexcept
|
||||
{ return _cpuid_edx(addr); }
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{ bfdebug_nhex(level, name, get(), msg); }
|
||||
}
|
||||
|
||||
inline void dump(int level, std::string *msg = nullptr)
|
||||
{
|
||||
eax::dump(level, msg);
|
||||
ebx::dump(level, msg);
|
||||
ecx::dump(level, msg);
|
||||
edx::dump(level, msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// *INDENT-ON*
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue