#define _WIN32_WINNT 0x0601
#include
#include
typedef BOOL(WINAPI * LPAPI_IDP)(VOID);
LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *pei);
BOOL DeleteFiberApproach();
int main(int argc, PCHAR argv[]){
//getchar();
HMODULE hModule = LoadLibrary("Kernel32");// 加载模块Kernel32
if (hModule == NULL){
printf("1.被调试,无法获取 kernel32.dll模块\n");//ExitProcess(0); // 如果发现程序被调试 直接退出进程
}
//FARPROC
LPAPI_IDP IsDebuggerPresent = GetProcAddress(hModule, "IsDebuggerPresent");// 获取下地址
if (IsDebuggerPresent == NULL){
printf("2.被调试,无法获取 IsDebuggerPresent 地址\n");//ExitProcess(0); // 如果发现程序被调试 直接退出进程
}
if (*(BYTE *)IsDebuggerPresent == 0xcc){
printf("3.被下 0xcc 断点\n");
}
if (*(BYTE *)IsDebuggerPresent != 0x64){
//printf("4.IsDebuggerPresent 函数地址被修改 这个可能不准\n");
}
if (IsDebuggerPresent()){
printf("5.IsDebuggerPresent 返回被调试状态\n");
}
BOOL isdebug;
CheckRemoteDebuggerPresent(GetCurrentProcess(), &isdebug);
if (isdebug){
printf("6.CheckRemoteDebuggerPresent 返回被调试状态\n");
}
int result = 0;
__asm{
mov eax, fs:[30h]
mov eax, [eax + 68h]
and eax, 0x70
mov result, eax
}
if (result){
printf("7.NtGlobalFlags 标志返回被调试状态\n");
}
result = 0;
int result1 = 0;
__asm{
// 进程的PEB
mov eax, fs : [30h]
// 进程的堆,我们随便访问了一个堆,下面是默认的堆
mov eax, [eax + 18h]
// 检查ForceFlag标志位,在没有被调试的情况下应该是4 z1 D s$ I: ^% q P5 _
mov eax, [eax + 10h]
mov result, eax
mov eax, fs :[30h]
// 进程的堆,我们随便访问了一个堆,下面是默认的堆
mov eax, [eax + 18h]
// 检查ForceFlag标志位,在没有被调试的情况下应该是4 z1 D s$ I: ^% q P5 _
mov eax, [eax + 0ch]
mov result1, eax
}
if (result){
//printf("8.ForceFlags 标志返回被调试状态 %x\n", result);
}
if (result1 != 2){
//printf("8.Heapflags 标志返回被调试状态 %x\n", result1);
}
typedef enum _PROCESSINFOCLASS {
ProcessBasicInformation = 0,
ProcessWow64Information = 26
} PROCESSINFOCLASS;
typedef NTSTATUS(WINAPI *NtQueryInformationProcessPtr)(
HANDLE processHandle,
PROCESSINFOCLASS processInformationClass,
PVOID processInformation,
ULONG processInformationLength,
PULONG returnLength);
int debugPort = 0;
hModule = LoadLibrary(TEXT("Ntdll.dll "));
NtQueryInformationProcessPtr NtQueryInformationProcess = (NtQueryInformationProcessPtr)GetProcAddress(hModule, "NtQueryInformationProcess");
NtQueryInformationProcess(GetCurrentProcess(), (PROCESSINFOCLASS)7, &debugPort, sizeof(debugPort), NULL);
if (debugPort == -1){
printf("9.NtQueryInformationProcess 调试端口 返回 %d 如果是 -1 表示被调试\n", debugPort);
}
//6.
//7.触发异常
//UnhandledExceptionFilterApproach();
if (UnhandledExceptionFilterApproach() == FALSE){
printf("10.正常");
} else{
printf("触发的异常被调试器捕获");
//ExitProcess(0);
}
//8
if (DeleteFiberApproach()){
//printf("11.lasterror错误号被修改 %p", GetLastError());
}
getchar();
return 0;
}
// 进程要注册的未处理异常处理程序A
LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *excp){
printf("-----------------------------------------------------\n");
printf("触发异常处理函数,说明没有被调试器截获\n");
printf("异常处理地址 %x\n", excp->ExceptionRecord->ExceptionAddress);
printf("CPU 寄存器:\n");
printf("eax %p ebx %p ecx %p edx %p eip %p\n", excp->ContextRecord->Eax,
excp->ContextRecord->Ebx, excp->ContextRecord->Ecx,
excp->ContextRecord->Edx, excp->ContextRecord->Eip);
printf("-----------------------------------------------------\n");
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)excp->ContextRecord->Eax);
// 修改寄存器eip的值
excp->ContextRecord->Eip += 2;
// 告诉操作系统,继续执行进程剩余的指令(指令保存在eip里),而不是关闭进程
return EXCEPTION_CONTINUE_EXECUTION;
}
//
BOOL UnhandledExceptionFilterApproach(){
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
__asm{
// 将eax清零
xor eax, eax
// 触发一个除零异常
div eax
}
return FALSE;
}
//
BOOL DeleteFiberApproach(){
char fib[1024] = { 0 };
// 会抛出一个异常并被调试器捕获
DeleteFiber(fib);
// 0x57的意思是ERROR_INVALID_PARAMETER
//printf("error = %x", GetLastError());
return (GetLastError() != 0x57);
}