|
PEB(Process Environment Block,进程环境块)是存放进程信息的结构体,尺寸非常大,我们首先看看PEB结构体:typedef struct _PEB { // Size: 0x1D8 000h UCHAR InheritedAddressSpace; 001h UCHAR ReadImageFileExecOptions; 002h UCHAR BeingDebugged; //Debug运行标志 003h UCHAR SpareBool; 004h HANDLE Mutant; 008h HINSTANCE ImageBaseAddress; //程序加载的基地址 00Ch struct _PEB_LDR_DATA *Ldr //Ptr32 _PEB_LDR_DATA 010h struct _RTL_USER_PROCESS_PARAMETERS *ProcessParameters; 014h ULONG SubSystemData; 018h HANDLE ProcessHeap; 01Ch KSPIN_LOCK FastPebLock; 020h ULONG FastPebLockRoutine; 024h ULONG FastPebUnlockRoutine; 028h ULONG EnvironmentUpdateCount; 02Ch ULONG KernelCallbackTable; 030h LARGE_INTEGER SystemReserved; 038h struct _PEB_FREE_BLOCK *FreeList 03Ch ULONG TlsExpansionCounter; 040h ULONG TlsBitmap; 044h LARGE_INTEGER TlsBitmapBits; 04Ch ULONG ReadOnlySharedMemoryBase; 050h ULONG ReadOnlySharedMemoryHeap; 054h ULONG ReadOnlyStaticServerData; 058h ULONG AnsiCodePageData; 05Ch ULONG OemCodePageData; 060h ULONG UnicodeCaseTableData; 064h ULONG NumberOfProcessors; 068h LARGE_INTEGER NtGlobalFlag; // Address of a local copy 070h LARGE_INTEGER CriticalSectionTimeout; 078h ULONG HeapSegmentReserve; 07Ch ULONG HeapSegmentCommit; 080h ULONG HeapDeCommitTotalFreeThreshold; 084h ULONG HeapDeCommitFreeBlockThreshold; 088h ULONG NumberOfHeaps; 08Ch ULONG MaximumNumberOfHeaps; 090h ULONG ProcessHeaps; 094h ULONG GdiSharedHandleTable; 098h ULONG ProcessStarterHelper; 09Ch ULONG GdiDCAttributeList; 0A0h KSPIN_LOCK LoaderLock; 0A4h ULONG OSMajorVersion; 0A8h ULONG OSMinorVersion; 0ACh USHORT OSBuildNumber; 0AEh USHORT OSCSDVersion; 0B0h ULONG OSPlatformId; 0B4h ULONG ImageSubsystem; 0B8h ULONG ImageSubsystemMajorVersion; 0BCh ULONG ImageSubsystemMinorVersion; 0C0h ULONG ImageProcessAffinityMask; 0C4h ULONG GdiHandleBuffer[0x22]; 14Ch ULONG PostProcessInitRoutine; 150h ULONG TlsExpansionBitmap; 154h UCHAR TlsExpansionBitmapBits[0x80]; 1D4h ULONG SessionId;} PEB, *PPEB; 其中与反调试技术密切相关的成员如下所示: 002h UCHAR BeingDebugged; 00Ch struct _PEB_LDR_DATA *Ldr; 018h HANDLE ProcessHeap; 068h LARGE_INTEGER NtGlobalFlag; 接下来分别讲解以上4个PEB成员。 1:BeingDebugged。当进程处于调试状态时,BeingDebugged的值会被设置为1,进程在非调试状态下运行时,其值被设置为0。所以我们可以通过判断这个成员的值来决定我们程序的运行流程。测试代码如下:int main(){ charresult=0; __asm { moveax,fs:[0x30];//获取PEB的地址。 moval,BYTE PTR [eax+2]; movresult,al;//得到BeingDebugged成员的值。 } if(result==1) printf("isdebugging\n"); else printf("notdebugging\n"); system("pause");//为了观察方便,添加的。 return0; } 2:Ldr。调试进程时,其堆内存就会出现一些特殊的标识,表示它正处于被调试状态。这些标识中最醒目的是在未使用的堆内存区域中填充着OxFEEEFEEE。我们利用这一特征即可判断进程是否处于被调试状态。PEB.Ldr成员指向一个_PEB_LDR_DATA结构体,而这个结构体就是在堆内存区域中创建的,所以我们可以扫描该区域来判断进程是否处于调试状态下。测试代码如下:int main(){ LPBYTEpLdr; DWORDpLdrSig[4]={0xEEFEEEFE,0xEEFEEEFE,0xEEFEEEFE,0xEEFEEEFE}; __asm { moveax,fs:[0x30]; //PEB地址 moveax,[eax+0xC];//Ldr movpLdr,eax; } __try { while(1) { if(!memcmp(pLdr,pLdrSig,sizeof(pLdrSig))) { printf("is debuggig\n"); break; } else { pLdr++; } } } __except(EXCEPTION_EXECUTE_HANDLER) { printf("notdebugging\n"); } system("pause"); return0; } 3:ProcessHeapProcessHeap是指向HEAP结构体的指针,在HEAP结构体中的两个成员Flags和Force Flags,它们的偏移分别为0xC和0x10,进程运行正常时,Heap.Flags的成员值为0x2,HEAP.ForceFlags成员的值为0x0。进程处于调试状态时,这些值会发生变化。测试代码如下:(只测试了ForceFlags成员的值,测试Flags成员的值的方法是一样的)。int main(){ intresult=0; __asm { moveax,fs:[0x30]; //PEB地址 moveax,[eax+0x18];//ProcessHeap成员 moveax,[eax+0x10];//ForceFlags成员 movresult,eax; } if(result!=0) printf("isdebugging\n"); else printf("notdebugging\n"); system("pause"); return0; } 4:NtGlobalFlag。调试进程时,PEB.NtGlobalFlag成员的值为被设置成0x70。所以,检测该成员的值即可判断进程是否处于被调试状态。测试代码如下:int main(){ intresult=0; __asm { moveax,fs:[0x30]; //PEB地址 moveax,[eax+0x68];//NtGlobalFlag成员 movresult,eax; } if(result==0x70) printf("isdebugging\n"); else printf("notdebugging\n"); system("pause"); return0; }
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
|