概述
对于之前的 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 反调试 和 代码上的实验所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复