x32dbg或x64dbg调试某个程序遇到异常:第一次异常于00007FFA2EDDA839 (406D1388, MS_VC_EXCEPTION)! 无视异常继续运行,加载一些dll文件后还是断在kernelbase.dll的00007FFA2EDDA839处,0F1F4400 00 nop dword ptr ds:[rax+rax],eax. 不过报异常的括号里面的内容变成了(E06D7363, CPP_EH_EXCEPTION). IDA选择Local Win32 debugger也容易出现406D1388异常,Ollydbg倒较少遇到这个异常。
在x64dbg中选择 调试 > 高级 > 隐藏调试器(PEB),便不会出现异常,能正常调试了。如果遇到故意引起异常来反调试的软件,可以使用一些x64dbg的插件,比如SharpOD. 还可以到https://github.com/x64dbg/x64dbg/wiki/Plugins下载ScyllaHide, TitanHide等。
PEB是指Process Environment Block,进程环境块,是Windows系统定义的结构体,其成员如下:(来源 PEB (winternl.h) - Win32 apps | Microsoft Learn)
typedef struct _PEB {
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID Reserved4[3];
PVOID AtlThunkSListPtr;
PVOID Reserved5;
ULONG Reserved6;
PVOID Reserved7;
ULONG Reserved8;
ULONG AtlThunkSListPtr32;
PVOID Reserved9[45];
BYTE Reserved10[96];
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
BYTE Reserved11[128];
PVOID Reserved12[1];
ULONG SessionId;
} PEB, *PPEB;
一个具体的例子如下:(来源 !peb (WinDbg) - Windows drivers | Microsoft Learn)
kd> !peb
PEB at 7ffdf000
InheritedAddressSpace: No
ReadImageFileExecOptions: No
BeingDebugged: No
ImageBaseAddress: 4ad00000
Ldr 77fbe900
Ldr.Initialized: Yes
Ldr.InInitializationOrderModuleList: 00241ef8 . 00242360
Ldr.InLoadOrderModuleList: 00241e90 . 00242350
Ldr.InMemoryOrderModuleList: 00241e98 . 00242358
Base TimeStamp Module
4ad00000 3d34633c Jul 16 11:17:32 2002 D:\WINDOWS\system32\cmd.exe
77f40000 3d346214 Jul 16 11:12:36 2002 D:\WINDOWS\system32\ntdll.dll
77e50000 3d3484ef Jul 16 13:41:19 2002 D:\WINDOWS\system32\kernel32.dll
....
SubSystemData: 00000000
ProcessHeap: 00140000
ProcessParameters: 00020000
WindowTitle: 'D:\Documents and Settings\Administrator\Desktop\Debuggers.lnk'
ImageFile: 'D:\WINDOWS\system32\cmd.exe'
CommandLine: '"D:\WINDOWS\system32\cmd.exe" '
DllPath: 'D:\WINDOWS\system32;D:\WINDOWS\system32;....
Environment: 00010000
ALLUSERSPROFILE=D:\Documents and Settings\All Users
APPDATA=D:\Documents and Settings\UserTwo\Application Data
CLIENTNAME=Console
....
windir=D:\WINDOWS
BeingDebugged成员用于指定该进程是否处于调试状态,我猜“隐藏调试器”的效果就是把PEB结构体中的BeingDebugged由True改为False.