当前位置:专业知识首页 >> 网站安全 >> 并非万能的万能断点
并非万能的万能断点
2007-12-20 16:22:14  作者:  来源:互联网  浏览次数:71  文字大小:【】【】【
  •   关于万能断点的历史,应该从Windows98下的hMemcpy算起。它主要用于大块的内存复制操作。在Windows2000下没有此函数,这是大家都知道的,然而是否果然如此呢?hMemcpy究竟是何方神圣,为什么在Windows98能用作万能断点?小知识:hMe ...
关于万能断点的历史,应该从Windows98下的hMemcpy算起。它主要用于大块的内存复制操作。在Windows2000下没有此函数,这是大家都知道的,然而是否果然如此呢?hMemcpy究竟是何方神圣,为什么在Windows98能用作万能断点?
小知识:hMemcpy是16 bits windows里的一个函数,全名Huge Memory Copy,俗称万能断点,它的操作很简单,只是将内存中的一块数据拷贝到另一个地方(Memcpy也有此功能),Win9x系统里很频繁地调用它处理数据。在Win NT/2K系统上相关的函数是Memcpy,但在Windows NT/2000中很少再调用Memcpy来处理数据了,用此函数设断基本上什么也拦不住。
那么Windows 2000/Xp下所谓的万能断点又是什么呢?
搜索USER32.DLL中:F3 A5 8B C8 83 E1 03 F3 A4 E8,这就是Point H。或者搜索8B C1 C1 E9 02 F3 A5 8B C8 83 E1 03 F3 A4 E8。一旦找到,它返回位置地址,也就是说在内存拷贝之前(实际的操作:F9,在内存中搜索上述字符串)。
寻找Point H的另外一个方法:如果有USER32.DLL的符号文件(USER32.PDB或USER32.DBG),可以在IDA中打开USER32.DLL,适用PDB插件加载上面的符号,然后可以搜索函数ECGetText。它就是Point H,或者说是Windows 2000/Xp下的万能断点。
下面请和我一起来揭开万能断点神秘面纱,在头文件windowsx..h的1333行宏定义如下:“#define hMemcpy MoveMemory”
看来还要顺藤摸瓜,摸摸MoveMemory的底细。MoveMemory在MAPIWIN.H的141行的宏定义如下:“#define MoveMemory(pbDst,pbSrc,cb) MemMove((pbDst),(pbSrc),(cb))”
该函数看来要退出历史舞台了,大概是为了兼容,所以MS提供了上面的宏定义。下面我们来看看和万能断点仅仅一个字节之差的一段机器码(选自USER32.DLL)
77D19999 C1E9 02 SHR ECX,2
77D1999C F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
77D1999E 8BC8 MOV ECX,EAX
77D199A0 83E1 03 AND ECX,3
77D199A3 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
77D199A5 8B5D 0C MOV EBX,DWORD PTR SS:[EBP+C]

下面是万能断点的机器码,注意比较机器码的不同。(黑色标注)
77D33538 8BC1 MOV EAX,ECX
77D3353A C1E9 02 SHR ECX,2
从这里开始:
77D3353D F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
77D3353F 8BC8 MOV ECX,EAX
77D33541 83E1 03 AND ECX,3
77D33544 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
77D33546 E8 E3FBFFFF CALL USER32.77D3312E
其中F3:A5是Rep Movs的机器码,无论是Rep Movs 还是Rep Movsd,OllyDbg已经给出答案了。
其完整形式是:“REP MOVS DWORD PTR ES:[EDI], DWORD PTR ES:[ESI]”
黑色标识的小差别导致了最后一句汇编代码的巨大差异,所谓失之毫厘,差之前里。万能断点的代码看似为某一个函数作准备:CALL USER32.77D3312E,似乎该函数才是幕后主脑。但它好像没有公开,大家如果安装了WINDBG不妨看看。另外系统调用该函数非常频繁,下断点之后会不断中断。
下面MemMove一段反汇编代码,对比看看,注意标示的部分:
004010D8 C1 E9 02 shr ecx,2
004010DB 83 E2 03 and edx,3
004010DE 83 F9 08 cmp ecx,8
004010E1 72 29 jb CopyUnwindUp (0040110c)
004010E3 F3 A5 Rep Movs dword ptr [edi],dword ptr [esi]
这是巧合吗?我个人有理由相信,所谓的万能断点确实是Windows用于处理内存拷贝和内存移动用的一段机器码。
这里简单说点汇编知识:“Rep Movs dword ptr [edi],dword ptr [esi]”是用ecx作计数器,控制循环次数,其中[edi]和[esi]均是内存地址。前后跟踪(回溯)一段代码发现该段万能断点由EditWndProc调用,代码如下:
77D32FC1 FF75 10 PUSH DWORD PTR SS:[EBP+10]
77D32FC4 51 PUSH ECX
77D32FC5 56 PUSH ESI
77D32FC6 E8 0C000000 CALL USER32.EditWndProc
77D32FCB 5F POP EDI; 0012EFF4
77D32FCC 5E POP ESI
77D32FCD 5B POP EBX
77D32FCE 5D POP EBP
在MSDN里查不到该函数的信息,看来是一个内部函数(未文档化)。从名字上看,应该是处理窗口Edit框的。不过在OllyDbg中可以直接用该函数名下断点,从现在的分析来看,似乎万能断点只能用于窗口过程,换个控制台的程序试试看。
#include <windows.h>
#include <stdio.h>
#define SIZE 20
int main(int argc, char* argv[])
{
char regCode[SIZE];
printf("please in put regCode: ");
scanf("%s", regCode);
if (0 == strcmp(regCode, "ngaut"))
{
printf("\nright\n");
}
else
{
printf("wrong\n");
}
return 0;
}
编译成Release版,用OllyDbg加载,右键单击汇编区域。果然有发现,该程序竟然没用USER32.DLL模块,只有Kernel32和ntdll模块。
这就验证了我的推断(icefire:多么聪明的头脑,值得学习)。我们不妨进一步研究,看看Kernel32和ntdll模块是否也有万能断点,用同样的操作方法发现Kernel32和ntdll模块也有“万能断点”,但是该万能断点并不能中断,只是虚有其表,无论是控制台程序还是GUI程序。
现在大家应该明白了吧?所谓的万能断点并非万能,它仅仅能处理GUI程序中和EDIT相关的内存移动或者内存复制。 {tag_点击标签样式三}
相关文章
友情链接 | 诚聘英才 | 关于我们 | 版权声明 | 联系我们 | 广告服务


  • 三七互动
  •     津ICP备05013802号    Powered by Phpcms 2007