核态获取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)。

  转载请注明出处!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值