diff --git a/vmicore/src/include/vmicore/vmi/IIntrospectionAPI.h b/vmicore/src/include/vmicore/vmi/IIntrospectionAPI.h index 90027030..269e683a 100644 --- a/vmicore/src/include/vmicore/vmi/IIntrospectionAPI.h +++ b/vmicore/src/include/vmicore/vmi/IIntrospectionAPI.h @@ -27,6 +27,8 @@ namespace VmiCore virtual uint64_t read64VA(addr_t virtualAddress, addr_t cr3) = 0; + virtual uint64_t readVA(addr_t virtualAddress, addr_t dtb, std::size_t size) = 0; + virtual bool readXVA(const addr_t virtualAddress, const addr_t cr3, std::vector& content, std::size_t size) = 0; diff --git a/vmicore/src/lib/vmi/LibvmiInterface.cpp b/vmicore/src/lib/vmi/LibvmiInterface.cpp index dcff5605..6a7d61fc 100644 --- a/vmicore/src/lib/vmi/LibvmiInterface.cpp +++ b/vmicore/src/lib/vmi/LibvmiInterface.cpp @@ -143,6 +143,28 @@ namespace VmiCore return extractedValue; } + uint64_t LibvmiInterface::readVA(addr_t virtualAddress, addr_t dtb, std::size_t size) + { + if (size > sizeof(uint64_t)) + { + throw VmiException(fmt::format("{}: Size parameter cannot be larger than return type of function", + std::source_location::current().function_name())); + } + + uint64_t result = 0; + auto accessContext = createVirtualAddressAccessContext(virtualAddress, dtb); + std::scoped_lock lock(libvmiLock); + if (vmi_read(vmiInstance, &accessContext, size, &result, nullptr) != VMI_SUCCESS) + { + throw VmiException(fmt::format("{}: Unable to read {} bytes from VA {:#x}", + std::source_location::current().function_name(), + size, + virtualAddress)); + } + + return result; + } + bool LibvmiInterface::readXVA(const addr_t virtualAddress, const addr_t cr3, std::vector& content, diff --git a/vmicore/src/lib/vmi/LibvmiInterface.h b/vmicore/src/lib/vmi/LibvmiInterface.h index f98abd5a..8a405e29 100644 --- a/vmicore/src/lib/vmi/LibvmiInterface.h +++ b/vmicore/src/lib/vmi/LibvmiInterface.h @@ -74,6 +74,8 @@ namespace VmiCore uint64_t read64VA(addr_t virtualAddress, addr_t cr3) override; + uint64_t readVA(addr_t virtualAddress, addr_t dtb, std::size_t size) override; + bool readXVA(const addr_t virtualAddress, const addr_t cr3, std::vector& content, diff --git a/vmicore/test/include/vmicore_test/vmi/mock_IntrospectionAPI.h b/vmicore/test/include/vmicore_test/vmi/mock_IntrospectionAPI.h index 6745712f..2020de51 100644 --- a/vmicore/test/include/vmicore_test/vmi/mock_IntrospectionAPI.h +++ b/vmicore/test/include/vmicore_test/vmi/mock_IntrospectionAPI.h @@ -19,6 +19,8 @@ namespace VmiCore MOCK_METHOD(uint64_t, read64VA, (uint64_t, uint64_t), (override)); + MOCK_METHOD(uint64_t, readVA, (addr_t, addr_t, std::size_t), (override)); + MOCK_METHOD(bool, readXVA, (uint64_t, uint64_t, std::vector&, std::size_t size), (override)); MOCK_METHOD(uint64_t, getCurrentVmId, (), (override)); diff --git a/vmicore/test/lib/vmi/mock_LibvmiInterface.h b/vmicore/test/lib/vmi/mock_LibvmiInterface.h index 18208318..0ca36cdd 100644 --- a/vmicore/test/lib/vmi/mock_LibvmiInterface.h +++ b/vmicore/test/lib/vmi/mock_LibvmiInterface.h @@ -23,6 +23,8 @@ namespace VmiCore MOCK_METHOD(uint64_t, read64VA, (const uint64_t, const uint64_t), (override)); + MOCK_METHOD(uint64_t, readVA, (addr_t, addr_t, std::size_t), (override)); + MOCK_METHOD(bool, readXVA, (const uint64_t, const uint64_t, std::vector&, std::size_t), (override)); MOCK_METHOD(void, write8PA, (const uint64_t, const uint8_t), (override));