反調試專題丨反調試之BeingDebugged

一、x86下IsDebuggerPresent反調試以及反反調試
1、反調試
進程結構體PEB偏移0x2處是一個標志位,當當前程序在調試狀態(tài)下時,這個標志位就會被改變:
nt!_PEB
???+0x000 InheritedAddressSpace?:?UChar
???+0x001 ReadImageFileExecOptions?:?UChar
???+0x002 BeingDebugged????:?UChar??????????????? isDbg值,8字節(jié)
???+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
?? .
?? .
?? .
而API IsdebuggerPresent函數(shù)就是檢測這個位置(不進內核),F(xiàn)S寄存器偏移0x30的地方就是PEB的地址,此函數(shù)的匯編實現(xiàn)如下:
7622C220 mov???????? eax,dword ptr fs:[00000030h]?
7622C226? movzx?????? eax,byte?ptr?[eax+2]?
下面是部分利用代碼:
DWORD WINAPI MyIsDebug(
LPVOID lpThreadParameter
)
{
????while?(1)?{
???????if?(IsDebuggerPresent())
???????{
?????????? 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;
}
也可以自己實現(xiàn)此函數(shù),可以避免對于IsDebuggerPresent函數(shù)的Hook或者斷點檢查:
bool?IsDebuggerR()
{
????bool?bRet?=?false;
??? __asm?{
?????? mov eax,?fs:?[0x30]
?????? mov al,?byte ptr[eax?+?2]
?????? mov bRet,?al
????}
????return?bRet;//返回TRUE是debug
}
DWORD IsDebuggerR()
{
??? DWORD MyPeb?=?__readfsdword(0x30);
??? DWORD MyFlag?=?*(DWORD*)(MyPeb+0x2)
????return?MyFlag;
}
效果如下:


2、對于IsdebuggerPresent的反反調試
1.?很多調試器有對應插件,可以過掉此反調試手段。
2.?在調試器中對此函數(shù)下斷點,修改其函數(shù)返回值,達到反反調試。
3.?通過對進程注入DLL,在DLL中Hook函數(shù)IsdebuggerPresent。
二、x64下反調試
1、反調試
64位系統(tǒng)下PEB結構有所變化,對于IsDebuggerPresent檢測的標志位位置并沒有區(qū)別,也就是說代碼通用,但是自定義由于x64不支持內聯(lián)匯編,所以引入asm文件,部分代碼如下:
mov rax,qword ptr gs:[60h]
movzx eax,byte?ptr[rax?+?2h]
當然也可以通過函數(shù)readgsqword獲取PEB地址進而獲取標志位結果。
2、反反調試
和x86沒有區(qū)別
最后,CheckRemoteDebuggerPresent函數(shù)也是和IsdebuggerPresent函數(shù)類似功能。