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.
233 lines
5.0 KiB
233 lines
5.0 KiB
#include "luna-1.hpp"
|
|
#include "raw_driver.hpp"
|
|
#include "patch_ctx/patch_ctx.hpp"
|
|
#include "map_driver.hpp"
|
|
|
|
namespace i6
|
|
{
|
|
inline nasa::kernel_ctx* kernel_ctx;
|
|
inline nasa::mem_ctx* mem_ctx;
|
|
inline nasa::patch_ctx* kernel_patch;
|
|
inline hook::detour* win32kbase_detour;
|
|
|
|
inline std::mutex syscall_lock;
|
|
inline void* kernel_hook_handler = nullptr;
|
|
inline void* win32u_handler = nullptr;
|
|
inline void* win32kbase_handler = nullptr;
|
|
inline void* patch_address = nullptr;
|
|
|
|
enum com_type
|
|
{
|
|
READ,
|
|
WRITE,
|
|
READ_KERNEL_MEMORY,
|
|
WRITE_KERNEL_MEMORY,
|
|
GET_PROCESS_BASE,
|
|
GET_MODULE_BASE
|
|
};
|
|
|
|
typedef struct _com_struct
|
|
{
|
|
com_type type;
|
|
unsigned pid;
|
|
unsigned size;
|
|
void* data_from;
|
|
void* data_to;
|
|
} com_struct, * pcom_struct;
|
|
|
|
bool begin()
|
|
{
|
|
//
|
|
// make kernel_ctx and fix syscall page so there is no physical memory mapped into this process!
|
|
//
|
|
if (!nasa::load_drv())
|
|
return false;
|
|
|
|
//
|
|
// make driver and get the address of hook handler.
|
|
//
|
|
const auto result =
|
|
i6::map_driver(
|
|
i6::luna_1,
|
|
sizeof(i6::luna_1),
|
|
&kernel_hook_handler
|
|
);
|
|
|
|
if (result != i6_error::error_success)
|
|
goto exit;
|
|
|
|
kernel_ctx = new nasa::kernel_ctx();
|
|
mem_ctx = new nasa::mem_ctx(*kernel_ctx, GetCurrentProcessId());
|
|
if (!kernel_ctx->clear_piddb_cache(nasa::drv_key, util::get_file_header((void*)raw_driver)->TimeDateStamp))
|
|
goto exit;
|
|
|
|
memset(i6::luna_1, NULL, sizeof(i6::luna_1));
|
|
win32kbase_handler =
|
|
util::get_module_export(
|
|
"win32kbase.sys",
|
|
"NtDCompositionBeginFrame"
|
|
);
|
|
|
|
if (!win32kbase_handler)
|
|
goto exit;
|
|
|
|
//
|
|
// needed for syscall
|
|
//
|
|
LoadLibrary("user32.dll");
|
|
win32u_handler =
|
|
::GetProcAddress(
|
|
LoadLibraryA("win32u.dll"),
|
|
"NtDCompositionBeginFrame"
|
|
);
|
|
|
|
if (!win32u_handler)
|
|
goto exit;
|
|
|
|
kernel_patch = new nasa::patch_ctx(mem_ctx);
|
|
patch_address = kernel_patch->patch(win32kbase_handler);
|
|
win32kbase_detour = new hook::detour(patch_address, kernel_hook_handler, false);
|
|
|
|
//
|
|
// enable patch and flush tlb!
|
|
//
|
|
kernel_patch->enable();
|
|
FLUSH_TLB;
|
|
|
|
exit:
|
|
if (mem_ctx) delete mem_ctx;
|
|
if (kernel_patch) delete kernel_patch;
|
|
if (kernel_ctx) delete kernel_ctx;
|
|
|
|
nasa::unmap_all();
|
|
if (!nasa::unload_drv())
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
void syscall(const pcom_struct com_data)
|
|
{
|
|
syscall_lock.lock();
|
|
win32kbase_detour->install();
|
|
reinterpret_cast<void(*)(pcom_struct)>(win32u_handler)(com_data);
|
|
win32kbase_detour->uninstall();
|
|
syscall_lock.unlock();
|
|
}
|
|
|
|
std::uintptr_t get_process_base(unsigned pid)
|
|
{
|
|
if (!pid)
|
|
return {};
|
|
|
|
com_struct com_data;
|
|
com_data.type = GET_PROCESS_BASE;
|
|
com_data.pid = pid;
|
|
syscall(&com_data);
|
|
return reinterpret_cast<std::uintptr_t>(com_data.data_from);
|
|
}
|
|
|
|
std::uintptr_t get_module_base(unsigned pid, const wchar_t* module_name)
|
|
{
|
|
if (!pid || !module_name)
|
|
return {};
|
|
|
|
com_struct com_data;
|
|
com_data.type = GET_MODULE_BASE;
|
|
com_data.data_to = (void*)module_name;
|
|
com_data.pid = pid;
|
|
syscall(&com_data);
|
|
return reinterpret_cast<std::uintptr_t>(com_data.data_from);
|
|
}
|
|
|
|
bool read(unsigned pid, std::uintptr_t addr, void* buffer, std::size_t size)
|
|
{
|
|
if (!pid || !addr || !buffer || !size)
|
|
return false;
|
|
|
|
com_struct com_data;
|
|
com_data.type = READ;
|
|
com_data.pid = pid;
|
|
com_data.data_from = reinterpret_cast<void*>(addr);
|
|
com_data.data_to = buffer;
|
|
com_data.size = size;
|
|
syscall(&com_data);
|
|
return true;
|
|
}
|
|
|
|
bool write(unsigned pid, std::uintptr_t addr, void* buffer, std::size_t size)
|
|
{
|
|
if (!pid || !addr || !buffer || !size)
|
|
return false;
|
|
|
|
com_struct com_data;
|
|
com_data.type = WRITE;
|
|
com_data.pid = pid;
|
|
com_data.data_from = buffer;
|
|
com_data.data_to = reinterpret_cast<void*>(addr);
|
|
com_data.size = size;
|
|
syscall(&com_data);
|
|
return true;
|
|
}
|
|
|
|
bool rkm(std::uintptr_t addr, void* buffer, std::size_t size)
|
|
{
|
|
if (!addr || !buffer || !size)
|
|
return false;
|
|
|
|
com_struct com_data;
|
|
com_data.type = READ_KERNEL_MEMORY;
|
|
com_data.data_from = reinterpret_cast<void*>(addr);
|
|
com_data.data_to = buffer;
|
|
com_data.size = size;
|
|
syscall(&com_data);
|
|
return true;
|
|
}
|
|
|
|
bool wkm(std::uintptr_t addr, void* buffer, std::size_t size)
|
|
{
|
|
if (!addr || !buffer || !size)
|
|
return false;
|
|
|
|
com_struct com_data;
|
|
com_data.type = WRITE_KERNEL_MEMORY;
|
|
com_data.data_from = buffer;
|
|
com_data.data_to = reinterpret_cast<void*>(addr);
|
|
com_data.size = size;
|
|
syscall(&com_data);
|
|
return true;
|
|
}
|
|
|
|
unsigned get_pid(const char* proc_name)
|
|
{
|
|
PROCESSENTRY32 proc_info;
|
|
proc_info.dwSize = sizeof(proc_info);
|
|
|
|
const auto proc_snapshot =
|
|
CreateToolhelp32Snapshot(
|
|
TH32CS_SNAPPROCESS,
|
|
NULL
|
|
);
|
|
|
|
if (proc_snapshot == INVALID_HANDLE_VALUE)
|
|
return NULL;
|
|
|
|
Process32First(proc_snapshot, &proc_info);
|
|
if (!strcmp(proc_info.szExeFile, proc_name))
|
|
{
|
|
CloseHandle(proc_snapshot);
|
|
return proc_info.th32ProcessID;
|
|
}
|
|
|
|
while (Process32Next(proc_snapshot, &proc_info))
|
|
{
|
|
if (!strcmp(proc_info.szExeFile, proc_name))
|
|
{
|
|
CloseHandle(proc_snapshot);
|
|
return proc_info.th32ProcessID;
|
|
}
|
|
}
|
|
|
|
CloseHandle(proc_snapshot);
|
|
return {};
|
|
}
|
|
} |