0x1 实现反调试的思路

主角——PEB

Process Environment Block 即进程环境信息块,这里包含了一些进程的信息

PEB的结构如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
typedef struct _PEB {
  BYTE                          Reserved1[2];
  BYTE                          BeingDebugged; //被调试状态
  BYTE                          Reserved2[1];
  PVOID                         Reserved3[2];
  PPEB_LDR_DATA                 Ldr;
  PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
  BYTE                          Reserved4[104];
  PVOID                         Reserved5[52];
  PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
  BYTE                          Reserved6[128];
  PVOID                         Reserved7[1];
  ULONG                         SessionId;
} PEB, *PPEB;

我们留意BeingDebugged字段,这里记录了进程启动时是否由Debugger启动,是则为1,否则为0。 BOOL WINAPI IsDebuggerPresent(void)这个函数实际上就是访问并返回BeingDebugged字段的值。下面我们进行验证。

0x2 实验过程

测试代码如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <iostream>
#include <string>
#include <windows.h>
int main(int argc, char* argv[]) 
{
    bool status;
    status = IsDebuggerPresent();
    if (status) {
        MessageBoxA(NULL, "Detected debugger", "Find Debugger", MB_OK);
    }
    else {
        MessageBoxA(NULL, "Not detected debugger", "No Debugger", MB_OK);
    }
    return 0;
}

利用VS反汇编的功能,跟进IsDebuggerPresent(),发现其实现了如下功能

mov eax,dword ptr fs:[00000030h]是将fs段偏移为0x30的内容存到eax,而该地址正是PEB的首地址指针

movzx eax,byte ptr [eax+2]由上文可知,这里是BeingDebugged的值。

通过内嵌ASM的方法,我们同样可以获得此处的值。

 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
#include <iostream>
#include <string>
#include <windows.h>
int Check()
{
    int flag = 0;
    __asm{
        pushad
        mov eax, dword ptr fs : [0x30]
        movzx eax, byte ptr[eax + 2]
        mov flag,eax
        popad
    }
    return flag;
}

int main(int argc, char* argv[]) 
{
    if (Check()) {
        MessageBoxA(NULL, "Detected debugger", "Find Debugger", MB_OK);
    }
    else {
        MessageBoxA(NULL, "Not detected debugger", "No Debugger", MB_OK);
    }
    return 0;
}

0x3 fs段常用偏移

mov eax, dword ptr fs:[0h]//SEH结构化异常处理地址

mov eax, dword ptr fs:[04h]//线程堆栈顶部

mov eax, dword ptr fs:[08h]//线程堆栈底部

mov eax, dword ptr fs:[0Ch]//SubSystemTib

mov eax, dword ptr fs:[10h]//FiberData

mov eax, dword ptr fs:[14h]//ArbitraryUserPointer

mov eax, dword ptr fs:[18h]//TEB线程环境块

mov eax, dword ptr fs:[20h]//ClientId 客户端ID结构

mov eax, dword ptr fs:[24h]//线程ID

mov eax, dword ptr fs:[30h]//PEB进程环境块

mov eax, dword ptr fs:[2Ch]//指向线程局部存储指针

mov eax, dword ptr fs:[34h]//上个错误号

mov eax, dword ptr fs:[1a8h]//激活上下文堆栈指针结构

mov eax, dword ptr fs:[1d4h]//GDI线程环境快作业结构?

mov eax, dword ptr fs:[6b4h]//RealClientId ID结构

mov eax, dword ptr fs:[bf8h]//静态Unicode字符串

mov eax, dword ptr fs:[f10h]//线程本地存储TLS

mov eax, dword ptr fs:[f50h]//活动ID

mov eax, dword ptr fs:[f74h]//CurrentIdealProcessor 当前处理器?

mov eax, dword ptr fs:[fb0h]//ActiveFrame活动框架

0x4 TEB

+0x000 NtTib : _NT_TIB

+0x01c EnvironmentPointer : Ptr32 Void

+0x020 ClientId : _CLIENT_ID //进程的pid

+0x028 ActiveRpcHandle : Ptr32 Void

+0x02c ThreadLocalStoragePointer : Ptr32 Void

+0x030 ProcessEnvironmentBlock : Ptr32 _PEB //进程PEB

+0x034 LastErrorValue : Uint4B

+0x038 CountOfOwnedCriticalSections : Uint4B

+0x03c CsrClientThread : Ptr32 Void

+0x040 Win32ThreadInfo : Ptr32 Void

+0x044 User32Reserved : [26] Uint4B

+0x0ac UserReserved : [5] Uint4B

+0x0c0 WOW32Reserved : Ptr32 Void

+0x0c4 CurrentLocale : Uint4B

+0x0c8 FpSoftwareStatusRegister : Uint4B

+0x0cc SystemReserved1 : [54] Ptr32 Void

+0x1a4 ExceptionCode : Int4B

+0x1a8 ActivationContextStack : _ACTIVATION_CONTEXT_STACK

+0x1bc SpareBytes1 : [24] UChar

+0x1d4 GdiTebBatch : _GDI_TEB_BATCH

+0x6b4 RealClientId : _CLIENT_ID

+0x6bc GdiCachedProcessHandle : Ptr32 Void

+0x6c0 GdiClientPID : Uint4B

+0x6c4 GdiClientTID : Uint4B

