Просто солью класс проверки целостности функций за неактуальностью в моих кругах. SecureContent.h #include <windows.h> #include <vector> static BYTE ContentPattern[42] = { 0xEB, 0x28, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; #define MARKER_NORM 0x90 #define POLY_SIZE 0x2A #define POLY_JUMP_DIST POLY_SIZE - 2 #define CONTENT_NORM \ __asm _emit 0xEB \ __asm _emit POLY_JUMP_DIST \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM #define PATTERN "x?xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" struct Content { DWORD StartPoint; size_t sizeofContent; void* Buffer; Content(DWORD _StartPoint, size_t _sizeofContent, void* _Buffer) : StartPoint(_StartPoint), sizeofContent(_sizeofContent), Buffer(_Buffer){ } }; class SecureContent { public: SecureContent(); bool Compare(const BYTE* pData, const BYTE* bMask, const char* szMask); DWORD FindPattern(DWORD dwAddress, DWORD dwLen, BYTE* bMask, char* szMask); Content GetContent(void* address); bool CompareContent(void* address, Content original); void FreeContentBuffer(Content content); ~SecureContent(); }; Code #include <windows.h> #include <vector> static BYTE ContentPattern[42] = { 0xEB, 0x28, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; #define MARKER_NORM 0x90 #define POLY_SIZE 0x2A #define POLY_JUMP_DIST POLY_SIZE - 2 #define CONTENT_NORM \ __asm _emit 0xEB \ __asm _emit POLY_JUMP_DIST \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM \ __asm _emit MARKER_NORM #define PATTERN "x?xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" struct Content { DWORD StartPoint; size_t sizeofContent; void* Buffer; Content(DWORD _StartPoint, size_t _sizeofContent, void* _Buffer) : StartPoint(_StartPoint), sizeofContent(_sizeofContent), Buffer(_Buffer){ } }; class SecureContent { public: SecureContent(); bool Compare(const BYTE* pData, const BYTE* bMask, const char* szMask); DWORD FindPattern(DWORD dwAddress, DWORD dwLen, BYTE* bMask, char* szMask); Content GetContent(void* address); bool CompareContent(void* address, Content original); void FreeContentBuffer(Content content); ~SecureContent(); }; SecureContent.cpp #include "SecureContent.h" SecureContent::SecureContent() { } bool SecureContent::Compare(const BYTE* pData, const BYTE* bMask, const char* szMask) { for (; *szMask; ++szMask, ++pData, ++bMask) if (*szMask == 'x' && *pData != *bMask) return false; return (*szMask) == NULL; } DWORD SecureContent::FindPattern(DWORD dwAddress, DWORD dwLen, BYTE* bMask, char* szMask) { for (DWORD i = 0; i < dwLen; i++) if (this->Compare((BYTE*)(dwAddress + i), bMask, szMask)) return (DWORD)(dwAddress + i); return NULL; } Content SecureContent::GetContent(void* address) { //ищим первый макрос DWORD dwStartContent = this->FindPattern(reinterpret_cast<DWORD>(address), POLY_SIZE, ContentPattern, (char*)PATTERN); //если нашло if (dwStartContent) { //Добавляем размер макроса dwStartContent += POLY_SIZE; //ищем второй макрос, конец контента DWORD dwEndContent = this->FindPattern(dwStartContent, POLY_SIZE, ContentPattern, (char*)PATTERN); //нашло конец контента if (dwEndContent) { //Размер контента DWORD offset_data = (dwEndContent - dwStartContent); //если >=1 if (offset_data >= 1) { //выделяем блок памяти размером в контент void* block = malloc(offset_data); //копируем контент в выделенную память memcpy(block, reinterpret_cast<void*>(dwStartContent), offset_data); //возвращаем структуру. return Content(dwStartContent, offset_data, block); } } } //Нуль return Content(NULL, NULL, NULL); } bool SecureContent::CompareContent(void* address, Content original) { //Получаем контент в режиме реального времени Content timeLine = this->GetContent(address); //Если контент реального времени прошел проверки if (timeLine.StartPoint && timeLine.sizeofContent && timeLine.Buffer) { //сравниваем память bool status = memcmp(timeLine.Buffer, original.Buffer, original.sizeofContent) == 0; //осовбождаем буфер this->FreeContentBuffer(timeLine); //возвращаем значение. return status; } return false; } void SecureContent::FreeContentBuffer(Content content) { if (content.Buffer) { free(content.Buffer); } } SecureContent::~SecureContent() { } Code #include "SecureContent.h" SecureContent::SecureContent() { } bool SecureContent::Compare(const BYTE* pData, const BYTE* bMask, const char* szMask) { for (; *szMask; ++szMask, ++pData, ++bMask) if (*szMask == 'x' && *pData != *bMask) return false; return (*szMask) == NULL; } DWORD SecureContent::FindPattern(DWORD dwAddress, DWORD dwLen, BYTE* bMask, char* szMask) { for (DWORD i = 0; i < dwLen; i++) if (this->Compare((BYTE*)(dwAddress + i), bMask, szMask)) return (DWORD)(dwAddress + i); return NULL; } Content SecureContent::GetContent(void* address) { //ищим первый макрос DWORD dwStartContent = this->FindPattern(reinterpret_cast<DWORD>(address), POLY_SIZE, ContentPattern, (char*)PATTERN); //если нашло if (dwStartContent) { //Добавляем размер макроса dwStartContent += POLY_SIZE; //ищем второй макрос, конец контента DWORD dwEndContent = this->FindPattern(dwStartContent, POLY_SIZE, ContentPattern, (char*)PATTERN); //нашло конец контента if (dwEndContent) { //Размер контента DWORD offset_data = (dwEndContent - dwStartContent); //если >=1 if (offset_data >= 1) { //выделяем блок памяти размером в контент void* block = malloc(offset_data); //копируем контент в выделенную память memcpy(block, reinterpret_cast<void*>(dwStartContent), offset_data); //возвращаем структуру. return Content(dwStartContent, offset_data, block); } } } //Нуль return Content(NULL, NULL, NULL); } bool SecureContent::CompareContent(void* address, Content original) { //Получаем контент в режиме реального времени Content timeLine = this->GetContent(address); //Если контент реального времени прошел проверки if (timeLine.StartPoint && timeLine.sizeofContent && timeLine.Buffer) { //сравниваем память bool status = memcmp(timeLine.Buffer, original.Buffer, original.sizeofContent) == 0; //осовбождаем буфер this->FreeContentBuffer(timeLine); //возвращаем значение. return status; } return false; } void SecureContent::FreeContentBuffer(Content content) { if (content.Buffer) { free(content.Buffer); } } SecureContent::~SecureContent() { } С чем это жевать? Пример использования #include <windows.h> #include <iostream> #include "SecureContent.h" void testContent() { CONTENT_NORM//макрос херачит буфер байт, для поиска начала контента int a = 4, b = 4; printf("content Test1: %d\n", a + b); printf("content Test2: %d\n", a * b); printf("content Test3: %d\n", a - b); CONTENT_NORM//конец контента. все что между двумя макросами является контентом который будет чекатся. } int main() { //Класс SecureContent ContentFree; //хапаем контент Content test = ContentFree.GetContent(&testContent); //дергаем адресс начала контента, чтобы пропатчить в се и проверить))) printf("content start address: 0x%X\n", test.StartPoint); system("pause"); //сравниваем контент if (ContentFree.CompareContent(&testContent, test)) { //совпал testContent(); //особождаем буфер ContentFree.FreeContentBuffer(test); } else { //Контент не совпал! printf("content no!\n"); } system("pause"); return 0; } Code #include <windows.h> #include <iostream> #include "SecureContent.h" void testContent() { CONTENT_NORM//макрос херачит буфер байт, для поиска начала контента int a = 4, b = 4; printf("content Test1: %d\n", a + b); printf("content Test2: %d\n", a * b); printf("content Test3: %d\n", a - b); CONTENT_NORM//конец контента. все что между двумя макросами является контентом который будет чекатся. } int main() { //Класс SecureContent ContentFree; //хапаем контент Content test = ContentFree.GetContent(&testContent); //дергаем адресс начала контента, чтобы пропатчить в се и проверить))) printf("content start address: 0x%X\n", test.StartPoint); system("pause"); //сравниваем контент if (ContentFree.CompareContent(&testContent, test)) { //совпал testContent(); //особождаем буфер ContentFree.FreeContentBuffer(test); } else { //Контент не совпал! printf("content no!\n"); } system("pause"); return 0; } Суть кода проста: делает дубликат участка кода, а после, сравнивает)) Что это значит? Это значит, что эта фича делает копию некого кода, которую потом, перед выполнением этого самого кода, можно сравнить и если этот самый код, целостность которого нужно проверять, не совпадает с скопированным кодом, это будет означать что он модифицирован, отладчиком на пример. И что же можно проверять спросите вы? на пример проверку лицензии в чите. если проверку лицензии пропатчили, это будет видно.
В чем проблема обойти это? делается элементарный хук в main перед началом всех функций. Не говорю уже о элементарном затирании этих маркеров проверки