2011年5月31日 星期二

隱藏驅動 搜尋方法(可找出某Np開頭的遊戲保護)

下面是關鍵代碼,可以查找斷開 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   


沒有留言:

張貼留言