今天在Win7下分析Hamachi VPN Client的时候用windbg挂载之,弹出了一个Win32 on5的错误,由于调试方面很生疏,以为是使用了什么反调试的技术。放IDA中查看导入函数,看到了IsDebuggerPresent,以为是这个东西在作怪,最后发现这个错误很愚蠢,刚使用Win7没多久,一直不习惯使用右键里的管理员权限运行,点右键以管理员权限运行windbg之后F6挂上去就可以开始了。下面开始进入主题吧。

===============================

函数的原型可以从连接http://msdn.microsoft.com/en-us/library/windows/desktop/ms680345(v=vs.85).aspx或者,如下所示:

BOOL WINAPI IsDebuggerPresent( void );

这个函数的用途就是用来检查程序是否在ring 3调试器中运行。关于这个函数google出来一大把的文章,这个函数很被鄙视~~~~

我自己写了一个hello world的小程序来调试调试,程序代码如下:

#include <windows.h>

#include <stdio.h>

#define _WIN32_WINNT 0x0500

int main( void )

{

bool isDebugged;

while ( true ) {

isDebugged = IsDebuggerPresent();

if ( isDebugged ) {

printf( "[-] kao, go away!\n" );

exit( -1 );

}

printf( "[+] Hello World!\n" );

}

return 0;

}

这个程序的目的是在console下输出hello world,如果程序没有在调试器中运行,使用了一个死循环,一直在hello world,

如果检查到程序在调试器中,程序就会退出。

接下来,我们的任务就是娱乐下可怜的hello  world,让它以为没有人在调戏它。

=======================================

调试过程:

=========

第一步:先让cmd下让hello world跑起来,可以在控制台下看到它不知疲倦的一直在hello world。

第二步:打开windbg  attach到这个程序

这个时候,程序会被断下来:

ntdll!DbgBreakPoint:

7c92120e cc              int     3

现在可以给IsDebuggerPresent函数下断点了;

bp  Kernel32!IsDebuggerPresent

现在可以用bl查看下断点,应该设置好了断点。

输入g,程序会在IsDebuggerPresent的入口处停下来

查看汇编代码:

7c813132 90              nop

kernel32!IsDebuggerPresent:

7c813133 64a118000000    mov     eax,dword ptr fs:[00000018h] fs:003b:00000018=7ffdf000

7c813139 8b4030          mov     eax,dword ptr [eax+30h]

7c81313c 0fb64002        movzx   eax,byte ptr [eax+2]

7c813140 c3              ret

7c813141 90              nop

7c813142 90              nop

红色的代码就是这个函数的实现了。

我们现在可以用p单步步过这几条指令,会到用户空间。

0040102f 7448            je      antidebug!main+0x69 (00401079)

00401031 8bf4            mov     esi,esp

00401033 ff153c514200    call    dword ptr [antidebug!_imp__IsDebuggerPresent (0042513c)]

00401039 3bf4            cmp     esi,esp

现在可以查看下eax的值为1,说明程序是在被调试的。

接下来,我们可以选择修改eax的值,这样这一轮循环,可以正常的输出hello world了,但下一次又需要重复这个过程了。

另一选择就是在内存中抹掉对这个函数的调用,从上面蓝色的指令行可以知道内存0x401033地址处开始的连续6个字节中存储了对这个函数调用的opcode。

我们可以用以下指令修改这6个字节

ew 0x401033 0xc031 修改内存

ew 0x401035 0xc031

ew 0x401037 0xc031

0xc031 为xor  eax, eax的opcode。

再用reax=0修改eax的值。

bc 0 去掉断点,现在g一下,就可以看到永不知疲倦的hello world了。

这个方法虽然管用,但是很野蛮、暴力,我们还有另一个更好的选择。

现在我们再回来看看IsDebuggerPresent函数的实现。

7c813133 64a118000000    mov     eax,dword ptr fs:[00000018h] fs:003b:00000018=7ffdf000

7c813139 8b4030          mov     eax,dword ptr [eax+30h]

7c81313c 0fb64002        movzx   eax,byte ptr [eax+2]

7c813140 c3              ret

Windows为每一个运行的进程在用户空间建立了一个进程环境块peb,我们可以用dt _peb来查看下这个数据结构,

每个进程默认有一个主线程,在用户空间为每一个线程建立一个线程环境块teb,同样也可以用dt _teb来查看下下这个数据结构。

其实teb据说以前叫tib,后来改名为teb了,但在数据结构的定义中teb的第一个元素就是tib,tib应该是win98时候的名称,

后来可能扩展了,改名为teb,但teb第一个包含了tib,使得它跟以前的tib兼容。

tib便宜0x18的地方有一个指针 self,这个指针指向了tib的起始地址,其实tib的起始地址就是teb的起始地址,所有从

这个指针我们就可以知道teb的起始地址了,从teb的数据结构中可以知道teb便宜0x30的地方也有一个指针,这个指针说明了

该线程是属于哪一个进程拥有的,指向了peb的起始地址,在从peb的数据结构中可以知道peb便宜0下的地方有一个变量,

:001> dt _peb 7ffd7000

ntdll!_PEB

+0x000 InheritedAddressSpace : 0 ''

