首页
社区
课程
招聘
[原创]通过驱动对象找到nt模块、得到函数地址
发表于: 2012-2-1 12:55 11099

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

2012-2-1 12:55
11099

本人无聊研究微点的驱动,发现里面有找到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;
};


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 6
支持
分享
最新回复 (8)
雪    币: 585
活跃值: (568)
能力值: ( LV13,RANK:290 )
在线值:
发帖
回帖
粉丝
2
sub_10AC4( (int)DriverObject );
                sub_15AAE();
2012-2-1 12:57
0
雪    币: 8205
活跃值: (3877)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
好东西呀 一大早起来就看到 不错哦
2012-2-1 13:38
0
雪    币: 585
活跃值: (568)
能力值: ( LV13,RANK:290 )
在线值:
发帖
回帖
粉丝
4
都13:38:30了,还一大早???
2012-2-1 14:30
0
雪    币: 1895
活跃值: (1642)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
IDA的F5。。。汇编级的寻址。。。- -、功力不够啊,被加多少多少到神马神马的地址这些绕晕了。。。
2012-2-6 14:50
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
找地址最难了

3q
2012-2-6 20:43
0
雪    币: 585
活跃值: (568)
能力值: ( LV13,RANK:290 )
在线值:
发帖
回帖
粉丝
7
扫描nt模块内存,定位未导出函数
http://bbs.pediy.com/showthread.php?t=143817&highlight=
2012-2-7 10:19
0
雪    币: 362
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习了....
2012-2-7 12:05
0
雪    币: 220
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
呵呵 不错 不错
2012-2-7 15:09
0
游客
登录 | 注册 方可回帖
返回
//