核态获取PsLoadedModuleList地址的稳定方法

    PsLoadedModuleList是Windows加载的所有内核模块构成的链表的表头,利用它可以枚举所有这些模块的信息,这些信息可用在AntiRootkit等方面。
    由于Windows 2003 Server SP1开始不再支持用户态访问Physical Memory,所以我这介绍一种在内核态获取PsLoadedModuleList地址的稳定方法。次方法已在Windows XP SP2和Windows 2003 SP1下测试通过。
    代码如下:
   

typedef struct _LDR_DATA_TABLE_ENTRY {
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    USHORT LoadCount;
    USHORT TlsIndex;
    union {
        LIST_ENTRY HashLinks;
        struct {
            PVOID SectionPointer;
            ULONG CheckSum;
        };
    };
    union {
        struct {
            ULONG TimeDateStamp;
        };
        struct {
            PVOID LoadedImports;
        };
    };
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

extern PLIST_ENTRY g_PsLoadedModuleList   ;
PLIST_ENTRY FindPsLoadedModuleList (IN PDRIVER_OBJECT DriverObject)
{
    PLDR_DATA_TABLE_ENTRY pModuleCurrent = NULL;
    PLDR_DATA_TABLE_ENTRY PsLoadedModuleList = NULL;

    if (DriverObject == NULL)
        return 0;

     pModuleCurrent = *((PLDR_DATA_TABLE_ENTRY*)(DriverObject->DriverSection));
    if (pModuleCurrent == NULL)
        return 0;

     PsLoadedModuleList = pModuleCurrent;

    while ((PLDR_DATA_TABLE_ENTRY)pModuleCurrent->InLoadOrderLinks.Flink != PsLoadedModuleList)
    {
        if (((pModuleCurrent->SizeOfImage == 0x00000000)
              && (pModuleCurrent->FullDllName.Length == 0))
              || (pModuleCurrent->FullDllName.Buffer == NULL))
        {
            return (PLIST_ENTRY) pModuleCurrent;
        }

          pModuleCurrent = (PLDR_DATA_TABLE_ENTRY)pModuleCurrent->InLoadOrderLinks.Flink;
    }

    return NULL;
}

    我在测试中发现了这样一个有趣的现象,在Windows 2003 Server SP1下PsLoadedModuleList满足((pModuleCurrent->SizeOfImage == 0x00000000) && (pModuleCurrent->FullDllName.Length == 0))而在WindowXP SP2PsLoadedModuleList满足(pModuleCurrent->FullDllName.Buffer == NULL)。

  转载请注明出处!

你可能感兴趣的:(windows,struct,list,String,table,null)