+0x6c8 GdiThreadLocalInfo : Ptr32 Void

+0x6cc Win32ClientInfo : [62] Uint4B

+0x7c4 glDispatchTable : [233] Ptr32 Void

+0xb68 glReserved1 : [29] Uint4B

+0xbdc glReserved2 : Ptr32 Void

+0xbe0 glSectionInfo : Ptr32 Void

+0xbe4 glSection : Ptr32 Void

+0xbe8 glTable : Ptr32 Void

+0xbec glCurrentRC : Ptr32 Void

+0xbf0 glContext : Ptr32 Void

+0xbf4 LastStatusValue : Uint4B

+0xbf8 StaticUnicodeString : _UNICODE_STRING

+0xc00 StaticUnicodeBuffer : [261] Uint2B

+0xe0c DeallocationStack : Ptr32 Void

+0xe10 TlsSlots : [64] Ptr32 Void //TLS值 是个数组[64]

+0xf10 TlsLinks : _LIST_ENTRY

+0xf18 Vdm : Ptr32 Void

+0xf1c ReservedForNtRpc : Ptr32 Void

+0xf20 DbgSsReserved : [2] Ptr32 Void

+0xf28 HardErrorsAreDisabled : Uint4B

+0xf2c Instrumentation : [16] Ptr32 Void

+0xf6c WinSockData : Ptr32 Void

+0xf70 GdiBatchCount : Uint4B

+0xf74 InDbgPrint : UChar

+0xf75 FreeStackOnTermination : UChar

+0xf76 HasFiberData : UChar

+0xf77 IdealProcessor : UChar

+0xf78 Spare3 : Uint4B

+0xf7c ReservedForPerf : Ptr32 Void

+0xf80 ReservedForOle : Ptr32 Void

+0xf84 WaitingOnLoaderLock : Uint4B

+0xf88 Wx86Thread : _Wx86ThreadState

+0xf94 TlsExpansionSlots : Ptr32 Ptr32 Void //TLS扩展值 是个数组[Ptr32]

+0xf98 ImpersonationLocale : Uint4B

+0xf9c IsImpersonating : Uint4B

+0xfa0 NlsCache : Ptr32 Void

+0xfa4 pShimData : Ptr32 Void

+0xfa8 HeapVirtualAffinity : Uint4B

+0xfac CurrentTransactionHandle : Ptr32 Void

+0xfb0 ActiveFrame : Ptr32 _TEB_ACTIVE_FRAME

+0xfb4 SafeThunkCall : UChar

+0xfb5 BooleanSpare : [3] UChar

0x5 PEB

typedef struct _PEB { UCHAR InheritedAddressSpace; // 00h

UCHAR ReadImageFileExecOptions; // 01h

UCHAR BeingDebugged; // 02h

UCHAR Spare; // 03h

PVOID Mutant; // 04h

PVOID ImageBaseAddress; // 08h 映像基址

PPEB_LDR_DATA Ldr; // 0Ch LDR_DATA结构

PRTL_USER_PROCESS_PARAMETERS ProcessParameters; // 10h

PVOID SubSystemData; // 14h

PVOID ProcessHeap; // 18h

PVOID FastPebLock; // 1Ch

PPEBLOCKROUTINE FastPebLockRoutine; // 20h

PPEBLOCKROUTINE FastPebUnlockRoutine; // 24h

ULONG EnvironmentUpdateCount; // 28h

PVOID* KernelCallbackTable; // 2Ch

PVOID EventLogSection; // 30h

PVOID EventLog; // 34h

PPEB_FREE_BLOCK FreeList; // 38h

ULONG TlsExpansionCounter; // 3Ch

PVOID TlsBitmap; // 40h

ULONG TlsBitmapBits[0x2]; // 44h

PVOID ReadOnlySharedMemoryBase; // 4Ch

PVOID ReadOnlySharedMemoryHeap; // 50h

PVOID* ReadOnlyStaticServerData; // 54h

PVOID AnsiCodePageData; // 58h

PVOID OemCodePageData; // 5Ch

PVOID UnicodeCaseTableData; // 60h

ULONG NumberOfProcessors; // 64h

ULONG NtGlobalFlag; // 68h

UCHAR Spare2[0x4]; // 6Ch

LARGE_INTEGER CriticalSectionTimeout; // 70h

ULONG HeapSegmentReserve; // 78h

ULONG HeapSegmentCommit; // 7Ch

ULONG HeapDeCommitTotalFreeThreshold; // 80h

ULONG HeapDeCommitFreeBlockThreshold; // 84h

ULONG NumberOfHeaps; // 88h

ULONG MaximumNumberOfHeaps; // 8Ch

PVOID** ProcessHeaps; // 90h

PVOID GdiSharedHandleTable; // 94h

PVOID ProcessStarterHelper; // 98h

PVOID GdiDCAttributeList; // 9Ch

PVOID LoaderLock; // A0h

ULONG OSMajorVersion; // A4h

ULONG OSMinorVersion; // A8h

ULONG OSBuildNumber; // ACh

ULONG OSPlatformId; // B0h

ULONG ImageSubSystem; // B4h

ULONG ImageSubSystemMajorVersion; // B8h

ULONG ImageSubSystemMinorVersion; // C0h

ULONG GdiHandleBuffer[0x22]; // C4h

PVOID ProcessWindowStation; // ???

} PEB, *PPEB;