+0x001 ReadImageFileExecOptions : 0 ''

+0x002 BeingDebugged    : 0x1 ''

+0x003 SpareBool        : 0 ''

这个标红的变量指明了进程是否是出于被调试状态。本质上IsDebuggerPresent就是检查了这个变量。
fs总是指向当前运行的线程的teb,现在应该很好理解IsDebuggerPresent的实现了,接下来我们就可以用eb直接修改BeingDebugged变量了。
到次关于IsDebuggerPresent的讨论应该可以暂时告一段落了。

IsDebuggerPresent学习相关推荐

  1. 未处理异常和C++异常——Windows核心编程学习手札之二十五

    未处理异常和C++异常 --Windows核心编程学习手札之二十五 当一个异常过滤器返回EXCEPTION_CONTINUE_SEARCH标识符时是告诉系统继续上溯调用树,寻找另外的异常过滤器,但当每 ...

  2. POCO C++库学习和分析 -- 序

    POCO C++库学习和分析 -- 序 1. POCO库概述: POCO是一个C++的开源库集.同一般的C++库相比,POCO的特点是提供了整一个应用框架.如果要做C++程序应用框架的快速开发,我觉得 ...

  3. POCO C++库学习和分析 -- 异常、错误处理、调试

    POCO C++库学习和分析 -- 异常.错误处理.调试 1. 异常处理 C++同C语言相比,提供了异常机制.通过使用try,catch关键字可以捕获异常,这种机制使得程序员在程序异常发生时,可以通过 ...

  4. 《逆向工程核心原理》学习笔记(六):高级逆向分析技术

    目录 前言 一.TLS回调函数 1.TLS简介 (1)IMAGE_DATA_DIRECTORY (2)IMAGE_TLS_DIRECTORY 2.TLS回调函数简介 3.示例1:HelloTls.ex ...

  5. 史上最全最完整,最详细,软件保护技术-程序脱壳篇-逆向工程学习记录

    title: 程序脱壳篇 date: {{ date }} tags: ['程序壳','程序脱壳篇'] categories: ['程序壳','程序脱壳篇'] excerpt: 壳是最早出现的专用加密 ...

  6. java入门 慕路径,Java入门基础知识总结学习教程大全【必看经典】

    类型的表达式,是循环条件,表达式3是党执行了一遍循环之后,修改控制循环的变量值. ??? for语句的执行过程是这样的:首先计算表达式1,完成必要的初始化工作:然后判断表达式2的值,如果表达式的值为t ...

  7. Java EE学习心得

    –Java EE学习心得   1.    称为编程专家的秘诀是: 思考-----编程--------思考------编程--.. 编程不能一步到位,不能一上来就编,必须先思考如何写,怎样写?然后再编程 ...

  8. FastAI 2019课程学习笔记 lesson 2:自行获取数据并创建分类器

    文章目录 数据获取 google_images_download 的安装和使用 挂载google 个人硬盘到Google colab中 删除不能打开文件 创建ImageDataBunch 训练模型 解 ...

  9. FastAI 课程学习笔记 lesson 1:宠物图片分类

    文章目录 代码解析 神奇的"%" 导入fastAI 库 下载解压数据集 untar_data 获取帮助文档 help() ? ?? doc 设置路径 get_image_files ...

最新文章

  1. 航天智慧物流!智能汽车竞赛—航天赛道开始报名啦!
  2. jmeter跨线程组传值
  3. 【Android工具】安卓手机轻松获取硬件数据和状态信息
  4. ML之分类预测之ElasticNet之PLoR:在二分类数据集上调用Glmnet库训练PLoR模型(T2)
  5. List集合中两种遍历方式
  6. 十五、java的基本数据类型
  7. 【转】android 完全退出应用程序
  8. 正常访问静态文件,不要找不到静态文件报404
  9. 最新版24H全自动在线要饭系统全开源源码
  10. spssfisher判别分析步骤_在SPSS中进行Fisher判别分析的具体操作及研究意义——【杏花开医学统计】...
  11. mysql登陆案例_Mysql用户登陆验证过程 案例
  12. 滴滴打车CTO张博:我们要这样玩社区和大数据
  13. IBM推出量子AI平台IBM z16
  14. QT3D学习之路03
  15. 基于‘匹配’技术的车牌自动识别系统
  16. android学习笔记----ListView和各种适配器简介
  17. 二十二.jmeter在linux下运行
  18. uni-app 小程序获取dom信息
  19. 浅析“物联网卡+公安”在社会治安防控中的应用
  20. 江苏省宿迁市谷歌高清卫星地图下载

热门文章

  1. C++之编码问题(Unicode,ASCII,本地默认)
  2. Spring Boot中普通类获取Spring容器中的Bean
  3. IE8 CSS hack
  4. Spring----学习参考博客书单链接
  5. 工作中linux定时任务的设置及相关配置
  6. hibernate对象管理
  7. 计算掩码、网络地址(最小主机地址,最高主机地址)、广播地址、IP地址范围、主机号...
  8. ModelSim之命令行仿真入门 (step 2)
  9. RGB_YUV_YCbCr
  10. 架设自己的WebDAV服务器作为AutoCAD WS的数据存储