在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编之类的方法破解自己。为了了解如何破解反调试技术,首先我们来看看反调试技术。

一、Windows API 方法

Win32 提供了两个 API, IsDebuggerPresent 和 CheckRemoteDebuggerPresent 可以用来检测当前进程是否正在被调试,以IsDebuggerPresent 函数为例,例子如下:

BOOL ret = IsDebuggerPresent();printf("ret = %d\n", ret);

破解方法很简单,就是在系统里将这两个函数 hook 掉,让这两个函数一直返回 false 就可以了,网上有很多做 hook API 工作的工具,也有很多工具源代码是开放的,所以这里就不细谈了。

二、查询进程 PEB 的 BeingDebugged 标志位

当进程被调试器所附加的时候,操作系统会自动设置这个标志位,因此在程序里定期查询这个标志位就可以了,例子如下:

bool PebIsDebuggedApproach()
{char result = 0;__asm{// 进程的PEB地址放在fs这个寄存器位置上mov eax, fs:[30h]// 查询BeingDebugged标志位mov al, BYTE PTR [eax + 2] mov result, al}return result != 0;
}

三、查询进程 PEB 的 NtGlobal 标志位

跟第二个方法一样,当进程被调试的时候,操作系统除了修改 BeingDebugged 这个标志位以外,还会修改其他几个地方,其中NtDll 中一些控制堆(Heap)操作的函数的标志位就会被修改,因此也可以查询这个标志位,例子如下:

bool PebNtGlobalFlagsApproach()
{int result = 0;__asm{// 进程的PEBmov eax, fs:[30h]// 控制堆操作函数的工作方式的标志位mov eax, [eax + 68h]// 操作系统会加上这些标志位FLG_HEAP_ENABLE_TAIL_CHECK, // FLG_HEAP_ENABLE_FREE_CHECK and FLG_HEAP_VALIDATE_PARAMETERS,// 它们的并集就是x70//// 下面的代码相当于C/C++的// eax = eax & 0x70and eax, 0x70mov result, eax}return result != 0;}

四、查询 进程堆 的一些 标志位

这个方法是第三个方法的变种,只要进程被调试,进程在堆上分配的内存,在分配的堆的头信息里,ForceFlags 这个标志位会被修改,因此可以通过判断这个标志位的方式来反调试。因为进程可以有很多的堆,因此只要检查任意一个堆的头信息就可以了,所以这个方法貌似很强大,例子如下:

bool HeapFlagsApproach()
{int result = 0;__asm{// 进程的PEBmov eax, fs:[30h]// 进程的堆,我们随便访问了一个堆,下面是默认的堆mov eax, [eax + 18h]// 检查ForceFlag标志位,在没有被调试的情况下应该是mov eax, [eax + 10h]mov result, eax}return result != 0;
}

五、使用 NtQueryInformationProcess 函数

NtQueryInformationProcess 函数是一个未公开的 API,它的第二个参数可以用来查询进程的调试端口。如果进程被调试,那么返回的端口值会是 -1,否则就是其他的值。由于这个函数是一个未公开的函数,因此需要使用 LoadLibrary 和 GetProceAddress的方法获取调用地址,示例代码如下:

// 声明一个函数指针。typedef NTSTATUS (WINAPI *NtQueryInformationProcessPtr)(HANDLE processHandle,PROCESSINFOCLASS processInformationClass,PVOID processInformation,ULONG processInformationLength,PULONG returnLength);bool NtQueryInformationProcessApproach()
{int debugPort = 0;HMODULE hModule = LoadLibrary(TEXT("Ntdll.dll "));NtQueryInformationProcessPtr NtQueryInformationProcess = (NtQueryInformationProcessPtr)GetProcAddress(hModule, "NtQueryInformationProcess");if ( NtQueryInformationProcess(GetCurrentProcess(), (PROCESSINFOCLASS)7, &debugPort, sizeof(debugPort), NULL) )printf("[ERROR NtQueryInformationProcessApproach] NtQueryInformationProcess failed\n");elsereturn debugPort == -1;return false;}

六、NtSetInformationThread 方法

这个也是使用 Windows 的一个未公开函数的方法,你可以在当前线程里调用 NtSetInformationThread,调用这个函数时,如果在第二个参数里指定 0x11 这个值(意思是 ThreadHideFromDebugger ),等于告诉操作系统,将所有附加的调试器统统取消掉。示例代码:

// 声明一个函数指针。typedef NTSTATUS (*NtSetInformationThreadPtr)(HANDLE threadHandle,THREADINFOCLASS threadInformationClass,PVOID threadInformation,ULONG threadInformationLength);void NtSetInformationThreadApproach()
{HMODULE hModule = LoadLibrary(TEXT("ntdll.dll"));NtSetInformationThreadPtr NtSetInformationThread = (NtSetInformationThreadPtr)GetProcAddress(hModule, "NtSetInformationThread");NtSetInformationThread(GetCurrentThread(), (THREADINFOCLASS)0x11, 0, 0);}

七、触发异常的方法

这个技术的原理是,首先,进程使用 SetUnhandledExceptionFilter 函数注册一个未处理异常处理 函数A,如果进程没有被调试的话,那么触发一个未处理异常,会导致操作系统将控制权交给先前注册的函数A;而如果进程被调试的话,那么这个未处理异常会被调试器捕捉,这样我们的 函数A 就没有机会运行了。

这里有一个技巧,就是触发未处理异常的时候,如果跳转回原来代码继续执行,而不是让操作系统关闭进程。方案是在函数A里修改eip的值,因为在 函数A 的 参数 _EXCEPTION_POINTERS 里,会保存当时触发异常的指令地址,所以在 函数A 里根据这个指令地址修改 寄存器eip 的值就可以了,示例代码如下:

// 进程要注册的未处理异常处理程序A
LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *pei)
{SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)pei->ContextRecord->Eax);// 修改寄存器eip的值pei->ContextRecord->Eip += 2;// 告诉操作系统,继续执行进程剩余的指令(指令保存在eip里),而不是关闭进程return EXCEPTION_CONTINUE_EXECUTION;
}bool UnhandledExceptionFilterApproach()
{SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);__asm{// 将eax清零xor eax, eax// 触发一个除零异常div eax}return false;}

八、调用 DeleteFiber 函数

如果给 DeleteFiber 函数传递一个无效的参数的话,DeleteFiber函数除了会抛出一个异常以外,还是将进程的LastError值设置为具体出错原因的代号。然而,如果进程正在被调试的话,这个LastError值会被修改,因此如果调试器绕过了第七步里讲的反调试技术的话,我们还可以通过验证LastError值是不是被修改过来检测调试器的存在,示例代码:

bool DeleteFiberApproach()
{char fib[1024] = {0};// 会抛出一个异常并被调试器捕获DeleteFiber(fib);// 0x57的意思是ERROR_INVALID_PARAMETERreturn (GetLastError() != 0x57);
}

反调试技术揭秘(转)相关推荐

  1. 反欺诈技术揭秘-设备指纹VS关系网络模型 此博文包含图片 (2017-05-12 10:23:52)转载▼ 标签: 设备指纹 关系网络 反欺诈 神经网络模型 分类: 风控 文章来源:网络(经整合梳理

    反欺诈技术揭秘-设备指纹VS关系网络模型 (2017-05-12 10:23:52) 转载▼ 标签: 设备指纹 关系网络 反欺诈 神经网络模型 分类: 风控 文章来源:网络(经整合梳理,仅供交流学习使 ...

  2. 静态反调试技术(2)

    文章目录 NtQueryInformationProcess() `ProcessDebugPort`(0x7) CheckRemoteDebuggerPresent() ProcessDebugOb ...

  3. 静态反调试技术(1)

    文章目录 声明 静态反调试目的 注意 PEB https://blog.csdn.net/CSNN2019/article/details/113113347 BeingDebugged(+0x2) ...

  4. 静态反调试技术(3)

    文章目录 ZwSetInformationThread 破解方法 **调试程序代码**: 利用TLS回调函数(详情通过以下链接查看) ETC 破解之法 **调试程序代码**: 篇章大总结: 反调试技术 ...

  5. windows平台下的反调试技术

    在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编啦之类的方法破解自己.为了了解如何破解反调试技术 ...

  6. Windows反调试技术全攻略

    在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编啦之类的方法破解自己.为了了解如何破解反调试技术 ...

  7. 如何绕过反调试技术——PhantOM插件总结

    PhantOM是OllyDbg的一款插件,可以用来绕过大多数的反调试技术,功能十分强大,所以单独对这个插件进行使用总结.(Ps:现在似乎不怎么常用,在64位下的兼容性比较差,现在比较常用的是sharp ...

  8. 详解反调试技术(转)

    反调试技术,恶意代码用它识别是否被调试,或者让调试器失效.恶意代码编写者意识到分析人员经常使用调试器来观察恶意代码的操作,因此他们使用反调试技术尽可能地延长恶意代码的分析时间.为了阻止调试器的分析,当 ...

  9. 恶意软件反检测技术简介:反调试技术解析

    本文中,我们将向读者介绍恶意软件用以阻碍对其进行逆向工程的各种反调试技术,以帮助读者很好的理解这些技术,从而能够更有效地对恶意软件进行动态检测和分析. 一.反调试技术 反调试技术是一种常见的反检测技术 ...

最新文章

  1. C语言字符串排序!_只愿与一人十指紧扣_新浪博客
  2. 1.Pytorch Basics
  3. JAVA 算法练习(二)
  4. OpenStack 虚拟机的磁盘文件类型与存储方式
  5. Linux 小知识翻译 - 「补丁」(patch)
  6. Filter 字符编码Filter 一
  7. python zipfile 文件压缩和文件
  8. YBTOJ:最短时间(长链剖分、线段树)
  9. Java制作VCARD
  10. Android官方开发文档Training系列课程中文版:创建自定义View之View的创建
  11. Windows10-1909各个版本进行下载地址汇总
  12. Java虚拟机专题之class文件结构(读书笔记)
  13. 图像处理------简单脸谱检测算法
  14. Linux命令详解词典高频命令(2)
  15. 《动手学深度学习》Mxnet环境搭建
  16. scratch英语计算机,scratch 2怎么做计算器
  17. 【Android】获取当前的安卓版本号的代码
  18. 柏西机器人_《勿忘我》孔木猴 ^第15章^ 最新更新:2020-08-03 17:37:51 晋江文学城_手机版...
  19. 人脸识别、二维码电子签到,让会议会展入场更加智能!
  20. 奥运会数据可视化展示

热门文章

  1. Spring Cloud Alibaba基础教程:Sentinel Dashboard中修改规则同步到Nacos
  2. 评测任务征集 | 全国知识图谱与语义计算大会(CCKS 2022)
  3. 论文浅尝 | 基于知识库的神经网络问题生成方法
  4. 机器学习十大经典算法之岭回归和LASSO回归
  5. Android官方开发文档Training系列课程中文版:线程执行操作之线程池操作
  6. Android官方开发文档Training系列课程中文版:管理系统UI之隐藏状态条
  7. 运用事理图谱搞事情:新闻预警、事件监测、文本可视化、出行规划与历时事件流生成
  8. 2021-11-05深度学习
  9. 前端vue实现pdf文件的在线预览
  10. ubuntu-18.04 修改用户名密码