• 驱动对象


    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
    ", "驱动卸载成功");
    }
    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
    ", &pList->BaseDllName); // 输出本地驱动名字
        // 双向链表,如果到结尾则返回头部
        while (pList != pNext) {
            DbgPrint("%wZ
    ", &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。

  • 相关阅读:
    近期用过的Linux口令备份
    使用白鹭引擎遇到的一些问题以及一些工具分享
    隐私政策
    又是一年年终总结
    初次数据整理
    skynet的timer似乎有问题
    golang .(type)语法
    mysqlbinlog输出sql
    Mysql中文字符串提取datetime
    ionic4请求skynet服务器的资源跨域问题
  • 原文地址:https://www.cnblogs.com/onetrainee/p/12579245.html
Copyright © 2020-2023  润新知