libintrovirt v0.57.4
IntroVirt introspection library
Loading...
Searching...
No Matches
FunctionCallFactory.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
25
26#include <log4cxx/logger.h>
27
28#include <functional>
29#include <memory>
30#include <mutex>
31#include <unordered_set>
32
33namespace introvirt {
34
35template <class T>
37 public:
38 FunctionCallReturnData(std::unique_ptr<T>&& handler) : handler(std::move(handler)) {}
39
40 std::shared_ptr<Breakpoint> bp;
41 std::unique_ptr<T> handler;
42};
43
44template <class T>
46 private:
47 static inline const log4cxx::LoggerPtr logger =
48 log4cxx::Logger::getLogger("introvirt.FunctionCallFactory");
49
50 public:
52 // Run our filter (if applicable)
53 if (filter_ && !filter_(event))
54 return;
55
56 // Create an instance
57 std::unique_ptr<T> handler;
58 retry:
59 try {
60 LOG4CXX_DEBUG(logger, "Entered TRY block");
61 handler = std::make_unique<T>(event);
63 auto* guest = event.domain().guest();
64 if (guest) {
65 LOG4CXX_DEBUG(logger, ex);
66 if (guest->page_in(event, ex.virtual_address())) {
67 LOG4CXX_DEBUG(logger,
68 "Successfully paged in " << n2hexstr(ex.virtual_address()));
69 goto retry;
70 }
71 LOG4CXX_WARN(logger, "Failed to page in " << n2hexstr(ex.virtual_address()));
72 throw;
73 }
74 }
75
76 // Deliver it
77 try {
78 callback_(event, *handler);
79 } catch (TraceableException& ex) {
80 LOG4CXX_WARN(logger, "Exception during callback: " << ex);
81 return;
82 }
83
84 // See if we want to hook the return
85 if (handler->hook_return()) {
86 auto& domain = event.domain();
87
88 // Create the return breakpoint
89 auto return_address = handler->return_address();
90
91 // Create an instance of the return data
92 auto return_data = std::make_shared<FunctionCallReturnData<T>>(std::move(handler));
93
94 auto return_bp = domain.create_breakpoint(
96 this, std::placeholders::_1, return_data));
97
98 return_data->bp = std::move(return_bp);
99 }
100 }
101
103 std::shared_ptr<FunctionCallReturnData<T>> return_data) {
104 // Check if this is the matching return
105 if (return_data->handler->is_return_event(event)) {
106 // Handle the return
107 return_data->handler->handle_return(event);
108
109 // Run the user's callback
110 try {
111 return_callback_(event, *(return_data->handler));
112 } catch (TraceableException& ex) {
113 LOG4CXX_WARN(logger, "Exception during callback: " << ex);
114 }
115
116 // Get rid of the breakpoint
117 return_data->bp.reset();
118 }
119 }
120
121 FunctionCallFactory(const guest_ptr<void>& address, std::function<void(Event&, T&)> callback,
122 std::function<void(Event&, T&)> return_callback,
123 std::function<bool(Event&)> filter = nullptr)
124 : callback_(callback), return_callback_(return_callback), filter_(filter) {
125
126 // Register a breakpoint for ourselves
127 auto& domain = const_cast<Domain&>(address.domain());
128 func_bp_ = domain.create_breakpoint(
129 address, std::bind(&FunctionCallFactory<T>::function_breakpoint_hit, this,
130 std::placeholders::_1));
131 }
132
134
135 private:
136 const std::function<void(Event&, T&)> callback_;
137 const std::function<void(Event&, T&)> return_callback_;
138 const std::function<bool(Event&)> filter_;
139
140 std::shared_ptr<Breakpoint> func_bp_;
141};
142
143} // namespace introvirt
A class representing a single Domain.
Definition Domain.hh:44
Interface class for hypervisor events.
Definition Event.hh:43
Definition FunctionCallFactory.hh:45
~FunctionCallFactory()
Definition FunctionCallFactory.hh:133
void function_breakpoint_hit(Event &event)
Definition FunctionCallFactory.hh:51
void function_ret_breakpoint_hit(Event &event, std::shared_ptr< FunctionCallReturnData< T > > return_data)
Definition FunctionCallFactory.hh:102
FunctionCallFactory(const guest_ptr< void > &address, std::function< void(Event &, T &)> callback, std::function< void(Event &, T &)> return_callback, std::function< bool(Event &)> filter=nullptr)
Definition FunctionCallFactory.hh:121
Definition FunctionCallFactory.hh:36
std::unique_ptr< T > handler
Definition FunctionCallFactory.hh:41
FunctionCallReturnData(std::unique_ptr< T > &&handler)
Definition FunctionCallFactory.hh:38
std::shared_ptr< Breakpoint > bp
Definition FunctionCallFactory.hh:40
Base class for exceptions with stack unwinding.
Definition TraceableException.hh:31
Thrown when translating a guest virtual address is marked as not present.
Definition VirtualAddressNotPresentException.hh:31
uint64_t virtual_address() const
Get the guest virtual address that was marked as not present.
Definition guest_ptr.hh:88
const Domain & domain() const
Definition guest_ptr.hh:144
Core IntroVirt classes.
Definition Cr0.hh:20
std::string n2hexstr(I w, size_t hex_len=sizeof(I)<< 1)
Definition n2hexstr.hh:23
unique_ptr< Domain > domain
Definition vmcall_interface.cc:48