反调试学习——IsDebuggerPresent

IsDebuggerPresent

***IsDebuggerPresent***的作用是检测自身进程是否处于调试状态,如果进程没有运行在调试器环境中,函数返回0;如果调试附加了进程,函数返回一个非零值。

写了个小程序试验绕过:
绕过目前我自己有两种思路:
1.在判断处做改变
2.在 IsDebuggerPresent做改变
代码如下:

if (IsDebuggerPresent())
	{
		MessageBox(TEXT("有调试器在调试!"));
	}
	else
	{
		MessageBox(TEXT("没有调试器在调试!"));
	}

IsDebuggerPresent函数很简单,没有任何参数,而它的反汇编如下:

mov eax,dword ptr fs:[30]
movzx eax,byte ptr ds:[eax+2]
ret 

很简单的几句汇编,其中fs:[30]为:

eax=0
dword ptr fs:[00917030]=00914000
.text:763490F0 kernelbase.dll:$1290F0 #1284F0 <IsDebuggerPresent>

而ds:[eax+2]为:

eax=00914000
byte ptr ds:[eax+2]=[00914002]=1
.text:763490F6 kernelbase.dll:$1290F6 #1284F6

判断处的代码:

00272B70 | 56                         | push esi                            |
00272B71 | 8BF1                       | mov esi,ecx                         |
00272B73 | FF15 F4B33D00              | call dword ptr ds:[<&IsDebuggerPres |
00272B79 | 85C0                       | test eax,eax                        |
00272B7B | B9 04F14000                | mov ecx,test.40F104                 | 40F104:L"没有有调试器在调试!"
00272B80 | 6A 00                      | push 0                              |
00272B82 | BA F0F04000                | mov edx,test.40F0F0                 | 40F0F0:L"有调试器在调试!!"
00272B87 | 0F44D1                     | cmove edx,ecx                       |
00272B8A | 8BCE                       | mov ecx,esi                         |
00272B8C | 6A 00                      | push 0                              |
00272B8E | 52                         | push edx                            |
00272B8F | E8 E2950100                | call test.28C176                    |
00272B94 | 5E                         | pop esi                             |
00272B95 | C3                         | ret                                 |

本来的思想是在判断处做出改变,可是学识太浅没弄明白,倒是在IsDebuggerPresent函数中做出改变并且成功

在程序运行的时候,刚开始没想在IsDebuggerPresent上下手,所以略过了它研究它之后的代码
在研究这段代码时,我的第一反应说改test:
00272B79 | 85C0                       | test eax,eax                        |
00272B7B | B9 04F14000                | mov ecx,test.40F104                 | 40F104:L"没有有调试器在调试!"
00272B80 | 6A 00                      | push 0                              |
00272B82 | BA F0F04000                | mov edx,test.40F0F0                 | 40F0F0:L"有调试器在调试!!"
00272B87 | 0F44D1                     | cmove edx,ecx                       |


可是后来发现不行啊,eax我该成0也没有用,照样能检测到
然后就跟着eax向上走,发现在IsDebuggerPresent函数处eax就被赋值成1了
movzx eax,byte ptr ds:[eax+2]
eax=00914000
byte ptr ds:[eax+2]=[00914002]=1
.text:763490F6 kernelbase.dll:$1290F6 #1284F6
eax就是在这里被赋值变成1的,所以跟随eax的地址 ==>     00 00 01 04 FF FF FF FF 00 00 27 00 80 5D 64 77 
其中eax+2的地址值就是01,所以把01更改成00就可以了,这样IsDebuggerPresent的判断就失效了


版权声明:本文为weixin_41693985原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。