Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #93, СЕНТЯБРЬ 2006 г.

On-line patching в секретах и советах

Крис касперски

Хакер, номер #093, стр. 093-080-3


if (N != sizeof(x_new)) return printf("-ERR:writing vm-memory!\x7\n");

}

Запускаем NtExplorer.crack.c, указав имя ломаемой программы (вместе с аргументами, если они есть) в командной строке и при этом происходит следующее. ASPack распаковывает код и передает программе управление (наша ломалка все еще ждет), программа видит, что она нифига не зарегистрированная, а демонстрационный строк давно истек, вот и выбрасывает диалоговое окно с требованием ввести серийный номер. К этому времени терпение у нашей ломалки кончается и пока пользователь вводит первый, пришедший ему на ум, серийный номер, jz loc_4E5A37 успешно заменяется на NOP/NOP и при нажатии на OK, защита говорит "thanks" и продолжает выполнение программы в обычном режиме. Пользуйся — не хочу.

Естественно, при следующем запуске мерзкий диалог появится вновь, отвлекая нас от работы и заставляя вводить тупые серийные номера. А нельзя ли без этого как ни будь обойтись? Можно! И сейчас мы покажем как!

Циклотрон или гонки на опережение

Продолжая исследование программы, мы обнаруживаем пару любопытных команд: mov b,[eax+10h], 1/mov eax, dword_582CE8, очевидно, устанавливающих флаг регистрации (что легко проверить экспериментальным путем под отладчиком).

Идея! Чтобы доломать программу окончательно, необходимо установить флаг регистрации в единицу еще до того, как он будет прочитан. То есть опередить защиту! В старые время эта задача решалась пошаговой трассировкой, но теперь протекторы поумнели и просто так трассировать себя не дадут, однако, поскольку между распаковкой кода и передачей управления защите проходит какое-то время, мы вполне можем опередить защиту, если будем выполнять ReadProcessMemory/WriteProcessMemory в бесконечном цикле. Для надежности можно понизить приобретет ломаемого процесса, чтобы не давать ему слишком много квантов процессорного времени, однако, если слишком увлечься этим, распаковка может вообще никогда не завершиться. В большинстве случаев, для успешного взлома вообще не требуется никаких игр с приоритетами!

Вся сложность (в данном случае) в том, что местоположение флага регистрации заранее не определено. Мы знаем лишь то, что он хранится по смещению 10h от блока памяти, на который указывает двойное слово 582CE8h, инициализируемое по ходу выполнения программы. Следовательно, алгоритм наших действий будет таков: дожидаемся пока 582CE8h приобретает ненулевое значение и записываем по смещению 10h значение 01h, после чего выходим из "циклотрона" и позволяем программе продолжить свое выполнение, в заблуждении, что она успешно зарегистрирована:

Ключевой фрагмент NtExplorer.crack.cyclon.c

// ждем инициализации x_off

while(!x) ReadProcessMemory(pi.hProcess,(void*)x_off,&x,sizeof(x),&N);

// ждем инициализации флага регистрации и записи результатов проверки защиты

while(count++<100)

{

WriteProcessMemory(pi.hProcess,(void*)(x+x_idx),&foo,sizeof(foo),&N);

Sleep(1);

}

С "гонками" кода все понятно. Дождавшись совпадения хакаемого кода (что свидетельствует о завершении распаковки данной части), мы модифицируем его и отваливаем в return, поскольку никто другой модифицировать его не собирается (самомодифицирующиеся программы — не в счет, это тема для отдельного разговора).

Назад на стр. 093-080-2  Содержание  Вперед на стр. 093-080-4