转载: https://blog.csdn.net/celestialwy/article/details/1261407
由于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 SP2下PsLoadedModuleList满足(pModuleCurrent->FullDllName.Buffer == NULL)。
转载请注明出处!
jpg改rar