⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memcrc32.cpp

📁 此为本书的配套光盘.本书结合实例
💻 CPP
字号:
/*--------------------------------------------------------------
   memcrc32.cpp -- 内存映像校验,仅校验代码区块

                           (c) 段钢 www.pediy.com, 2003
  --------------------------------------------------------------*/

#include <windows.h>

DWORD CRC32(BYTE*,DWORD);
BOOL CodeSectionCRC32( );
	


int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
	
	if(CodeSectionCRC32())
		MessageBox(NULL,TEXT ("CRC32 Check OK!"),TEXT ("OK"),MB_ICONEXCLAMATION);
	else
    		MessageBox(NULL,"File corrupted! !","CRC error",MB_ICONEXCLAMATION);
	return 0;
}

////////////////////////////////////////////////////////////////
// 计算代码区块的CRC32值
//

BOOL CodeSectionCRC32( )
{

	DWORD fileSize,OriginalCRC32,NumberOfBytesRW;
	DWORD CodeSectionRVA,CodeSectionSize,NumberOfRvaAndSizes,DataDirectorySize,ImageBase;
	BYTE* pMZheader,pPEheaderRVA;
	TCHAR  *pBuffer ;
	TCHAR szFileName[MAX_PATH]; 

	GetModuleFileName(NULL,szFileName,MAX_PATH);
	//打开文件
	HANDLE hFile = CreateFile(
		szFileName,
		GENERIC_READ,
		FILE_SHARE_READ, 
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	 if ( hFile != INVALID_HANDLE_VALUE )
	 {

		//获得文件长度 :
		fileSize = GetFileSize(hFile,NULL);
		if (fileSize == 0xFFFFFFFF) return FALSE;

		pBuffer = new TCHAR [fileSize];     // 申请内存,也可用VirtualAlloc等函数申请内存
		ReadFile(hFile,pBuffer, fileSize, &NumberOfBytesRW, NULL);//读取文件内容
		CloseHandle(hFile);  //关闭文件
		
	 }
	 else
		 return FALSE;
	
	pMZheader=(BYTE*)pBuffer; //此时pMZheader指向文件头
	pPEheaderRVA = *(pMZheader+0x3c);//读3ch处的PE文件头指针
	//定位到PE文件头(即字串“PE\0\0”处)前4个字节处,并读出储存在这里的CRC-32值:
	OriginalCRC32 =*((DWORD *)(pMZheader+pPEheaderRVA-4));


	NumberOfRvaAndSizes=*((DWORD *)(pMZheader+pPEheaderRVA+0x74));//得到数据目录结构数量
	DataDirectorySize=NumberOfRvaAndSizes*0x8;//得到数据目录结构大小
	ImageBase=*((DWORD *)(pMZheader+pPEheaderRVA+0x34));//得到基地址
	
	/*
	//假设第一个区块就是代码区块
	CodeSectionRVA=*((DWORD *)(pMZheader+pPEheaderRVA+0x78+DataDirectorySize+0xc));//得到代码块的RVA值
	CodeSectionSize=*((DWORD *)(pMZheader+pPEheaderRVA+0x78+DataDirectorySize+0x8));//得到代码块的内存大小
	*/

	delete pBuffer;  // 释放内存


	//if(OriginalCRC32==CRC32((BYTE*)(CodeSectionRVA+ImageBase),CodeSectionSize)) //是从磁盘文件得到代码块的地址和大小来计算CRC32值
	//直接填上代码区块的地址和大小,方法是先随便填一数据,编译后用PE工具查看生成文件的代码区块的RVA和大小,再填进来重新编译
	if(OriginalCRC32==CRC32((BYTE*) 0x401000,0x29de)) 
		return TRUE;
	else
		return FALSE;
}



////////////////////////////////////////////////////////////////
// 计算字符串的CRC32值
// 参数:欲计算CRC32值字符串的首地址和大小
// 返回值: 返回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);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -