📄 memcrc32.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 + -