Windows
PE 文件结构图
PEB 结构
32位及64位TEB、PEB详解
x86/x64 PE文件头详解
本文档使用 MrDoc 发布
-
+
首页
32位及64位TEB、PEB详解
# 说明 - 先列出结构体,再进一步的说明。不参考结构体理解起来有困难。 # 参考资料 > [TEB(线程环境块)学习](https://blog.csdn.net/weixin_44156885/article/details/100729365) > [从TEB到PEB再到SEH(一)](https://bbs.kanxue.com/thread-223816.htm) > [PEB结构:获取模块kernel32基址技术及原理分析](https://bbs.kanxue.com/thread-266678.htm) > [TEB系列 (geoffchappell.com)](https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/pebteb/teb/index.htm) > [TEB和PEB | Sp4n9x's Blog](https://sp4n9x.github.io/2021/04/14/TEB_and_PEB/) > [TEB/PEB定位PE文件导入导出表_指向peb-CSDN博客](https://blog.csdn.net/w_g3366/article/details/100600579) > [Vergilius Project | _TEB32](https://www.vergiliusproject.com/kernels/x64/windows-10/22h2/_TEB32) # TEB(Thread Environment Block/线程环境块) - TEB即为线程环境块, 进程中每一条线程都对应着的自己的 "TEB"。所以在调试过程中在不同线程里查看 TEB 的地址是不一样的。 ## 结构 ### 32 位 ``` //0x1000 bytes (sizeof) struct _TEB32 { struct _NT_TIB32 NtTib; //0x0 ULONG EnvironmentPointer; //0x1c struct _CLIENT_ID32 ClientId; //0x20 ULONG ActiveRpcHandle; //0x28 ULONG ThreadLocalStoragePointer; //0x2c ULONG ProcessEnvironmentBlock; //0x30 ULONG LastErrorValue; //0x34 ULONG CountOfOwnedCriticalSections; //0x38 ULONG CsrClientThread; //0x3c ULONG Win32ThreadInfo; //0x40 ULONG User32Reserved[26]; //0x44 ULONG UserReserved[5]; //0xac ULONG WOW32Reserved; //0xc0 ULONG CurrentLocale; //0xc4 ULONG FpSoftwareStatusRegister; //0xc8 ULONG ReservedForDebuggerInstrumentation[16]; //0xcc ULONG SystemReserved1[26]; //0x10c CHAR PlaceholderCompatibilityMode; //0x174 UCHAR PlaceholderHydrationAlwaysExplicit; //0x175 CHAR PlaceholderReserved[10]; //0x176 ULONG ProxiedProcessId; //0x180 struct _ACTIVATION_CONTEXT_STACK32 _ActivationStack; //0x184 UCHAR WorkingOnBehalfTicket[8]; //0x19c LONG ExceptionCode; //0x1a4 ULONG ActivationContextStackPointer; //0x1a8 ULONG InstrumentationCallbackSp; //0x1ac ULONG InstrumentationCallbackPreviousPc; //0x1b0 ULONG InstrumentationCallbackPreviousSp; //0x1b4 UCHAR InstrumentationCallbackDisabled; //0x1b8 UCHAR SpareBytes[23]; //0x1b9 ULONG TxFsContext; //0x1d0 struct _GDI_TEB_BATCH32 GdiTebBatch; //0x1d4 struct _CLIENT_ID32 RealClientId; //0x6b4 ULONG GdiCachedProcessHandle; //0x6bc ULONG GdiClientPID; //0x6c0 ULONG GdiClientTID; //0x6c4 ULONG GdiThreadLocalInfo; //0x6c8 ULONG Win32ClientInfo[62]; //0x6cc ULONG glDispatchTable[233]; //0x7c4 ULONG glReserved1[29]; //0xb68 ULONG glReserved2; //0xbdc ULONG glSectionInfo; //0xbe0 ULONG glSection; //0xbe4 ULONG glTable; //0xbe8 ULONG glCurrentRC; //0xbec ULONG glContext; //0xbf0 ULONG LastStatusValue; //0xbf4 struct _STRING32 StaticUnicodeString; //0xbf8 WCHAR StaticUnicodeBuffer[261]; //0xc00 ULONG DeallocationStack; //0xe0c ULONG TlsSlots[64]; //0xe10 struct LIST_ENTRY32 TlsLinks; //0xf10 ULONG Vdm; //0xf18 ULONG ReservedForNtRpc; //0xf1c ULONG DbgSsReserved[2]; //0xf20 ULONG HardErrorMode; //0xf28 ULONG Instrumentation[9]; //0xf2c struct _GUID ActivityId; //0xf50 ULONG SubProcessTag; //0xf60 ULONG PerflibData; //0xf64 ULONG EtwTraceData; //0xf68 ULONG WinSockData; //0xf6c ULONG GdiBatchCount; //0xf70 union { struct _PROCESSOR_NUMBER CurrentIdealProcessor; //0xf74 ULONG IdealProcessorValue; //0xf74 struct { UCHAR ReservedPad0; //0xf74 UCHAR ReservedPad1; //0xf75 UCHAR ReservedPad2; //0xf76 UCHAR IdealProcessor; //0xf77 }; }; ULONG GuaranteedStackBytes; //0xf78 ULONG ReservedForPerf; //0xf7c ULONG ReservedForOle; //0xf80 ULONG WaitingOnLoaderLock; //0xf84 ULONG SavedPriorityState; //0xf88 ULONG ReservedForCodeCoverage; //0xf8c ULONG ThreadPoolData; //0xf90 ULONG TlsExpansionSlots; //0xf94 ULONG MuiGeneration; //0xf98 ULONG IsImpersonating; //0xf9c ULONG NlsCache; //0xfa0 ULONG pShimData; //0xfa4 ULONG HeapData; //0xfa8 ULONG CurrentTransactionHandle; //0xfac ULONG ActiveFrame; //0xfb0 ULONG FlsData; //0xfb4 ULONG PreferredLanguages; //0xfb8 ULONG UserPrefLanguages; //0xfbc ULONG MergedPrefLanguages; //0xfc0 ULONG MuiImpersonation; //0xfc4 union { volatile USHORT CrossTebFlags; //0xfc8 USHORT SpareCrossTebBits:16; //0xfc8 }; union { USHORT SameTebFlags; //0xfca struct { USHORT SafeThunkCall:1; //0xfca USHORT InDebugPrint:1; //0xfca USHORT HasFiberData:1; //0xfca USHORT SkipThreadAttach:1; //0xfca USHORT WerInShipAssertCode:1; //0xfca USHORT RanProcessInit:1; //0xfca USHORT ClonedThread:1; //0xfca USHORT SuppressDebugMsg:1; //0xfca USHORT DisableUserStackWalk:1; //0xfca USHORT RtlExceptionAttached:1; //0xfca USHORT InitialThread:1; //0xfca USHORT SessionAware:1; //0xfca USHORT LoadOwner:1; //0xfca USHORT LoaderWorker:1; //0xfca USHORT SkipLoaderInit:1; //0xfca USHORT SpareSameTebBits:1; //0xfca }; }; ULONG TxnScopeEnterCallback; //0xfcc ULONG TxnScopeExitCallback; //0xfd0 ULONG TxnScopeContext; //0xfd4 ULONG LockCount; //0xfd8 LONG WowTebOffset; //0xfdc ULONG ResourceRetValue; //0xfe0 ULONG ReservedForWdf; //0xfe4 ULONGLONG ReservedForCrt; //0xfe8 struct _GUID EffectiveContainerId; //0xff0 }; ``` ### 64 位 ``` //0x1838 bytes (sizeof) struct _TEB64 { struct _NT_TIB64 NtTib; //0x0 ULONGLONG EnvironmentPointer; //0x38 struct _CLIENT_ID64 ClientId; //0x40 ULONGLONG ActiveRpcHandle; //0x50 ULONGLONG ThreadLocalStoragePointer; //0x58 ULONGLONG ProcessEnvironmentBlock; //0x60 ULONG LastErrorValue; //0x68 ULONG CountOfOwnedCriticalSections; //0x6c ULONGLONG CsrClientThread; //0x70 ULONGLONG Win32ThreadInfo; //0x78 ULONG User32Reserved[26]; //0x80 ULONG UserReserved[5]; //0xe8 ULONGLONG WOW32Reserved; //0x100 ULONG CurrentLocale; //0x108 ULONG FpSoftwareStatusRegister; //0x10c ULONGLONG ReservedForDebuggerInstrumentation[16]; //0x110 ULONGLONG SystemReserved1[30]; //0x190 CHAR PlaceholderCompatibilityMode; //0x280 UCHAR PlaceholderHydrationAlwaysExplicit; //0x281 CHAR PlaceholderReserved[10]; //0x282 ULONG ProxiedProcessId; //0x28c struct _ACTIVATION_CONTEXT_STACK64 _ActivationStack; //0x290 UCHAR WorkingOnBehalfTicket[8]; //0x2b8 LONG ExceptionCode; //0x2c0 UCHAR Padding0[4]; //0x2c4 ULONGLONG ActivationContextStackPointer; //0x2c8 ULONGLONG InstrumentationCallbackSp; //0x2d0 ULONGLONG InstrumentationCallbackPreviousPc; //0x2d8 ULONGLONG InstrumentationCallbackPreviousSp; //0x2e0 ULONG TxFsContext; //0x2e8 UCHAR InstrumentationCallbackDisabled; //0x2ec UCHAR UnalignedLoadStoreExceptions; //0x2ed UCHAR Padding1[2]; //0x2ee struct _GDI_TEB_BATCH64 GdiTebBatch; //0x2f0 struct _CLIENT_ID64 RealClientId; //0x7d8 ULONGLONG GdiCachedProcessHandle; //0x7e8 ULONG GdiClientPID; //0x7f0 ULONG GdiClientTID; //0x7f4 ULONGLONG GdiThreadLocalInfo; //0x7f8 ULONGLONG Win32ClientInfo[62]; //0x800 ULONGLONG glDispatchTable[233]; //0x9f0 ULONGLONG glReserved1[29]; //0x1138 ULONGLONG glReserved2; //0x1220 ULONGLONG glSectionInfo; //0x1228 ULONGLONG glSection; //0x1230 ULONGLONG glTable; //0x1238 ULONGLONG glCurrentRC; //0x1240 ULONGLONG glContext; //0x1248 ULONG LastStatusValue; //0x1250 UCHAR Padding2[4]; //0x1254 struct _STRING64 StaticUnicodeString; //0x1258 WCHAR StaticUnicodeBuffer[261]; //0x1268 UCHAR Padding3[6]; //0x1472 ULONGLONG DeallocationStack; //0x1478 ULONGLONG TlsSlots[64]; //0x1480 struct LIST_ENTRY64 TlsLinks; //0x1680 ULONGLONG Vdm; //0x1690 ULONGLONG ReservedForNtRpc; //0x1698 ULONGLONG DbgSsReserved[2]; //0x16a0 ULONG HardErrorMode; //0x16b0 UCHAR Padding4[4]; //0x16b4 ULONGLONG Instrumentation[11]; //0x16b8 struct _GUID ActivityId; //0x1710 ULONGLONG SubProcessTag; //0x1720 ULONGLONG PerflibData; //0x1728 ULONGLONG EtwTraceData; //0x1730 ULONGLONG WinSockData; //0x1738 ULONG GdiBatchCount; //0x1740 union { struct _PROCESSOR_NUMBER CurrentIdealProcessor; //0x1744 ULONG IdealProcessorValue; //0x1744 struct { UCHAR ReservedPad0; //0x1744 UCHAR ReservedPad1; //0x1745 UCHAR ReservedPad2; //0x1746 UCHAR IdealProcessor; //0x1747 }; }; ULONG GuaranteedStackBytes; //0x1748 UCHAR Padding5[4]; //0x174c ULONGLONG ReservedForPerf; //0x1750 ULONGLONG ReservedForOle; //0x1758 ULONG WaitingOnLoaderLock; //0x1760 UCHAR Padding6[4]; //0x1764 ULONGLONG SavedPriorityState; //0x1768 ULONGLONG ReservedForCodeCoverage; //0x1770 ULONGLONG ThreadPoolData; //0x1778 ULONGLONG TlsExpansionSlots; //0x1780 ULONGLONG DeallocationBStore; //0x1788 ULONGLONG BStoreLimit; //0x1790 ULONG MuiGeneration; //0x1798 ULONG IsImpersonating; //0x179c ULONGLONG NlsCache; //0x17a0 ULONGLONG pShimData; //0x17a8 ULONG HeapData; //0x17b0 UCHAR Padding7[4]; //0x17b4 ULONGLONG CurrentTransactionHandle; //0x17b8 ULONGLONG ActiveFrame; //0x17c0 ULONGLONG FlsData; //0x17c8 ULONGLONG PreferredLanguages; //0x17d0 ULONGLONG UserPrefLanguages; //0x17d8 ULONGLONG MergedPrefLanguages; //0x17e0 ULONG MuiImpersonation; //0x17e8 union { volatile USHORT CrossTebFlags; //0x17ec USHORT SpareCrossTebBits:16; //0x17ec }; union { USHORT SameTebFlags; //0x17ee struct { USHORT SafeThunkCall:1; //0x17ee USHORT InDebugPrint:1; //0x17ee USHORT HasFiberData:1; //0x17ee USHORT SkipThreadAttach:1; //0x17ee USHORT WerInShipAssertCode:1; //0x17ee USHORT RanProcessInit:1; //0x17ee USHORT ClonedThread:1; //0x17ee USHORT SuppressDebugMsg:1; //0x17ee USHORT DisableUserStackWalk:1; //0x17ee USHORT RtlExceptionAttached:1; //0x17ee USHORT InitialThread:1; //0x17ee USHORT SessionAware:1; //0x17ee USHORT LoadOwner:1; //0x17ee USHORT LoaderWorker:1; //0x17ee USHORT SkipLoaderInit:1; //0x17ee USHORT SpareSameTebBits:1; //0x17ee }; }; ULONGLONG TxnScopeEnterCallback; //0x17f0 ULONGLONG TxnScopeExitCallback; //0x17f8 ULONGLONG TxnScopeContext; //0x1800 ULONG LockCount; //0x1808 LONG WowTebOffset; //0x180c ULONGLONG ResourceRetValue; //0x1810 ULONGLONG ReservedForWdf; //0x1818 ULONGLONG ReservedForCrt; //0x1820 struct _GUID EffectiveContainerId; //0x1828 }; ``` ## 重要成员 ### 32 位 - `0x00 NtTib (TIB) `:线程环境块 - `0x20 ClientId`:进程和线程信息 - `0x30 ProcessEnvironmentBlock (PEB) `:进程环境块,结构体指针(4Byte) - `0x3c CsrClientThread`:负责处理用户态和内核态之间的通信 - `0x40 Win32ThreadInfo `: ### 64 位 - `0x00 NtTib (TIB) `:线程环境块,内嵌结构体 - `0x40 ClientId`:进程和线程信息,内嵌结构体 - `0x60 ProcessEnvironmentBlock (PEB) `:进程环境块,结构体指针(8Byte) - `0x70 CsrClientThread`:负责处理用户态和内核态之间的通信 - `0x78 Win32ThreadInfo `: # TIB(Thread Information Block/线程信息块) - `TEB 调用 TIB 不是指针调用,而是将 TIB 结构体作为一个成员包含在 TEB中。` ## 结构 ### 32 位 ``` //0x1c bytes (sizeof) struct _NT_TIB32 { ULONG ExceptionList; //0x0 ULONG StackBase; //0x4 ULONG StackLimit; //0x8 ULONG SubSystemTib; //0xc union { ULONG FiberData; //0x10 ULONG Version; //0x10 }; ULONG ArbitraryUserPointer; //0x14 ULONG Self; //0x18 }; ``` ### 64 位 ``` copy //0x38 bytes (sizeof) struct _NT_TIB { struct _EXCEPTION_REGISTRATION_RECORD* ExceptionList; //0x0 VOID* StackBase; //0x8 VOID* StackLimit; //0x10 VOID* SubSystemTib; //0x18 union { VOID* FiberData; //0x20 ULONG Version; //0x20 }; VOID* ArbitraryUserPointer; //0x28 struct _NT_TIB* Self; //0x30 }; ``` ## 重要成员 - 偏移相较于 TEB 和 TIB 都是这个值 ### 32 位 - 0x00 `ExceptionList`:即为指向**_EXCEPTION_REGISTRATION_RECORD**结构体的链表指针(SEH) - 0x04 StackBase:这里为线程堆栈顶部 - 0x08 StackLimit:这里为线程堆栈底部 - 0x0c FiberData:线程数据 - 0x18 `Self`:4Byte,这为_NT_TIB结构体的自引用指针,即为NtCurrentTeb()函数所读出的TEB结构体指针 ### 64 位 - 0x00 `ExceptionList`:即为指向_EXCEPTION_REGISTRATION_RECORD结构体的链表指针(SEH) - 0x08 StackBase:这里为线程堆栈顶部 - 0x10 StackLimit:这里为线程堆栈底部 - 0x18 FiberData:线程数据 - 0x30 `Self`:8Byte,这为_NT_TIB结构体的自引用指针,即为NtCurrentTeb()函数所读出的TEB结构体指针 # CLIENT_ID ## 结构 ### 32 位 ``` //0x8 bytes (sizeof) struct _CLIENT_ID32 { ULONG UniqueProcess; //0x0 ULONG UniqueThread; //0x4 }; ``` ### 64 位 ``` //0x10 bytes (sizeof) struct _CLIENT_ID { VOID* UniqueProcess; //0x0 VOID* UniqueThread; //0x8 }; ``` ## 重要成员 **UniqueProcess**:这个为当前进程的的 Pid,可用函数 GetCurrentProcessId() 访问当前结构体成员获取进程标识符(32 位是 4 字节,64 位是 8 字节) **UniqueThread**: 这个为当前线程的的 Tid,可用函数 GetCurrentThreadId() 访问当前结构体成员获取线程标识符(32 位是 4 字节,64 位是 8 字节) # PEB(Process Environment Block/进程环境块) ## 结构 ### 32 位 ``` //0x480 bytes (sizeof) struct _PEB32 { UCHAR InheritedAddressSpace; //0x0 UCHAR ReadImageFileExecOptions; //0x1 UCHAR BeingDebugged; //0x2 union { UCHAR BitField; //0x3 struct { UCHAR ImageUsesLargePages:1; //0x3 UCHAR IsProtectedProcess:1; //0x3 UCHAR IsImageDynamicallyRelocated:1; //0x3 UCHAR SkipPatchingUser32Forwarders:1; //0x3 UCHAR IsPackagedProcess:1; //0x3 UCHAR IsAppContainer:1; //0x3 UCHAR IsProtectedProcessLight:1; //0x3 UCHAR IsLongPathAwareProcess:1; //0x3 }; }; ULONG Mutant; //0x4 ULONG ImageBaseAddress; //0x8 ULONG Ldr; //0xc ULONG ProcessParameters; //0x10 ULONG SubSystemData; //0x14 ULONG ProcessHeap; //0x18 ULONG FastPebLock; //0x1c ULONG AtlThunkSListPtr; //0x20 ULONG IFEOKey; //0x24 union { ULONG CrossProcessFlags; //0x28 struct { ULONG ProcessInJob:1; //0x28 ULONG ProcessInitializing:1; //0x28 ULONG ProcessUsingVEH:1; //0x28 ULONG ProcessUsingVCH:1; //0x28 ULONG ProcessUsingFTH:1; //0x28 ULONG ProcessPreviouslyThrottled:1; //0x28 ULONG ProcessCurrentlyThrottled:1; //0x28 ULONG ProcessImagesHotPatched:1; //0x28 ULONG ReservedBits0:24; //0x28 }; }; union { ULONG KernelCallbackTable; //0x2c ULONG UserSharedInfoPtr; //0x2c }; ULONG SystemReserved; //0x30 ULONG AtlThunkSListPtr32; //0x34 ULONG ApiSetMap; //0x38 ULONG TlsExpansionCounter; //0x3c ULONG TlsBitmap; //0x40 ULONG TlsBitmapBits[2]; //0x44 ULONG ReadOnlySharedMemoryBase; //0x4c ULONG SharedData; //0x50 ULONG ReadOnlyStaticServerData; //0x54 ULONG AnsiCodePageData; //0x58 ULONG OemCodePageData; //0x5c ULONG UnicodeCaseTableData; //0x60 ULONG NumberOfProcessors; //0x64 ULONG NtGlobalFlag; //0x68 union _LARGE_INTEGER CriticalSectionTimeout; //0x70 ULONG HeapSegmentReserve; //0x78 ULONG HeapSegmentCommit; //0x7c ULONG HeapDeCommitTotalFreeThreshold; //0x80 ULONG HeapDeCommitFreeBlockThreshold; //0x84 ULONG NumberOfHeaps; //0x88 ULONG MaximumNumberOfHeaps; //0x8c ULONG ProcessHeaps; //0x90 ULONG GdiSharedHandleTable; //0x94 ULONG ProcessStarterHelper; //0x98 ULONG GdiDCAttributeList; //0x9c ULONG LoaderLock; //0xa0 ULONG OSMajorVersion; //0xa4 ULONG OSMinorVersion; //0xa8 USHORT OSBuildNumber; //0xac USHORT OSCSDVersion; //0xae ULONG OSPlatformId; //0xb0 ULONG ImageSubsystem; //0xb4 ULONG ImageSubsystemMajorVersion; //0xb8 ULONG ImageSubsystemMinorVersion; //0xbc ULONG ActiveProcessAffinityMask; //0xc0 ULONG GdiHandleBuffer[34]; //0xc4 ULONG PostProcessInitRoutine; //0x14c ULONG TlsExpansionBitmap; //0x150 ULONG TlsExpansionBitmapBits[32]; //0x154 ULONG SessionId; //0x1d4 union _ULARGE_INTEGER AppCompatFlags; //0x1d8 union _ULARGE_INTEGER AppCompatFlagsUser; //0x1e0 ULONG pShimData; //0x1e8 ULONG AppCompatInfo; //0x1ec struct _STRING32 CSDVersion; //0x1f0 ULONG ActivationContextData; //0x1f8 ULONG ProcessAssemblyStorageMap; //0x1fc ULONG SystemDefaultActivationContextData; //0x200 ULONG SystemAssemblyStorageMap; //0x204 ULONG MinimumStackCommit; //0x208 ULONG SparePointers[4]; //0x20c ULONG SpareUlongs[5]; //0x21c ULONG WerRegistrationData; //0x230 ULONG WerShipAssertPtr; //0x234 ULONG pUnused; //0x238 ULONG pImageHeaderHash; //0x23c union { ULONG TracingFlags; //0x240 struct { ULONG HeapTracingEnabled:1; //0x240 ULONG CritSecTracingEnabled:1; //0x240 ULONG LibLoaderTracingEnabled:1; //0x240 ULONG SpareTracingBits:29; //0x240 }; }; ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x248 ULONG TppWorkerpListLock; //0x250 struct LIST_ENTRY32 TppWorkerpList; //0x254 ULONG WaitOnAddressHashTable[128]; //0x25c ULONG TelemetryCoverageHeader; //0x45c ULONG CloudFileFlags; //0x460 ULONG CloudFileDiagFlags; //0x464 CHAR PlaceholderCompatibilityMode; //0x468 CHAR PlaceholderCompatibilityModeReserved[7]; //0x469 ULONG LeapSecondData; //0x470 union { ULONG LeapSecondFlags; //0x474 struct { ULONG SixtySecondEnabled:1; //0x474 ULONG Reserved:31; //0x474 }; }; ULONG NtGlobalFlag2; //0x478 }; ``` ### 64 位 ``` //0x7c8 bytes (sizeof) struct _PEB { UCHAR InheritedAddressSpace; //0x0 UCHAR ReadImageFileExecOptions; //0x1 UCHAR BeingDebugged; //0x2 union { UCHAR BitField; //0x3 struct { UCHAR ImageUsesLargePages:1; //0x3 UCHAR IsProtectedProcess:1; //0x3 UCHAR IsImageDynamicallyRelocated:1; //0x3 UCHAR SkipPatchingUser32Forwarders:1; //0x3 UCHAR IsPackagedProcess:1; //0x3 UCHAR IsAppContainer:1; //0x3 UCHAR IsProtectedProcessLight:1; //0x3 UCHAR IsLongPathAwareProcess:1; //0x3 }; }; UCHAR Padding0[4]; //0x4 VOID* Mutant; //0x8 VOID* ImageBaseAddress; //0x10 struct _PEB_LDR_DATA* Ldr; //0x18 struct _RTL_USER_PROCESS_PARAMETERS* ProcessParameters; //0x20 VOID* SubSystemData; //0x28 VOID* ProcessHeap; //0x30 struct _RTL_CRITICAL_SECTION* FastPebLock; //0x38 union _SLIST_HEADER* volatile AtlThunkSListPtr; //0x40 VOID* IFEOKey; //0x48 union { ULONG CrossProcessFlags; //0x50 struct { ULONG ProcessInJob:1; //0x50 ULONG ProcessInitializing:1; //0x50 ULONG ProcessUsingVEH:1; //0x50 ULONG ProcessUsingVCH:1; //0x50 ULONG ProcessUsingFTH:1; //0x50 ULONG ProcessPreviouslyThrottled:1; //0x50 ULONG ProcessCurrentlyThrottled:1; //0x50 ULONG ProcessImagesHotPatched:1; //0x50 ULONG ReservedBits0:24; //0x50 }; }; UCHAR Padding1[4]; //0x54 union { VOID* KernelCallbackTable; //0x58 VOID* UserSharedInfoPtr; //0x58 }; ULONG SystemReserved; //0x60 ULONG AtlThunkSListPtr32; //0x64 VOID* ApiSetMap; //0x68 ULONG TlsExpansionCounter; //0x70 UCHAR Padding2[4]; //0x74 VOID* TlsBitmap; //0x78 ULONG TlsBitmapBits[2]; //0x80 VOID* ReadOnlySharedMemoryBase; //0x88 VOID* SharedData; //0x90 VOID** ReadOnlyStaticServerData; //0x98 VOID* AnsiCodePageData; //0xa0 VOID* OemCodePageData; //0xa8 VOID* UnicodeCaseTableData; //0xb0 ULONG NumberOfProcessors; //0xb8 ULONG NtGlobalFlag; //0xbc union _LARGE_INTEGER CriticalSectionTimeout; //0xc0 ULONGLONG HeapSegmentReserve; //0xc8 ULONGLONG HeapSegmentCommit; //0xd0 ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 ULONG NumberOfHeaps; //0xe8 ULONG MaximumNumberOfHeaps; //0xec VOID** ProcessHeaps; //0xf0 VOID* GdiSharedHandleTable; //0xf8 VOID* ProcessStarterHelper; //0x100 ULONG GdiDCAttributeList; //0x108 UCHAR Padding3[4]; //0x10c struct _RTL_CRITICAL_SECTION* LoaderLock; //0x110 ULONG OSMajorVersion; //0x118 ULONG OSMinorVersion; //0x11c USHORT OSBuildNumber; //0x120 USHORT OSCSDVersion; //0x122 ULONG OSPlatformId; //0x124 ULONG ImageSubsystem; //0x128 ULONG ImageSubsystemMajorVersion; //0x12c ULONG ImageSubsystemMinorVersion; //0x130 UCHAR Padding4[4]; //0x134 ULONGLONG ActiveProcessAffinityMask; //0x138 ULONG GdiHandleBuffer[60]; //0x140 VOID (*PostProcessInitRoutine)(); //0x230 VOID* TlsExpansionBitmap; //0x238 ULONG TlsExpansionBitmapBits[32]; //0x240 ULONG SessionId; //0x2c0 UCHAR Padding5[4]; //0x2c4 union _ULARGE_INTEGER AppCompatFlags; //0x2c8 union _ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 VOID* pShimData; //0x2d8 VOID* AppCompatInfo; //0x2e0 struct _UNICODE_STRING CSDVersion; //0x2e8 struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 ULONGLONG MinimumStackCommit; //0x318 VOID* SparePointers[4]; //0x320 ULONG SpareUlongs[5]; //0x340 VOID* WerRegistrationData; //0x358 VOID* WerShipAssertPtr; //0x360 VOID* pUnused; //0x368 VOID* pImageHeaderHash; //0x370 union { ULONG TracingFlags; //0x378 struct { ULONG HeapTracingEnabled:1; //0x378 ULONG CritSecTracingEnabled:1; //0x378 ULONG LibLoaderTracingEnabled:1; //0x378 ULONG SpareTracingBits:29; //0x378 }; }; UCHAR Padding6[4]; //0x37c ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 ULONGLONG TppWorkerpListLock; //0x388 struct _LIST_ENTRY TppWorkerpList; //0x390 VOID* WaitOnAddressHashTable[128]; //0x3a0 VOID* TelemetryCoverageHeader; //0x7a0 ULONG CloudFileFlags; //0x7a8 ULONG CloudFileDiagFlags; //0x7ac CHAR PlaceholderCompatibilityMode; //0x7b0 CHAR PlaceholderCompatibilityModeReserved[7]; //0x7b1 struct _LEAP_SECOND_DATA* LeapSecondData; //0x7b8 union { ULONG LeapSecondFlags; //0x7c0 struct { ULONG SixtySecondEnabled:1; //0x7c0 ULONG Reserved:31; //0x7c0 }; }; ULONG NtGlobalFlag2; //0x7c4 }; ``` ## 重要成员 ### 32 位 - 0x2 UCHAR BeingDebugged:1Byte - 0x8 ULONG ImageBaseAddress:4Byte - 0xc ULONG Ldr:4Byte,结构体指针 - 0x18 ULONG ProcessHeap:4Byte - 0x68 ULONG NtGlobalFlag:4Byte - 0x88 ULONG NumberOfHeaps:4Byte - 0x90 ULONG ProcessHeaps:4Byte ### 64 位 - 0x2 UCHAR BeingDebugged:1Byte - 0x10 VOID* ImageBaseAddress:8Byte - 0x18 ULONG Ldr:8Byte,结构体指针 - 0x30 ULONG ProcessHeap:8Byte - 0xbc ULONG NtGlobalFlag:4Byte - 0xe8 ULONG NumberOfHeaps:4Byte - 0xf0 VOID** ProcessHeaps:8Byte ## 重点介绍 ### BeingDebugged - 表示**进程当前是否处于调试状态**,也就是函数 IsDebuggerPresent()所访问的结构体成员。 - 该值如果是 1 则表示调试状态,为 0 则不是调试状态。 ### ImageBaseAddress - 自身的 ImageBase ,这里是**实际装载地址**,不是 PE 头中的 ImageBase,PE 头中的是建议装载地址,可能和这里不一样。GetModuleHandle 就是获取这个结构。 ### Ldr - **包含了 3 个模块链表结构体_LIST_ENTRY,每个 dll 加载时都生成一个 LDR_DATA_TABLE_ENTRY 结构体,里面也`内嵌`了这三个 _LIST_ENTRY,并互相形成链表。** #### 32 位 ``` //0x30 bytes (sizeof) struct _PEB_LDR_DATA { ULONG Length; //0x0 UCHAR Initialized; //0x4 VOID* SsHandle; //0x8 struct _LIST_ENTRY InLoadOrderModuleList; //0xc struct _LIST_ENTRY InMemoryOrderModuleList; //0x14 struct _LIST_ENTRY InInitializationOrderModuleList; //0x1c VOID* EntryInProgress; //0x24 UCHAR ShutdownInProgress; //0x28 VOID* ShutdownThreadId; //0x2c }; ``` #### 64 位 ``` //0x58 bytes (sizeof) struct _PEB_LDR_DATA { ULONG Length; //0x0 UCHAR Initialized; //0x4 VOID* SsHandle; //0x8 struct _LIST_ENTRY InLoadOrderModuleList; //0x10 struct _LIST_ENTRY InMemoryOrderModuleList; //0x20 struct _LIST_ENTRY InInitializationOrderModuleList; //0x30 VOID* EntryInProgress; //0x40 UCHAR ShutdownInProgress; //0x48 VOID* ShutdownThreadId; //0x50 }; ``` #### 成员分析 - Length:结构体的大小 - Initialized:进程是否初始化完成,完成是 0x1 - InLoadOrderModuleList:`内嵌结构体,非指针,第二个参数指向下一个`,模块链表,以加载顺序排序 - InMemoryOrderModuleList:`内嵌结构体,非指针,第二个参数指向下一个`模块链表,以内存位置排序 - InInitializationOrderModuleList:`内嵌结构体,非指针,第二个参数指向下一个`模块链表,以初始化顺序排序 - 这三个成员的结构体如下 ##### _LIST_ENTRY ``` // 32 位 // 0x8 bytes (sizeof) struct _LIST_ENTRY { struct _LIST_ENTRY* Flink; // 0x0 struct _LIST_ENTRY* Blink; // 0x4 }; // 64 位 // 0x10 bytes (sizeof) struct _LIST_ENTRY { struct _LIST_ENTRY* Flink; // 0x0 struct _LIST_ENTRY* Blink; // 0x8 }; ``` - 一个不包含参数的双链表,用来索引模块。 #### _LDR_DATA_TABLE_ENTRY(Dll 描述) - **LDR_DATA_TABLE_ENTRY 是 Windows 操作系统中的一个结构体,它用于表示加载的动态链接库(DLL)的信息。每当在进程中加载一个 DLL 时,系统都会创建一个 LDR_DATA_TABLE_ENTRY 结构来描述该 DLL。** ##### 32 位 ``` //0xa8 bytes (sizeof) struct _LDR_DATA_TABLE_ENTRY { struct _LIST_ENTRY InLoadOrderLinks; //0x0 struct _LIST_ENTRY InMemoryOrderLinks; //0x8 struct _LIST_ENTRY InInitializationOrderLinks; //0x10 VOID* DllBase; //0x18 VOID* EntryPoint; //0x1c ULONG SizeOfImage; //0x20 struct _UNICODE_STRING FullDllName; //0x24 struct _UNICODE_STRING BaseDllName; //0x2c union { UCHAR FlagGroup[4]; //0x34 ULONG Flags; //0x34 struct { ULONG PackagedBinary:1; //0x34 ULONG MarkedForRemoval:1; //0x34 ULONG ImageDll:1; //0x34 ULONG LoadNotificationsSent:1; //0x34 ULONG TelemetryEntryProcessed:1; //0x34 ULONG ProcessStaticImport:1; //0x34 ULONG InLegacyLists:1; //0x34 ULONG InIndexes:1; //0x34 ULONG ShimDll:1; //0x34 ULONG InExceptionTable:1; //0x34 ULONG ReservedFlags1:2; //0x34 ULONG LoadInProgress:1; //0x34 ULONG LoadConfigProcessed:1; //0x34 ULONG EntryProcessed:1; //0x34 ULONG ProtectDelayLoad:1; //0x34 ULONG ReservedFlags3:2; //0x34 ULONG DontCallForThreads:1; //0x34 ULONG ProcessAttachCalled:1; //0x34 ULONG ProcessAttachFailed:1; //0x34 ULONG CorDeferredValidate:1; //0x34 ULONG CorImage:1; //0x34 ULONG DontRelocate:1; //0x34 ULONG CorILOnly:1; //0x34 ULONG ChpeImage:1; //0x34 ULONG ReservedFlags5:2; //0x34 ULONG Redirected:1; //0x34 ULONG ReservedFlags6:2; //0x34 ULONG CompatDatabaseProcessed:1; //0x34 }; }; USHORT ObsoleteLoadCount; //0x38 USHORT TlsIndex; //0x3a struct _LIST_ENTRY HashLinks; //0x3c ULONG TimeDateStamp; //0x44 struct _ACTIVATION_CONTEXT* EntryPointActivationContext; //0x48 VOID* Lock; //0x4c struct _LDR_DDAG_NODE* DdagNode; //0x50 struct _LIST_ENTRY NodeModuleLink; //0x54 struct _LDRP_LOAD_CONTEXT* LoadContext; //0x5c VOID* ParentDllBase; //0x60 VOID* SwitchBackContext; //0x64 struct _RTL_BALANCED_NODE BaseAddressIndexNode; //0x68 struct _RTL_BALANCED_NODE MappingInfoIndexNode; //0x74 ULONG OriginalBase; //0x80 union _LARGE_INTEGER LoadTime; //0x88 ULONG BaseNameHashValue; //0x90 enum _LDR_DLL_LOAD_REASON LoadReason; //0x94 ULONG ImplicitPathOptions; //0x98 ULONG ReferenceCount; //0x9c ULONG DependentLoadFlags; //0xa0 UCHAR SigningLevel; //0xa4 }; ``` ##### 64 位 ``` //0x120 bytes (sizeof) struct _LDR_DATA_TABLE_ENTRY { struct _LIST_ENTRY InLoadOrderLinks; //0x0 struct _LIST_ENTRY InMemoryOrderLinks; //0x10 struct _LIST_ENTRY InInitializationOrderLinks; //0x20 VOID* DllBase; //0x30 VOID* EntryPoint; //0x38 ULONG SizeOfImage; //0x40 struct _UNICODE_STRING FullDllName; //0x48 struct _UNICODE_STRING BaseDllName; //0x58 union { UCHAR FlagGroup[4]; //0x68 ULONG Flags; //0x68 struct { ULONG PackagedBinary:1; //0x68 ULONG MarkedForRemoval:1; //0x68 ULONG ImageDll:1; //0x68 ULONG LoadNotificationsSent:1; //0x68 ULONG TelemetryEntryProcessed:1; //0x68 ULONG ProcessStaticImport:1; //0x68 ULONG InLegacyLists:1; //0x68 ULONG InIndexes:1; //0x68 ULONG ShimDll:1; //0x68 ULONG InExceptionTable:1; //0x68 ULONG ReservedFlags1:2; //0x68 ULONG LoadInProgress:1; //0x68 ULONG LoadConfigProcessed:1; //0x68 ULONG EntryProcessed:1; //0x68 ULONG ProtectDelayLoad:1; //0x68 ULONG ReservedFlags3:2; //0x68 ULONG DontCallForThreads:1; //0x68 ULONG ProcessAttachCalled:1; //0x68 ULONG ProcessAttachFailed:1; //0x68 ULONG CorDeferredValidate:1; //0x68 ULONG CorImage:1; //0x68 ULONG DontRelocate:1; //0x68 ULONG CorILOnly:1; //0x68 ULONG ChpeImage:1; //0x68 ULONG ReservedFlags5:2; //0x68 ULONG Redirected:1; //0x68 ULONG ReservedFlags6:2; //0x68 ULONG CompatDatabaseProcessed:1; //0x68 }; }; USHORT ObsoleteLoadCount; //0x6c USHORT TlsIndex; //0x6e struct _LIST_ENTRY HashLinks; //0x70 ULONG TimeDateStamp; //0x80 struct _ACTIVATION_CONTEXT* EntryPointActivationContext; //0x88 VOID* Lock; //0x90 struct _LDR_DDAG_NODE* DdagNode; //0x98 struct _LIST_ENTRY NodeModuleLink; //0xa0 struct _LDRP_LOAD_CONTEXT* LoadContext; //0xb0 VOID* ParentDllBase; //0xb8 VOID* SwitchBackContext; //0xc0 struct _RTL_BALANCED_NODE BaseAddressIndexNode; //0xc8 struct _RTL_BALANCED_NODE MappingInfoIndexNode; //0xe0 ULONGLONG OriginalBase; //0xf8 union _LARGE_INTEGER LoadTime; //0x100 ULONG BaseNameHashValue; //0x108 enum _LDR_DLL_LOAD_REASON LoadReason; //0x10c ULONG ImplicitPathOptions; //0x110 ULONG ReferenceCount; //0x114 ULONG DependentLoadFlags; //0x118 UCHAR SigningLevel; //0x11c }; ``` ##### _LDR_DATA_TABLE_ENTRY 分析 - DllBase(32位 0x18,64 位 0x30)所指向的地址是 DOS头(MZ)。 - FullDllName 是个 _UNICODE_STRING 结构体,注意这个结构体的第三个参数才是指向字符串的指针。 - BaseDllName 和上面一样,区别是 FullDllName 保存的是包含了路径的模块名称,而 BaseDllName 是只有模块名称例如: - FullDllName:C:\Windows\SYSTEM32\RTWorkQ.DLL - BaseDllName:RTWorkQ.DLL - 可以看到 _LDR_DATA_TABLE_ENTRY 前三个**内嵌结构体**就是 _LIST_ENTRY,他们和 PEB 中的三个 _LIST_ENTRY 相互索引形成链表。如下: <=>PEB.Ldr.InLoadOrderModuleList<=>_LDR_DATA_TABLE_ENTRY[1].InLoadOrderLinks<=>_LDR_DATA_TABLE_ENTRY[2].InLoadOrderLinks<=>......直到最后一项索引到PEB.Ldr.InLoadOrderModuleList中,形成一个`闭合环形双向链表`。**另外两个链表也是类似。** - 32 位 struct _LIST_ENTRY InLoadOrderLinks; //0x0 struct _LIST_ENTRY InMemoryOrderLinks; //0x8 struct _LIST_ENTRY InInitializationOrderLinks; //0x10 VOID* DllBase; //0x18 VOID* EntryPoint; //0x1c ULONG SizeOfImage; //0x20 struct _UNICODE_STRING FullDllName; //0x24 struct _UNICODE_STRING BaseDllName; //0x2c - 64位 struct _LIST_ENTRY InLoadOrderLinks; //0x0 struct _LIST_ENTRY InMemoryOrderLinks; //0x10 struct _LIST_ENTRY InInitializationOrderLinks; //0x20 VOID* DllBase; //0x30 VOID* EntryPoint; //0x38 ULONG SizeOfImage; //0x40 struct _UNICODE_STRING FullDllName; //0x48 struct _UNICODE_STRING BaseDllName; //0x58 - `索引重点!!!`以 64 位为例: - 从 PEB.Ldr.InLoadOrderModuleList[1] (记住,第二个成员才是往后的指针索引) 往后索引 _LDR_DATA_TABLE_ENTRY,其 FullDllName 的偏移量是 0x48 - 0x00 = 0x48 - 从 PEB.Ldr.InMemoryOrderModuleList[1] (记住,第二个成员才是往后的指针索引)往后索引 _LDR_DATA_TABLE_ENTRY,其 FullDllName 的偏移量是 0x48 - 0x10 = 0x38 - 从 PEB.Ldr.InInitializationOrderModuleList[1] 记住,第二个成员才是往后的指针索引往后索引 _LDR_DATA_TABLE_ENTRY,其 FullDllName 的偏移量是 0x48 - 0x20 = 0x28 - `往前同理!!!` - `结构体指向的不是_LDR_DATA_TABLE_ENTRY结构体的头部,而是对应链表成员的头部`,对了,_UNICODE_STRING 也是个内嵌进入 _LDR_DATA_TABLE_ENTRY 的结构体,其结构如下: ``` // 32 位 // 0x8 bytes (sizeof) struct _UNICODE_STRING { USHORT Length; //0x0 USHORT MaximumLength; //0x2 WCHAR* Buffer; //0x4 }; // 64 位 // 0x10 bytes (sizeof) struct _UNICODE_STRING { USHORT Length; //0x0 USHORT MaximumLength; //0x2 WCHAR* Buffer; //0x8,这里是指针 }; ``` - 也就是说,想找到真正的名字,还需要在原有指向 FullDllName 的偏移基础上 +0x08 才是真正名字字符串的偏倚。 ### ProcessHeap -`进程堆的句柄`,这个字段存储了进程的主堆(Main Heap)的句柄。每个进程都有一个主堆,用于分配内存块。通过这个句柄,可以对主堆进行各种操作,如申请内存、释放内存等。 #### 结构 ##### Win10 32 位 ProcessHeap ``` //0x258 bytes (sizeof) struct _HEAP { union { struct _HEAP_SEGMENT Segment; //0x0 struct { struct _HEAP_ENTRY Entry; //0x0 ULONG SegmentSignature; //0x8 ULONG SegmentFlags; //0xc struct _LIST_ENTRY SegmentListEntry; //0x10 struct _HEAP* Heap; //0x18 VOID* BaseAddress; //0x1c ULONG NumberOfPages; //0x20 struct _HEAP_ENTRY* FirstEntry; //0x24 struct _HEAP_ENTRY* LastValidEntry; //0x28 ULONG NumberOfUnCommittedPages; //0x2c ULONG NumberOfUnCommittedRanges; //0x30 USHORT SegmentAllocatorBackTraceIndex; //0x34 USHORT Reserved; //0x36 struct _LIST_ENTRY UCRSegmentList; //0x38 }; }; ULONG Flags; //0x40 ULONG ForceFlags; //0x44 ULONG CompatibilityFlags; //0x48 ULONG EncodeFlagMask; //0x4c struct _HEAP_ENTRY Encoding; //0x50 ULONG Interceptor; //0x58 ULONG VirtualMemoryThreshold; //0x5c ULONG Signature; //0x60 ULONG SegmentReserve; //0x64 ULONG SegmentCommit; //0x68 ULONG DeCommitFreeBlockThreshold; //0x6c ULONG DeCommitTotalFreeThreshold; //0x70 ULONG TotalFreeSize; //0x74 ULONG MaximumAllocationSize; //0x78 USHORT ProcessHeapsListIndex; //0x7c USHORT HeaderValidateLength; //0x7e VOID* HeaderValidateCopy; //0x80 USHORT NextAvailableTagIndex; //0x84 USHORT MaximumTagIndex; //0x86 struct _HEAP_TAG_ENTRY* TagEntries; //0x88 struct _LIST_ENTRY UCRList; //0x8c ULONG AlignRound; //0x94 ULONG AlignMask; //0x98 struct _LIST_ENTRY VirtualAllocdBlocks; //0x9c struct _LIST_ENTRY SegmentList; //0xa4 USHORT AllocatorBackTraceIndex; //0xac ULONG NonDedicatedListLength; //0xb0 VOID* BlocksIndex; //0xb4 VOID* UCRIndex; //0xb8 struct _HEAP_PSEUDO_TAG_ENTRY* PseudoTagEntries; //0xbc struct _LIST_ENTRY FreeLists; //0xc0 struct _HEAP_LOCK* LockVariable; //0xc8 LONG (*CommitRoutine)(VOID* arg1, VOID** arg2, ULONG* arg3); //0xcc union _RTL_RUN_ONCE StackTraceInitVar; //0xd0 struct _RTL_HEAP_MEMORY_LIMIT_DATA CommitLimitData; //0xd4 VOID* FrontEndHeap; //0xe4 USHORT FrontHeapLockCount; //0xe8 UCHAR FrontEndHeapType; //0xea UCHAR RequestedFrontEndHeapType; //0xeb WCHAR* FrontEndHeapUsageData; //0xec USHORT FrontEndHeapMaximumIndex; //0xf0 volatile UCHAR FrontEndHeapStatusBitmap[257]; //0xf2 struct _HEAP_COUNTERS Counters; //0x1f4 struct _HEAP_TUNING_PARAMETERS TuningParameters; //0x250 }; ``` ##### Win10 64 位 ProcessHeap ``` //0x2c0 bytes (sizeof) struct _HEAP { union { struct _HEAP_SEGMENT Segment; //0x0 struct { struct _HEAP_ENTRY Entry; //0x0 ULONG SegmentSignature; //0x10 ULONG SegmentFlags; //0x14 struct _LIST_ENTRY SegmentListEntry; //0x18 struct _HEAP* Heap; //0x28 VOID* BaseAddress; //0x30 ULONG NumberOfPages; //0x38 struct _HEAP_ENTRY* FirstEntry; //0x40 struct _HEAP_ENTRY* LastValidEntry; //0x48 ULONG NumberOfUnCommittedPages; //0x50 ULONG NumberOfUnCommittedRanges; //0x54 USHORT SegmentAllocatorBackTraceIndex; //0x58 USHORT Reserved; //0x5a struct _LIST_ENTRY UCRSegmentList; //0x60 }; }; ULONG Flags; //0x70 ULONG ForceFlags; //0x74 ULONG CompatibilityFlags; //0x78 ULONG EncodeFlagMask; //0x7c struct _HEAP_ENTRY Encoding; //0x80 ULONG Interceptor; //0x90 ULONG VirtualMemoryThreshold; //0x94 ULONG Signature; //0x98 ULONGLONG SegmentReserve; //0xa0 ULONGLONG SegmentCommit; //0xa8 ULONGLONG DeCommitFreeBlockThreshold; //0xb0 ULONGLONG DeCommitTotalFreeThreshold; //0xb8 ULONGLONG TotalFreeSize; //0xc0 ULONGLONG MaximumAllocationSize; //0xc8 USHORT ProcessHeapsListIndex; //0xd0 USHORT HeaderValidateLength; //0xd2 VOID* HeaderValidateCopy; //0xd8 USHORT NextAvailableTagIndex; //0xe0 USHORT MaximumTagIndex; //0xe2 struct _HEAP_TAG_ENTRY* TagEntries; //0xe8 struct _LIST_ENTRY UCRList; //0xf0 ULONGLONG AlignRound; //0x100 ULONGLONG AlignMask; //0x108 struct _LIST_ENTRY VirtualAllocdBlocks; //0x110 struct _LIST_ENTRY SegmentList; //0x120 USHORT AllocatorBackTraceIndex; //0x130 ULONG NonDedicatedListLength; //0x134 VOID* BlocksIndex; //0x138 VOID* UCRIndex; //0x140 struct _HEAP_PSEUDO_TAG_ENTRY* PseudoTagEntries; //0x148 struct _LIST_ENTRY FreeLists; //0x150 struct _HEAP_LOCK* LockVariable; //0x160 LONG (*CommitRoutine)(VOID* arg1, VOID** arg2, ULONGLONG* arg3); //0x168 union _RTL_RUN_ONCE StackTraceInitVar; //0x170 struct _RTL_HEAP_MEMORY_LIMIT_DATA CommitLimitData; //0x178 VOID* FrontEndHeap; //0x198 USHORT FrontHeapLockCount; //0x1a0 UCHAR FrontEndHeapType; //0x1a2 UCHAR RequestedFrontEndHeapType; //0x1a3 WCHAR* FrontEndHeapUsageData; //0x1a8 USHORT FrontEndHeapMaximumIndex; //0x1b0 volatile UCHAR FrontEndHeapStatusBitmap[129]; //0x1b2 struct _HEAP_COUNTERS Counters; //0x238 struct _HEAP_TUNING_PARAMETERS TuningParameters; //0x2b0 }; ``` ##### 反调试介绍 - 在 WinXP 中,ProcessHeap标志位于PEB结构中偏移为0x18处,第一个堆头部有一个属性字段,这个属性叫做ForceFlags(ULONG)属性偏移为0x44,该属性为0说明程序没有被调试,非0说明被调试,另外的Flags(ULONG) 属性偏移为 0x40,当值为 2 说明被调试,不为2则说明没有被调试。 - 在 Win10 中,ProcessHeap标志位于PEB结构中偏移为0x30,Flags(ULONG)偏移是 0x70,其值为 0x40000062 表示被调试;ForceFlags(ULONG)偏移是 0x74,其值为 0x40000060 表示被调试。 ### NtGlobalFlag - 几个 Flages 的值进行 OR(位或) 的结果,`无论 32 位还是 64 位,调试状态是 0x70。` ### NumberOfHeaps - 这个字段存储了进程中存在的堆的数量。除了主堆外,一个进程还可以创建其他的堆。 ### ProcessHeaps - 除了主堆(ProcessHeap字段表示的堆)外,一个进程还可以创建多个辅助堆。辅助堆的句柄会被存储在 ProcessHeaps 指针数组中。遍历该指针数组可获取到所有辅助堆的句柄。 # 综合介绍 ## TEB 定位:fs:[0x18]、gs:[0x30] - 定位方法:在 x64dbg 中【ctrl+G】输入"teb()"或"fs:[0x18]"(32位情况下)、"gs:[0x30]"(64位情况下)就可以定位到 TEB 了。但是不是说 FS/GS 就保存着 TEB 的信息吗?为什么不直接使用 FS/GS 呢?原因如下: - 首先是不能直接跳转到 FS/GS 段寄存器,如果使用了 fs:[0x00] 或 gs:[0x00] 实际上是将 fs/gs 段中偏移是 0x00 的地址保存的值当作地址,又进行了一次寻址取值操作! - TIB 是 TEB 的开头内嵌的一个结构体,所以 TIB 的开头就是 TEB 的开头。TIB 结构体中有一个成员是**Self**:这为_NT_TIB结构体的自引用指针,即保存了 TIB 的开头地址。而 TIB.self 在 32 位和 64 位的偏移分别是 0x18 和 0x30。所以从 fs:[0x00] 或 gs:[0x00] 取值就是取的 TIB 的开头,也就是 TEB 的开头。
别卷了
2024年8月8日 15:54
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码