反调试专题丨反调试之NtGlobaFlag-当前视点
来源:哔哩哔哩 | 2023-06-28 12:54:57

一、32位系统

nt!_PEB   +0x000 InheritedAddressSpace : UChar   +0x001 ReadImageFileExecOptions : UChar   +0x002 BeingDebugged    : UChar                isDbg值,8字节   +0x003 BitField         : UChar   +0x003 ImageUsesLargePages : Pos 0, 1 Bit   +0x003 IsProtectedProcess : Pos 1, 1 Bit   +0x003 IsLegacyProcess  : Pos 2, 1 Bit   +0x003 IsImageDynamicallyRelocated : Pos 3, 1 Bit   +0x003 SkipPatchingUser32Forwarders : Pos 4, 1 Bit   +0x003 SpareBits        : Pos 5, 3 Bits   +0x004 Mutant           : Ptr32 Void   +0x008 ImageBaseAddress : Ptr32 Void              镜像基址   +0x00c Ldr              : Ptr32 _PEB_LDR_DATA             _PEB_LDR_DATA结构   +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS   +0x014 SubSystemData    : Ptr32 Void   +0x018 ProcessHeap      : Ptr32 Void                +0x01c FastPebLock      : Ptr32 _RTL_CRITICAL_SECTION   +0x020 AtlThunkSListPtr : Ptr32 Void   +0x024 IFEOKey          : Ptr32 Void   +0x028 CrossProcessFlags : Uint4B   +0x028 ProcessInJob     : Pos 0, 1 Bit   +0x028 ProcessInitializing : Pos 1, 1 Bit   +0x028 ProcessUsingVEH  : Pos 2, 1 Bit   +0x028 ProcessUsingVCH  : Pos 3, 1 Bit   +0x028 ProcessUsingFTH  : Pos 4, 1 Bit   +0x028 ReservedBits0    : Pos 5, 27 Bits   +0x02c KernelCallbackTable : Ptr32 Void   +0x02c UserSharedInfoPtr : Ptr32 Void   +0x030 SystemReserved   : [1] Uint4B   +0x034 AtlThunkSListPtr32 : Uint4B   +0x038 ApiSetMap        : Ptr32 Void   +0x03c TlsExpansionCounter : Uint4B   +0x040 TlsBitmap        : Ptr32 Void   +0x044 TlsBitmapBits    : [2] Uint4B   +0x04c ReadOnlySharedMemoryBase : Ptr32 Void   +0x050 HotpatchInformation : Ptr32 Void   +0x054 ReadOnlyStaticServerData : Ptr32 Ptr32 Void   +0x058 AnsiCodePageData : Ptr32 Void   +0x05c OemCodePageData  : Ptr32 Void   +0x060 UnicodeCaseTableData : Ptr32 Void   +0x064 NumberOfProcessors : Uint4B            CPU的个数   +0x068 NtGlobalFlag     : Uint4B   .   .   .

PEB 有一个名为NtGlobalFlag(32位系统下偏移量0x68)的字段,程序可以挑战该字段以确定它们是否正在被调试。通常,当进程未被调试时,NtGlobalFlag字段包含值0x0。调试进程时,该字段通常包含值0x70,表示设置了以下标志:


(相关资料图)

标志

FLG_HEAP_ENABLE_TAIL_CHECK

FLG_HEAP_ENABLE_FREE_CHECK

FLG_HEAP_VALIDATE_PARAMETERS

其余

所以可以通过检测此标志位来检测是否被调试。实现代码可以通过汇编或者通过C++实现,汇编实现如下:

DWORD MyIsDebug1(){    DWORD Flag = 0;    __asm {    mov eax,fs:[30h]    mov eax,[eax+68h]    mov Flag,eax}    return Flag;}

完整代码如下:

