下面是關鍵代碼,可以查找斷開 PsLoadedModuleList 鏈的驅動,比如 Np開頭的遊戲保護

PDIRECTORY_BASIC_INFORMATION    pDriverBuffer = NULL;
pDriverBuffer = (PDIRECTORY_BASIC_INFORMATION)m_cSysInfo.QueryDirectoryObject(L"\\Driver", &uMemSize);

查找驅動物件目錄下的所有物件,查找代碼如下。

PVOID CNativeSysInfo::QueryDirectoryObject(PWSTR pwsDirPath, PULONG puMemSize)
{
    NTSTATUS            ntStatus;
    UNICODE_STRING      usDirPath;
    OBJECT_ATTRIBUTES   oa;
    HANDLE              hDir = NULL;
    PVOID               pBuffer = NULL;
    ULONG               uLength = 0x800;
    ULONG               uContext = 0;
    ULONG               uResult = 0;

    // 
判斷函數是否存在
    if(m_lpRtlInitUnicodeString == NULL ||
       m_lpZwOpenDirectoryObject == NULL ||
       m_lpZwQueryDirectoryObject == NULL ||
       m_lpZwClose == NULL)
    {
        return NULL;
    }

    // 
打開目錄物件
    m_lpRtlInitUnicodeString(&usDirPath, pwsDirPath);
    InitializeObjectAttributes(&oa, &usDirPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
    ntStatus = m_lpZwOpenDirectoryObject(&hDir, DIRECTORY_QUERY, &oa);
    if(ntStatus != STATUS_SUCCESS)
    {
        TRACE(_T("ZwOpenDirectoryObject failed!"));
        goto _exit;
    }

    // 
查詢目錄物件
    do
    {
        if(pBuffer)
            VirtualFree(pBuffer, uLength, MEM_DECOMMIT);

        uLength *= 2;

        pBuffer = VirtualAlloc(NULL, uLength, MEM_COMMIT, PAGE_READWRITE);
        if(pBuffer == NULL)
            goto _exit;

        ntStatus = m_lpZwQueryDirectoryObject(hDir, pBuffer, uLength, FALSE, TRUE, &uContext, &uResult);

    } while(ntStatus == STATUS_MORE_ENTRIES || ntStatus == STATUS_BUFFER_TOO_SMALL);

    // 
判斷查詢是否成功完成
    if(ntStatus == STATUS_SUCCESS)
    {
        if(puMemSize)
            *puMemSize = uLength;
    }
    else
    {
        VirtualFree(pBuffer, uLength, MEM_DECOMMIT);
        pBuffer = NULL;
    }

_exit:

    if(hDir)
    {
        m_lpZwClose(hDir);
        hDir = NULL;
    }

    return pBuffer;
}

然後把得到的結果和常規結果比較就可以找到隱藏驅動。隱藏驅動的相關資訊可以通過下面的方式得到。

    PDRIVER_OBJECT          pDrvObject = NULL;

    RtlInitUnicodeString(&usDirPath, (PCWSTR)pvInBuf);
    ntStatus = ObReferenceObjectByName(&usDirPath,
                                       OBJ_CASE_INSENSITIVE,
                                       NULL,
                                       0,
                                       *IoDriverObjectType,
                                       KernelMode,
                                       NULL,
                                       (PVOID*)&pDrvObject);

有了 DRIVER_OBJECT 結構就啥都有了!:)

下面是一個隱藏驅動的例子,用上面的辦法可以發現。

void _EraseDrvFromModList(PDRIVER_OBJECT pDrvObject)
{
    PLDR_DATA_TABLE_ENTRY   pOwen;
    PLDR_DATA_TABLE_ENTRY   pPrev;
    PLDR_DATA_TABLE_ENTRY   pNext;

    pOwen = (PLDR_DATA_TABLE_ENTRY)pDrvObject->DriverSection;
    pPrev = (PLDR_DATA_TABLE_ENTRY)pOwen->InLoadOrderModuleList.Blink;
    pNext = (PLDR_DATA_TABLE_ENTRY)pOwen->InLoadOrderModuleList.Flink;
    pPrev->InLoadOrderModuleList.Flink = (PLIST_ENTRY)pNext;
    pNext->InLoadOrderModuleList.Blink = (PLIST_ENTRY)pPrev;

    pOwen->InLoadOrderModuleList.Flink = (PLIST_ENTRY)pOwen;
    pOwen->InLoadOrderModuleList.Blink = (PLIST_ENTRY)pOwen;
}

Rootkit

Rootkit   

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 殘月影 的頭像
    殘月影

    Rootkit --逆向工程技術--

    殘月影 發表在 痞客邦 留言(0) 人氣()