首页
社区
课程
招聘
[原创]IsDebuggerPresent 反调试填坑记录
发表于: 2019-7-30 20:02 8831

[原创]IsDebuggerPresent 反调试填坑记录

2019-7-30 20:02
8831

之前分析rdpscan远控后门的时候接触到Windows API下的反调试,这里就记录下。


首先是 IsDebuggerPresent 函数


IsDebuggerPresent函数可以用来检测本进程是否处于被调试状态,当然,这种方法的实用性不大。


作用:

如果当前进程在调试器的上下文中运行,则返回值为非零值。

如果当前进程未在调试器的上下文中运行,则返回值为零。


实际原理:

这个函数会看PEB中的BeingDebugged是否为0,不为0就表示无调试器,否则非0表示有调试器。


关于IsDebuggerPresent在调试时没有返回非0值退出进程,是ollydbg存在反反调试插件造成的IsDebuggerPresent失效。


原文出处: https://bbs.pediy.com/thread-144819.htm


里面有用到这段代码

来判断是否被调试,这里经过实际测试后发现与结果不同,与当前系统环境有关系。


在使用文中介绍的环境vc++6.0 进行编译,发现失败,之后修改代码后才成功编译(修改后的部分见截图)。


此函数在winbase.h中声明如下:WINBASEAPI BOOL WINAPI IsDebuggerPresent(void);


直接调用此函数的源程序在用vc++6.0编译时会报连接错误,原因是kernel32.lib中找不到_IsDebuggerPresent这个符号。


为了使用此函数,不得不使用LoadLibrary动态加载kernel32.dll,或者使用GetModuleHandle获取kernel32.dll的映像地址,然后使用GetProcAddress取得IsDebuggerPresent的地址。


代码如下:

环境1:vc6.0、WinXp


demo:

在第一种环境下,取出的字节都为0x64。


环境2:vs2017、Win10


demo:

在第二种环境下,取出的字节也都为0x64。


环境3:Win7 vs2015


demo:

因为前面使用了含有反调试插件的ollydbg版本,导致IsDebuggerPresent一直没有效果。


这里就使用原版ollydbg2.01测试如下,IsDebuggerPresent有了效果,执行完后返回值为非0,排除相关因素影响。

但最后发现不论是直接运行或者是被调试器调试,这个字节一直是0x64。


所以如果使用这个逻辑判断是否处于调试环境中,可能会导致误报,实际上这里判断函数首字节是否为0x64(原始)只是为了判断当前此API函数是否被HOOK了。这也证明了以前的代码对这个函数首字节是否为0x64作判断是不准的,因为在win7以上系统,需要对应kernelBase中的IsDebuggerPresent,而不是kernel32中的IsDebuggerPresent。



收藏
免费 2
支持
分享
最新回复 (8)
雪    币: 8377
活跃值: (4961)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
(BOOL(*)())GetProcAddress(hModule, "IsDebuggerPresent")    楼主问下(BOOL(*)())这个是什么作用
2019-7-31 00:41
0
雪    币: 688
活跃值: (3580)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
3
大道在我 (BOOL(*)())GetProcAddress(hModule, "IsDebuggerPresent") 楼主问下(BOOL(*)())这个是什么作用
老铁不好好睡觉
2019-7-31 05:11
0
雪    币: 17421
活跃值: (5004)
能力值: ( LV9,RANK:450 )
在线值:
发帖
回帖
粉丝
4
大道在我 (BOOL(*)())GetProcAddress(hModule, "IsDebuggerPresent") 楼主问下(BOOL(*)())这个是什么作用
typedef BOOL (_stdcall *LPAPI_IDP)();
LPAPI_IDP IsDebuggerPresent = GetProcAddress(hModule, "IsDebuggerPresent");  // 获取下地址
这段代码,在vc6.0下报错,error C2275: 'LPAPI_IDP' : illegal use of this type as an expression
只能转换为如下:
BOOL (*IsDebuggerPresent)(); //新增的部分
IsDebuggerPresent = (BOOL(*)())GetProcAddress(hModule, "IsDebuggerPresent");  // 获取下地址
不用typedef,直接转换为函数指针。
2019-7-31 10:43
0
雪    币: 6086
活跃值: (1117)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
大道在我 (BOOL(*)())GetProcAddress(hModule, "IsDebuggerPresent") 楼主问下(BOOL(*)())这个是什么作用
判断GetProcAddress是否成功吧,下面不是还有个if。。。
2019-7-31 10:45
0
雪    币: 8377
活跃值: (4961)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
jishuzhain typedef BOOL (_stdcall *LPAPI_IDP)(); LPAPI_IDP IsDebuggerPresent = GetProcAddress(hModule, "I ...
这个强制转换是将他转换为一个BOOL类型的地址还是什么?
最后于 2019-7-31 16:31 被大道在我编辑 ,原因:
2019-7-31 16:19
0
雪    币: 10817
活跃值: (2805)
能力值: ( LV5,RANK:71 )
在线值:
发帖
回帖
粉丝
7
一本正经的胡说八道。BOOL IsDebuggerPresent(); 跟0x64有毛关系。
2019-7-31 20:12
0
雪    币: 17421
活跃值: (5004)
能力值: ( LV9,RANK:450 )
在线值:
发帖
回帖
粉丝
8
大道在我 jishuzhain typedef BOOL (_stdcall *LPAPI_IDP)(); LPAPI_IDP IsDebuggerPresent = ...
是转为返回值为BOOL类型的函数指针,与该函数原本声明的要求一致。
2019-8-2 16:38
0
雪    币: 1449
活跃值: (4483)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
直接改PEB的beingdebug
2023-4-7 23:27
0
游客
登录 | 注册 方可回帖
返回
//