Files
2026-06-23 13:18:59 +08:00

260 lines
7.2 KiB
C++

#include "kernel_function.h"
#include "kernel_api.h"
#include "utils.h"
#pragma warning(disable : 4309)
#pragma warning(disable : 4838)
namespace kernel_function
{
auto FindProcess(const CHAR* ProcessName) -> PEPROCESS
{
PEPROCESS process{ 0 };
for (ULONG i = 4; i < 0x401000; i += 4)
{
auto status = PsLookupProcessByProcessId(ULongToHandle(i), &process);
if (!NT_SUCCESS(status))
continue;
auto image_file_name = reinterpret_cast<char*>(kernel_api::psgetprocessimagefilname(process));
if (!strcmp(image_file_name, ProcessName))
return process;
ObDereferenceObject(process);
}
return process;
}
auto GetKernelModule(CONST CHAR* Module) -> uintptr_t
{
UNICODE_STRING unFuncName{ 0 };
void* buffer = nullptr;
DWORD buffer_size = 0;
retry:
buffer = ExAllocatePool(NonPagedPool, buffer_size);
NTSTATUS status = kernel_api::ntquerysysteminformation(static_cast <SYSTEM_INFORMATION_CLASS>(11), buffer, buffer_size, &buffer_size);
if (status == STATUS_INFO_LENGTH_MISMATCH)
{
if (buffer)
ExFreePool(buffer);
goto retry;
}
uintptr_t base = 0;
const auto modulebase = static_cast<PRTL_PROCESS_MODULES>(buffer);
if (!modulebase)
return 0;
for (auto i = 0u; i < modulebase->NumberOfModules; i++)
{
const char* current_module_name = (reinterpret_cast<char*>(modulebase->Modules[i].FullPathName) + modulebase->Modules[i].OffsetToFileName);
if (!_stricmp(current_module_name, Module))
{
const auto ImageBase = modulebase->Modules[i].ImageBase;
base = (uintptr_t)ImageBase;
break;
}
}
ExFreePool(buffer);
return base;
}
auto GetProcessModule(HANDLE Pid, UNICODE_STRING ModuleName, PVOID Buffer) -> NTSTATUS
{
NTSTATUS status = STATUS_SUCCESS;
PEPROCESS process = NULL;
UNICODE_STRING UniCodeName{ 0 };
uintptr_t ModuleBase = 0;
status = PsLookupProcessByProcessId(Pid, &process);
if (!NT_SUCCESS(status))
{
DbgPrintEx(77, 0, "[drv_memory] PsLookupProcessByProcessId failed with status %x\n", status);
return status;
}
BOOLEAN Is64 = (utils::PsGetProcessWow64Process(process) != NULL) ? TRUE : FALSE;
KAPC_STATE ApcState;
KeStackAttachProcess(process, &ApcState);
if (Is64)
{
PPEB32 Peb32 = (PPEB32)utils::PsGetProcessWow64Process(process);
PLIST_ENTRY32 LdrEntry32 = (PLIST_ENTRY32)((PPEB_LDR_DATA32)Peb32->Ldr)->InLoadOrderModuleList.Flink;
while (LdrEntry32 != &((PPEB_LDR_DATA32)Peb32->Ldr)->InLoadOrderModuleList)
{
PLDR_DATA_TABLE_ENTRY32 LdrDataTableEntry32 = (PLDR_DATA_TABLE_ENTRY32)LdrEntry32;
if (LdrDataTableEntry32->BaseDllName.Buffer == NULL) continue;
RtlInitUnicodeString(&UniCodeName, (PWCHAR)LdrDataTableEntry32->BaseDllName.Buffer);
if (RtlEqualUnicodeString(&ModuleName, &UniCodeName, TRUE))
{
ModuleBase = (uintptr_t)LdrDataTableEntry32->DllBase;
break;
}
LdrEntry32 = (PLIST_ENTRY32)LdrEntry32->Flink;
}
}
else
{
PPEB64 Peb64 = (PPEB64)utils::PsGetProcessPeb(process);
PLIST_ENTRY64 LdrEntry64 = (PLIST_ENTRY64)((PPEB_LDR_DATA64)Peb64->Ldr)->InLoadOrderModuleList.Flink;
while (LdrEntry64 != &((PPEB_LDR_DATA64)Peb64->Ldr)->InLoadOrderModuleList)
{
PLDR_DATA_TABLE_ENTRY64 LdrDataTableEntry64 = (PLDR_DATA_TABLE_ENTRY64)LdrEntry64;
if (LdrDataTableEntry64->BaseDllName.Buffer == NULL) continue;
RtlInitUnicodeString(&UniCodeName, LdrDataTableEntry64->BaseDllName.Buffer);
if (RtlEqualUnicodeString(&UniCodeName, &ModuleName, TRUE))
{
ModuleBase = (uintptr_t)LdrDataTableEntry64->DllBase;
break;
}
LdrEntry64 = (PLIST_ENTRY64)LdrEntry64->Flink;
}
}
KeUnstackDetachProcess(&ApcState);
ObDereferenceObject(process);
RtlCopyMemory(Buffer, &ModuleBase, sizeof(uintptr_t));
return status;
}
auto MmMDLPagesCopy(IN PVOID Address, PVOID Buff, SIZE_T Size, BYTE Type, CHAR AccessMode) -> NTSTATUS
{
PMDL pMDL = IoAllocateMdl(Address, (ULONG)Size, FALSE, FALSE, NULL);
if (!pMDL) return STATUS_INSUFFICIENT_RESOURCES;
__try
{
MmProbeAndLockPages(pMDL, AccessMode, IoReadAccess);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
IoFreeMdl(pMDL);
return STATUS_ACCESS_DENIED;
}
PVOID NewAddress = MmMapLockedPagesSpecifyCache(pMDL, KernelMode, MmNonCached, NULL, 0, NormalPagePriority);
if (!NewAddress)
{
MmUnlockPages(pMDL);
IoFreeMdl(pMDL);
return STATUS_INSUFFICIENT_RESOURCES;
}
if (Type == 0x0000001)
RtlCopyMemory(Buff, NewAddress, Size);
if (Type == 0x0000002)
RtlCopyMemory(NewAddress, Buff, Size);
MmUnmapLockedPages(NewAddress, pMDL);
MmUnlockPages(pMDL);
IoFreeMdl(pMDL);
return STATUS_SUCCESS;
}
auto GetMmverifyCallBackFlags() -> uintptr_t
{
uintptr_t pfunc_address = NULL;
auto version = utils::GetVersion();
if (version.dwBuildNumber == 7600 || version.dwBuildNumber == 7601)
{
auto pfunc_extport_address = reinterpret_cast<unsigned char*>(utils::kernel_get_expotr_func(L"ObRegisterCallbacks"));
for (size_t i = 0; i < 0x256; i++)
{
if (pfunc_extport_address[i] == 0x74 && pfunc_extport_address[i + 1] == 0x09)
{
pfunc_address = (uintptr_t)(*(long*)(&pfunc_extport_address[i + 3]) + &pfunc_extport_address[i + 7]);
break;
}
}
}
else
{
auto pfunc_extport_address = reinterpret_cast<unsigned char*>(utils::kernel_get_expotr_func(L"PsSetCreateThreadNotifyRoutineEx"));
for (size_t i = 0; i < 0x256; i++)
{
if (pfunc_extport_address[i] == 0xE8)
{
pfunc_address = (uintptr_t)(*(long*)(&pfunc_extport_address[i + 1]) + &pfunc_extport_address[i + 5]);
break;
}
}
}
return pfunc_address;
}
//ÆÁ±Î0xC0000022LL´íÎó
auto Mack_MmVerifyCallBackFlags(BYTE** orgin_byte) -> BOOL
{
uintptr_t pfunc_address = GetMmverifyCallBackFlags();
if (!pfunc_address)
return FALSE;
//xor,rax,rax
//mov rax,1
//ret
char shellcode[] = { 0x31, 0xC0, 0xB8, 0x01, 0x00 ,0x00, 0x00,0xC3 };
memcpy(orgin_byte, (CONST void*)pfunc_address, sizeof(shellcode));
auto status = MmMDLPagesCopy((PVOID)pfunc_address, &shellcode, sizeof(shellcode), 0x0000002, KernelMode);
if (!NT_SUCCESS(status))
return FALSE;
return TRUE;
}
auto Orgin_MmVerifyCallBackFlags(BYTE* orgin_byte) -> BOOL
{
uintptr_t pfunc_address = GetMmverifyCallBackFlags();
if (!pfunc_address)
return FALSE;
auto status = MmMDLPagesCopy((PVOID)pfunc_address, orgin_byte, sizeof(orgin_byte), 0x0000002, KernelMode);
if (!NT_SUCCESS(status))
return FALSE;
return TRUE;
}
auto ke_stack_attch_process(PEPROCESS PROCESS) -> KAPC_STATE
{
KAPC_STATE apc_state{ 0 };
KeStackAttachProcess(PROCESS, &apc_state);
return apc_state;
}
auto ke_unstack_detach_process(KAPC_STATE apc_state) -> void
{
KeUnstackDetachProcess(&apc_state);
}
auto GetgSessionGlobalSlots() -> uintptr_t {
static uintptr_t gSessionGlobalSlots;
if (gSessionGlobalSlots == NULL) {
auto win32k = GetKernelModule("win32k.sys");
if (!win32k)
return NULL;
auto W32GetSessionStateForSession = utils::FindSectionsCode(win32k, "\x48\x8b\x05\x00\x00\x00\x00\xff\xc9\x48\x8b\x04\xc8", "xxx????xxxxxx", ".text");
if (!W32GetSessionStateForSession)
return NULL;
gSessionGlobalSlots = (*(ULONG*)(W32GetSessionStateForSession + 3)) + (W32GetSessionStateForSession + 7);
}
return gSessionGlobalSlots;
}
}