Немой укор за компьютерный хардкор Крис Касперски Спецвыпуск: Хакер, номер #048, стр. 048-058-7 } Откомпилировав файл обычным образом, зашифруй его по методике, описанной выше, и запусти на выполнение. Будем надеяться, что он заработает с первого раза. Проблемы обновления кода через интернет Техника самомодификации тесно связана с задачей автоматического обновления кода через интернет. Решение этой задачи требует обширных знаний и инженерного мышления. Вот неполный перечень подводных камней, с которыми нам придется столкнуться: - как встроить двоичный код в исполняемый файл? - как оповестить все экземпляры удаленной программы о факте обновления? - как защититься от поддельных обновлений? По-хорошему эта тема требует отдельной книги, здесь же мы лишь очертим проблему. Начнем с того, что концепции модульного и процедурного программирования (без которых сейчас никуда) нуждаются в определенных механизмах межпроцедурного взаимодействия. По меньшей мере, одна процедура должна уметь вызывать другую. Например: Что здесь неправильно? А вот что. Функция printf находится вне функции my_func, и ее адрес наперед неизвестен. В обычной жизни эту задачу решает линкер, однако мы же не собираемся встраивать его в обновляемую программу, верно? Поэтому необходимо разработать собственный механизм импорта/экспорта всех необходимых функций. В простейшем случае будет достаточно передать нашей функции указатели на все необходимые ей функции как аргументы, тогда она не будет привязана к своему местоположению в памяти и станет полностью перемещаема (см. рисунок 9). Глобальные и статические переменные и константные строки использовать запрещается (компилятор размещает их в другой секции). Также необходимо убедиться, что компилятор в порядке проявления собственной инициативы не впендюрил в код никакой отсебятины наподобие вызова функций, контролирующих границы стека на предмет переполнения. Впрочем, в большинстве случаев такая инициатива легко отключается через ключи командной строки, описанные в прилагаемой к компилятору документации. Откомпилировав полученный файл, мы должны скомпоновать его в 32-разрядный бинарник. Далеко не каждый линкер способен на такое, и зачастую двоичный код выдирается из исполняемого файла любым подручным HEX-редактором (например, тем же HIEW'ом). Теперь мы имеем готовый модуль обновления, имеем обновляемую программу. Остается только добавить первое ко второму. Поскольку Windows блокирует запись во все исполняющиеся в данный момент файлы, обновить сам себя файл не может и эту операцию приходится выполнять в несколько стадий. Сначала исполняемый файл, условно обозначенный нами как А, переименовывает себя в В (переименованию запущенных файлов Windows не мешает), затем файл B создает свою копию под именем A, дописывает модуль обновления в его конец как оверлей (более опытные хакеры могут скорректировать значение поля ImageSize), после чего завершает свое выполнение, передавая бразды правления файлу A, удаляющему временный файл B с диска. Разумеется, это не единственно возможная схема и, кстати говоря, далеко не самая лучшая из всех, но на первых порах сойдет и она. |