基于crc32实现的内存的代码校验
来源:互联网 发布:收益最多的理财软件 编辑:程序博客网 时间:2024/06/05 18:00
原理:
a,crc32函数的实现
b,内存校验:顾名思义,运行在内存代码通过crc32得到一个值,当第二次运行可执行文件的时候,可以把第一次保存下来的值和第二次运行的结果相比较,从而根据比较结果判断时候内存数据吧被修改。
1,crc32算法的实现部分:
DWORD CRC32(BYTE* ptr,DWORD Size){ DWORDcrcTable[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值 DWORDcrcTmp2= 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; DWORDdwCodeSize = stParam->dwEnd - stParam->dwStart; BYTE*pbyteBuf = NULL; pbyteBuf= (BYTE *)stParam->dwStart; DWORDdwOldProtect = 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下断点,然后就来到线程函数了。
一直往下找,找到比较代码cmpeax,0xa0eb5866这一句,把这个地址保存下来,就是我们要校验的地址。可以直接用在代码中。。
3,测试:
让debug版本的程序运行起来,ce附加进程。
点击Memory View,定位到我们要保护的代码段。
找到我们要保护的代码,然后用ce修改一下内存的数值试试,我想修改0x40127a。只要这个内存地址在我们要保护的代码中就可以。
哈哈哈,还不错吧。内存校验不难吧。
转自:http://bbs.pediy.com/showthread.php?t=140471
- 基于crc32实现的内存的代码校验
- VB的CRC32校验代码
- crc32校验的c语言实现
- CRC32校验的简单理解
- ITU-T I363.5 CRC32校验的C实现
- 循环冗余校验 CRC32 的 C 语言实现
- CRC32校验C代码
- java 实现CRC32校验
- java 实现CRC32校验
- java 实现CRC32校验
- CRC32校验C实现
- CRC32碰撞的实现
- CRC32碰撞的实现
- CRC32碰撞的实现
- 在VC中实现快速获取文件的CRC32校验值的方法
- CRC32校验算法-C实现
- CRC32校验原理及实现
- CRC32校验算法-C实现
- NYOJ-数的位数-69
- 关于WIN32 窗口信息的各种获取
- The Diffrerence 在 :map 和 :noremap 里 in VIM
- 当 IDENTITY_INSERT 设置为 OFF 时,不能为表中的标识列插入显式值
- 硬盘使用遇到的问题之一------插入没有显示
- 基于crc32实现的内存的代码校验
- VS2010全局配置
- NYOJ-开灯问题-77
- Servelt中的request.getAttribute(),request.getParameter()的区别
- poj3264线段树---区间最大最小值查询(RMQ)
- android 界面之 progressbar
- PHP抓取页面的几种方式
- 黑马程序员—交通灯管理系统
- Oracle远程连接sqlplus字符串