个人理解
2019.6.19 在汇编面前没有任何程序有秘密(opcode层面做的技巧改动没接触到),调试是打开程序内部乃至程序一切的一把钥匙,反调试就是让钥匙失效的一种手段。反调试根据破坏调试过程的时间不同整体分为静态反调试和动态反调试两大类,静态反调试主要在调试的初期通过检测某些调试标志阻止调试过程继续,找到原因后可以一次解决。动态反调试在调试过程中阻拦调试者,可在调试过程中频繁被触发,需要一直关注。
静态反调试
PEB
BeginDebug:调试标记位
LDR:内存状态
Heap(Flags、Force Flags):堆状态
NtGlobalFlag:内核全局标记
TEB
StaticUnicodeString:静态缓冲区
原始API
NtQueryInformationProcess()
·ProcessDebugPort(0x07):获取调试端口
·ProcessDebugObjectHandle(0x1E):获取调试句柄
·ProcessDebugFlag(0x1F):获取调试标记
NtQuerySystemInformation()
·SystemKernelDebuggerInformation(0x23):获取系统调试状态(双机)
NtQueryObject():遍历系统内核对象
攻击调试器
NtSetInformationThread()
·ThreadHideFormDebugger(0x11) 需导入加载
打开进程检查
SetDebugPrivilege:检查进程是否具有调试权限
TLS回调函数
使用普通API
·父进程检查
·窗口名检查
进程名检查
文件名及文件路径检查
注册表检查
动态反调试
使用SEH
·异常
·断点
·SetUnhandleedExceptionFilter()
时间检查
RDTSC:读取时间戳计数器的内容
单步检查
补丁检查
·0xCC扫描:根据规则扫描程序内的0xCC,如发现有则可能被下了软件断点
·Hash扫描:扫描关键代码段的Hash值,如不对则证明在运行是被修改/调试
·API断点扫描:扫描API第一字节是否为0xCC,如是则被调试了
反反汇编
·指令截断:将一条指令截断,进而导致反汇编引擎后续指令解析错误
·指令混淆:将敏感指令块拆分成多块或若干条不相干指令迷惑调试者
·指令膨胀:将一条指令膨胀为数十条指令,但其行为与这一条指令一致
·代码乱序:将原有代码执行顺序在内存级别中打乱,用跳转指令链接,如JMP等,干扰调试
偷取代码
·偷取OEP代码:将OEP代码移动到其他地方加密执行
·偷取API代码:将API部分的部分代码移动到其他地方。
分页保护
·运行时保护分页:修改代码及数据段保护属性干扰分析
壳
·压缩壳:配合OEP加密
·加密壳:添加各种反调试手段干扰分析
虚拟机
·API虚拟机:将部分常用API放到虚拟机中模拟执行
·指令集虚拟机:将任一段指令放到虚拟机中保护起来