首页
社区
课程
招聘
[原创]基于crc32实现的内存的代码校验
发表于: 2011-9-23 01:31 14697

[原创]基于crc32实现的内存的代码校验

2011-9-23 01:31
14697
原理:a,crc32函数的实现
      b,内存校验:顾名思义,运行在内存代码通过crc32得到一个值,当第二次运行可执行文件的时候,可以把第一次保存下来的值和第二次运行的结果相比较,从而根据比较结果判断时候内存数据吧被修改。

1,crc32算法的实现部分:
DWORD CRC32(BYTE* ptr,DWORD Size)
{
   
        DWORD crcTable[256],crcTmp1;
       
        //动态生成CRC-32表
        for (int i=0; i<256; i++)
         {
                crcTmp1 = i;
                for (int j=8; j>0; j--)
                 {
                        if (crcTmp1&1) crcTmp1 = (crcTmp1 >> 1) ^ 0xEDB88320L;
                         else crcTmp1 >>= 1;
                }

                 crcTable[i] = crcTmp1;
         }
        //计算CRC32值
        DWORD crcTmp2= 0xFFFFFFFF;
        while(Size--)
        {
                crcTmp2 = ((crcTmp2>>8) & 0x00FFFFFF) ^ crcTable[ (crcTmp2^(*ptr)) & 0xFF ];
                ptr++;
        }
       
        return (crcTmp2^0xFFFFFFFF);
}
2,代码实现:
A,要保护的代码:
ProtectStart:   //要保护的代码的起始地址
        __asm
        {
               inc eax   //花指令
                   dec eax
                   push eax
                   pop eax
        }
start:
           HMODULE hMod = GetModuleHandle(NULL);//同样是花指令
           HMODULE hUser32 = LoadLibrary("user32.dll");
ProtectEnd:               //要保护代码的终结地址
           DWORD dwThreadId = 0;

           STBINGLEPARAM stParam = {0};
       stParam.hEvent = CreateEvent(NULL,FALSE,FALSE,"bingle");
          
           DWORD dwAddr = 0;  //一个缓存空间
           __asm mov eax,offset ProtectStart  //计算代码的起始地址
           __asm mov dwAddr,eax
           stParam.dwStart = dwAddr; //保存在我们自己定义的结构体里

       __asm mov eax,offset ProtectEnd //计算保护代码的结束地址,同样保存在自己定义的                   结构体里。
           __asm mov dwAddr,eax
           stParam.dwEnd = dwAddr;
          
           printf("开始了\n");
             CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)bingleProc,(LPVOID)&stParam,0,&dwThreadId);
B,创建了一个线程,用来计算校验值。并且将线程的创建放在循环中,这样保证在程序运行的过程中,会不断的监视内存的数据是否改变。
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)bingleProc,(LPVOID)&stParam,0,&dwThreadId);

           DWORD dwRet = 0;
           dwRet = WaitForSingleObject(stParam.hEvent,INFINITE);
           while(dwRet == WAIT_OBJECT_0)
           {
               Sleep(5000);
           CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)bingleProc,(LPVOID)&stParam,0,&dwThreadId);
                   dwRet = WaitForSingleObject(stParam.hEvent,INFINITE);
           }
上边的代码是创建线程的,根据创建线程的返回值来作为循环条件。其中stParam是我自定义结构体生成的一个对象。这个对象保存在堆栈中。该结构体的定义如下:
#pragma pack(1)
typedef struct __STBINGLEPARAM
{
  HANDLE hEvent;  //用于同步的一个信号量
  DWORD dwStart;  //要校验的代码的起始地址
  DWORD dwEnd;   //要校验的代码的终结地址
}STBINGLEPARAM,*PBINGLEPARAM;
#pragma pack()

接下来是是线程函数了。
STBINGLEPARAM *stParam = (STBINGLEPARAM *)lpParameter;
   
        DWORD dwCodeSize = stParam->dwEnd - stParam->dwStart;
        BYTE *pbyteBuf = NULL;
        pbyteBuf = (BYTE *)stParam->dwStart;
       
        DWORD dwOldProtect = 0;
        VirtualProtect((LPVOID)stParam->dwStart,4*1024,PAGE_EXECUTE_READWRITE,&dwOldProtect);
        if(CRC32(pbyteBuf,dwCodeSize) != 0xa0eb5866)
        {
           MessageBox(NULL,"bingle","代码被修改了",NULL);
           printf("代码被修改了\n");

           SetEvent(stParam->hEvent);
           ExitProcess(0);
        }

        SetEvent(stParam->hEvent); //执行完上边的代码开始传信,让主线程继续运行
在这里要说的是中的0xa0eb5866,这个是我在od中让代码运行起来找到的。
在创建的线程函数体中找到0x40100a,ctrl+g来到这个地址,F2下断点,然后就来到线程函数了。

一直往下找,找到比较代码cmp eax,0xa0eb5866这一句,把这个地址保存下来,就是我们要校验的地址。可以直接用在代码中。。

3,测试:
让debug版本的程序运行起来,ce附加进程。
点击Memory View,定位到我们要保护的代码段。

找到我们要保护的代码,然后用ce修改一下内存的数值试试,我想修改0x40127a。只要这个内存地址在我们要保护的代码中就可以。

哈哈哈,还不错吧。内存校验不难吧。。

明天要交作业。周围同学用java开发库的算法来做保护,说实话,俺不会。今晚做了个这个应付老师。大学的老师,哈哈。。。还是自学的好。。

[课程]Android-CTF解题方法汇总!

上传的附件:
收藏
免费 6
支持
分享
最新回复 (4)
雪    币: 27
活跃值: (90)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
2
不错,学习
2011-9-23 09:33
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
简单做个HASH也能达到你的要求了吧
2011-9-23 09:54
0
雪    币: 1392
活跃值: (4872)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
4
MARK一记。话说 有重定位的数据怎么办
2012-10-16 17:34
0
雪    币: 3020
活跃值: (3065)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
5
MARK 直接CRC 区段
2012-10-16 17:51
0
游客
登录 | 注册 方可回帖
返回
//