九天雁翎的博客
如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。 -- Paul Graham

通过全局变量和自擦除代码来防Dump(2)


通过全局变量和自擦除代码来防Dump(2)

write by 九天雁翎(JTianLing) -- www.jtianling.com

讨论新闻组及文件

通过全局变量和自擦除代码来防Dump 》中我提到了用WriteProcessMemory来完成代码段的自擦除,其实这并不是什么好的手段,因为使用了Win32 API,对于分析你代码的人来说,这是明摆着告诉对方你要干什么,破解手段在原文中也提到了不少。其实,当时我去搜寻WriteMemroy API但是并不存在的时候,我就在想,为什么微软不提供,并且,同样的,有ReadProcessMemory但是有ReadMemory,为什么要使用的时候都需要通过GetCurrentProcess()作为第一参数这样奇怪的形式,这个MS一贯的作风不符。这两个函数只在WinCE中有提供,普通Windows并没有,其实后来仔细想想就想通了,因为读写另外的进程的内存你必须要通过额外API,所以有这样的API给你来使用,但是读写自己的内存根本就不需要别的特殊的API,自己进程访问和改写自己进程中的数据是没有限制的。因此,需要做自擦除的操作仅仅需要memcpy或者memset就可以了!

下面是改进的示例:

 1 #include "windows.h"
 2 #include "tchar.h"
 3
 4 void Run()
 5 {
 6     // begin of the func
 7     DWORD ldwBegin = 0;
 8     __asm
 9     {
10         call $+5
11         pop eax
12         mov ldwBegin, eax
13     }
14     DWORD ldwOldPro = 0;
15     // Must have this step
16     if(!VirtualProtect((void*)ldwBegin, 1000, PAGE_EXECUTE_READWRITE, &ldwOldPro))
17     {
18         printf( "VirtualProtectEx failed (%d)./n", GetLastError() );
19         return;
20     }
21
22     MessageBox(NULL, _T("Right"), _T("Hello World"), MB_OK);
23
24         // begin of the func
25     DWORD ldwEnd = 0;
26     __asm
27     {
28         call $+5
29         pop eax
30         mov ldwEnd, eax
31     }
32
33     DWORD ldwFuncLen = ldwEnd - ldwBegin;
34     BYTE *lpbyRand = new BYTE[ldwFuncLen];
35
36     DWORD ldwWritten = 0;
37     memcpy((void*)ldwBegin, lpbyRand, ldwFuncLen);
38
39     delete[] lpbyRand;
40 }
41
42 int main(int argc, char* argv[])
43 {
44     Run();
45     MessageBox(NULL, _T("OK"), _T("OK"), MB_OK);
46
47     return 0;
48 }
49
50

 

这样做后,就没有办法简单的将memcpy挂上使其无效化来使得擦除无效,而且,从发现你的目的的难度上来讲也更加大一些,毕竟memcpy这种函数使用的频率太高了,你可能因为各种原因使用它,而不仅仅是反Dump的目的。这也加大了分析的难度:)

 

 

 

 

 

write by 九天雁翎(JTianLing) -- www.jtianling.com

 

分类:  未分类 
标签:  防Dump 

Posted By 九天雁翎 at 九天雁翎的博客 on 2009年02月09日

前一篇: 通过全局变量和自擦除代码来防Dump 后一篇: 潜心开始学习网络编程的第一步 ,UNP(Unix Network Programming)第一章,时间服务器到windows的移植