mirror of
https://github.com/momo5502/hypervisor.git
synced 2025-04-19 13:42:55 +00:00
Add non-threadsafe process callbacks
This commit is contained in:
parent
a6e0d7de47
commit
65417e3e7a
@ -29,6 +29,10 @@ target_link_libraries(driver
|
|||||||
shared
|
shared
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_compile_options(driver PRIVATE
|
||||||
|
"/Zc:threadSafeInit-"
|
||||||
|
)
|
||||||
|
|
||||||
target_link_options(driver PRIVATE
|
target_link_options(driver PRIVATE
|
||||||
"/IGNORE:4210"
|
"/IGNORE:4210"
|
||||||
)
|
)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include "hypervisor.hpp"
|
#include "hypervisor.hpp"
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
|
#include "process_callback.hpp"
|
||||||
|
|
||||||
#define DOS_DEV_NAME L"\\DosDevices\\HelloDev"
|
#define DOS_DEV_NAME L"\\DosDevices\\HelloDev"
|
||||||
#define DEV_NAME L"\\Device\\HelloDev"
|
#define DEV_NAME L"\\Device\\HelloDev"
|
||||||
@ -16,8 +17,13 @@ public:
|
|||||||
: sleep_callback_([this](const sleep_callback::type type)
|
: sleep_callback_([this](const sleep_callback::type type)
|
||||||
{
|
{
|
||||||
this->sleep_notification(type);
|
this->sleep_notification(type);
|
||||||
})
|
}),
|
||||||
, irp_(driver_object, DEV_NAME, DOS_DEV_NAME)
|
process_callback_(
|
||||||
|
[this](const HANDLE parent_id, const HANDLE process_id, const process_callback::type type)
|
||||||
|
{
|
||||||
|
this->process_notification(parent_id, process_id, type);
|
||||||
|
}),
|
||||||
|
irp_(driver_object, DEV_NAME, DOS_DEV_NAME)
|
||||||
{
|
{
|
||||||
debug_log("Driver started\n");
|
debug_log("Driver started\n");
|
||||||
}
|
}
|
||||||
@ -41,6 +47,7 @@ private:
|
|||||||
bool hypervisor_was_enabled_{false};
|
bool hypervisor_was_enabled_{false};
|
||||||
hypervisor hypervisor_{};
|
hypervisor hypervisor_{};
|
||||||
sleep_callback sleep_callback_{};
|
sleep_callback sleep_callback_{};
|
||||||
|
process_callback::scoped_process_callback process_callback_{};
|
||||||
irp irp_{};
|
irp irp_{};
|
||||||
|
|
||||||
void sleep_notification(const sleep_callback::type type)
|
void sleep_notification(const sleep_callback::type type)
|
||||||
@ -58,6 +65,19 @@ private:
|
|||||||
this->hypervisor_.enable();
|
this->hypervisor_.enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void process_notification(HANDLE /*parent_id*/, const HANDLE process_id, const process_callback::type type)
|
||||||
|
{
|
||||||
|
if (type == process_callback::type::create)
|
||||||
|
{
|
||||||
|
debug_log("Created process: %X\n", process_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == process_callback::type::destroy)
|
||||||
|
{
|
||||||
|
debug_log("Destroyed process: %X\n", process_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
global_driver* global_driver_instance{nullptr};
|
global_driver* global_driver_instance{nullptr};
|
||||||
|
@ -115,7 +115,7 @@ int atexit(const globals::destructor destructor)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
globals::destructors->push_back(destructor);
|
globals::destructors->push_front(destructor);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -168,29 +168,45 @@ namespace utils
|
|||||||
|
|
||||||
T& push_back(const T& obj)
|
T& push_back(const T& obj)
|
||||||
{
|
{
|
||||||
auto& entry = this->add_uninitialized_entry();
|
auto& entry = this->add_uninitialized_entry_back();
|
||||||
|
|
||||||
new(&entry) T(obj);
|
new(&entry) T(obj);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
T& push_back(T&& obj)
|
T& push_back(T&& obj)
|
||||||
{
|
{
|
||||||
auto& entry = this->add_uninitialized_entry();
|
auto& entry = this->add_uninitialized_entry_back();
|
||||||
|
|
||||||
new(&entry) T(std::move(obj));
|
new(&entry) T(std::move(obj));
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
T& emplace_back(Args&&... args)
|
T& emplace_back(Args&&... args)
|
||||||
{
|
{
|
||||||
auto& entry = this->add_uninitialized_entry();
|
auto& entry = this->add_uninitialized_entry_back();
|
||||||
|
|
||||||
new(&entry) T(std::forward<Args>(args)...);
|
new(&entry) T(std::forward<Args>(args)...);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& push_front(const T& obj)
|
||||||
|
{
|
||||||
|
auto& entry = this->add_uninitialized_entry_front();
|
||||||
|
new(&entry) T(obj);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& push_front(T&& obj)
|
||||||
|
{
|
||||||
|
auto& entry = this->add_uninitialized_entry_front();
|
||||||
|
new(&entry) T(std::move(obj));
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
T& emplace_front(Args&&... args)
|
||||||
|
{
|
||||||
|
auto& entry = this->add_uninitialized_entry_front();
|
||||||
|
new(&entry) T(std::forward<Args>(args)...);
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,6 +287,30 @@ namespace utils
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void erase(T& entry)
|
||||||
|
{
|
||||||
|
auto** insertion_point = &this->entries_;
|
||||||
|
while (*insertion_point)
|
||||||
|
{
|
||||||
|
if ((*insertion_point)->entry != &entry)
|
||||||
|
{
|
||||||
|
insertion_point = &(*insertion_point)->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* list_entry = *insertion_point;
|
||||||
|
*insertion_point = list_entry->next;
|
||||||
|
|
||||||
|
list_entry->entry->~T();
|
||||||
|
this->object_allocator_.free(list_entry->entry_base);
|
||||||
|
this->list_allocator_.free(list_entry->this_base);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("Bad entry");
|
||||||
|
}
|
||||||
|
|
||||||
iterator erase(iterator iterator)
|
iterator erase(iterator iterator)
|
||||||
{
|
{
|
||||||
auto* list_entry = iterator.get_entry();
|
auto* list_entry = iterator.get_entry();
|
||||||
@ -350,19 +390,12 @@ namespace utils
|
|||||||
destructor.cancel();
|
destructor.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_entry& create_uninitialized_list_entry()
|
||||||
T& add_uninitialized_entry()
|
|
||||||
{
|
{
|
||||||
void* list_base = {};
|
void* list_base = {};
|
||||||
void* entry_base = {};
|
void* entry_base = {};
|
||||||
this->allocate_entry(list_base, entry_base);
|
this->allocate_entry(list_base, entry_base);
|
||||||
|
|
||||||
auto** insertion_point = &this->entries_;
|
|
||||||
while (*insertion_point)
|
|
||||||
{
|
|
||||||
insertion_point = &(*insertion_point)->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* obj = align_pointer<T>(entry_base);
|
auto* obj = align_pointer<T>(entry_base);
|
||||||
auto* entry = align_pointer<list_entry>(list_base);
|
auto* entry = align_pointer<list_entry>(list_base);
|
||||||
|
|
||||||
@ -371,9 +404,30 @@ namespace utils
|
|||||||
entry->next = nullptr;
|
entry->next = nullptr;
|
||||||
entry->entry = obj;
|
entry->entry = obj;
|
||||||
|
|
||||||
*insertion_point = entry;
|
return *entry;
|
||||||
|
}
|
||||||
|
|
||||||
return *obj;
|
T& add_uninitialized_entry_back()
|
||||||
|
{
|
||||||
|
auto** insertion_point = &this->entries_;
|
||||||
|
while (*insertion_point)
|
||||||
|
{
|
||||||
|
insertion_point = &(*insertion_point)->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& entry = this->create_uninitialized_list_entry();
|
||||||
|
*insertion_point = &entry;
|
||||||
|
|
||||||
|
return *entry.entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& add_uninitialized_entry_front()
|
||||||
|
{
|
||||||
|
auto& entry = this->create_uninitialized_list_entry();
|
||||||
|
entry.next = this->entries_;
|
||||||
|
this->entries_ = &entry;
|
||||||
|
|
||||||
|
return *entry.entry;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
65
src/driver/process_callback.cpp
Normal file
65
src/driver/process_callback.cpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include "std_include.hpp"
|
||||||
|
#include "process_callback.hpp"
|
||||||
|
#include "list.hpp"
|
||||||
|
#include "logging.hpp"
|
||||||
|
|
||||||
|
namespace process_callback
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
utils::list<callback_function>& get_callback_list()
|
||||||
|
{
|
||||||
|
static utils::list<callback_function> list{};
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_notification_callback(const HANDLE parent_id, const HANDLE process_id, const BOOLEAN create)
|
||||||
|
{
|
||||||
|
const auto& list = get_callback_list();
|
||||||
|
for (const auto& callback : list)
|
||||||
|
{
|
||||||
|
callback(parent_id, process_id, create == FALSE ? type::destroy : type::create);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class process_notifier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
process_notifier()
|
||||||
|
: added_(PsSetCreateProcessNotifyRoutine(process_notification_callback, FALSE) == STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
get_callback_list();
|
||||||
|
|
||||||
|
if (!added_)
|
||||||
|
{
|
||||||
|
debug_log("Failed to register process notification callback\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~process_notifier()
|
||||||
|
{
|
||||||
|
if (this->added_)
|
||||||
|
{
|
||||||
|
PsSetCreateProcessNotifyRoutine(process_notification_callback, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool added_{};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void* add(callback_function callback)
|
||||||
|
{
|
||||||
|
static process_notifier _;
|
||||||
|
return &get_callback_list().push_back(std::move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove(void* handle)
|
||||||
|
{
|
||||||
|
if (handle)
|
||||||
|
{
|
||||||
|
get_callback_list().erase(*static_cast<callback_function*>(handle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
src/driver/process_callback.hpp
Normal file
42
src/driver/process_callback.hpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "functional.hpp"
|
||||||
|
|
||||||
|
namespace process_callback
|
||||||
|
{
|
||||||
|
enum class type
|
||||||
|
{
|
||||||
|
create,
|
||||||
|
destroy,
|
||||||
|
};
|
||||||
|
|
||||||
|
using callback = void(HANDLE parent_id, HANDLE process_id, type type);
|
||||||
|
using callback_function = std::function<callback>;
|
||||||
|
|
||||||
|
void* add(callback_function callback);
|
||||||
|
void remove(void* handle);
|
||||||
|
|
||||||
|
class scoped_process_callback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
scoped_process_callback() = default;
|
||||||
|
|
||||||
|
scoped_process_callback(callback_function function)
|
||||||
|
: handle_(add(std::move(function)))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~scoped_process_callback()
|
||||||
|
{
|
||||||
|
remove(this->handle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
scoped_process_callback(scoped_process_callback&& obj) noexcept = delete;
|
||||||
|
scoped_process_callback& operator=(scoped_process_callback&& obj) noexcept = delete;
|
||||||
|
|
||||||
|
scoped_process_callback(const scoped_process_callback& obj) = delete;
|
||||||
|
scoped_process_callback& operator=(const scoped_process_callback& obj) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* handle_{};
|
||||||
|
};
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user