PEB进程环境快,下面是其一些结构

//===============================================================================================//
typedef struct _UNICODE_STR
{USHORT Length;USHORT MaximumLength;PWSTR pBuffer;
} UNICODE_STR, *PUNICODE_STR;// WinDbg> dt -v ntdll!_LDR_DATA_TABLE_ENTRY
//__declspec( align(8) ) 
typedef struct _LDR_DATA_TABLE_ENTRY
{//LIST_ENTRY InLoadOrderLinks; // As we search from PPEB_LDR_DATA->InMemoryOrderModuleList we dont use the first entry.LIST_ENTRY InMemoryOrderModuleList;LIST_ENTRY InInitializationOrderModuleList;PVOID DllBase;PVOID EntryPoint;ULONG SizeOfImage;UNICODE_STR FullDllName;UNICODE_STR BaseDllName;ULONG Flags;SHORT LoadCount;SHORT TlsIndex;LIST_ENTRY HashTableEntry;ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;// WinDbg> dt -v ntdll!_PEB_LDR_DATA
typedef struct _PEB_LDR_DATA //, 7 elements, 0x28 bytes
{DWORD dwLength;DWORD dwInitialized;LPVOID lpSsHandle;LIST_ENTRY InLoadOrderModuleList;LIST_ENTRY InMemoryOrderModuleList;LIST_ENTRY InInitializationOrderModuleList;LPVOID lpEntryInProgress;
} PEB_LDR_DATA, * PPEB_LDR_DATA;// WinDbg> dt -v ntdll!_PEB_FREE_BLOCK
typedef struct _PEB_FREE_BLOCK // 2 elements, 0x8 bytes
{struct _PEB_FREE_BLOCK * pNext;DWORD dwSize;
} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK;// struct _PEB is defined in Winternl.h but it is incomplete
// WinDbg> dt -v ntdll!_PEB
typedef struct __PEB // 65 elements, 0x210 bytes
{BYTE bInheritedAddressSpace;BYTE bReadImageFileExecOptions;BYTE bBeingDebugged;BYTE bSpareBool;LPVOID lpMutant;LPVOID lpImageBaseAddress;PPEB_LDR_DATA pLdr;LPVOID lpProcessParameters;LPVOID lpSubSystemData;LPVOID lpProcessHeap;PRTL_CRITICAL_SECTION pFastPebLock;LPVOID lpFastPebLockRoutine;LPVOID lpFastPebUnlockRoutine;DWORD dwEnvironmentUpdateCount;LPVOID lpKernelCallbackTable;DWORD dwSystemReserved;DWORD dwAtlThunkSListPtr32;PPEB_FREE_BLOCK pFreeList;DWORD dwTlsExpansionCounter;LPVOID lpTlsBitmap;DWORD dwTlsBitmapBits[2];LPVOID lpReadOnlySharedMemoryBase;LPVOID lpReadOnlySharedMemoryHeap;LPVOID lpReadOnlyStaticServerData;LPVOID lpAnsiCodePageData;LPVOID lpOemCodePageData;LPVOID lpUnicodeCaseTableData;DWORD dwNumberOfProcessors;DWORD dwNtGlobalFlag;LARGE_INTEGER liCriticalSectionTimeout;DWORD dwHeapSegmentReserve;DWORD dwHeapSegmentCommit;DWORD dwHeapDeCommitTotalFreeThreshold;DWORD dwHeapDeCommitFreeBlockThreshold;DWORD dwNumberOfHeaps;DWORD dwMaximumNumberOfHeaps;LPVOID lpProcessHeaps;LPVOID lpGdiSharedHandleTable;LPVOID lpProcessStarterHelper;DWORD dwGdiDCAttributeList;LPVOID lpLoaderLock;DWORD dwOSMajorVersion;DWORD dwOSMinorVersion;WORD wOSBuildNumber;WORD wOSCSDVersion;DWORD dwOSPlatformId;DWORD dwImageSubsystem;DWORD dwImageSubsystemMajorVersion;DWORD dwImageSubsystemMinorVersion;DWORD dwImageProcessAffinityMask;DWORD dwGdiHandleBuffer[34];LPVOID lpPostProcessInitRoutine;LPVOID lpTlsExpansionBitmap;DWORD dwTlsExpansionBitmapBits[32];DWORD dwSessionId;ULARGE_INTEGER liAppCompatFlags;ULARGE_INTEGER liAppCompatFlagsUser;LPVOID lppShimData;LPVOID lpAppCompatInfo;UNICODE_STR usCSDVersion;LPVOID lpActivationContextData;LPVOID lpProcessAssemblyStorageMap;LPVOID lpSystemDefaultActivationContextData;LPVOID lpSystemAssemblyStorageMap;DWORD dwMinimumStackCommit;
} _PEB, * _PPEB;


1.1原理:FS段寄存器指向当前的TEB结构,在TEB偏移0x30处是PEB指针,通过这个指针即可取得PEB的地址。


1.2实现方法:


__asm


{


mov eax,fs:[0x30]


mov PEB,eax


}

也可以使用内联函数

pPeb =(PPEB) __readfsdword( 0x30 );

从PEB中可得到进程加载到内存的模块,结构关系如下

PEB结构-编程之家

PEB结构-编程之家

打印模块代码如下:

//EnumInLoadModule.c
//compile:cl EnumInLoadModule.c
#include <windows.h>
#include <stdio.h>#define CONTAINING_RECORD(address, type, field) ((type *)( \(PCHAR)(address) - \(ULONG_PTR)(&((type *)0)->field)))typedef struct _UNICODE_STRING {USHORT  Length;USHORT  MaximumLength;PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;typedef struct _PEB_LDR_DATA
{DWORD Length;UCHAR Initialized;PVOID SsHandle;LIST_ENTRY InLoadOrderModuleList;LIST_ENTRY InMemoryOrderModuleList;LIST_ENTRY InInitializationOrderModuleList;PVOID EntryInProgress;
}PEB_LDR_DATA,*PPEB_LDR_DATA;typedef struct _LDR_DATA_TABLE_ENTRY
{LIST_ENTRY InLoadOrderLinks;LIST_ENTRY InMemoryOrderLinks;LIST_ENTRY InInitializationOrderLinks;PVOID DllBase;PVOID EntryPoint;DWORD SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;DWORD Flags;WORD LoadCount;WORD TlsIndex;LIST_ENTRY HashLinks;PVOID SectionPointer;DWORD CheckSum;DWORD TimeDateStamp;PVOID LoadedImports;PVOID EntryPointActivationContext;PVOID PatchInformation;
}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;//此结构不完整,因为我们只需要用这么多
typedef struct _PEB
{UCHAR InheritedAddressSpace;UCHAR ReadImageFileExecOptions;UCHAR BeingDebugged;UCHAR SpareBool;PVOID Mutant;PVOID ImageBaseAddress;PPEB_LDR_DATA Ldr;
}PEB,*PPEB;int main(void)
{PLDR_DATA_TABLE_ENTRY pLdrDataEntry = NULL;PLIST_ENTRY pListEntryStart = NULL,pListEntryEnd = NULL;PPEB_LDR_DATA pPebLdrData = NULL;PPEB pPeb = NULL;// STEP 1: process the kernels exports for the functions our loader needs...// get the Process Enviroment Block
#ifdef _WIN64pPeb = (PPEB)__readgsqword( 0x60 );
#else
#ifdef WIN_ARMpPeb =(PPEB)( *(DWORD *)( (BYTE *)_MoveFromCoprocessor( 15, 0, 13, 0, 2 ) + 0x30 ));
#else _WIN32pPeb =(PPEB) __readfsdword( 0x30 );
#endif
#endif//__asm//{//	//1、通过fs:[30h]获取当前进程的_PEB结构//	mov eax,dword ptr fs:[30h];//	mov pPeb,eax//}//2、通过_PEB的Ldr成员获取_PEB_LDR_DATA结构pPebLdrData = pPeb->Ldr;//3、通过_PEB_LDR_DATA的InMemoryOrderModuleList成员获取_LIST_ENTRY结构pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink;//查找所有已载入到内存中的模块do{//4、通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY,InMemoryOrderLinks);//5、输出_LDR_DATA_TABLE_ENTRY的BaseDllName或FullDllName成员信息printf("%S\n",pLdrDataEntry->BaseDllName.Buffer);pListEntryStart = pListEntryStart->Flink;}while(pListEntryStart != pListEntryEnd);system("pause");
}