我是靠谱客的博主 安详万宝路,最近开发中收集的这篇文章主要介绍windows 反调试 和 代码上的实验,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 

对于之前的 SEH ,MS 提供的一些反调试的函数,同样可以达到保护程序的目的, 对于反调试 ,我想,我们可以通过一些小实验来学习。 那么,首先,我们应该对 操作系统有一点了解,进程,当我们双击一个可执行文件时,程序运行在系统中,系统会为它产生一个进程,我们可以通过任务管理器来查看,当然,我们可以 Process.exe 这个工具来查看(内核调试 经常用),我们可以观察到 进程可以分成两种:1 系统级的(ring 0) 2;用户级的(ring 3),

通过,在每一个进程下,可能又有一个或若干个子进程,它们从父进程中继承一些属性,同时它们 有又自己的东西。

好了,现在我们知道了,一个程序时怎么样在系统的环境下运行的,我们可以开始对 反调试进行分析其原理了。

BOOL WINAPI IsDebuggerPresent(void); 是一个 MS 提供给我们检测 调试情况的函数,它有 IsDebuggerPresentW 和

IsDebuggerPresentA 两种, 刚开始学习 破解的时候,下断点 对这两种情况不是很清楚,现在可以比较清楚的分析他们

的不动点和产生的效果了。。。 首先,IsDebuggerPresentW 做为他们最终的调用者,换句话说,他能将 IsDebuggerPresent 产生的消息断下,无论是 UNICODE 还是 ASCII 的,这个有涉及一个字符的问题,好像是在 NT 架构以后,ms的

系统中对字符的处理,无论是使用 UNICODE 还是 ASCII 的,最后都会转换成 UNICODE,。

那好,下ASCII的函数断点有什么用呢?  我想,如果程序中运用到了 这样的函数时,它能比较准确的段在产生消息的地方,而不是经过处理后(也就是UNICODE--->ASCII)的过程后的地址;

好了,现在我们可以通过一个实验来验证一下。。。

我就写一个 MFC 的测试案例吧。。。

关键代码:

void CAnti1Dlg::OnBnClickedIsdebuggerpresent()

{

// TODO: Add your control notification handler code here if (IsDebuggerPresent())

{

MessageBox(NULL, TEXT("found"), NULL);

EndDialog(0);

}

else

{

MessageBox(NULL, TEXT("no found"), NULL);

}

}void CAnti1Dlg::OnBnClickedCheckremotedebuggerpresent()

{

// TODO: Add your control notification handler code here

HANDLE handle;

PBOOL pbDebuggerPresent = FALSE; handle = GetModuleHandle(NULL);

 

pbDebuggerPresent = (PBOOL)IsDebuggerPresent(); if (CheckRemoteDebuggerPresent(handle, pbDebuggerPresent))

{

MessageBox(NULL, TEXT("found"), NULL);

EndDialog(0);

}

else

{

MessageBox(NULL, TEXT("no found"), NULL);

}

}

1:  OD 不隐藏的时候, 运行程序。 "found" 程序发现了 调试器

2:  当隐藏后 没有发现。。

 

从上面的实验我们 应该好好的想想, 插件是怎么样骗过程序的检查的???

好,我们 跟踪一下程序。。

程序刚开始的地方:

00411BB3 > /E9 F8200000 jmp wWinMainCRTStartup-------------------------》》》》》》》》》》》Start

00411BB8 |E9 414B0000 jmp CRect::MoveToY

00411BBD |E9 B22F0000 jmp exit ; jmp to MSVCR90D.exit

00411BC2 |E9 B51E0000 jmp CDC::GetSafeHdc

00411BC7 |E9 994C0000 jmp CRect::operator-=

00411BCC |E9 D5910000 jmp _errno ; jmp to MSVCR90D._errno

00411BD1 |E9 C4830000 jmp CAtlAllocator::RemoveModule我们搜索: IsDebuggerPresent。。。

来到这里:

00415FB8 >- FF25 44584200 jmp dword ptr [<&KERNEL32.IsDebu>; kernel32.IsDebuggerPresent------------!!!!!!!

00415FBE >- FF25 F4574200 jmp dword ptr [<&KERNEL32.Interl>; kernel32.InterlockedExchange

00415FC4 >- FF25 8C574200 jmp dword ptr [<&KERNEL32.Sleep>>; kernel32.Sleep

00415FCA >- FF25 90574200 jmp dword ptr [<&KERNEL32.Interl>; kernel32.InterlockedCompareExchange

00415FD0 >- FF25 94574200 jmp dword ptr [<&KERNEL32.GetSta>; kernel32.GetStartupInfoW

00415FD6 >- FF25 98574200 jmp dword ptr [<&KERNEL32.SetUnh>; kernel32.SetUnhandledExceptionFilter

00415FDC >- FF25 9C574200 jmp dword ptr [<&KERNEL32.QueryP>; kernel32.QueryPerformanceCounter跟进这个 跳转看看它想干什么??、

7C813089 50 push eax

7C81308A FF15 F015807C call dword ptr [<&ntdll.NtQueryDe>; ntdll.ZwQueryDefaultUILanguage

7C813090 85C0 test eax, eax

7C813092 0F85 CD510300 jnz 7C848265

7C813098 66:8B45 FC mov ax, word ptr [ebp-4]

7C81309C C9 leave

7C81309D C3 retn

7C81309E 90 nop

7C81309F 90 nop

7C8130A0 90 nop

7C8130A1 90 nop

7C8130A2 90 nop

7C8130A3 > 64:A1 18000000 mov eax, dword ptr fs:[18] ; 来到这里

7C8130A9 8B40 30 mov eax, dword ptr [eax+30]

7C8130AC 0FB640 02 movzx eax, byte ptr [eax+2]

7C8130B0 C3 retn

7C8130B1 90 nop

。。。。知道了。。原来程序执行到这里,返回就 KO 了。。

那么我们可以不通过 插件,同样可以 patch 掉 它。。。实现山寨版 的隐藏功能,哈哈。。。

只要修改这一句就可以,当然没还可以修改别的。。

7C8130A3 > 64:A1 18000000 mov eax, dword ptr fs:[18] ; 来到这里

就它改为 ret 就搞定了。。。

太晚了,先睡觉再说。。。

 

反调试未完。。。。

 

 

 

 

 

 

 

最后

以上就是安详万宝路为你收集整理的windows 反调试 和 代码上的实验的全部内容,希望文章能够帮你解决windows 反调试 和 代码上的实验所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(74)

评论列表共有 0 条评论

立即
投稿
返回
顶部