On-line patching в секретах и советах Крис касперски Хакер, номер #093, стр. 093-080-2 Мы будем действовать простым, но достаточно надежным путем, срабатывающим в 99,999% случаях – запускаем процесс, ждем несколько секунд пока оно там распаковывается, читаем память активного процесса, чтобы убедиться, что по данному адресу расположено то, что нам нужно (иначе ругаемся на неверную версию ломаемой программы), и "в живую" (без всякого наркоза) записываем сюда "исправленную" версию машинных команд. Возьмем, например, NtExplorer от RuntimeSoftware. С помощью PEiD убедимся, что он упакован ASPack 2.11c, а, значит, прямой bit-hack невозможен. Что же, поступим по другому! Снимаем с программы дамп, загружаем его в дизассемблер и по перекрестным ссылкам к строке "Thank you for licensing Runtime's DiskExplorer" выходим на следующий код: Фрагмент защитного механизма NtExporer'а 04E59DB call sub_4E55B0 04E59E0 test al, al 04E59E2 jz loc_4E5A37 ; —> облом с регистрацией 04E59E4 mov eax, dword_582CE8 04E59E9 mov b,[eax+10h], 1 04E59ED mov eax, dword_582CE8 04E59F2 call sub_4E53B8 ; запись данных в реестр 04E59F7 test al, al 04E59F9 jz loc_4E5A15 04E59FB push 0 04E59FD mov cx, word_4E5B08 04E5A04 mov dl, 2 04E5A06 mov eax,aThankYou;"Thank you for licensing…" Мы видим условный переход jz loc_4E5A37, "шунтирующий" вывод строки об успешной регистрации. Очевидно, что забив его двумя командами NOP (если только в программе не присутствует других проверок), мы сломаем защиту и тогда любой регистрационный номер будет восприниматься как правильный. Пишем "ломалку", алгоритм работы которой ясен из комментариев. NtExplorer.crack.c — простейшая on-line ломалка main(int c, char **v) { DWORD N; STARTUPINFO si; PROCESS_INFORMATION pi; unsigned char *buf; // данные для патча (пример) unsigned char x_old[] = {0x74,0x53}; // оригинальные байты unsigned char x_new[] = {0x90,0x90}; // хакаемые байты void* x_off = 0x04E59E2; // арес для хака memset(&si,0,sizeof(si));buf=malloc(sizeof(x_old)); // запуск процесса для взлома if (!CreateProcess(0,GetCommandLine()+strlen(v[0])+ ((GetCommandLine()[0]=='\"')?3:1),0,0,0,0,0,0,&si,&pi)) return printf("-ERR:run %s\x7\n",GetCommandLine()+strlen(v[0])+ ((GetCommandLine()[0]=='\"')?3:1)); // ждем завершения распаковки for (N=0;N<69;N++) {printf("pls,wait:%c\r","-\\|/"[N%4]); Sleep(100);} // начинаем патчить printf("ok, make patch\n"); // проверка версии ломаемой программы ReadProcessMemory(pi.hProcess, x_off, buf, sizeof(x_old), &N); if (N != sizeof(x_old)) return printf("-ERR:reading vm-memory!\x7\n"); if (memcmp(x_old,buf,sizeof(x_old))) return printf("-ERR:incorrect ver!\x7\n"); // падчим условный переход WriteProcessMemory(pi.hProcess, x_off,x_new,sizeof(x_new),&N); |