#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(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 (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(buffer); if (!modulebase) return 0; for (auto i = 0u; i < modulebase->NumberOfModules; i++) { const char* current_module_name = (reinterpret_cast(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(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(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; } }