#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.被調(diào)試,無法獲取 kernel32.dll模塊\n");//ExitProcess(0); // 如果發(fā)現(xiàn)程序被調(diào)試 直接退出進(jìn)程
}
//FARPROC
LPAPI_IDP IsDebuggerPresent = GetProcAddress(hModule, "IsDebuggerPresent");// 獲取下地址
if (IsDebuggerPresent == NULL){
printf("2.被調(diào)試,無法獲取 IsDebuggerPresent 地址\n");//ExitProcess(0); // 如果發(fā)現(xiàn)程序被調(diào)試 直接退出進(jìn)程
}
if (*(BYTE *)IsDebuggerPresent == 0xcc){
printf("3.被下 0xcc 斷點(diǎn)\n");
}
if (*(BYTE *)IsDebuggerPresent != 0x64){
//printf("4.IsDebuggerPresent 函數(shù)地址被修改 這個(gè)可能不準(zhǔn)\n");
}
if (IsDebuggerPresent()){
printf("5.IsDebuggerPresent 返回被調(diào)試狀態(tài)\n");
}
BOOL isdebug;
CheckRemoteDebuggerPresent(GetCurrentProcess(), &isdebug);
if (isdebug){
printf("6.CheckRemoteDebuggerPresent 返回被調(diào)試狀態(tài)\n");
}
int result = 0;
__asm{
mov eax, fs:[30h]
mov eax, [eax + 68h]
and eax, 0x70
mov result, eax
}
if (result){
printf("7.NtGlobalFlags 標(biāo)志返回被調(diào)試狀態(tài)\n");
}
result = 0;
int result1 = 0;
__asm{
// 進(jìn)程的PEB
mov eax, fs : [30h]
// 進(jìn)程的堆,我們隨便訪問了一個(gè)堆萧锉,下面是默認(rèn)的堆
mov eax, [eax + 18h]
// 檢查ForceFlag標(biāo)志位珊随,在沒有被調(diào)試的情況下應(yīng)該是4 z1 D s$ I: ^% q P5 _
mov eax, [eax + 10h]
mov result, eax
mov eax, fs :[30h]
// 進(jìn)程的堆,我們隨便訪問了一個(gè)堆柿隙,下面是默認(rèn)的堆
mov eax, [eax + 18h]
// 檢查ForceFlag標(biāo)志位叶洞,在沒有被調(diào)試的情況下應(yīng)該是4 z1 D s$ I: ^% q P5 _
mov eax, [eax + 0ch]
mov result1, eax
}
if (result){
//printf("8.ForceFlags 標(biāo)志返回被調(diào)試狀態(tài) %x\n", result);
}
if (result1 != 2){
//printf("8.Heapflags 標(biāo)志返回被調(diào)試狀態(tài) %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 調(diào)試端口 返回 %d 如果是 -1 表示被調(diào)試\n", debugPort);
}
//6.
//7.觸發(fā)異常
//UnhandledExceptionFilterApproach();
if (UnhandledExceptionFilterApproach() == FALSE){
printf("10.正常");
} else{
printf("觸發(fā)的異常被調(diào)試器捕獲");
//ExitProcess(0);
}
//8
if (DeleteFiberApproach()){
//printf("11.lasterror錯(cuò)誤號(hào)被修改 %p", GetLastError());
}
getchar();
return 0;
}
// 進(jìn)程要注冊(cè)的未處理異常處理程序A
LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *excp){
printf("-----------------------------------------------------\n");
printf("觸發(fā)異常處理函數(shù),說明沒有被調(diào)試器截獲\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;
// 告訴操作系統(tǒng),繼續(xù)執(zhí)行進(jìn)程剩余的指令(指令保存在eip里)禀崖,而不是關(guān)閉進(jìn)程
return EXCEPTION_CONTINUE_EXECUTION;
}
//
BOOL UnhandledExceptionFilterApproach(){
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
__asm{
// 將eax清零
xor eax, eax
// 觸發(fā)一個(gè)除零異常
div eax
}
return FALSE;
}
//
BOOL DeleteFiberApproach(){
char fib[1024] = { 0 };
// 會(huì)拋出一個(gè)異常并被調(diào)試器捕獲
DeleteFiber(fib);
// 0x57的意思是ERROR_INVALID_PARAMETER
//printf("error = %x", GetLastError());
return (GetLastError() != 0x57);
}