// : 此文件包含 "main" 函数。程序执行将在此处开始并结束。//#include #include DWORD MyIsDebug1(){    DWORD Flag = 0;    __asm {    mov eax,fs:[30h]    mov eax,[eax+68h]    mov Flag,eax}    return Flag;}DWORD WINAPI MyIsDebug(    LPVOID lpThreadParameter){    DWORD myFlag = 0;    while (1) {       myFlag = MyIsDebug1();       if (myFlag == 0x70)       {           MessageBox(NULL, L"警告", L"调试中", MB_OK);       }    }    return 1;}int main(){    //IsDebuggerPresent();    CreateThread(NULL, NULL, MyIsDebug, NULL, NULL, NULL);    std::cout << "Hello World!\n";    system("pause");    return 0;}

二、64位系统

ntdll!_PEB  +0x000 InheritedAddressSpace : UChar  +0x001 ReadImageFileExecOptions : UChar  +0x002 BeingDebugged    : UChar  +0x003 BitField         : UChar  +0x003 ImageUsesLargePages : Pos 0, 1 Bit  +0x003 IsProtectedProcess : Pos 1, 1 Bit  +0x003 IsImageDynamicallyRelocated : Pos 2, 1 Bit  +0x003 SkipPatchingUser32Forwarders : Pos 3, 1 Bit  +0x003 IsPackagedProcess : Pos 4, 1 Bit  +0x003 IsAppContainer   : Pos 5, 1 Bit  +0x003 IsProtectedProcessLight : Pos 6, 1 Bit  +0x003 IsLongPathAwareProcess : Pos 7, 1 Bit  +0x004 Padding0         : [4] UChar  +0x008 Mutant           : Ptr64 Void  +0x010 ImageBaseAddress : Ptr64 Void  +0x018 Ldr              : Ptr64 _PEB_LDR_DATA  +0x020 ProcessParameters : Ptr64 _RTL_USER_PROCESS_PARAMETERS  +0x028 SubSystemData    : Ptr64 Void  +0x030 ProcessHeap      : Ptr64 Void  +0x038 FastPebLock      : Ptr64 _RTL_CRITICAL_SECTION  +0x040 AtlThunkSListPtr : Ptr64 _SLIST_HEADER  +0x048 IFEOKey          : Ptr64 Void  +0x050 CrossProcessFlags : Uint4B  +0x050 ProcessInJob     : Pos 0, 1 Bit  +0x050 ProcessInitializing : Pos 1, 1 Bit  +0x050 ProcessUsingVEH  : Pos 2, 1 Bit  +0x050 ProcessUsingVCH  : Pos 3, 1 Bit  +0x050 ProcessUsingFTH  : Pos 4, 1 Bit  +0x050 ProcessPreviouslyThrottled : Pos 5, 1 Bit  +0x050 ProcessCurrentlyThrottled : Pos 6, 1 Bit  +0x050 ReservedBits0    : Pos 7, 25 Bits  +0x054 Padding1         : [4] UChar  +0x058 KernelCallbackTable : Ptr64 Void  +0x058 UserSharedInfoPtr : Ptr64 Void  +0x060 SystemReserved   : Uint4B  +0x064 AtlThunkSListPtr32 : Uint4B  +0x068 ApiSetMap        : Ptr64 Void  +0x070 TlsExpansionCounter : Uint4B  +0x074 Padding2         : [4] UChar  +0x078 TlsBitmap        : Ptr64 Void  +0x080 TlsBitmapBits    : [2] Uint4B  +0x088 ReadOnlySharedMemoryBase : Ptr64 Void  +0x090 SharedData       : Ptr64 Void  +0x098 ReadOnlyStaticServerData : Ptr64 Ptr64 Void  +0x0a0 AnsiCodePageData : Ptr64 Void  +0x0a8 OemCodePageData  : Ptr64 Void  +0x0b0 UnicodeCaseTableData : Ptr64 Void  +0x0b8 NumberOfProcessors : Uint4B  +0x0bc NtGlobalFlag     : Uint4B

可以看到64位系统下面,NtGlobalFlag标志位有所不同,位于PEB偏移0xbc。其余和x86没有区别。可以通过readgsqword(60h)获取到PED地址,再检查偏移0xbc位置标志位达到反调试效果。

三、反反调试

1. 手动修改标志位

2. 使用OD插件

3. 在WinDbg中,在禁用调试堆的情况下启动程序 ( windbg -hd )

精彩推荐