- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第二十二章-OllyDbg反调试之UnhandledExceptionFilter,ZwQueryInformationProcess
本章我们继续讨论反调试技术,我们将介绍反调试的另外两个小技巧,由于其中一个可以配合另一个来使用,所以我们两个一起介绍。本章我们使用上一章打过补丁的OllyDbg,也就是Nvp11,其中HideDebugger插件的配置如下:
这里我们可以看到其中有一个Unhandled exception tricks的选项。接下来我们将学习Unhandled exception和另一个API函数ZwQueryInformationProcess检测调试器的工作原理。
这里我们实验的对象叫做sphynx。如果你勾选上了HideDebugger插件的Unhandled exception tricks就可以正常运行起来了,但是使用插件之前我们还是来介绍一下它的实现原理。
另外说一点,我们现在暂时不解决这个CrackMe,我们只是来看看该CrackMe是如何检测OD的。
我们使用Nvp11(打过补丁的OllyDbg)加载该CrackMe,并且确保HideDebugger1.23插件的配置如第一幅图所示,接着将Debugging options-Exceptions选项中忽略的异常选项全部勾选上。
运行起来。
出现了CrackMe的主窗口,那么反调试体现在哪里呢?我们随便输入一个错误的序列号然后点击Check按钮。
OD的左下方提示存在不可处理的异常,程序将关闭,我们继续运行。
好了,我们不用OLLYDBG加载该CrackMe,它是不会关闭的,我们可以尝试输入不同的序列号,同样也不会关闭。
好了,现在我们重新启动该CrackMe,看看其使用了哪些API函数。
我们记得HideDebugger插件中有绕过该反调试的选项。
我们设置该选项前先来学习一下如何手工绕过该反调试以及其原理。
我们先来看看MSDN中关于SetUnhandledExceptionFilter的说明。
该函数的唯一一个参数为异常处理函数指针。当程序发生异常是,且程序不处于调试模式(在VS或者其他调试器里运行)则首先调用该异常处理函数。因此,程序可以主动抛出一个异常来判断当前程序是否正在被调试,嘿嘿,这里我们并不需要使用ZwQueryInformationProcess。
我们回到OD中,看到SetUnhandledExceptionFilter的调用处。
正如你所看到的,只有一个参数,在程序执行过程中会抛出一个异常,如果当前程序没有被调试,那么就会调用该参数指定的异常处理函数,嘿嘿。这里该异常处理函数入口地址为401108,如果当前程序正在被调试的话,程序最终将终止运行。
这是我们看到的该程序安装的其中一个异常处理函数,当有异常发生并且当前程序没有被调试的情况下,该异常处理函数将得以执行。
好了,我们现在给SetUnhandledExceptionFilter,UnhandledExceptionFilter这两个函数设置断点。
我们运行起来。
断在了SetUnhandledExceptionFilter的入口处。我们看下堆栈的情况。
正如你所看到的异常处理函数入口地址为401108,我们在命令栏中输入BP 401108给该函数设置断点。
我们运行起来,可以看到又断在SetUnhandledExceptionFilter的入口处,这个调用来至一个shellext.dll。
我们对这处调用不感兴趣,异常处理函数前面已经设置过了,所以我们将对SetUnhandledExceptionFilter设置的断点删除掉。
现在,我们随便输入一个错误的序列号,然后单击Check按钮,将会断在系统默认的异常处理函数入口处,因为程序有异常发生,并且当前程序正在被调试,所以,并不会首先调用程序之前设置的入口为401108的异常处理函数,而异常转交给调试器处理了,而调试器也无法处理该异常,所以最终调用系统默认的异常处理函数UnhandledExceptionFilter来处理,嘿嘿。
这个API函数用来检测当前程序是否正在被调试,我们F8键单步看看该函数是如何实现检测调试器的。
这里是我们今天要介绍的第二个反调试知识点,这个函数也可以单独用来检测调试器只需要把InfoClass设置为7。
该函数通过将InfoClass参数设置为7,将可以获取到当前进程是否被调试的信息,该信息将保存在Buffer参数指向的缓冲区中。
我们在数据窗口中定位到给缓冲区。
我们可以看到该缓冲区的大小为4个字节,如果该缓冲区返回的是FFFFFFFF的话表示当前程序正在被调试,如果返回的是0的话,表示当前程序没有被调试,我们按F8键单步执行该函数,看看缓冲区中返回的是什么。
我们可以看到返回值为F
文档评论(0)