Skip to content

Commit

Permalink
WIP: vmi_mmap_guest_2
Browse files Browse the repository at this point in the history
  • Loading branch information
Dorian Eikenberg committed Jan 2, 2024
1 parent 42ef320 commit af9b0b9
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 48 deletions.
18 changes: 14 additions & 4 deletions vmicore/src/lib/vmi/LibvmiInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,19 +183,29 @@ namespace VmiCore
return true;
}

std::vector<void*> LibvmiInterface::mmapGuest(addr_t baseVA, addr_t dtb, std::size_t numberOfPages)
void LibvmiInterface::write8PA(addr_t physicalAddress, uint8_t value)
{
auto accessContext = createPhysicalAddressAccessContext(physicalAddress);
std::scoped_lock<std::mutex> lock(libvmiLock);
if (vmi_write_8(vmiInstance, &accessContext, &value) == VMI_FAILURE)
{
throw VmiException(fmt::format("{}: Unable to write {:#x} to PA {:#x}", __func__, value, physicalAddress));
}
}

gsl::owner<mapped_regions_t*> LibvmiInterface::mmapGuest(addr_t baseVA, addr_t dtb, std::size_t numberOfPages)
{
auto accessPointers = std::vector<void*>(numberOfPages);
gsl::owner<mapped_regions_t*> regions = nullptr;
auto accessContext = createVirtualAddressAccessContext(baseVA, dtb);
std::lock_guard<std::mutex> lock(libvmiLock);
if (vmi_mmap_guest(vmiInstance, &accessContext, numberOfPages, PROT_READ, accessPointers.data()) != VMI_SUCCESS)
if (vmi_mmap_guest_2(vmiInstance, &accessContext, numberOfPages, &regions) != VMI_SUCCESS)
{
throw VmiException(fmt::format("{}: Unable to create memory mapping for VA {:#x} with number of pages {}",
__func__,
baseVA,
numberOfPages));
}
return accessPointers;
return regions;
}

void LibvmiInterface::write8PA(addr_t physicalAddress, uint8_t value)
Expand Down
5 changes: 3 additions & 2 deletions vmicore/src/lib/vmi/LibvmiInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define LIBVMI_EXTRA_JSON

#include "libvmi/libvmi_extra.h"
#include <gsl/pointers>
#include <json-c/json.h>

namespace VmiCore
Expand All @@ -33,7 +34,7 @@ namespace VmiCore

virtual void clearEvent(vmi_event_t& event, bool deallocate) = 0;

virtual std::vector<void*> mmapGuest(addr_t baseVA, addr_t dtb, std::size_t numberOfPages) = 0;
virtual gsl::owner<mapped_regions_t*> mmapGuest(addr_t baseVA, addr_t dtb, std::size_t numberOfPages) = 0;

virtual void write8PA(addr_t physicalAddress, uint8_t value) = 0;

Expand Down Expand Up @@ -81,7 +82,7 @@ namespace VmiCore
[[nodiscard]] bool
readXVA(addr_t virtualAddress, addr_t cr3, std::vector<uint8_t>& content, std::size_t size) override;

std::vector<void*> mmapGuest(addr_t baseVA, addr_t dtb, std::size_t numberOfPages) override;
gsl::owner<mapped_regions_t*> mmapGuest(addr_t baseVA, addr_t dtb, std::size_t numberOfPages) override;

void write8PA(addr_t physicalAddress, uint8_t value) override;

Expand Down
46 changes: 7 additions & 39 deletions vmicore/src/lib/vmi/MemoryMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,18 @@
namespace VmiCore
{
MemoryMapping::MemoryMapping(addr_t guestBaseVA,
const std::vector<void*>& accessPointers,
gsl::owner<mapped_regions_t*> mappedRegions,
const std::shared_ptr<ILogging>& logging)
: logger(logging->newNamedLogger(FILENAME_STEM)), mappings(std::make_shared<std::vector<MappedRegion>>())
{
// find coherent regions that are not interrupted by NULL access pointers
std::size_t numPagesInRegion = 0;
void* currentBase = nullptr;

for (std::size_t i = 0; i < accessPointers.size(); i++)
for (std::size_t i = 0; i < mappedRegions->size; i++)
{
auto* accessPointer = accessPointers[i];

if (accessPointer != nullptr)
{
mappingSize += PagingDefinitions::pageSizeInBytes;

// new region starts
if (currentBase == nullptr)
{
currentBase = accessPointer;
}
numPagesInRegion++;
}
// current region ends
else if (currentBase != nullptr)
{
mappings->emplace_back(guestBaseVA + (i - numPagesInRegion) * PagingDefinitions::pageSizeInBytes,
std::span(reinterpret_cast<uint8_t*>(currentBase),
numPagesInRegion * PagingDefinitions::pageSizeInBytes));
numPagesInRegion = 0;
currentBase = nullptr;
}
}

// current region is mapped until the end of the array
if (currentBase != nullptr)
{
mappings->emplace_back(guestBaseVA +
(accessPointers.size() - numPagesInRegion) * PagingDefinitions::pageSizeInBytes,
std::span(reinterpret_cast<uint8_t*>(currentBase),
numPagesInRegion * PagingDefinitions::pageSizeInBytes));
// TODO: Figure out how to pass a non-contiguous region to YARA
// mappings->emplace_back(
// mappedRegions->regions[i].start_va,
// std::span<uint8_t>(mappedRegions->regions[i].access_ptrs,
// mappedRegions->regions[i].num_pages));
}

sizeInGuest = accessPointers.size() * PagingDefinitions::pageSizeInBytes;
}

MemoryMapping::~MemoryMapping()
Expand Down
4 changes: 3 additions & 1 deletion vmicore/src/lib/vmi/MemoryMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#define VMICORE_MEMORYMAPPING_H

#include "../io/ILogging.h"
#include "LibvmiInterface.h"
#include <gsl/pointers>
#include <memory>
#include <vector>
#include <vmicore/types.h>
Expand All @@ -13,7 +15,7 @@ namespace VmiCore
{
public:
MemoryMapping(addr_t guestBaseVA,
const std::vector<void*>& accessPointers,
gsl::owner<mapped_regions_t*> mappedRegions,
const std::shared_ptr<ILogging>& logging);

~MemoryMapping() override;
Expand Down
3 changes: 2 additions & 1 deletion vmicore/test/lib/vmi/MemoryMapping_UnitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using testing::NiceMock;
using VmiCore::PagingDefinitions::numberOfPageIndexBits;
using VmiCore::PagingDefinitions::pageSizeInBytes;

/*
namespace VmiCore
{
constexpr uint64_t testBaseVA = 0x123 << numberOfPageIndexBits;
Expand Down Expand Up @@ -121,3 +121,4 @@ namespace VmiCore
EXPECT_EQ(*memoryMapping.getMappedRegions().lock(), expectedMappedRegions);
}
}
*/
2 changes: 1 addition & 1 deletion vmicore/test/lib/vmi/mock_LibvmiInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace VmiCore

MOCK_METHOD(bool, readXVA, (uint64_t, uint64_t, std::vector<uint8_t>&, std::size_t), (override));

MOCK_METHOD(std::vector<void*>, mmapGuest, (addr_t, addr_t, std::size_t), (override));
MOCK_METHOD(gsl::owner<mapped_regions_t*>, mmapGuest, (addr_t, addr_t, std::size_t), (override));

MOCK_METHOD(void, write8PA, (uint64_t, uint8_t), (override));

Expand Down

0 comments on commit af9b0b9

Please sign in to comment.