C++CRC 32 를 사용 하여 메모리 이미지 의 완전 성 을 측정 하 는 절차

.text 코드 세그먼트 만 검사:
일반적인 프로그램 에는 적어도 코드 세그먼트,데이터 세그먼트 가 포함 되 어 있 지만 데이터 세그먼트 에 저 장 된 데 이 터 는 자주 변동 이 발생 합 니 다.예 를 들 어 우리 의 전체 변수,정적 변수 등 은 데이터 세그먼트 에 기본적으로 저장 되 고 코드 세그먼트 는 변화 가 발생 하지 않 습 니 다.우 리 는 검사 할 때'text 메모리 세그먼트 의 데이터 완전 성 을 중시 하면 됩 니 다.메모리 에 대한 검사 역시 디 버 거 의 CC 정지점 을 막 을 수 있 습 니 다.이 정지점 원 리 는 하단 에 int3 명령 을 기록 하 는 것 입 니 다.똑 같이 감지 할 수 있 습 니 다.

검사 방향 은 다음 과 같다.
1.우선 메모리 에서 PE 코드 바이트 의 RVA 와 바이트 크기 를 얻 습 니 다.
2.얻 은 RVA 와 마디 크기 에 따라 crc 32 또는 RC4 값 을 계산한다.
3.저 장 된 원본 CRC 32 값 을 읽 고 검사 결과 와 비교
1.먼저 첫 번 째 단 계 를 실현 하고 메모리 이미지 의 시작 주소 와 크기 를 읽 습 니 다.우 리 는 이렇게 할 수 있 습 니 다.

#include <stdio.h>
#include <windows.h>

int main(int argc, char *argv[])
{
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNtHeader = NULL;
	PIMAGE_SECTION_HEADER pSecHeader = NULL;
	DWORD ImageBase;

	//      
	ImageBase = (DWORD)GetModuleHandle(NULL);

	//    PE   
	pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;

	//    NT 
	pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader + pDosHeader->e_lfanew);

	//          ,           .text 
	pSecHeader = IMAGE_FIRST_SECTION(pNtHeader);

	//            
	DWORD va_base = ImageBase + pSecHeader->VirtualAddress;   //      va   
	DWORD sec_len = pSecHeader->Misc.VirtualSize;             //        
	
	printf("    (.text): %x -->     : %x 
", va_base, sec_len); system("pause"); return 0; }
2.두 번 째 부분 은 체크 섬 을 계산 한 다음 에 이 섹 션 의 CRC 32 값 을 계산 하고 전역 변 수 를 저장 하 는 것 입 니 다.즉,프로그램 이 열 린 후에 메모리 crc 32 값 을 계산 하고 전역 변수 에 넣 은 다음 에 스 레 드 를 열 어 3 초 에 한 번 씩 메모리 변 화 를 감지 하고 변화 하면 실행 이나 팝 업 창 알림 을 종료 합 니 다.PE 공백 위 치 를 미리 계산 해서 확인 하고 기록 할 수도 있 습 니 다.

#include <stdio.h>
#include <windows.h>

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);
}

//      CRC32   
DWORD CheckMemory()
{
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNtHeader = NULL;
	PIMAGE_SECTION_HEADER pSecHeader = NULL;
	DWORD ImageBase;

	//      
	ImageBase = (DWORD)GetModuleHandle(NULL);

	//    PE   
	pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
	pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader + pDosHeader->e_lfanew);

	//          ,           .text 
	pSecHeader = IMAGE_FIRST_SECTION(pNtHeader);
	DWORD va_base = ImageBase + pSecHeader->VirtualAddress;   //      va   
	DWORD sec_len = pSecHeader->Misc.VirtualSize;             //        
	//printf("    (.text): %x -->     : %x 
", va_base, sec_len); DWORD CheckCRC32 = CRC32((BYTE*)(va_base), sec_len); // printf(".text CRC32 = %x
", CheckCRC32); return CheckCRC32; } int main(int argc,char *argv[]) { // .text CRC32 DWORD OriginalCRC32 = 0; // , , CRC32 OriginalCRC32 = CheckMemory(); while (1) { Sleep(3000); DWORD NewCRC32 = CheckMemory(); if (OriginalCRC32 == NewCRC32) printf(" .
"); else printf("
"); } system("pause"); return 0; }

위의 코드 는 전체 프로그램 을 보호 하 는 것 입 니 다.실제 응용 에서 효율 을 높이 기 위해 서 는 그 중의 한 세 션 코드 만 보호 하면 됩 니 다.그러면 효율 을 높 일 수 있 습 니 다.모든 코드 를 조금 만 수정 하면 특정한 세 션 에 대한 메모리 검 사 를 실현 할 수 있 습 니 다.

#include <stdio.h>
#include <windows.h>

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);
}

//      CRC32   
DWORD CheckMemory(DWORD va_base, DWORD sec_len)
{
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNtHeader = NULL;
	PIMAGE_SECTION_HEADER pSecHeader = NULL;
	DWORD ImageBase;
	ImageBase = (DWORD)GetModuleHandle(NULL);
	pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
	pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader + pDosHeader->e_lfanew);

	//              
	// pSecHeader = IMAGE_FIRST_SECTION(pNtHeader);
	// DWORD va_base1 = ImageBase + pSecHeader->VirtualAddress;   //      va   
	// DWORD sec_len1 = pSecHeader->Misc.VirtualSize;             //        
	// printf("    (.text): %x -->     : %x 
", va_base1, sec_len1); DWORD CheckCRC32 = CRC32((BYTE*)(va_base), sec_len); return CheckCRC32; } int main(int argc, char *argv[]) { // .text CRC32 DWORD OriginalCRC32 = 0; DWORD begin_addr, end_addr, size; // __asm mov begin_addr, offset begin; __asm mov end_addr, offset end; // size = end_addr - begin_addr; // OriginalCRC32 = CheckMemory(begin_addr, size); while (1) { begin: // printf("hello lyshark
"); printf("hello lyshark
"); printf("hello lyshark
"); end: // if (OriginalCRC32 == CheckMemory(begin_addr, size)) printf("
"); else printf("
"); Sleep(3000); } system("pause"); return 0; }

디스크 검사 와 메모리 검사 두 가지 방식 을 결합 하여 종합 적 으로 보호 하면 소프트웨어 의 안전성 을 크게 향상 시 킬 수 있 습 니 다.돌아 가 는 방식 은 전역 변수 와 정확 한 값 으로 수정 하 는 곳 을 찾 으 면 됩 니 다.마찬가지 로 더욱 폭력 적 이 고 판단 조건 을 직접 바 꿀 수 있 습 니 다.
출처:https://www.cnblogs.com/lyshark
이상 은 C++에서 CRC 32 를 사용 하여 메모리 이미지 의 완전 성 을 측정 하 는 절차 에 대한 상세 한 내용 입 니 다.C++에서 CRC 32 로 메모리 이미지 의 완전 성 을 측정 하 는 데 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!

좋은 웹페이지 즐겨찾기