libintrovirt v0.57.4
IntroVirt introspection library
Loading...
Searching...
No Matches
GuestAllocation.hh
Go to the documentation of this file.
1/*
2 * Copyright 2021 Assured Information Security, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17
20
21#include <algorithm>
22#include <optional>
23#include <string_view>
24#include <type_traits>
25
26namespace introvirt {
27namespace inject {
28
29// GuestAllocation for single objects
30template <typename _Tp>
32 using pointer_type = typename guest_ptr<_Tp>::pointer_type;
33
34 public:
35 static_assert(std::is_pod_v<_Tp>, "GuestAllocation types must be POD if not specialized");
36
40 uint64_t address() const { return ptr_.address(); }
41
45 operator const guest_ptr<_Tp>&() const { return ptr_; }
46
50 operator guest_ptr<void>() const { return ptr_; }
51
57 const guest_ptr<_Tp>& ptr() const { return ptr_; }
58
69 guest_ptr<_Tp> result(ptr_);
70 ptr_.reset();
71 region_size_ = 0;
72 return result;
73 }
74
80 template <typename Tp = _Tp, typename std::enable_if_t<std::is_array_v<Tp>>* dummy = nullptr>
81 explicit GuestAllocation(size_t length) {
82 static_assert(_is_array(), "Only array types require a runtime length");
83
85 guest_ = domain.guest();
86 introvirt_assert(guest_ != nullptr, "");
87 region_size_ = sizeof(std::remove_all_extents_t<_Tp>) * length;
88
89 // allocate will round up region_size_
90 ptr_.reset(guest_->allocate(region_size_), length);
91 }
92
93 template <typename... _Args, typename Tp = _Tp,
94 typename std::enable_if_t<!std::is_array_v<Tp>>* dummy = nullptr>
95 explicit GuestAllocation(_Args&&... __args) {
96 static_assert(!_is_array(), "Array types require a runtime length");
97
99 guest_ = domain.guest();
100 introvirt_assert(guest_ != nullptr, "");
101 region_size_ = sizeof(_Tp);
102
103 // allocate will round up region_size_
105
106 // Assign the value to the pointer
107 *ptr_ = _Tp(std::forward<_Args>(__args)...);
108 }
109
111 if (region_size_ != 0) {
113 }
114 }
115
118
120 : guest_(src.guest_), ptr_(std::move(src.ptr_)), region_size_(src.region_size_) {
121
122 src.region_size_ = 0;
123 }
125 guest_ = src.guest_;
126 ptr_ = std::move(src.ptr_);
127 region_size_ = src.region_size_;
128
129 src.region_size_ = 0;
130 }
131
132 protected:
133 static constexpr bool _is_array() { return std::is_array_v<_Tp>; }
134
138};
139
140// allocate for single objects
141template <typename _Tp, typename... _Args>
142inline GuestAllocation<_Tp> allocate(_Args&&... args) {
143 return GuestAllocation<_Tp>(std::forward<_Args>(args)...);
144}
145
146// allocate for arrays with runtime lengths
147template <typename _Tp>
148inline GuestAllocation<_Tp> allocate(size_t num) {
149 return GuestAllocation<_Tp>(num);
150}
151
152// Special wrapper for strings
153inline auto allocate(std::string_view str) {
154 // Allocate length + 1 for the null terminator
155 auto result = allocate<char[]>(str.length() + 1);
156 auto& ptr = result.ptr();
157
158 // Copy the string and null terminate it
159 std::copy(str.begin(), str.end(), ptr.begin());
160 ptr[str.length()] = '\0';
161
162 return result;
163}
164
165// Special wrapper for utf16 strings
166inline auto allocate(std::u16string_view str) {
167 // Allocate length + 1 for the null terminator
168 auto result = allocate<char16_t[]>(str.length() + 1);
169 auto& ptr = result.ptr();
170
171 // Copy the string and null terminate it
172 std::copy(str.begin(), str.end(), ptr.begin());
173 ptr[str.length()] = '\0';
174
175 return result;
176}
177
178template <typename _Tp>
180 static_assert(!std::is_array_v<_Tp>, "Arrays of this type are not supported");
181
182 public:
183 operator _Tp*() { return value_.get(); }
184 _Tp& operator*() { return *value_; }
185 _Tp* get() { return value_.get(); }
186 _Tp* operator->() { return value_.get(); }
187
188 uint64_t address() const { return ptr().address(); }
189
190 guest_ptr<void> ptr() const { return allocation_->ptr(); }
191 operator guest_ptr<void>() const { return allocation_->ptr(); }
192
196
197 protected:
198 std::optional<GuestAllocation<uint8_t[]>> allocation_;
199 std::shared_ptr<_Tp> value_;
200};
201
202} // namespace inject
203} // namespace introvirt
static Domain & thread_local_domain()
Get the domain for the current thread.
Base interface for a Guest.
Definition Guest.hh:35
virtual guest_ptr< void > allocate(size_t &region_size, bool executable=false)=0
Allocate a region of memory in the guest.
virtual void guest_free(const guest_ptr< void > &ptr, size_t region_size)=0
Free a region of memory in the guest.
Definition guest_ptr.hh:88
typename std::add_pointer_t< basic_type > pointer_type
Definition guest_ptr.hh:93
Definition GuestAllocation.hh:179
_Tp * operator->()
Definition GuestAllocation.hh:186
std::shared_ptr< _Tp > value_
Definition GuestAllocation.hh:199
uint64_t address() const
Definition GuestAllocation.hh:188
_Tp & operator*()
Definition GuestAllocation.hh:184
guest_ptr< void > ptr() const
Definition GuestAllocation.hh:190
GuestAllocationComplexBase(const GuestAllocationComplexBase &)=delete
_Tp * get()
Definition GuestAllocation.hh:185
std::optional< GuestAllocation< uint8_t[]> > allocation_
Definition GuestAllocation.hh:198
GuestAllocationComplexBase & operator=(const GuestAllocationComplexBase &)=delete
Definition GuestAllocation.hh:31
~GuestAllocation()
Definition GuestAllocation.hh:110
uint64_t address() const
Get the underlying address.
Definition GuestAllocation.hh:40
GuestAllocation(size_t length)
GuestAllocation array constructor.
Definition GuestAllocation.hh:81
guest_ptr< _Tp > release()
Release this memory from management.
Definition GuestAllocation.hh:68
GuestAllocation(const GuestAllocation &)=delete
GuestAllocation(GuestAllocation &&src) noexcept
Definition GuestAllocation.hh:119
GuestAllocation(_Args &&... __args)
Definition GuestAllocation.hh:95
GuestAllocation & operator=(const GuestAllocation &)=delete
guest_ptr< _Tp > ptr_
Definition GuestAllocation.hh:136
Guest * guest_
Definition GuestAllocation.hh:135
size_t region_size_
Definition GuestAllocation.hh:137
const guest_ptr< _Tp > & ptr() const
Get a copy of the underlying pointer.
Definition GuestAllocation.hh:57
GuestAllocation & operator=(GuestAllocation &&src) noexcept
Definition GuestAllocation.hh:124
static constexpr bool _is_array()
Definition GuestAllocation.hh:133
Type-safe guest virtual address pointer and guest_ptr template.
#define introvirt_assert(condition, msg)
Definition introvirt_assert.hh:32
GuestAllocation< _Tp > allocate(_Args &&... args)
Definition GuestAllocation.hh:142
Core IntroVirt classes.
Definition Cr0.hh:20
unique_ptr< Domain > domain
Definition vmcall_interface.cc:48