PEB在反调试中的常用点
前言和老手聊起PEB在反调试中常用的几个点, 做个试验.记录开Winxp虚拟机调试模式, 连上Windbg.先用Windbg附加记事本,将PEB列出来.!process 0 0PROCESS 82091650SessionId: 0Cid: 04e4Peb: 7ffde000ParentCid: 0170DirBase: 07f8024
·
前言
和老手聊起PEB在反调试中常用的几个点, 做个试验.
前段时间玩cm, 打掉反调试还是挺费时间的. 熟练之后就好了:)
反调试手段挺多的, 应该有几百种吧, 如果没见过, 看行为选择是否NOP掉.
遇到反调试时,调试器的使用状态或cm运行结果应该会有不同的.
调试器有反应好弄, 总能找到让调试器失灵的点.
要是让运行结果不对, 那应该不太好找.
记录
查看PEB
双机调试看到的TEB不对, 可能附加有问题吧.
直接在WinXp虚拟机中装了x86版的windbg, 在菜单上附加正在运行的notepad.exe
0:001> dg @fs
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0038 7ffde000 00000fff Data RW Ac 3 Bg By P Nl 000004f3
fs:[0]是_NT_TIB地址, 地址是7ffde000
0:001> dd fs:[0]
0038:00000000 00acffe4 00ad0000 00acf000 00000000
0038:00000010 00001e00 00000000 7ffde000 00000000
0038:00000020 000007cc 000001b8 00000000 00000000
0038:00000030 7ffd3000 00000000 00000000 00000000
0038:00000040 00000000 00000000 00000000 00000000
0038:00000050 00000000 00000000 00000000 00000000
0038:00000060 00000000 00000000 00000000 00000000
0038:00000070 00000000 00000000 00000000 00000000
0:001> dd 7ffde000
7ffde000 00acffe4 00ad0000 00acf000 00000000
7ffde010 00001e00 00000000 7ffde000 00000000
7ffde020 000007cc 000001b8 00000000 00000000
7ffde030 7ffd3000 00000000 00000000 00000000
7ffde040 00000000 00000000 00000000 00000000
7ffde050 00000000 00000000 00000000 00000000
7ffde060 00000000 00000000 00000000 00000000
7ffde070 00000000 00000000 00000000 00000000
0:001> dt _NT_TIB 7ffde000
ntdll!_NT_TIB
+0x000 ExceptionList : 0x00acffe4 _EXCEPTION_REGISTRATION_RECORD
+0x004 StackBase : 0x00ad0000 Void
+0x008 StackLimit : 0x00acf000 Void
+0x00c SubSystemTib : (null)
+0x010 FiberData : 0x00001e00 Void
+0x010 Version : 0x1e00
+0x014 ArbitraryUserPointer : (null)
+0x018 Self : 0x7ffde000 _NT_TIB
[TIB + 0x18]中是 _TEB的地址
0:001> dt _TEB 7ffde000
ntdll!_TEB
+0x000 NtTib : _NT_TIB
+0x01c EnvironmentPointer : (null)
+0x020 ClientId : _CLIENT_ID
+0x028 ActiveRpcHandle : (null)
+0x02c ThreadLocalStoragePointer : (null)
+0x030 ProcessEnvironmentBlock : 0x7ffd3000 _PEB
+0x034 LastErrorValue : 0
+0x038 CountOfOwnedCriticalSections : 0
+0x03c CsrClientThread : (null)
+0x040 Win32ThreadInfo : (null)
+0x044 User32Reserved : [26] 0
+0x0ac UserReserved : [5] 0
+0x0c0 WOW32Reserved : (null)
+0x0c4 CurrentLocale : 0x804
+0x0c8 FpSoftwareStatusRegister : 0
+0x0cc SystemReserved1 : [54] (null)
+0x1a4 ExceptionCode : 0n0
+0x1a8 ActivationContextStack : _ACTIVATION_CONTEXT_STACK
+0x1bc SpareBytes1 : [24] ""
+0x1d4 GdiTebBatch : _GDI_TEB_BATCH
+0x6b4 RealClientId : _CLIENT_ID
+0x6bc GdiCachedProcessHandle : (null)
+0x6c0 GdiClientPID : 0
+0x6c4 GdiClientTID : 0
+0x6c8 GdiThreadLocalInfo : (null)
+0x6cc Win32ClientInfo : [62] 0
+0x7c4 glDispatchTable : [233] (null)
+0xb68 glReserved1 : [29] 0
+0xbdc glReserved2 : (null)
+0xbe0 glSectionInfo : (null)
+0xbe4 glSection : (null)
+0xbe8 glTable : (null)
+0xbec glCurrentRC : (null)
+0xbf0 glContext : (null)
+0xbf4 LastStatusValue : 0
+0xbf8 StaticUnicodeString : _UNICODE_STRING ""
+0xc00 StaticUnicodeBuffer : [261] 0
+0xe0c DeallocationStack : 0x00ac0000 Void
+0xe10 TlsSlots : [64] (null)
+0xf10 TlsLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0xf18 Vdm : (null)
+0xf1c ReservedForNtRpc : (null)
+0xf20 DbgSsReserved : [2] (null)
+0xf28 HardErrorsAreDisabled : 0
+0xf2c Instrumentation : [16] (null)
+0xf6c WinSockData : (null)
+0xf70 GdiBatchCount : 0
+0xf74 InDbgPrint : 0 ''
+0xf75 FreeStackOnTermination : 0 ''
+0xf76 HasFiberData : 0 ''
+0xf77 IdealProcessor : 0 ''
+0xf78 Spare3 : 0
+0xf7c ReservedForPerf : (null)
+0xf80 ReservedForOle : (null)
+0xf84 WaitingOnLoaderLock : 0
+0xf88 Wx86Thread : _Wx86ThreadState
+0xf94 TlsExpansionSlots : (null)
+0xf98 ImpersonationLocale : 0
+0xf9c IsImpersonating : 0
+0xfa0 NlsCache : (null)
+0xfa4 pShimData : (null)
+0xfa8 HeapVirtualAffinity : 0
+0xfac CurrentTransactionHandle : (null)
+0xfb0 ActiveFrame : (null)
+0xfb4 SafeThunkCall : 0 ''
+0xfb5 BooleanSpare : [3] ""
[TEB+0x30]中是PEB地址7ffd3000
0:001> dt 0x7ffd3000 _PEB
ntdll!_PEB
+0x000 InheritedAddressSpace : 0 ''
+0x001 ReadImageFileExecOptions : 0 ''
+0x002 BeingDebugged : 0x1 ''
+0x003 SpareBool : 0 ''
+0x004 Mutant : 0xffffffff Void
+0x008 ImageBaseAddress : 0x01000000 Void
+0x00c Ldr : 0x001a1e90 _PEB_LDR_DATA
+0x010 ProcessParameters : 0x00020000 _RTL_USER_PROCESS_PARAMETERS
+0x014 SubSystemData : (null)
+0x018 ProcessHeap : 0x000a0000 Void
+0x01c FastPebLock : 0x7c99d600 _RTL_CRITICAL_SECTION
+0x020 FastPebLockRoutine : 0x7c921000 Void
+0x024 FastPebUnlockRoutine : 0x7c9210e0 Void
+0x028 EnvironmentUpdateCount : 1
+0x02c KernelCallbackTable : 0x77d12970 Void
+0x030 SystemReserved : [1] 0
+0x034 AtlThunkSListPtr32 : 0
+0x038 FreeList : (null)
+0x03c TlsExpansionCounter : 0
+0x040 TlsBitmap : 0x7c99d5c0 Void
+0x044 TlsBitmapBits : [2] 0xfffff
+0x04c ReadOnlySharedMemoryBase : 0x7f6f0000 Void
+0x050 ReadOnlySharedMemoryHeap : 0x7f6f0000 Void
+0x054 ReadOnlyStaticServerData : 0x7f6f0688 -> (null)
+0x058 AnsiCodePageData : 0x7ffa0000 Void
+0x05c OemCodePageData : 0x7ffa0000 Void
+0x060 UnicodeCaseTableData : 0x7ffd1000 Void
+0x064 NumberOfProcessors : 1
+0x068 NtGlobalFlag : 0
+0x070 CriticalSectionTimeout : _LARGE_INTEGER 0xffffe86d`079b8000
+0x078 HeapSegmentReserve : 0x100000
+0x07c HeapSegmentCommit : 0x2000
+0x080 HeapDeCommitTotalFreeThreshold : 0x10000
+0x084 HeapDeCommitFreeBlockThreshold : 0x1000
+0x088 NumberOfHeaps : 9
+0x08c MaximumNumberOfHeaps : 0x10
+0x090 ProcessHeaps : 0x7c99cfc0 -> 0x000a0000 Void
+0x094 GdiSharedHandleTable : 0x00480000 Void
+0x098 ProcessStarterHelper : (null)
+0x09c GdiDCAttributeList : 0x14
+0x0a0 LoaderLock : 0x7c99b178 Void
+0x0a4 OSMajorVersion : 5
+0x0a8 OSMinorVersion : 1
+0x0ac OSBuildNumber : 0xa28
+0x0ae OSCSDVersion : 0x300
+0x0b0 OSPlatformId : 2
+0x0b4 ImageSubsystem : 2
+0x0b8 ImageSubsystemMajorVersion : 4
+0x0bc ImageSubsystemMinorVersion : 0
+0x0c0 ImageProcessAffinityMask : 0
+0x0c4 GdiHandleBuffer : [34] 0
+0x14c PostProcessInitRoutine : (null)
+0x150 TlsExpansionBitmap : 0x7c99d5b8 Void
+0x154 TlsExpansionBitmapBits : [32] 0
+0x1d4 SessionId : 0
+0x1d8 AppCompatFlags : _ULARGE_INTEGER 0x0
+0x1e0 AppCompatFlagsUser : _ULARGE_INTEGER 0x0
+0x1e8 pShimData : (null)
+0x1ec AppCompatInfo : (null)
+0x1f0 CSDVersion : _UNICODE_STRING "Service Pack 3"
+0x1f8 ActivationContextData : 0x00090000 Void
+0x1fc ProcessAssemblyStorageMap : 0x000a2f50 Void
+0x200 SystemDefaultActivationContextData : 0x00080000 Void
+0x204 SystemAssemblyStorageMap : (null)
+0x208 MinimumStackCommit : 0
PEB反调试的点
PEB.BeingDebugged
BOOL fnAntiDebug_PebBeingDebugged()
{
int iPebBeingDebugged = 0;
_asm {
pushfd
pushad
// fs:[0x0] is _NT_TIB
// fs:[0x18] is _NT_TEB
/**
0:001> dt 7ffde000 _NT_TIB
ntdll!_NT_TIB
+0x000 ExceptionList : 0x00acffe4 _EXCEPTION_REGISTRATION_RECORD
+0x004 StackBase : 0x00ad0000 Void
+0x008 StackLimit : 0x00acf000 Void
+0x00c SubSystemTib : (null)
+0x010 FiberData : 0x00001e00 Void
+0x010 Version : 0x1e00
+0x014 ArbitraryUserPointer : (null)
+0x018 Self : 0x7ffde000 _NT_TIB
*/
// fs:x 已经是取内容
mov eax, fs:0x18 ; addr => _NT_TEB
/**
0:001> dt 0x7ffde000 _TEB
ntdll!_TEB
+0x000 NtTib : _NT_TIB
+0x01c EnvironmentPointer : (null)
+0x020 ClientId : _CLIENT_ID
+0x028 ActiveRpcHandle : (null)
+0x02c ThreadLocalStoragePointer : (null)
+0x030 ProcessEnvironmentBlock : 0x7ffd3000 _PEB
*/
mov eax, [eax + 0x30] ; _PEB
/**
0:001> dt 0x7ffd3000 _PEB
ntdll!_PEB
+0x000 InheritedAddressSpace : 0 ''
+0x001 ReadImageFileExecOptions : 0 ''
+0x002 BeingDebugged : 0x1 ''
*/
movzx eax, BYTE PTR [eax + 0x2] ; _PEB.BeingDebugged
mov iPebBeingDebugged, eax
popad
popfd
}
return (iPebBeingDebugged != 0);
}
Peb.NtGlobalFlag
BOOL fnAntiDebug_PebNtGlobalFlag()
{
int iPebNtGlobalFlag = 0;
_asm {
pushfd
pushad
mov eax, fs:0x18 ; addr => _NT_TEB
mov eax, [eax + 0x30] ; _PEB
/**
0:001> dt 0x7ffd3000 _PEB
ntdll!_PEB
+0x000 InheritedAddressSpace : 0 ''
+0x001 ReadImageFileExecOptions : 0 ''
+0x002 BeingDebugged : 0x1 ''
+0x003 SpareBool : 0 ''
+0x004 Mutant : 0xffffffff Void
+0x008 ImageBaseAddress : 0x01000000 Void
+0x00c Ldr : 0x001a1e90 _PEB_LDR_DATA
+0x010 ProcessParameters : 0x00020000 _RTL_USER_PROCESS_PARAMETERS
+0x014 SubSystemData : (null)
+0x018 ProcessHeap : 0x000a0000 Void
+0x01c FastPebLock : 0x7c99d600 _RTL_CRITICAL_SECTION
+0x020 FastPebLockRoutine : 0x7c921000 Void
+0x024 FastPebUnlockRoutine : 0x7c9210e0 Void
+0x028 EnvironmentUpdateCount : 1
+0x02c KernelCallbackTable : 0x77d12970 Void
+0x030 SystemReserved : [1] 0
+0x034 AtlThunkSListPtr32 : 0
+0x038 FreeList : (null)
+0x03c TlsExpansionCounter : 0
+0x040 TlsBitmap : 0x7c99d5c0 Void
+0x044 TlsBitmapBits : [2] 0xfffff
+0x04c ReadOnlySharedMemoryBase : 0x7f6f0000 Void
+0x050 ReadOnlySharedMemoryHeap : 0x7f6f0000 Void
+0x054 ReadOnlyStaticServerData : 0x7f6f0688 -> (null)
+0x058 AnsiCodePageData : 0x7ffa0000 Void
+0x05c OemCodePageData : 0x7ffa0000 Void
+0x060 UnicodeCaseTableData : 0x7ffd1000 Void
+0x064 NumberOfProcessors : 1
+0x068 NtGlobalFlag : 0
+0x070 CriticalSectionTimeout : _LARGE_INTEGER 0xffffe86d`079b8000
*/
mov al, [eax+68h] ; _PEB.NtGlobalFlag
and al, 70h
cmp al, 70h
jne NOT_ON_DEBUG_ENV
mov eax, 1
mov iPebNtGlobalFlag, eax
NOT_ON_DEBUG_ENV:
popad
popfd
}
return (iPebNtGlobalFlag != 0);
}
Peb.ProcessHeap
BOOL fnAntiDebug_PebProcessHeap()
{
int iOnDebugDev = 0;
DWORD dwVer = GetVersion();
_asm {
pushfd
pushad
; 确定 _PEB.ProcessHeap 后面多少偏移是调试标记
mov eax, dwVer ; 0x1db10106
cmp al, 6
cmc ; Inverts Carry Flag
sbb ebx, ebx
and ebx, 34h
mov eax, fs:0x18 ; addr => _NT_TEB
mov eax, [eax + 0x30] ; _PEB
/**
0:001> dt 0x7ffd3000 _PEB
ntdll!_PEB
+0x000 InheritedAddressSpace : 0 ''
+0x001 ReadImageFileExecOptions : 0 ''
+0x002 BeingDebugged : 0x1 ''
+0x003 SpareBool : 0 ''
+0x004 Mutant : 0xffffffff Void
+0x008 ImageBaseAddress : 0x01000000 Void
+0x00c Ldr : 0x001a1e90 _PEB_LDR_DATA
+0x010 ProcessParameters : 0x00020000 _RTL_USER_PROCESS_PARAMETERS
+0x014 SubSystemData : (null)
+0x018 ProcessHeap : 0x000a0000 Void
*/
mov eax, [eax+18h] ; _PEB.ProcessHeap
; ForceFlags
; HEAP_TAIL_CHECKING_ENABLED
; HEAP_FREE_CHECKING_ENABLED
; HEAP_VALIDATE_PARAMETERS_ENABLED
cmp [eax+ebx+10h], 40000060h
jne NOT_ON_DEBUG_ENV
mov eax, 1
mov iOnDebugDev, eax
NOT_ON_DEBUG_ENV:
popad
popfd
}
return (iOnDebugDev != 0);
}
Heap’s Content On Peb.ProcessHeap
整理了2个版本, 检测原理 : 被调试时,堆后面有8个连续的0xab.
BOOL fnAntiDebug_PebHeapAlloc()
{
BYTE* pHeap = (BYTE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 0x10);
int iOnDebugDev = 0;
DWORD dwVer = GetVersion();
if (pHeap) {
__asm {
pushfd
pushad
mov edx, pHeap // save the pHeap
xor ebx, ebx
mov eax, dwVer
cmp al, 6
push ebp
sbb ebp, ebp
jb L1 // Process Environment Block
mov eax, fs:0x18
mov eax, [eax + 0x30] // _PEB
mov eax, [eax+18h] // get process heap base
mov ecx, [eax+24h] // check for protected heap
jecxz L1
mov ecx, [ecx]
test [eax+4ch], ecx
cmovne ebx, [eax+50h] // conditionally get heap key
L1:
mov eax, edx
movzx edx, WORD PTR [eax-8] // size
xor dx, bx
movzx ecx, BYTE PTR [eax+ebp-1] // overhead
pop ebp
sub eax, ecx
lea edi, [edx*8+eax]
mov al, 0abh
mov cl, 8
repe scasb
// 被调试的程序中, 在堆后面有8个连续的0xab
jne NOT_ON_DEBUG_ENV
mov eax, 1
mov iOnDebugDev, eax
NOT_ON_DEBUG_ENV:
popad
popfd
}
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, pHeap);
pHeap = NULL;
}
return (iOnDebugDev != 0);
}
BOOL fnAntiDebug_PebHeapAlloc_V1()
{
BYTE* pHeap = (BYTE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 0x10);
int iOnDebugDev = 0;
DWORD dwVer = GetVersion();
if (pHeap) {
__asm {
pushfd
pushad
mov eax, pHeap
movzx ecx, BYTE PTR [eax - 1] // get the heap alloc size (0x10 + 8)
lea edi, [eax + ecx - 8]
mov al, 0abh
mov cl, 8
repe scasb
// 被调试的程序中, 在堆后面有8个连续的0xab
jne NOT_ON_DEBUG_ENV
mov eax, 1
mov iOnDebugDev, eax
NOT_ON_DEBUG_ENV:
popad
popfd
}
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, pHeap);
pHeap = NULL;
}
return (iOnDebugDev != 0);
}
更多推荐
所有评论(0)