反調(diào)試專題丨反調(diào)試之基于SEH異常
反調(diào)試之基于SEH異常
在如果程序出現(xiàn)異常,如果有調(diào)試器,根據(jù)優(yōu)先級,調(diào)試器會優(yōu)先接管異常,從而就會跳過異常處理,如果沒有調(diào)試器,那么程序就會接收異常。那么我們就可以注冊一個異常,讓程序出現(xiàn)異常,看異常被誰接管:
#include
#include
#include
DWORD WINAPI MyIsDebug(
LPVOID lpThreadParameter
)
{
while (1) {
__try {
_asm int 3;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
MessageBox(NULL, L"警告", L"一切正常", MB_OK);
continue;
}
MessageBox(NULL, L"警告", L"調(diào)試中", MB_OK);
return 1;
}
return 1;
}
int main()
{
printf("被調(diào)試了");
CreateThread(NULL, NULL, MyIsDebug, NULL, NULL, NULL);
system("pause");
return 0;
}
這里是注冊一個線程,在線程回調(diào)函數(shù),設(shè)一個循環(huán),循環(huán)里面放入一個int 3斷點,也就是CC斷點,直接在VS中運(yùn)行,編譯器也是一個調(diào)試器,也會被檢測出來:
?

在文件夾中打開:
?

當(dāng)然異常注冊有很多方法,不僅僅是int 3,但凡可以觸發(fā)異常都可以,例如釋放句柄,當(dāng)然這個異常在調(diào)試狀態(tài)下才會觸發(fā),所以稍作改動:
#include
#include
#include
DWORD WINAPI MyIsDebug(
LPVOID lpThreadParameter
)
{
while (1) {
__try {
CloseHandle(reinterpret_cast < HANDLE>(0x9999999));
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
MessageBox(NULL, L"警告", L"一切正常", MB_OK);
return 0;
}
if (IsDebuggerPresent())
{
MessageBox(NULL, L"警告", L"調(diào)試中", MB_OK);
}
}
return 1;
}
int main()
{
CreateThread(NULL, NULL, MyIsDebug, NULL, NULL, NULL);
system("pause");
return 0;
}

