/* --------------------------------------------------------------------------- * демонстрация противодействия программным (CCh) точкам останова, * установленным на API функции, путем их копирования целиком в своей * локальный буфер ----------------------------------------------------------------------------*/ #include <stdio.h> #include <windows.h> #define Year_EXPIRED 2000 #define MAX_CODE_SIZE (69*1024) // ПРОСТЕЙШИЙ КОПИРОВЩИК API-ФУНКЦИЙ // ================================= // копирует всю функцию в свой локальный буфер целиком и возращает адрес // точки входа // // ARG: // p - указатль на API-функцию // dst - указатель на буфер куда копировать // (размер буфера должет составлять не менее 69 Кб) // // RET: // !NULL - указатель на точку входа // // NOTE: // 1) если программная точка останова на API функцию уже установлена, // то под отладчиком защищенное приложение просто грохнется void* ZenCpy(char *p, char *dst) { memcpy(dst, p - MAX_CODE_SIZE/2, MAX_CODE_SIZE); return dst + MAX_CODE_SIZE/2; } int main() { int a; HANDLE h; DWORD xl; HINSTANCE hdll; OVERLAPPED over; SYSTEMTIME SystemTime; // буфера для копирования начала API-функций HANDLE ZGetStdHandle[MAX_CODE_SIZE]; HANDLE ZGetLocalTime[MAX_CODE_SIZE]; HANDLE ZWriteConsole[MAX_CODE_SIZE]; // строка, которая будет выводится на экран ("trial expired\n") char EXPIRED[] = "\x12\x14\x0F\x07\x0A\x46\x03\x1E\x16\x0F\x14\x03\x02\x6B\x6C\x6B\x6C\x6B\x6C"; char s[]="*"; // объявляем указатели на динамически загружаемые фунции HANDLE(WINAPI *XGetStdHandle)(DWORD nStdHandle); void (WINAPI *XGetLocalTime)(LPSYSTEMTIME lpSystemTime); BOOL (WINAPI *XWriteConsole)(HANDLE hConsoleOutput, CONST VOID *lpBuffer, DWORD nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved); fprintf(stderr, "CopyAPI\n"); // ПОЛУЧАЕМ ОПИСАТЕЛЬ БИБЛИОТЕКИ KERNEL32.DLL // ========================================== // (это наиболее уязвимое место защиты и в реальных защитах лучше // использовать stealth-загрузку) hdll = LoadLibrary("KERNEL32.DLL"); if (!hdll) return 0; // ПОЛУЧАЕМ АДРЕСА НЕОБХОДИМЫХ ФУНКЦИЙ // ======================================================================= // (в реальных программах лучше использовать _собственную_ реализацию // GetProcAddress, иначе хакер вас быстро раскусит) XGetStdHandle = (HANDLE (WINAPI*)(DWORD nStdHandle)) GetProcAddress (hdll, "GetStdHandle"); if (!XGetStdHandle) return 0; XGetLocalTime = (void (WINAPI*)(LPSYSTEMTIME lpSystemTime)) GetProcAddress(hdll, "GetLocalTime"); if (!XGetLocalTime) return 0; XWriteConsole = (BOOL (WINAPI*)(HANDLE hConsoleOutput,CONST VOID *lpBuffer, DWORD nNumberOfCharsToWrite,LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)) GetProcAddress(hdll, "WriteConsoleA"); if (!XWriteConsole) return 0; // КОПИРУЕМ ФУНКЦИИ В СВОЙ ЛОКАЛЬНЫЙ БУФЕР // ======================================================================= XGetStdHandle = (HANDLE (WINAPI*)(DWORD nStdHandle)) ZenCpy((char *) XGetStdHandle, (char *)ZGetStdHandle); // обрабатываем GetLocalTime XGetLocalTime = (void (WINAPI*)(LPSYSTEMTIME lpSystemTime)) ZenCpy((char *) XGetLocalTime, (char *)ZGetLocalTime); // обрабатываем WriteConsoleA XWriteConsole = (BOOL (WINAPI*)(HANDLE hConsoleOutput, CONST VOID *lpBuffer, DWORD nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)) ZenCpy((char *) XWriteConsole, (char *)ZWriteConsole); // ДЕМОНСТРАЦИОННЫЙ ЗАЩИТНЫЙ МЕХАНИЗМ // ======================================================================= // получаем описатель консоли h = XGetStdHandle(STD_OUTPUT_HANDLE);//здесь получаем ошибку // опрашиваем текущее время XGetLocalTime(&SystemTime);//скорее всего и здесь будет ошибка // лицензия истекла? if ((SystemTime.wYear >= Year_EXPIRED)) { // расшифровываем строку и выводим ругательство на экран for (a = 0; a < strlen(EXPIRED); a++) { s[0] = (EXPIRED[a] ^ 0x66); XWriteConsole(h, &s[0], 1, &xl, &over); } // выходим exit(-1); } printf("OK\n"); } |