-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
VMICore: Introduce memory mapping API
- Loading branch information
1 parent
e59b933
commit cfbe9d4
Showing
21 changed files
with
311 additions
and
272 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#ifndef VMICORE_IMEMORYMAPPING_H | ||
#define VMICORE_IMEMORYMAPPING_H | ||
|
||
#include "MappedRegion.h" | ||
#include <stdexcept> | ||
|
||
namespace VmiCore | ||
{ | ||
class MemoryMappingError : public std::runtime_error | ||
{ | ||
using std::runtime_error::runtime_error; | ||
}; | ||
|
||
/** | ||
* Class representing chunks of memory that were able to be mapped within in a given virtual address range. | ||
*/ | ||
class IMemoryMapping | ||
{ | ||
public: | ||
virtual ~IMemoryMapping() = default; | ||
|
||
/** | ||
* Retrieves a set of memory mapping descriptors. See MappedRegion.h for details. Elements are ordered from | ||
* lowest to highest guest VA. | ||
* | ||
* @throws MemoryMappingError Will occur if unmap has already been called. | ||
*/ | ||
[[nodiscard]] virtual std::span<const MappedRegion> getMappedRegions() const = 0; | ||
|
||
/** | ||
* Will unmap all mappings. This function will also be called as soon as an instance of this class goes out of | ||
* scope. | ||
*/ | ||
virtual void unmap() = 0; | ||
|
||
protected: | ||
IMemoryMapping() = default; | ||
}; | ||
} | ||
|
||
#endif // VMICORE_IMEMORYMAPPING_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#ifndef VMICORE_MAPPEDREGION_H | ||
#define VMICORE_MAPPEDREGION_H | ||
|
||
#include "../os/PagingDefinitions.h" | ||
#include "../types.h" | ||
#include <cstdint> | ||
#include <span> | ||
#include <stdexcept> | ||
|
||
namespace VmiCore | ||
{ | ||
/** | ||
* Represents a chunk of contiguous memory that has been mapped into the address space of the introspection | ||
* application. | ||
*/ | ||
struct MappedRegion | ||
{ | ||
/// A virtual address representing the start of the memory region inside the guest. | ||
addr_t guestBaseVA; | ||
/// Size of the memory region in pages. Will always be the finest granularity, even if the guest uses large | ||
/// pages. | ||
std::size_t num_pages; | ||
/// Base address of the mapped memory region inside the introspection application's address space. | ||
void* mappingBase; | ||
|
||
MappedRegion(addr_t guestBaseVA, std::size_t num_pages, void* mappingBase) | ||
: guestBaseVA(guestBaseVA), num_pages(num_pages), mappingBase(mappingBase) | ||
{ | ||
} | ||
|
||
MappedRegion(addr_t guestBaseVA, std::span<uint8_t> mapping) | ||
: guestBaseVA(guestBaseVA), | ||
num_pages(mapping.size() / PagingDefinitions::pageSizeInBytes), | ||
mappingBase(static_cast<void*>(mapping.data())) | ||
{ | ||
if (mapping.size() % PagingDefinitions::pageSizeInBytes != 0) | ||
{ | ||
throw std::invalid_argument("Mapping has to be page aligned"); | ||
} | ||
} | ||
|
||
/** | ||
* Convenience method for safe access to the mapped memory. | ||
*/ | ||
[[nodiscard]] std::span<const uint8_t> asSpan() const | ||
{ | ||
return {static_cast<uint8_t*>(mappingBase), num_pages * PagingDefinitions::pageSizeInBytes}; | ||
} | ||
|
||
bool operator==(const MappedRegion&) const = default; | ||
}; | ||
} | ||
|
||
#endif // VMICORE_MAPPEDREGION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#include "MemoryMapping.h" | ||
#include <vmicore/filename.h> | ||
|
||
// Currently implemented in GNU libstdc++ but missing in LLVM libc++. | ||
#ifdef __cpp_lib_is_layout_compatible | ||
#include <type_traits> | ||
|
||
static_assert(std::is_layout_compatible_v<mapped_region, VmiCore::MappedRegion>, | ||
"Layout of libvmi mapped_region not compatible with VmiCore MappedRegion"); | ||
#endif | ||
|
||
namespace VmiCore | ||
{ | ||
MemoryMapping::MemoryMapping(const std::shared_ptr<ILogging>& logging, | ||
std::shared_ptr<ILibvmiInterface> vmiInterface, | ||
mapped_regions_t mappedRegions) | ||
: logger(logging->newNamedLogger(FILENAME_STEM)), | ||
vmiInterface(std::move(vmiInterface)), | ||
libvmiMappings(mappedRegions) | ||
{ | ||
} | ||
|
||
MemoryMapping::~MemoryMapping() | ||
{ | ||
if (isMapped) | ||
{ | ||
unmap(); | ||
} | ||
} | ||
|
||
std::span<const MappedRegion> MemoryMapping::getMappedRegions() const | ||
{ | ||
if (!isMapped) | ||
{ | ||
throw MemoryMappingError("Cannot retrieve mappings for regions that have already been unmapped"); | ||
} | ||
|
||
return {std::bit_cast<MappedRegion*>(libvmiMappings.regions), libvmiMappings.size}; | ||
} | ||
|
||
void MemoryMapping::unmap() | ||
{ | ||
if (isMapped) | ||
{ | ||
vmiInterface->freeMappedRegions(libvmiMappings); | ||
|
||
isMapped = false; | ||
} | ||
} | ||
} |
Oops, something went wrong.