反调试技术概览:怎么恶心怎么来
PEB相关
特点:一般在调试的开始阻拦调试者,调试者只需找到原因后可一次性突破。
PEB:
BeginDebug:调试标记位
Ldr:内存状态
Heap(Flags,Force,Flags):堆状态
NtGlobaFlag:内核全局标记
TEB:
StaticUnicodeString:静态缓冲区
使用原始API:
NtQueryInformationProcess()
ProcessDebugPort(0x07);获取调试端口
ProcessDebugObjectHandle(0x1E);获取调试句柄
ProcessDebugFlag(0x1F);获取调试标记
NtQuerySystemInformation()
SystemKermelDebuggerInformation(0x23);获取系统调试状态(双机调试)
NtQueryObject():遍历系统内核对象
攻击调试器
分离调试器
NtSetInformationThread()--------ThreaHideFormDebugger(0x11)
打开进程检查
SeDebugPrivilege;检查进程是否具有调试权限
利用TLS回调函数
使用普通API父进程检查
窗口名检查
进程名遍历
文件名及遍历
文件名及文件路径检查
注册表检查
动态调试
特点:一般在调试过程中阻拦调试者,可在调试的过程中被频繁触发,因此需要调试者随时关注
使用SEH
异常;断点;SetUnhandleadExceptionFilter()
时间检查
RDTSC:汇编指令,读取时间数计数器的内容
单步检查
补丁检查
0XCC扫描:根据规则扫描程序内的0XCC,如发现则有可能被下了断点
Hash扫描:扫描关键代码段的Hash值,如不对则证明在运行时被修改/调试
API断点扫描:扫描API的第一个字节是否为0XCC,是的话证明被调试了
反反汇编
指令截断:将一条指令截断,进而导致反汇编引擎后续指令解析错误
指令混淆:将敏感指令拆分成多块或几块不相干的指令迷惑调试者
指令膨胀:将一条指令膨胀到数十条指令,但其行为与这一条指令一致
指令乱序:将原有代码执行顺序在内存级别中打乱,用jmp链接,干扰调试者
偷取代码
偷取OEP代码:将OEP代码移动到其他地方加密执行
偷取API代码:将api的部分起始代码移动到其他地方
分页保护
运行时保护分页:修改代码及数据段保护属性干扰分析
壳
压缩壳:配合OEP加密可以使调试者很难顺利逆向
加密壳:添加各种反调试手段干扰调试者分析
虚拟机
API虚拟机:将部分常用API放到虚拟机中模拟执行
指令级虚拟机:可以将任意一段指令放到虚拟机中保护起来