初识反调试
初识反调试
1. IsDebuggerPresent()
函数
包含在debugapi.h
头文件中,函数原型:
1 | BOOL IsDebuggerPresent(); //未在调试器中运行时返回值为零,否则为非零值 |
该函数允许程序确定是否正在调试它,以便可以修改其行为
2. PEB->BeingDebugged
FS标志段寄存器总是指向TEB(当前的线程环境块),其中包含一个指针指向当前PEB(进程环境块),该结构体包含一个成员BeingDebugged,它是一个标志位,用于标识当前进程是否正在被调试
3. NtQueryInformationProcess
函数
包含在ntdll.h
头文件中,语法如下:
1 | __kernel_entry NTSTATUS NtQueryInformationProcess( |
其检索一个WORD_PTR值,该值是进程的调试器端口号。非零值指示进程正在环3调试器的控制下运行,如果进程没有调试器,则返回零
4. EPROCESS_DebugPort
获取系统内核中标记进程信息的结构体EPROCESS,通过EPROCESS结构体中的DebugPort成员判断进程是否正在被调试,一般无法使用普通方法实现,需要内核调试
5. 异常处理检测
处理异常时,正常运行过程会将信息发给Windows的SEH异常捕获流程,而进行调试时则会发给调试器
6. 断点检测
函数断点体现为0xCC,可通过对比内存数据中的指令数据与磁盘内文件的数据进行对比,如发现存在不同,则说明有断点,即程序被调试
7. 检测调试器进程
通过枚举进程,判断进程名是否为调试器进程名,如果是,则说明程序正在被调试
还可通过查看是否存在调试器的窗口,判断程序是否正在被调试。可使用VC++中附带的Spy++查找窗口名
8. 时间检测
程序运行时,如果被调试,则由于会出现单步运行等过程,程序运行速度会变慢,因此可通过检测程序运行时间,判断程序是否正在被调试
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 hanafuda_store's Blog!