You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
physmeme/physmeme-lib/kernel_ctx/kernel_ctx.h

133 lines
2.9 KiB

5 years ago
#pragma once
#include <windows.h>
#include <iostream>
5 years ago
#include <string_view>
#include <vector>
#include <thread>
#include <atomic>
#include "../util/util.hpp"
#include "../physmeme/physmeme.hpp"
#include "../util/hook.hpp"
namespace physmeme
{
//
// offset of function into a physical page
// used for comparing bytes when searching
//
inline std::uint16_t nt_page_offset{};
//
// rva of nt function we are going to hook
//
inline std::uint32_t nt_rva{};
//
// base address of ntoskrnl (inside of this process)
//
inline const std::uint8_t* ntoskrnl_buffer{};
//
// has the page been found yet?
//
inline std::atomic<bool> is_page_found = false;
//
// mapping of a syscalls physical memory (for installing hooks)
//
inline std::atomic<void*> psyscall_func{};
//
// you can edit this how you choose, im hooking NtShutdownSystem.
//
inline const std::pair<std::string_view, std::string_view> syscall_hook = { "NtShutdownSystem", "ntdll.dll" };
5 years ago
class kernel_ctx
{
public:
//
// default constructor
//
5 years ago
kernel_ctx();
//
// allocate kernel pool of desired size and type
//
5 years ago
void* allocate_pool(std::size_t size, POOL_TYPE pool_type = NonPagedPool);
//
// allocate kernel pool of size, pool tag, and type
//
5 years ago
void* allocate_pool(std::size_t size, ULONG pool_tag = 'MEME', POOL_TYPE pool_type = NonPagedPool);
//
// read kernel memory with RtlCopyMemory
//
void read_kernel(void* addr, void* buffer, std::size_t size);
5 years ago
//
// write kernel memory with RtlCopyMemory
//
void write_kernel(void* addr, void* buffer, std::size_t size);
//
// zero kernel memory using RtlZeroMemory
//
void zero_kernel_memory(void* addr, std::size_t size);
5 years ago
//
// clear piddb cache of a specific driver
//
bool clear_piddb_cache(const std::string& file_name, const std::uint32_t timestamp);
5 years ago
template <class T>
T read_kernel(void* addr)
5 years ago
{
if (!addr)
return {};
5 years ago
T buffer;
read_kernel(addr, (void*)&buffer, sizeof(T));
5 years ago
return buffer;
}
template <class T>
void write_kernel(void* addr, const T& data)
5 years ago
{
if (!addr)
return;
write_kernel(addr, (void*)&data, sizeof(T));
5 years ago
}
template <class T, class ... Ts>
std::invoke_result_t<T, Ts...> syscall(void* addr, Ts ... args) const
5 years ago
{
static const auto proc =
GetProcAddress(
GetModuleHandleA("ntdll.dll"),
syscall_hook.first.data()
);
5 years ago
hook::make_hook(psyscall_func, addr);
auto result = reinterpret_cast<T>(proc)(args ...);
5 years ago
hook::remove(psyscall_func);
return result;
}
private:
//
// find and map the physical page of a syscall into this process
//
void map_syscall(std::uintptr_t begin, std::uintptr_t end) const;
//
// used in conjunction with get_process_base.
//
PEPROCESS get_peprocess(unsigned pid) const;
//
// get base address of process (used to compare and ensure we find the right page).
//
void* get_proc_base(unsigned pid) const;
5 years ago
};
}