欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

通过驱动对象找到nt模块、得到函数地址

通过驱动对象找到nt模块、得到函数地址

本人无聊研究微点的驱动,发现里面有找到nt模块的方法,以前没遇见过,发出来供大家参考。
知道此方法的人,请飞过。
思路:
DRIVER_OBJECT里的变量DriverSection是指向LDR_DATA_TABLE_ENTRY的指针,通过遍历LDR_DATA_TABLE_ENTRY来查找nt模块。
typedef struct _DRIVER_OBJECT {
+0x000  CSHORT  Type;
+0x002  CSHORT  Size;
+0x004  PDEVICE_OBJECT  DeviceObject; //指向驱动最近创建的设备对象,驱动通过DeviceObject->NextDevice可以得到这个驱动创建的所有设备对象。
+0x008  ULONG  Flags;
+0x00c  PVOID  DriverStart;
+0x010  ULONG  DriverSize;
+0x014  PVOID  DriverSection; // 为指针PLDR_DATA_TABLE_ENTRY
+0x018  PDRIVER_EXTENSION  DriverExtension; 
+0x01c  UNICODE_STRING  DriverName;
+0x024  PUNICODE_STRING  HardwareDatabase;
+0x028  struct _FAST_IO_DISPATCH *FastIoDispatch;
+0x02c  PDRIVER_INITIALIZE  DriverInit;  // 保存DriverEntry地址
+0x030  PDRIVER_STARTIO  DriverStartIo; // 这个函数是用来异步处理IRP包的
+0x034  PDRIVER_UNLOAD  DriverUnload;
+0x038  PDRIVER_DISPATCH  MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
} DRIVER_OBJECT;
typedef struct _LDR_DATA_TABLE_ENTRY {
    LIST_ENTRY     LoadOrder;
    LIST_ENTRY     MemoryOrder;
    LIST_ENTRY     InitializationOrder;
    PVOID          ModuleBaseAddress;
    PVOID          EntryPoint;
    ULONG          ModuleSize;
    UNICODE_STRING FullModuleName;
    UNICODE_STRING ModuleName;
    ULONG          Flags;
    USHORT         LoadCount;
    USHORT         TlsIndex;
    union {
        LIST_ENTRY Hash;
        struct {
            PVOID SectionPointer;
            ULONG CheckSum;
        };
    };
    ULONG   TimeStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

详细请看图:

下面是代码: 在xp sp3 32bit下测试,OK
extern ULONG NtBuildNumber;
ULONG pDllBaseOfNt_dword_254B4 = 0;
ULONG pSizeOfImageOfNt_dword_254B8 = 0;
ULONG pAddrOf_LDR_DATA_TABLE_ENTRYOfNt_dword_254AC = 0;
ULONG puniFullDllNameOfNt_dword_254C0 = 0;
ULONG pKeInsertQueueApc_dword_23718 = 0;
ULONG pKeInsertQueueApc_dword_22110 = 0;
ULONG pMmGetSystemRoutineAddress_dword_23724 = 0;
ULONG pIofCallDriver_dword_23730 = 0;
ULONG pObReferenceObjectByName_dword_23754 = 0;
ULONG pIoRegisterDriverReinitialization_dword_2376C = 0;
ULONG pMmUnmapViewOfSection_dword_23778 = 0;
ULONG pPsSetCreateProcessNotifyRoutine_dword_23784 = 0;
ULONG pPsSetCreateThreadNotifyRoutine_dword_23790 = 0;
ULONG pPsSetLoadImageNotifyRoutine_dword_2379C = 0;
ULONG pPsTerminateSystemThread_dword_22084 = 0;
ULONG pPsCreateSystemThread_dword_21F00 = 0;

// PDRIVER_OBJECT
int __stdcall sub_10AC4(int pDRIVER_OBJECT)
{
  int result; // eax@1
  int pDriverSection_v2; // edi@2
  unsigned int pModuleBaseAddress_v3; // ecx@4
  int uModuleSize_v4; // edx@4
  int v5; // ecx@8
  
  result = pDRIVER_OBJECT;
  if ( pDRIVER_OBJECT )
  {
    pDriverSection_v2 = *(DWORD *)(pDRIVER_OBJECT + 0x14);// pDriverSection_v2指向 
    // typedef struct _LDR_DATA_TABLE_ENTRY {
    //     LIST_ENTRY     LoadOrder;
    //     LIST_ENTRY     MemoryOrder;
    //     LIST_ENTRY     InitializationOrder;
    //     PVOID          ModuleBaseAddress;
    //     PVOID          EntryPoint;
    //     ULONG          ModuleSize;
    //     UNICODE_STRING FullModuleName;
    //     UNICODE_STRING ModuleName;
    //     ULONG          Flags;
    //     USHORT         LoadCount;
    //     USHORT         TlsIndex;
    //     union {
    //         LIST_ENTRY Hash;
    //         struct {
    //             PVOID SectionPointer;
    //             ULONG CheckSum;
    //         };
    //     };
    //     ULONG   TimeStamp;
    // } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
    if ( pDriverSection_v2 )
    {
      result = *(DWORD *)(pDriverSection_v2 + 4);
      if ( result != pDriverSection_v2 )
      {
        while ( 1 )                             // 通过当前驱动对象,循环查找nt模块的基址和大小,
        {
          pModuleBaseAddress_v3 = *(DWORD *)(result + 24);
          uModuleSize_v4 = *(DWORD *)(result + 32);
          if ( (unsigned int)NtBuildNumber > pModuleBaseAddress_v3 )
          {
            if ( (unsigned int)NtBuildNumber < uModuleSize_v4 + pModuleBaseAddress_v3 )
              break;
          }
          result = *(DWORD *)(result + 4);
          if ( result == pDriverSection_v2 )
            return result;
        }
        pDllBaseOfNt_dword_254B4 = *(DWORD *)(result + 24);// nt模块基址
        pSizeOfImageOfNt_dword_254B8 = uModuleSize_v4;// nt模块大小
        v5 = *(DWORD *)(result + 4);
        result += 0x24u;
        pAddrOf_LDR_DATA_TABLE_ENTRYOfNt_dword_254AC = v5;// 这个变量保存nt的结构体_LDR_DATA_TABLE_ENTRY的地址
        puniFullDllNameOfNt_dword_254C0 = result;
      }
    }
  }
  return result;
};
// 得到指定函数地址
int __stdcall GetFunAddr_f0048(int pModuleBase, const char *pFunName)
{
  int v2; // ecx@3
  int v3; // ecx@4
  int v4; // eax@5
  int v5; // esi@6
  int v6; // edi@6
  int v7; // ebx@6
  int result; // eax@11
  unsigned int v9; // [sp+Ch] [bp-1Ch]@7
  int v10; // [sp+14h] [bp-14h]@7
  unsigned int v11; // [sp+18h] [bp-10h]@6
  unsigned int v12; // [sp+1Ch] [bp-Ch]@6
  unsigned int v13; // [sp+20h] [bp-8h]@5
  unsigned int v14; // [sp+24h] [bp-4h]@6
  
  if ( pModuleBase
    && pFunName
    && (v2 = pModuleBase + *(DWORD *)(pModuleBase + 60)) != 0
    && (v3 = v2 + 120) != 0
    && (v13 = *(DWORD *)v3, (v4 = pModuleBase + *(DWORD *)v3) != 0)
    && (v14 = 0,
        v5 = pModuleBase + *(DWORD *)(v4 + 28),
        v6 = pModuleBase + *(DWORD *)(v4 + 36),
        v7 = pModuleBase + *(DWORD *)(v4 + 32),
        v11 = *(DWORD *)(v4 + 24),
        v12 = *(DWORD *)(v3 + 4),
        v11) )
  {
    while ( 1 )
    {
      v10 = *( WORD *)(v6 + 2 * v14);
      v9 = *(DWORD *)(v5 + 4 * v10);
      if ( v9 < v13 || v9 > v13 + (unsigned __int64)v12 )
      {
        if ( !_stricmp((const char *)(pModuleBase + *(DWORD *)(v7 + 4 * v14)), pFunName) )
          break;
      }
      ++v14;
      if ( v14 >= v11 )
        goto LABEL_11;
    }
    result = pModuleBase + *(DWORD *)(v5 + 4 * v10);
  }
  else
  {
LABEL_11:
    result = 0;
  }
  return result;
};
 
int __cdecl sub_15AAE()
{
  int v0; // eax@1
  int result; // eax@1
  
/*  memset(&dword_23700, 0, 0xA0u);
  dword_23700 = 13;
  //*/
  v0 = GetFunAddr_f0048(pDllBaseOfNt_dword_254B4, "KeInsertQueueApc");
  pKeInsertQueueApc_dword_23718 = v0;
  pKeInsertQueueApc_dword_22110 = v0;
  pMmGetSystemRoutineAddress_dword_23724 = GetFunAddr_f0048(pDllBaseOfNt_dword_254B4, "MmGetSystemRoutineAddress");
  pIofCallDriver_dword_23730 = GetFunAddr_f0048(pDllBaseOfNt_dword_254B4, "IofCallDriver");
  pObReferenceObjectByName_dword_23754 = GetFunAddr_f0048(pDllBaseOfNt_dword_254B4, "ObReferenceObjectByName");
  pIoRegisterDriverReinitialization_dword_2376C = GetFunAddr_f0048(
    pDllBaseOfNt_dword_254B4,
    "IoRegisterDriverReinitialization");
  pMmUnmapViewOfSection_dword_23778 = GetFunAddr_f0048(pDllBaseOfNt_dword_254B4, "MmUnmapViewOfSection");
  pPsSetCreateProcessNotifyRoutine_dword_23784 = GetFunAddr_f0048(
    pDllBaseOfNt_dword_254B4,
    "PsSetCreateProcessNotifyRoutine");
  pPsSetCreateThreadNotifyRoutine_dword_23790 = GetFunAddr_f0048(
    pDllBaseOfNt_dword_254B4,
    "PsSetCreateThreadNotifyRoutine");
  pPsSetLoadImageNotifyRoutine_dword_2379C = GetFunAddr_f0048(pDllBaseOfNt_dword_254B4, "PsSetLoadImageNotifyRoutine");
  pPsTerminateSystemThread_dword_22084 = GetFunAddr_f0048(pDllBaseOfNt_dword_254B4, "PsTerminateSystemThread");
  result = GetFunAddr_f0048(pDllBaseOfNt_dword_254B4, "PsCreateSystemThread");
  pPsCreateSystemThread_dword_21F00 = result;
  return result;
};

上传的附件 driver_and_idb.zip

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功