TEB
Windows是一个强大的操作系统。为了方便开发者,微软将进程中的每个线程都设置了一个独立的结构数据。这个结构体内存储着当前线程大量的信息。这个结构被称为TEB(线程环境块)。通过TEB结构内的成员属性向下扩展,可以得到很多线程信息。这其中还包含大量的未公开数据。
在不同结构中的TEB结构的偏移查询:
x86-32 |
Yes |
mov eax, fs:[n] |
x86-64 |
Yes |
mov rax, gs:[n] |
arm |
No |
Cannot use offset load from coprocessor register |
arm64 |
Yes |
ldr x0, [x18, #n] |
alpha |
No |
Address returned by dedicated instruction |
ia64 |
Yes |
Can calculate effective address directly from r13 |
MIPS |
No |
No absolute addressing mode |
PowerPC |
Yes |
lwz r0, n(r13) |
对于TEB来说,最简单的获取方式就是通过fs:[0x18]来获取
pTEB->0x18 == *pTEB
fs:[0x18] == TEB
pTEB->0x30 == fs:[0x30] == PEB
SEH:pTEB->0 == fs:[0] == SEH链
PEB
PEB(进程环境块)是TEB的一个成员
这个结构中存储着整个进程的信息。通过对PEB中成员的向下扩展可以找到一个存储着该进程所有模块数据的链表。
0x01 引入
常见的反调试函数:IsDebuggerPresent()
本质上是读取当前进程的PEB里BeingDebugged的值用于判断自己是否处于调试状态
0x02 PEB相关标志位反调试
PEB是一个非常庞大的数据结构,它是用来存储每个进程的运行时数据。下图为Windows 10的_PEB部分结构。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| struct _PEB { UCHAR InheritedAddressSpace; UCHAR ReadImageFileExecOptions; UCHAR BeingDebugged; union { UCHAR BitField; struct { UCHAR ImageUsesLargePages:1; UCHAR IsProtectedProcess:1; UCHAR IsImageDynamicallyRelocated:1; UCHAR SkipPatchingUser32Forwarders:1; UCHAR IsPackagedProcess:1; UCHAR IsAppContainer:1; UCHAR IsProtectedProcessLight:1; UCHAR SpareBits:1; }; }; VOID* Mutant; VOID* ImageBaseAddress; struct _PEB_LDR_DATA* Ldr; struct _RTL_USER_PROCESS_PARAMETERS* ProcessParameters; VOID* SubSystemData; VOID* ProcessHeap; struct _RTL_CRITICAL_SECTION* FastPebLock; VOID* AtlThunkSListPtr; VOID* IFEOKey; union { ULONG CrossProcessFlags; struct { ULONG ProcessInJob:1; ULONG ProcessInitializing:1; ULONG ProcessUsingVEH:1; ULONG ProcessUsingVCH:1; ULONG ProcessUsingFTH:1; ULONG ReservedBits0:27; }; }; union { VOID* KernelCallbackTable; VOID* UserSharedInfoPtr; }; ULONG SystemReserved[1]; ULONG AtlThunkSListPtr32; VOID* ApiSetMap; ULONG TlsExpansionCounter; VOID* TlsBitmap; ULONG TlsBitmapBits[2]; VOID* ReadOnlySharedMemoryBase; VOID* SparePvoid0; VOID** ReadOnlyStaticServerData; VOID* AnsiCodePageData; VOID* OemCodePageData; VOID* UnicodeCaseTableData; ULONG NumberOfProcessors; ULONG NtGlobalFlag; union _LARGE_INTEGER CriticalSectionTimeout; ULONG HeapSegmentReserve; ULONG HeapSegmentCommit; ULONG HeapDeCommitTotalFreeThreshold; ULONG HeapDeCommitFreeBlockThreshold; ULONG NumberOfHeaps; ULONG MaximumNumberOfHeaps; VOID** ProcessHeaps; VOID* GdiSharedHandleTable; VOID* ProcessStarterHelper; ULONG GdiDCAttributeList; struct _RTL_CRITICAL_SECTION* LoaderLock; ULONG OSMajorVersion; ULONG OSMinorVersion; USHORT OSBuildNumber; USHORT OSCSDVersion; ULONG OSPlatformId; ULONG ImageSubsystem; ULONG ImageSubsystemMajorVersion; ULONG ImageSubsystemMinorVersion; ULONG ActiveProcessAffinityMask; ULONG GdiHandleBuffer[34]; VOID (*PostProcessInitRoutine)(); VOID* TlsExpansionBitmap; ULONG TlsExpansionBitmapBits[32]; ULONG SessionId; union _ULARGE_INTEGER AppCompatFlags; union _ULARGE_INTEGER AppCompatFlagsUser; VOID* pShimData; VOID* AppCompatInfo; struct _UNICODE_STRING CSDVersion; struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; ULONG MinimumStackCommit; struct _FLS_CALLBACK_INFO* FlsCallback; struct _LIST_ENTRY FlsListHead; VOID* FlsBitmap; ULONG FlsBitmapBits[4]; ULONG FlsHighIndex; VOID* WerRegistrationData; VOID* WerShipAssertPtr; VOID* pUnused; VOID* pImageHeaderHash; union { ULONG TracingFlags; struct { ULONG HeapTracingEnabled:1; ULONG CritSecTracingEnabled:1; ULONG LibLoaderTracingEnabled:1; ULONG SpareTracingBits:29; }; }; ULONGLONG CsrServerReadOnlySharedMemoryBase; ULONG TppWorkerpListLock; struct _LIST_ENTRY TppWorkerpList; VOID* WaitOnAddressHashTable[128]; };
|
参考资料
一图流:
https://bbs.kanxue.com/thread-266678.htm#msg_header_h1_2
微软未公开数据:(收藏收藏,包含API,结构体等信息)
http://undocumented.ntinternals.net/