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版权协议,转载请附上原文出处链接和本声明。