在intel的x86寄存器中有一种叫标志寄存器:
标志寄存器中的TF(Trap Flag)位,CPU在执行完一条指令后,如果检测到标志寄存器的TF位为1,则会产生一个int 1中断,然后再将TF置为0,后进行int 1中断后继续执行。操作系统上可以视为异常。
再加上出现了异常如果有调试器就会返回给调试器,如果调试器继续往下走也没啥问题,因为我们这里的异常代码是一个nop,而一个普通运行的进程因为没调试器,所以就会走异常处理程序,所以就是走异常处理程序的就是正常进程,没走的就是异常。
代码实践:
#include<Windows.h> #include<iostream> #include<tlhelp32.h> using namespace std; void HaveStep() { cout << "检测到了单步调试" << endl; ExitProcess(0); } void NoStep() { cout << "没有检测到单步调试" << endl; } void CheckTFflag() { cout << "test" << endl; DWORD HaveStepAddr = (DWORD)HaveStep; __try { __asm { pushfd or dword ptr ss : [esp] , 0x100 popfd nop jmp HaveStepAddr } } __except (1) { NoStep(); } } int main() { CheckTFflag(); system("pause"); return 0; }
正常运行的结果和采用vs单步调试的结果: