Esempio n. 1
0
//--------------------------------------------------------------------------------------
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);
    }
}
Esempio n. 2
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;
}