mirror of
https://github.com/momo5502/hypervisor.git
synced 2025-04-20 05:55:44 +00:00
160 lines
2.9 KiB
C++
160 lines
2.9 KiB
C++
#include "std_include.hpp"
|
|
#include "process.hpp"
|
|
#include "type_traits.hpp"
|
|
#include "exception.hpp"
|
|
|
|
namespace process
|
|
{
|
|
process_handle::process_handle(const PEPROCESS handle, const bool own)
|
|
: own_(own), handle_(handle)
|
|
{
|
|
}
|
|
|
|
process_handle::~process_handle()
|
|
{
|
|
this->release();
|
|
}
|
|
|
|
process_handle::process_handle(process_handle&& obj) noexcept
|
|
: process_handle()
|
|
{
|
|
this->operator=(std::move(obj));
|
|
}
|
|
|
|
process_handle& process_handle::operator=(process_handle&& obj) noexcept
|
|
{
|
|
if (this != &obj)
|
|
{
|
|
this->release();
|
|
this->own_ = obj.own_;
|
|
this->handle_ = obj.handle_;
|
|
obj.own_ = false;
|
|
obj.handle_ = nullptr;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
process_handle::process_handle(const process_handle& obj)
|
|
{
|
|
this->operator=(obj);
|
|
}
|
|
|
|
process_handle& process_handle::operator=(const process_handle& obj)
|
|
{
|
|
if (this != &obj)
|
|
{
|
|
this->release();
|
|
this->own_ = obj.own_;
|
|
this->handle_ = obj.handle_;
|
|
|
|
if (this->own_ && this->handle_)
|
|
{
|
|
ObReferenceObject(this->handle_);
|
|
}
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
process_handle::operator bool() const
|
|
{
|
|
return this->handle_ != nullptr;
|
|
}
|
|
|
|
process_handle::operator PEPROCESS() const
|
|
{
|
|
return this->handle_;
|
|
}
|
|
|
|
bool process_handle::is_alive() const
|
|
{
|
|
if (!this->handle_)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
LARGE_INTEGER zero_time{};
|
|
zero_time.QuadPart = 0;
|
|
|
|
return KeWaitForSingleObject(this->handle_, Executive, KernelMode, FALSE, &zero_time) != STATUS_WAIT_0;
|
|
}
|
|
|
|
process_id process_handle::get_id() const
|
|
{
|
|
if (!this->handle_)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return process_id_from_handle(PsGetProcessId(this->handle_));
|
|
}
|
|
|
|
const char* process_handle::get_image_filename() const
|
|
{
|
|
if (!this->handle_)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
return PsGetProcessImageFileName(this->handle_);
|
|
}
|
|
|
|
void process_handle::release()
|
|
{
|
|
if (this->own_ && this->handle_)
|
|
{
|
|
ObDereferenceObject(this->handle_);
|
|
}
|
|
|
|
this->handle_ = nullptr;
|
|
this->own_ = false;
|
|
}
|
|
|
|
process_id process_id_from_handle(HANDLE handle)
|
|
{
|
|
return process_id(size_t(handle));
|
|
}
|
|
|
|
HANDLE handle_from_process_id(const process_id process)
|
|
{
|
|
return HANDLE(size_t(process));
|
|
}
|
|
|
|
process_handle find_process_by_id(const process_id process)
|
|
{
|
|
PEPROCESS process_obj{};
|
|
if (PsLookupProcessByProcessId(handle_from_process_id(process), &process_obj) != STATUS_SUCCESS)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
return process_handle{process_obj, true};
|
|
}
|
|
|
|
process_handle get_current_process()
|
|
{
|
|
return process_handle{PsGetCurrentProcess(), false};
|
|
}
|
|
|
|
process_id get_current_process_id()
|
|
{
|
|
return get_current_process().get_id();
|
|
}
|
|
|
|
scoped_process_attacher::scoped_process_attacher(const process_handle& process)
|
|
{
|
|
if (!process || !process.is_alive())
|
|
{
|
|
throw std::runtime_error("Invalid process");
|
|
}
|
|
|
|
KeStackAttachProcess(process, &this->apc_state_);
|
|
}
|
|
|
|
scoped_process_attacher::~scoped_process_attacher()
|
|
{
|
|
KeUnstackDetachProcess(&this->apc_state_);
|
|
}
|
|
}
|