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.
93 lines
2.6 KiB
93 lines
2.6 KiB
#pragma once
|
|
#include <Windows.h>
|
|
#include <winternl.h>
|
|
#include <map>
|
|
#include <string>
|
|
#include <time.h>
|
|
#include <atomic>
|
|
#include <vector>
|
|
#include <iostream>
|
|
|
|
namespace nt
|
|
{
|
|
namespace win32u
|
|
{
|
|
using syscall_table_t = std::vector<std::pair<std::string, std::uintptr_t>>;
|
|
inline syscall_table_t syscall_table = ([&]()-> syscall_table_t
|
|
{
|
|
PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY syscall_policy{};
|
|
syscall_policy.DisallowWin32kSystemCalls = true;
|
|
|
|
std::printf("disable win32ksyscall -> %d\n",
|
|
SetProcessMitigationPolicy(ProcessSystemCallDisablePolicy,
|
|
&syscall_policy, sizeof syscall_policy));
|
|
|
|
LoadLibraryA("user32.dll");
|
|
syscall_table_t result;
|
|
|
|
const auto win32u =
|
|
reinterpret_cast<PIMAGE_DOS_HEADER>(
|
|
LoadLibraryA("win32u.dll"));
|
|
|
|
const auto nt_header =
|
|
reinterpret_cast<PIMAGE_NT_HEADERS64>(
|
|
reinterpret_cast<std::uintptr_t>(win32u) + win32u->e_lfanew);
|
|
|
|
const auto export_rvas =
|
|
nt_header->OptionalHeader.DataDirectory[
|
|
IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
|
|
|
const auto exports =
|
|
reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(
|
|
reinterpret_cast<std::uintptr_t>(win32u) + export_rvas);
|
|
|
|
const auto name_rva =
|
|
reinterpret_cast<std::uint32_t*>(
|
|
reinterpret_cast<std::uintptr_t>(win32u) + exports->AddressOfNames);
|
|
|
|
for (auto idx = 0u; idx < exports->NumberOfNames; ++idx)
|
|
{
|
|
const auto function_name =
|
|
reinterpret_cast<const char*>(
|
|
reinterpret_cast<std::uintptr_t>(win32u) + name_rva[idx]);
|
|
|
|
// add Nt functions...
|
|
if (!strncmp(function_name, "Nt", 2))
|
|
{
|
|
const auto func_rva =
|
|
reinterpret_cast<std::uint32_t*>(
|
|
reinterpret_cast<std::uintptr_t>(win32u) + exports->AddressOfFunctions);
|
|
|
|
const auto ordinal_rva =
|
|
reinterpret_cast<std::uint16_t*>(
|
|
reinterpret_cast<std::uintptr_t>(win32u) + exports->AddressOfNameOrdinals);
|
|
|
|
const auto function_addr =
|
|
reinterpret_cast<std::uintptr_t>(win32u) + func_rva[ordinal_rva[idx]];
|
|
|
|
result.push_back({ function_name, function_addr });
|
|
}
|
|
}
|
|
return result;
|
|
})();
|
|
|
|
inline auto syscall() -> std::uintptr_t
|
|
{
|
|
static const auto random = [&](int min, int max) -> int
|
|
{
|
|
if (static std::atomic<bool> first = false; !first.exchange(true))
|
|
srand(time(NULL));
|
|
|
|
return min + rand() % ((max + 1) - min);
|
|
};
|
|
|
|
const auto [function_name, function_addr] =
|
|
syscall_table[random(NULL, syscall_table.size())];
|
|
|
|
std::printf("%s -> 0x%p\n", function_name.c_str(), function_addr);
|
|
std::getchar();
|
|
|
|
return reinterpret_cast<std::uintptr_t(*)(std::uintptr_t)>(function_addr)(0xC0FFEE);
|
|
}
|
|
}
|
|
} |