驅動對象


Windows內核分析索引目錄:https://www.cnblogs.com/onetrainee/p/11675224.html

驅動對象(驅動隱藏技術)

1._DRIVER_OBJECT結構體

2. xx.sys中的INIT節區

3. DriverObject.DriverSection節區

4. 遍歷全部驅動

5. 驅動隱藏

6. 更進一步的驅動隱藏技巧

7. 總結

 

 

1._DRIVER_OBJECT結構體

 

2. xx.sys中的INIT節區

  DriverObject.DriverInit 其就啟動該節區中的代碼,但是該節區啟動之后就會自動刪除。

  在調試時應該注意,使用IDA查看在節區的函數但是無法動態調試。

  

 

3. DriverObject.DriverSection節區

  該節區指向 _LDR_DATA_ENTRY_TABLE結構體,保存着該驅動的有關信息。

  同時其存在三個雙向鏈表,可以用其來遍歷全部驅動。

  //0x50 bytes (sizeof)
  typedef struct _LDR_DATA_TABLE_ENTRY
  {
      struct _LIST_ENTRY InLoadOrderLinks;                                    //0x0
      struct _LIST_ENTRY InMemoryOrderLinks;                                  //0x8
      struct _LIST_ENTRY InInitializationOrderLinks;                          //0x10
      VOID* DllBase;                                                          //0x18
      VOID* EntryPoint;                                                       //0x1c
      ULONG SizeOfImage;                                                      //0x20
      struct _UNICODE_STRING FullDllName;                                     //0x24
      struct _UNICODE_STRING BaseDllName;                                     //0x2c
      ULONG Flags;                                                            //0x34
      USHORT LoadCount;                                                       //0x38
      USHORT TlsIndex;                                                        //0x3a
      union
      {
          struct _LIST_ENTRY HashLinks;                                       //0x3c
          struct
          {
              VOID* SectionPointer;                                           //0x3c
              ULONG CheckSum;                                                 //0x40
          };
      };
      union
      {
          ULONG TimeDateStamp;                                                //0x44
          VOID* LoadedImports;                                                //0x44
      };
      VOID* EntryPointActivationContext;                                      //0x48
      VOID* PatchInformation;                                                 //0x4c
  }LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;

4. 遍歷全部驅動

#include <ntddk.h>
#include <intrin.h>
#include <ntstrsafe.h>

//0x50 bytes (sizeof)
typedef struct _LDR_DATA_TABLE_ENTRY
{
    struct _LIST_ENTRY InLoadOrderLinks;                                    //0x0
    struct _LIST_ENTRY InMemoryOrderLinks;                                  //0x8
    struct _LIST_ENTRY InInitializationOrderLinks;                          //0x10
    VOID* DllBase;                                                          //0x18
    VOID* EntryPoint;                                                       //0x1c
    ULONG SizeOfImage;                                                      //0x20
    struct _UNICODE_STRING FullDllName;                                     //0x24
    struct _UNICODE_STRING BaseDllName;                                     //0x2c
    ULONG Flags;                                                            //0x34
    USHORT LoadCount;                                                       //0x38
    USHORT TlsIndex;                                                        //0x3a
    union
    {
        struct _LIST_ENTRY HashLinks;                                       //0x3c
        struct
        {
            VOID* SectionPointer;                                           //0x3c
            ULONG CheckSum;                                                 //0x40
        };
    };
    union
    {
        ULONG TimeDateStamp;                                                //0x44
        VOID* LoadedImports;                                                //0x44
    };
    VOID* EntryPointActivationContext;                                      //0x48
    VOID* PatchInformation;                                                 //0x4c
}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;

VOID DriverUnload(_In_ struct _DRIVER_OBJECT* DriverObject) {
    DbgPrint("%s\r\n", "驅動卸載成功");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath) {
    DbgPrint("地址:%x", pDriver);
    pDriver->DriverUnload = DriverUnload;
    
    PLDR_DATA_TABLE_ENTRY pList = (PLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;
    PLDR_DATA_TABLE_ENTRY pNext = pList->InLoadOrderLinks.Flink;
    
    DbgPrint("%wZ\n", &pList->BaseDllName); // 輸出本地驅動名字
    // 雙向鏈表,如果到結尾則返回頭部
    while (pList != pNext) {
        DbgPrint("%wZ\n", &pNext->BaseDllName);
        pNext = pNext->InLoadOrderLinks.Flink; // 輸出下一個驅動名字
    }

    return STATUS_SUCCESS;
}

 

5. 驅動隱藏

  我們采用最基本的斷鏈來測試一下:

      PLDR_DATA_TABLE_ENTRY pList = (PLDR_DATA_TABLE_ENTRY)pDriver->DriverSection;
   RemoveEntryList((PLIST_ENTRY)pList);

  如果我們采用上面那種遍歷方法自然遍歷不到,但是如果使用PcHunter等工具來查看,則明顯無法刪除干凈。

  

 

6. 更進一步的驅動隱藏技巧(代碼2-4)

  我們下面使用MiProcessLoaderEntry內核函數來實現驅動隱藏效果。

  1)在IDA中定位其特征碼

    

   2)特征碼搜索在內核函數中

    

   3)調用內核函數將該鏈表從節區中移除

    調用內核函數移除之后,我門將該節區的Section指向下一個,之后再用PcHunter掃描其結果如下。

    

  4)對於節區屬性更進一步清空

    上面那步之后,我們還可以發現其有關屬性,我們下面對其屬性進一步清空。

    

  5)在驅動卸載時恢復

    我們在發現卸載驅動時,恢復Section節區,然后調用函數在掛在鏈表中,讓系統自動卸載。

    

 

7. 總結

  首先,我們發現其並沒有完全成功繞過PcHunter,我們之后會利用內存加載,句柄表等知識進一步完善驅動隱藏技術。

  對於驅動隱藏,要知道我們分析某些程序時是反PcHunter,其會不斷掃描鏈表發現有PcHunter等工具,然后結束自身進程(另外還有OD等),我們可以利用該策略隱藏自己的PcHunter。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM